PR target/18668
[official-gcc.git] / gcc / config / i386 / i386.md
blobe168d112933e713cdf23b47eb5499c8499aaaf96
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, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, 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)
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_FIX_NOTRUNC          31)
88    (UNSPEC_MASKMOV              32)
89    (UNSPEC_MOVMSK               33)
90    (UNSPEC_MOVNT                34)
91    (UNSPEC_MOVA                 38)
92    (UNSPEC_MOVU                 39)
93    (UNSPEC_SHUFFLE              41)
94    (UNSPEC_RCP                  42)
95    (UNSPEC_RSQRT                43)
96    (UNSPEC_SFENCE               44)
97    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
98    (UNSPEC_PAVGUSB              49)
99    (UNSPEC_PFRCP                50)
100    (UNSPEC_PFRCPIT1             51)
101    (UNSPEC_PFRCPIT2             52)
102    (UNSPEC_PFRSQRT              53)
103    (UNSPEC_PFRSQIT1             54)
104    (UNSPEC_PSHUFLW              55)
105    (UNSPEC_PSHUFHW              56)
106    (UNSPEC_MFENCE               59)
107    (UNSPEC_LFENCE               60)
108    (UNSPEC_PSADBW               61)
109    (UNSPEC_ADDSUB               71)
110    (UNSPEC_HADD                 72)
111    (UNSPEC_HSUB                 73)
112    (UNSPEC_MOVSHDUP             74)
113    (UNSPEC_MOVSLDUP             75)
114    (UNSPEC_LDQQU                76)
115    (UNSPEC_MOVDDUP              77)
117    ; x87 Floating point
118    (UNSPEC_FPATAN               65)
119    (UNSPEC_FYL2X                66)
120    (UNSPEC_FYL2XP1              67)
121    (UNSPEC_FRNDINT              68)
122    (UNSPEC_F2XM1                69)
124    ; x87 Double output FP
125    (UNSPEC_SINCOS_COS           80)
126    (UNSPEC_SINCOS_SIN           81)
127    (UNSPEC_TAN_ONE              82)
128    (UNSPEC_TAN_TAN              83)
129    (UNSPEC_XTRACT_FRACT         84)
130    (UNSPEC_XTRACT_EXP           85)
131    (UNSPEC_FSCALE_FRACT         86)
132    (UNSPEC_FSCALE_EXP           87)
133    (UNSPEC_FPREM_F              88)
134    (UNSPEC_FPREM_U              89)
135    (UNSPEC_FPREM1_F             90)
136    (UNSPEC_FPREM1_U             91)
138    ; x87 Rounding
139    (UNSPEC_FRNDINT_FLOOR        96)
140    (UNSPEC_FRNDINT_CEIL         97)
141    (UNSPEC_FRNDINT_TRUNC        98)
142    (UNSPEC_FRNDINT_MASK_PM      99)
144    ; REP instruction
145    (UNSPEC_REP                  75)
147    (UNSPEC_EH_RETURN            76)
149    (UNSPEC_COPYSIGN             100)
150   ])
152 (define_constants
153   [(UNSPECV_BLOCKAGE            0)
154    (UNSPECV_STACK_PROBE         10)
155    (UNSPECV_EMMS                31)
156    (UNSPECV_LDMXCSR             37)
157    (UNSPECV_STMXCSR             40)
158    (UNSPECV_FEMMS               46)
159    (UNSPECV_CLFLUSH             57)
160    (UNSPECV_ALIGN               68)
161    (UNSPECV_MONITOR             69)
162    (UNSPECV_MWAIT               70)
163   ])
165 ;; Registers by name.
166 (define_constants
167   [(BP_REG                       6)
168    (SP_REG                       7)
169    (FLAGS_REG                   17)
170    (FPSR_REG                    18)
171    (DIRFLAG_REG                 19)
172   ])
174 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
175 ;; from i386.c.
177 ;; In C guard expressions, put expressions which may be compile-time
178 ;; constants first.  This allows for better optimization.  For
179 ;; example, write "TARGET_64BIT && reload_completed", not
180 ;; "reload_completed && TARGET_64BIT".
183 ;; Processor type.  This attribute must exactly match the processor_type
184 ;; enumeration in i386.h.
185 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
186   (const (symbol_ref "ix86_tune")))
188 ;; A basic instruction type.  Refinements due to arguments to be
189 ;; provided in other attributes.
190 (define_attr "type"
191   "other,multi,
192    alu,alu1,negnot,imov,imovx,lea,
193    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
194    icmp,test,ibr,setcc,icmov,
195    push,pop,call,callv,leave,
196    str,cld,
197    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
198    sselog,sselog1,sseiadd,sseishft,sseimul,
199    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
200    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
201   (const_string "other"))
203 ;; Main data type used by the insn
204 (define_attr "mode"
205   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
206   (const_string "unknown"))
208 ;; The CPU unit operations uses.
209 (define_attr "unit" "integer,i387,sse,mmx,unknown"
210   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
211            (const_string "i387")
212          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
213                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
214            (const_string "sse")
215          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
216            (const_string "mmx")
217          (eq_attr "type" "other")
218            (const_string "unknown")]
219          (const_string "integer")))
221 ;; The (bounding maximum) length of an instruction immediate.
222 (define_attr "length_immediate" ""
223   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
224            (const_int 0)
225          (eq_attr "unit" "i387,sse,mmx")
226            (const_int 0)
227          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
228                           imul,icmp,push,pop")
229            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
230          (eq_attr "type" "imov,test")
231            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
232          (eq_attr "type" "call")
233            (if_then_else (match_operand 0 "constant_call_address_operand" "")
234              (const_int 4)
235              (const_int 0))
236          (eq_attr "type" "callv")
237            (if_then_else (match_operand 1 "constant_call_address_operand" "")
238              (const_int 4)
239              (const_int 0))
240          ;; We don't know the size before shorten_branches.  Expect
241          ;; the instruction to fit for better scheduling.
242          (eq_attr "type" "ibr")
243            (const_int 1)
244          ]
245          (symbol_ref "/* Update immediate_length and other attributes! */
246                       abort(),1")))
248 ;; The (bounding maximum) length of an instruction address.
249 (define_attr "length_address" ""
250   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
251            (const_int 0)
252          (and (eq_attr "type" "call")
253               (match_operand 0 "constant_call_address_operand" ""))
254              (const_int 0)
255          (and (eq_attr "type" "callv")
256               (match_operand 1 "constant_call_address_operand" ""))
257              (const_int 0)
258          ]
259          (symbol_ref "ix86_attr_length_address_default (insn)")))
261 ;; Set when length prefix is used.
262 (define_attr "prefix_data16" ""
263   (if_then_else (ior (eq_attr "mode" "HI")
264                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
265     (const_int 1)
266     (const_int 0)))
268 ;; Set when string REP prefix is used.
269 (define_attr "prefix_rep" "" 
270   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
271     (const_int 1)
272     (const_int 0)))
274 ;; Set when 0f opcode prefix is used.
275 (define_attr "prefix_0f" ""
276   (if_then_else 
277     (ior (eq_attr "type" "imovx,setcc,icmov")
278          (eq_attr "unit" "sse,mmx"))
279     (const_int 1)
280     (const_int 0)))
282 ;; Set when REX opcode prefix is used.
283 (define_attr "prefix_rex" ""
284   (cond [(and (eq_attr "mode" "DI")
285               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
286            (const_int 1)
287          (and (eq_attr "mode" "QI")
288               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
289                   (const_int 0)))
290            (const_int 1)
291          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
292              (const_int 0))
293            (const_int 1)
294         ]
295         (const_int 0)))
297 ;; Set when modrm byte is used.
298 (define_attr "modrm" ""
299   (cond [(eq_attr "type" "str,cld,leave")
300            (const_int 0)
301          (eq_attr "unit" "i387")
302            (const_int 0)
303          (and (eq_attr "type" "incdec")
304               (ior (match_operand:SI 1 "register_operand" "")
305                    (match_operand:HI 1 "register_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "push")
308               (not (match_operand 1 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "pop")
311               (not (match_operand 0 "memory_operand" "")))
312            (const_int 0)
313          (and (eq_attr "type" "imov")
314               (and (match_operand 0 "register_operand" "")
315                    (match_operand 1 "immediate_operand" "")))
316            (const_int 0)
317          (and (eq_attr "type" "call")
318               (match_operand 0 "constant_call_address_operand" ""))
319              (const_int 0)
320          (and (eq_attr "type" "callv")
321               (match_operand 1 "constant_call_address_operand" ""))
322              (const_int 0)
323          ]
324          (const_int 1)))
326 ;; The (bounding maximum) length of an instruction in bytes.
327 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
328 ;; Later we may want to split them and compute proper length as for
329 ;; other insns.
330 (define_attr "length" ""
331   (cond [(eq_attr "type" "other,multi,fistp,frndint")
332            (const_int 16)
333          (eq_attr "type" "fcmp")
334            (const_int 4)
335          (eq_attr "unit" "i387")
336            (plus (const_int 2)
337                  (plus (attr "prefix_data16")
338                        (attr "length_address")))]
339          (plus (plus (attr "modrm")
340                      (plus (attr "prefix_0f")
341                            (plus (attr "prefix_rex")
342                                  (const_int 1))))
343                (plus (attr "prefix_rep")
344                      (plus (attr "prefix_data16")
345                            (plus (attr "length_immediate")
346                                  (attr "length_address")))))))
348 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
349 ;; `store' if there is a simple memory reference therein, or `unknown'
350 ;; if the instruction is complex.
352 (define_attr "memory" "none,load,store,both,unknown"
353   (cond [(eq_attr "type" "other,multi,str")
354            (const_string "unknown")
355          (eq_attr "type" "lea,fcmov,fpspc,cld")
356            (const_string "none")
357          (eq_attr "type" "fistp,leave")
358            (const_string "both")
359          (eq_attr "type" "frndint")
360            (const_string "load")
361          (eq_attr "type" "push")
362            (if_then_else (match_operand 1 "memory_operand" "")
363              (const_string "both")
364              (const_string "store"))
365          (eq_attr "type" "pop")
366            (if_then_else (match_operand 0 "memory_operand" "")
367              (const_string "both")
368              (const_string "load"))
369          (eq_attr "type" "setcc")
370            (if_then_else (match_operand 0 "memory_operand" "")
371              (const_string "store")
372              (const_string "none"))
373          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
374            (if_then_else (ior (match_operand 0 "memory_operand" "")
375                               (match_operand 1 "memory_operand" ""))
376              (const_string "load")
377              (const_string "none"))
378          (eq_attr "type" "ibr")
379            (if_then_else (match_operand 0 "memory_operand" "")
380              (const_string "load")
381              (const_string "none"))
382          (eq_attr "type" "call")
383            (if_then_else (match_operand 0 "constant_call_address_operand" "")
384              (const_string "none")
385              (const_string "load"))
386          (eq_attr "type" "callv")
387            (if_then_else (match_operand 1 "constant_call_address_operand" "")
388              (const_string "none")
389              (const_string "load"))
390          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (and (match_operand 0 "memory_operand" "")
394               (match_operand 1 "memory_operand" ""))
395            (const_string "both")
396          (match_operand 0 "memory_operand" "")
397            (const_string "store")
398          (match_operand 1 "memory_operand" "")
399            (const_string "load")
400          (and (eq_attr "type"
401                  "!alu1,negnot,ishift1,
402                    imov,imovx,icmp,test,
403                    fmov,fcmp,fsgn,
404                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
405                    mmx,mmxmov,mmxcmp,mmxcvt")
406               (match_operand 2 "memory_operand" ""))
407            (const_string "load")
408          (and (eq_attr "type" "icmov")
409               (match_operand 3 "memory_operand" ""))
410            (const_string "load")
411         ]
412         (const_string "none")))
414 ;; Indicates if an instruction has both an immediate and a displacement.
416 (define_attr "imm_disp" "false,true,unknown"
417   (cond [(eq_attr "type" "other,multi")
418            (const_string "unknown")
419          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
420               (and (match_operand 0 "memory_displacement_operand" "")
421                    (match_operand 1 "immediate_operand" "")))
422            (const_string "true")
423          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
424               (and (match_operand 0 "memory_displacement_operand" "")
425                    (match_operand 2 "immediate_operand" "")))
426            (const_string "true")
427         ]
428         (const_string "false")))
430 ;; Indicates if an FP operation has an integer source.
432 (define_attr "fp_int_src" "false,true"
433   (const_string "false"))
435 ;; Defines rounding mode of an FP operation.
437 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
438   (const_string "any"))
440 ;; Describe a user's asm statement.
441 (define_asm_attributes
442   [(set_attr "length" "128")
443    (set_attr "type" "multi")])
445 ;; All x87 floating point modes
446 (define_mode_macro X87MODEF [SF DF XF])
448 ;; All integer modes handled by x87 fisttp operator.
449 (define_mode_macro X87MODEI [HI SI DI])
451 ;; All integer modes handled by integer x87 operators.
452 (define_mode_macro X87MODEI12 [HI SI])
454 ;; All SSE floating point modes
455 (define_mode_macro SSEMODEF [SF DF])
457 ;; All integer modes handled by SSE cvtts?2si* operators.
458 (define_mode_macro SSEMODEI24 [SI DI])
461 ;; Scheduling descriptions
463 (include "pentium.md")
464 (include "ppro.md")
465 (include "k6.md")
466 (include "athlon.md")
469 ;; Operand and operator predicates
471 (include "predicates.md")
474 ;; Compare instructions.
476 ;; All compare insns have expanders that save the operands away without
477 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
478 ;; after the cmp) will actually emit the cmpM.
480 (define_expand "cmpdi"
481   [(set (reg:CC FLAGS_REG)
482         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
483                     (match_operand:DI 1 "x86_64_general_operand" "")))]
484   ""
486   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
487     operands[0] = force_reg (DImode, operands[0]);
488   ix86_compare_op0 = operands[0];
489   ix86_compare_op1 = operands[1];
490   DONE;
493 (define_expand "cmpsi"
494   [(set (reg:CC FLAGS_REG)
495         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
496                     (match_operand:SI 1 "general_operand" "")))]
497   ""
499   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
500     operands[0] = force_reg (SImode, operands[0]);
501   ix86_compare_op0 = operands[0];
502   ix86_compare_op1 = operands[1];
503   DONE;
506 (define_expand "cmphi"
507   [(set (reg:CC FLAGS_REG)
508         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
509                     (match_operand:HI 1 "general_operand" "")))]
510   ""
512   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
513     operands[0] = force_reg (HImode, operands[0]);
514   ix86_compare_op0 = operands[0];
515   ix86_compare_op1 = operands[1];
516   DONE;
519 (define_expand "cmpqi"
520   [(set (reg:CC FLAGS_REG)
521         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
522                     (match_operand:QI 1 "general_operand" "")))]
523   "TARGET_QIMODE_MATH"
525   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
526     operands[0] = force_reg (QImode, operands[0]);
527   ix86_compare_op0 = operands[0];
528   ix86_compare_op1 = operands[1];
529   DONE;
532 (define_insn "cmpdi_ccno_1_rex64"
533   [(set (reg FLAGS_REG)
534         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
535                  (match_operand:DI 1 "const0_operand" "n,n")))]
536   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
537   "@
538    test{q}\t{%0, %0|%0, %0}
539    cmp{q}\t{%1, %0|%0, %1}"
540   [(set_attr "type" "test,icmp")
541    (set_attr "length_immediate" "0,1")
542    (set_attr "mode" "DI")])
544 (define_insn "*cmpdi_minus_1_rex64"
545   [(set (reg FLAGS_REG)
546         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
547                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
548                  (const_int 0)))]
549   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
550   "cmp{q}\t{%1, %0|%0, %1}"
551   [(set_attr "type" "icmp")
552    (set_attr "mode" "DI")])
554 (define_expand "cmpdi_1_rex64"
555   [(set (reg:CC FLAGS_REG)
556         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
557                     (match_operand:DI 1 "general_operand" "")))]
558   "TARGET_64BIT"
559   "")
561 (define_insn "cmpdi_1_insn_rex64"
562   [(set (reg FLAGS_REG)
563         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
564                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
565   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
566   "cmp{q}\t{%1, %0|%0, %1}"
567   [(set_attr "type" "icmp")
568    (set_attr "mode" "DI")])
571 (define_insn "*cmpsi_ccno_1"
572   [(set (reg FLAGS_REG)
573         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
574                  (match_operand:SI 1 "const0_operand" "n,n")))]
575   "ix86_match_ccmode (insn, CCNOmode)"
576   "@
577    test{l}\t{%0, %0|%0, %0}
578    cmp{l}\t{%1, %0|%0, %1}"
579   [(set_attr "type" "test,icmp")
580    (set_attr "length_immediate" "0,1")
581    (set_attr "mode" "SI")])
583 (define_insn "*cmpsi_minus_1"
584   [(set (reg FLAGS_REG)
585         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
586                            (match_operand:SI 1 "general_operand" "ri,mr"))
587                  (const_int 0)))]
588   "ix86_match_ccmode (insn, CCGOCmode)"
589   "cmp{l}\t{%1, %0|%0, %1}"
590   [(set_attr "type" "icmp")
591    (set_attr "mode" "SI")])
593 (define_expand "cmpsi_1"
594   [(set (reg:CC FLAGS_REG)
595         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
596                     (match_operand:SI 1 "general_operand" "ri,mr")))]
597   ""
598   "")
600 (define_insn "*cmpsi_1_insn"
601   [(set (reg FLAGS_REG)
602         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
603                  (match_operand:SI 1 "general_operand" "ri,mr")))]
604   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
605     && ix86_match_ccmode (insn, CCmode)"
606   "cmp{l}\t{%1, %0|%0, %1}"
607   [(set_attr "type" "icmp")
608    (set_attr "mode" "SI")])
610 (define_insn "*cmphi_ccno_1"
611   [(set (reg FLAGS_REG)
612         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
613                  (match_operand:HI 1 "const0_operand" "n,n")))]
614   "ix86_match_ccmode (insn, CCNOmode)"
615   "@
616    test{w}\t{%0, %0|%0, %0}
617    cmp{w}\t{%1, %0|%0, %1}"
618   [(set_attr "type" "test,icmp")
619    (set_attr "length_immediate" "0,1")
620    (set_attr "mode" "HI")])
622 (define_insn "*cmphi_minus_1"
623   [(set (reg FLAGS_REG)
624         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
625                            (match_operand:HI 1 "general_operand" "ri,mr"))
626                  (const_int 0)))]
627   "ix86_match_ccmode (insn, CCGOCmode)"
628   "cmp{w}\t{%1, %0|%0, %1}"
629   [(set_attr "type" "icmp")
630    (set_attr "mode" "HI")])
632 (define_insn "*cmphi_1"
633   [(set (reg FLAGS_REG)
634         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
635                  (match_operand:HI 1 "general_operand" "ri,mr")))]
636   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
637    && ix86_match_ccmode (insn, CCmode)"
638   "cmp{w}\t{%1, %0|%0, %1}"
639   [(set_attr "type" "icmp")
640    (set_attr "mode" "HI")])
642 (define_insn "*cmpqi_ccno_1"
643   [(set (reg FLAGS_REG)
644         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
645                  (match_operand:QI 1 "const0_operand" "n,n")))]
646   "ix86_match_ccmode (insn, CCNOmode)"
647   "@
648    test{b}\t{%0, %0|%0, %0}
649    cmp{b}\t{$0, %0|%0, 0}"
650   [(set_attr "type" "test,icmp")
651    (set_attr "length_immediate" "0,1")
652    (set_attr "mode" "QI")])
654 (define_insn "*cmpqi_1"
655   [(set (reg FLAGS_REG)
656         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
657                  (match_operand:QI 1 "general_operand" "qi,mq")))]
658   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
659     && ix86_match_ccmode (insn, CCmode)"
660   "cmp{b}\t{%1, %0|%0, %1}"
661   [(set_attr "type" "icmp")
662    (set_attr "mode" "QI")])
664 (define_insn "*cmpqi_minus_1"
665   [(set (reg FLAGS_REG)
666         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
667                            (match_operand:QI 1 "general_operand" "qi,mq"))
668                  (const_int 0)))]
669   "ix86_match_ccmode (insn, CCGOCmode)"
670   "cmp{b}\t{%1, %0|%0, %1}"
671   [(set_attr "type" "icmp")
672    (set_attr "mode" "QI")])
674 (define_insn "*cmpqi_ext_1"
675   [(set (reg FLAGS_REG)
676         (compare
677           (match_operand:QI 0 "general_operand" "Qm")
678           (subreg:QI
679             (zero_extract:SI
680               (match_operand 1 "ext_register_operand" "Q")
681               (const_int 8)
682               (const_int 8)) 0)))]
683   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
684   "cmp{b}\t{%h1, %0|%0, %h1}"
685   [(set_attr "type" "icmp")
686    (set_attr "mode" "QI")])
688 (define_insn "*cmpqi_ext_1_rex64"
689   [(set (reg FLAGS_REG)
690         (compare
691           (match_operand:QI 0 "register_operand" "Q")
692           (subreg:QI
693             (zero_extract:SI
694               (match_operand 1 "ext_register_operand" "Q")
695               (const_int 8)
696               (const_int 8)) 0)))]
697   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
698   "cmp{b}\t{%h1, %0|%0, %h1}"
699   [(set_attr "type" "icmp")
700    (set_attr "mode" "QI")])
702 (define_insn "*cmpqi_ext_2"
703   [(set (reg FLAGS_REG)
704         (compare
705           (subreg:QI
706             (zero_extract:SI
707               (match_operand 0 "ext_register_operand" "Q")
708               (const_int 8)
709               (const_int 8)) 0)
710           (match_operand:QI 1 "const0_operand" "n")))]
711   "ix86_match_ccmode (insn, CCNOmode)"
712   "test{b}\t%h0, %h0"
713   [(set_attr "type" "test")
714    (set_attr "length_immediate" "0")
715    (set_attr "mode" "QI")])
717 (define_expand "cmpqi_ext_3"
718   [(set (reg:CC FLAGS_REG)
719         (compare:CC
720           (subreg:QI
721             (zero_extract:SI
722               (match_operand 0 "ext_register_operand" "")
723               (const_int 8)
724               (const_int 8)) 0)
725           (match_operand:QI 1 "general_operand" "")))]
726   ""
727   "")
729 (define_insn "cmpqi_ext_3_insn"
730   [(set (reg FLAGS_REG)
731         (compare
732           (subreg:QI
733             (zero_extract:SI
734               (match_operand 0 "ext_register_operand" "Q")
735               (const_int 8)
736               (const_int 8)) 0)
737           (match_operand:QI 1 "general_operand" "Qmn")))]
738   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
739   "cmp{b}\t{%1, %h0|%h0, %1}"
740   [(set_attr "type" "icmp")
741    (set_attr "mode" "QI")])
743 (define_insn "cmpqi_ext_3_insn_rex64"
744   [(set (reg FLAGS_REG)
745         (compare
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 0 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)
751           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
752   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
753   "cmp{b}\t{%1, %h0|%h0, %1}"
754   [(set_attr "type" "icmp")
755    (set_attr "mode" "QI")])
757 (define_insn "*cmpqi_ext_4"
758   [(set (reg FLAGS_REG)
759         (compare
760           (subreg:QI
761             (zero_extract:SI
762               (match_operand 0 "ext_register_operand" "Q")
763               (const_int 8)
764               (const_int 8)) 0)
765           (subreg:QI
766             (zero_extract:SI
767               (match_operand 1 "ext_register_operand" "Q")
768               (const_int 8)
769               (const_int 8)) 0)))]
770   "ix86_match_ccmode (insn, CCmode)"
771   "cmp{b}\t{%h1, %h0|%h0, %h1}"
772   [(set_attr "type" "icmp")
773    (set_attr "mode" "QI")])
775 ;; These implement float point compares.
776 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
777 ;; which would allow mix and match FP modes on the compares.  Which is what
778 ;; the old patterns did, but with many more of them.
780 (define_expand "cmpxf"
781   [(set (reg:CC FLAGS_REG)
782         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
783                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
784   "TARGET_80387"
786   ix86_compare_op0 = operands[0];
787   ix86_compare_op1 = operands[1];
788   DONE;
791 (define_expand "cmpdf"
792   [(set (reg:CC FLAGS_REG)
793         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
794                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
795   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
797   ix86_compare_op0 = operands[0];
798   ix86_compare_op1 = operands[1];
799   DONE;
802 (define_expand "cmpsf"
803   [(set (reg:CC FLAGS_REG)
804         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
805                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
806   "TARGET_80387 || TARGET_SSE_MATH"
808   ix86_compare_op0 = operands[0];
809   ix86_compare_op1 = operands[1];
810   DONE;
813 ;; FP compares, step 1:
814 ;; Set the FP condition codes.
816 ;; CCFPmode     compare with exceptions
817 ;; CCFPUmode    compare with no exceptions
819 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
820 ;; used to manage the reg stack popping would not be preserved.
822 (define_insn "*cmpfp_0_sf"
823   [(set (match_operand:HI 0 "register_operand" "=a")
824         (unspec:HI
825           [(compare:CCFP
826              (match_operand:SF 1 "register_operand" "f")
827              (match_operand:SF 2 "const0_operand" "X"))]
828         UNSPEC_FNSTSW))]
829   "TARGET_80387"
830   "* return output_fp_compare (insn, operands, 0, 0);"
831   [(set_attr "type" "multi")
832    (set_attr "mode" "SF")])
834 (define_insn "*cmpfp_0_df"
835   [(set (match_operand:HI 0 "register_operand" "=a")
836         (unspec:HI
837           [(compare:CCFP
838              (match_operand:DF 1 "register_operand" "f")
839              (match_operand:DF 2 "const0_operand" "X"))]
840         UNSPEC_FNSTSW))]
841   "TARGET_80387"
842   "* return output_fp_compare (insn, operands, 0, 0);"
843   [(set_attr "type" "multi")
844    (set_attr "mode" "DF")])
846 (define_insn "*cmpfp_0_xf"
847   [(set (match_operand:HI 0 "register_operand" "=a")
848         (unspec:HI
849           [(compare:CCFP
850              (match_operand:XF 1 "register_operand" "f")
851              (match_operand:XF 2 "const0_operand" "X"))]
852         UNSPEC_FNSTSW))]
853   "TARGET_80387"
854   "* return output_fp_compare (insn, operands, 0, 0);"
855   [(set_attr "type" "multi")
856    (set_attr "mode" "XF")])
858 (define_insn "*cmpfp_sf"
859   [(set (match_operand:HI 0 "register_operand" "=a")
860         (unspec:HI
861           [(compare:CCFP
862              (match_operand:SF 1 "register_operand" "f")
863              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
864           UNSPEC_FNSTSW))]
865   "TARGET_80387"
866   "* return output_fp_compare (insn, operands, 0, 0);"
867   [(set_attr "type" "multi")
868    (set_attr "mode" "SF")])
870 (define_insn "*cmpfp_df"
871   [(set (match_operand:HI 0 "register_operand" "=a")
872         (unspec:HI
873           [(compare:CCFP
874              (match_operand:DF 1 "register_operand" "f")
875              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
876           UNSPEC_FNSTSW))]
877   "TARGET_80387"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "mode" "DF")])
882 (define_insn "*cmpfp_xf"
883   [(set (match_operand:HI 0 "register_operand" "=a")
884         (unspec:HI
885           [(compare:CCFP
886              (match_operand:XF 1 "register_operand" "f")
887              (match_operand:XF 2 "register_operand" "f"))]
888           UNSPEC_FNSTSW))]
889   "TARGET_80387"
890   "* return output_fp_compare (insn, operands, 0, 0);"
891   [(set_attr "type" "multi")
892    (set_attr "mode" "XF")])
894 (define_insn "*cmpfp_u"
895   [(set (match_operand:HI 0 "register_operand" "=a")
896         (unspec:HI
897           [(compare:CCFPU
898              (match_operand 1 "register_operand" "f")
899              (match_operand 2 "register_operand" "f"))]
900           UNSPEC_FNSTSW))]
901   "TARGET_80387
902    && FLOAT_MODE_P (GET_MODE (operands[1]))
903    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
904   "* return output_fp_compare (insn, operands, 0, 1);"
905   [(set_attr "type" "multi")
906    (set (attr "mode")
907      (cond [(match_operand:SF 1 "" "")
908               (const_string "SF")
909             (match_operand:DF 1 "" "")
910               (const_string "DF")
911            ]
912            (const_string "XF")))])
914 (define_insn "*cmpfp_<mode>"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI
917           [(compare:CCFP
918              (match_operand 1 "register_operand" "f")
919              (match_operator 3 "float_operator"
920                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
921           UNSPEC_FNSTSW))]
922   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
923    && FLOAT_MODE_P (GET_MODE (operands[1]))
924    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
925   "* return output_fp_compare (insn, operands, 0, 0);"
926   [(set_attr "type" "multi")
927    (set_attr "fp_int_src" "true")
928    (set_attr "mode" "<MODE>")])
930 ;; FP compares, step 2
931 ;; Move the fpsw to ax.
933 (define_insn "x86_fnstsw_1"
934   [(set (match_operand:HI 0 "register_operand" "=a")
935         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
936   "TARGET_80387"
937   "fnstsw\t%0"
938   [(set_attr "length" "2")
939    (set_attr "mode" "SI")
940    (set_attr "unit" "i387")])
942 ;; FP compares, step 3
943 ;; Get ax into flags, general case.
945 (define_insn "x86_sahf_1"
946   [(set (reg:CC FLAGS_REG)
947         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
948   "!TARGET_64BIT"
949   "sahf"
950   [(set_attr "length" "1")
951    (set_attr "athlon_decode" "vector")
952    (set_attr "mode" "SI")])
954 ;; Pentium Pro can do steps 1 through 3 in one go.
956 (define_insn "*cmpfp_i_mixed"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_MIX_SSE_I387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
971 (define_insn "*cmpfp_i_sse"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "TARGET_SSE_MATH
976    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
977    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
978   "* return output_fp_compare (insn, operands, 1, 0);"
979   [(set_attr "type" "ssecomi")
980    (set (attr "mode")
981      (if_then_else (match_operand:SF 1 "" "")
982         (const_string "SF")
983         (const_string "DF")))
984    (set_attr "athlon_decode" "vector")])
986 (define_insn "*cmpfp_i_i387"
987   [(set (reg:CCFP FLAGS_REG)
988         (compare:CCFP (match_operand 0 "register_operand" "f")
989                       (match_operand 1 "register_operand" "f")))]
990   "TARGET_80387 && TARGET_CMOVE
991    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
992    && FLOAT_MODE_P (GET_MODE (operands[0]))
993    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
994   "* return output_fp_compare (insn, operands, 1, 0);"
995   [(set_attr "type" "fcmp")
996    (set (attr "mode")
997      (cond [(match_operand:SF 1 "" "")
998               (const_string "SF")
999             (match_operand:DF 1 "" "")
1000               (const_string "DF")
1001            ]
1002            (const_string "XF")))
1003    (set_attr "athlon_decode" "vector")])
1005 (define_insn "*cmpfp_iu_mixed"
1006   [(set (reg:CCFPU FLAGS_REG)
1007         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1008                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1009   "TARGET_MIX_SSE_I387
1010    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1011    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1012   "* return output_fp_compare (insn, operands, 1, 1);"
1013   [(set_attr "type" "fcmp,ssecomi")
1014    (set (attr "mode")
1015      (if_then_else (match_operand:SF 1 "" "")
1016         (const_string "SF")
1017         (const_string "DF")))
1018    (set_attr "athlon_decode" "vector")])
1020 (define_insn "*cmpfp_iu_sse"
1021   [(set (reg:CCFPU FLAGS_REG)
1022         (compare:CCFPU (match_operand 0 "register_operand" "x")
1023                        (match_operand 1 "nonimmediate_operand" "xm")))]
1024   "TARGET_SSE_MATH
1025    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1026    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1027   "* return output_fp_compare (insn, operands, 1, 1);"
1028   [(set_attr "type" "ssecomi")
1029    (set (attr "mode")
1030      (if_then_else (match_operand:SF 1 "" "")
1031         (const_string "SF")
1032         (const_string "DF")))
1033    (set_attr "athlon_decode" "vector")])
1035 (define_insn "*cmpfp_iu_387"
1036   [(set (reg:CCFPU FLAGS_REG)
1037         (compare:CCFPU (match_operand 0 "register_operand" "f")
1038                        (match_operand 1 "register_operand" "f")))]
1039   "TARGET_80387 && TARGET_CMOVE
1040    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1041    && FLOAT_MODE_P (GET_MODE (operands[0]))
1042    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1043   "* return output_fp_compare (insn, operands, 1, 1);"
1044   [(set_attr "type" "fcmp")
1045    (set (attr "mode")
1046      (cond [(match_operand:SF 1 "" "")
1047               (const_string "SF")
1048             (match_operand:DF 1 "" "")
1049               (const_string "DF")
1050            ]
1051            (const_string "XF")))
1052    (set_attr "athlon_decode" "vector")])
1054 ;; Move instructions.
1056 ;; General case of fullword move.
1058 (define_expand "movsi"
1059   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1060         (match_operand:SI 1 "general_operand" ""))]
1061   ""
1062   "ix86_expand_move (SImode, operands); DONE;")
1064 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1065 ;; general_operand.
1067 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1068 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1069 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1070 ;; targets without our curiosities, and it is just as easy to represent
1071 ;; this differently.
1073 (define_insn "*pushsi2"
1074   [(set (match_operand:SI 0 "push_operand" "=<")
1075         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1076   "!TARGET_64BIT"
1077   "push{l}\t%1"
1078   [(set_attr "type" "push")
1079    (set_attr "mode" "SI")])
1081 ;; For 64BIT abi we always round up to 8 bytes.
1082 (define_insn "*pushsi2_rex64"
1083   [(set (match_operand:SI 0 "push_operand" "=X")
1084         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1085   "TARGET_64BIT"
1086   "push{q}\t%q1"
1087   [(set_attr "type" "push")
1088    (set_attr "mode" "SI")])
1090 (define_insn "*pushsi2_prologue"
1091   [(set (match_operand:SI 0 "push_operand" "=<")
1092         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1093    (clobber (mem:BLK (scratch)))]
1094   "!TARGET_64BIT"
1095   "push{l}\t%1"
1096   [(set_attr "type" "push")
1097    (set_attr "mode" "SI")])
1099 (define_insn "*popsi1_epilogue"
1100   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1101         (mem:SI (reg:SI SP_REG)))
1102    (set (reg:SI SP_REG)
1103         (plus:SI (reg:SI SP_REG) (const_int 4)))
1104    (clobber (mem:BLK (scratch)))]
1105   "!TARGET_64BIT"
1106   "pop{l}\t%0"
1107   [(set_attr "type" "pop")
1108    (set_attr "mode" "SI")])
1110 (define_insn "popsi1"
1111   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1112         (mem:SI (reg:SI SP_REG)))
1113    (set (reg:SI SP_REG)
1114         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1115   "!TARGET_64BIT"
1116   "pop{l}\t%0"
1117   [(set_attr "type" "pop")
1118    (set_attr "mode" "SI")])
1120 (define_insn "*movsi_xor"
1121   [(set (match_operand:SI 0 "register_operand" "=r")
1122         (match_operand:SI 1 "const0_operand" "i"))
1123    (clobber (reg:CC FLAGS_REG))]
1124   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1125   "xor{l}\t{%0, %0|%0, %0}"
1126   [(set_attr "type" "alu1")
1127    (set_attr "mode" "SI")
1128    (set_attr "length_immediate" "0")])
1130 (define_insn "*movsi_or"
1131   [(set (match_operand:SI 0 "register_operand" "=r")
1132         (match_operand:SI 1 "immediate_operand" "i"))
1133    (clobber (reg:CC FLAGS_REG))]
1134   "reload_completed
1135    && operands[1] == constm1_rtx
1136    && (TARGET_PENTIUM || optimize_size)"
1138   operands[1] = constm1_rtx;
1139   return "or{l}\t{%1, %0|%0, %1}";
1141   [(set_attr "type" "alu1")
1142    (set_attr "mode" "SI")
1143    (set_attr "length_immediate" "1")])
1145 (define_insn "*movsi_1"
1146   [(set (match_operand:SI 0 "nonimmediate_operand"
1147                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1148         (match_operand:SI 1 "general_operand"
1149                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1150   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1152   switch (get_attr_type (insn))
1153     {
1154     case TYPE_SSELOG1:
1155       if (get_attr_mode (insn) == MODE_TI)
1156         return "pxor\t%0, %0";
1157       return "xorps\t%0, %0";
1159     case TYPE_SSEMOV:
1160       switch (get_attr_mode (insn))
1161         {
1162         case MODE_TI:
1163           return "movdqa\t{%1, %0|%0, %1}";
1164         case MODE_V4SF:
1165           return "movaps\t{%1, %0|%0, %1}";
1166         case MODE_SI:
1167           return "movd\t{%1, %0|%0, %1}";
1168         case MODE_SF:
1169           return "movss\t{%1, %0|%0, %1}";
1170         default:
1171           gcc_unreachable ();
1172         }
1174     case TYPE_MMXADD:
1175       return "pxor\t%0, %0";
1177     case TYPE_MMXMOV:
1178       if (get_attr_mode (insn) == MODE_DI)
1179         return "movq\t{%1, %0|%0, %1}";
1180       return "movd\t{%1, %0|%0, %1}";
1182     case TYPE_LEA:
1183       return "lea{l}\t{%1, %0|%0, %1}";
1185     default:
1186       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1187         abort();
1188       return "mov{l}\t{%1, %0|%0, %1}";
1189     }
1191   [(set (attr "type")
1192      (cond [(eq_attr "alternative" "2")
1193               (const_string "mmx")
1194             (eq_attr "alternative" "3,4,5")
1195               (const_string "mmxmov")
1196             (eq_attr "alternative" "6")
1197               (const_string "sselog1")
1198             (eq_attr "alternative" "7,8,9,10,11")
1199               (const_string "ssemov")
1200             (and (ne (symbol_ref "flag_pic") (const_int 0))
1201                  (match_operand:SI 1 "symbolic_operand" ""))
1202               (const_string "lea")
1203            ]
1204            (const_string "imov")))
1205    (set (attr "mode")
1206      (cond [(eq_attr "alternative" "2,3")
1207               (const_string "DI")
1208             (eq_attr "alternative" "6,7")
1209               (if_then_else
1210                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1211                 (const_string "V4SF")
1212                 (const_string "TI"))
1213             (and (eq_attr "alternative" "8,9,10,11")
1214                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1215               (const_string "SF")
1216            ]
1217            (const_string "SI")))])
1219 ;; Stores and loads of ax to arbitrary constant address.
1220 ;; We fake an second form of instruction to force reload to load address
1221 ;; into register when rax is not available
1222 (define_insn "*movabssi_1_rex64"
1223   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1224         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1225   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1226   "@
1227    movabs{l}\t{%1, %P0|%P0, %1}
1228    mov{l}\t{%1, %a0|%a0, %1}"
1229   [(set_attr "type" "imov")
1230    (set_attr "modrm" "0,*")
1231    (set_attr "length_address" "8,0")
1232    (set_attr "length_immediate" "0,*")
1233    (set_attr "memory" "store")
1234    (set_attr "mode" "SI")])
1236 (define_insn "*movabssi_2_rex64"
1237   [(set (match_operand:SI 0 "register_operand" "=a,r")
1238         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1239   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1240   "@
1241    movabs{l}\t{%P1, %0|%0, %P1}
1242    mov{l}\t{%a1, %0|%0, %a1}"
1243   [(set_attr "type" "imov")
1244    (set_attr "modrm" "0,*")
1245    (set_attr "length_address" "8,0")
1246    (set_attr "length_immediate" "0")
1247    (set_attr "memory" "load")
1248    (set_attr "mode" "SI")])
1250 (define_insn "*swapsi"
1251   [(set (match_operand:SI 0 "register_operand" "+r")
1252         (match_operand:SI 1 "register_operand" "+r"))
1253    (set (match_dup 1)
1254         (match_dup 0))]
1255   ""
1256   "xchg{l}\t%1, %0"
1257   [(set_attr "type" "imov")
1258    (set_attr "mode" "SI")
1259    (set_attr "pent_pair" "np")
1260    (set_attr "athlon_decode" "vector")])
1262 (define_expand "movhi"
1263   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1264         (match_operand:HI 1 "general_operand" ""))]
1265   ""
1266   "ix86_expand_move (HImode, operands); DONE;")
1268 (define_insn "*pushhi2"
1269   [(set (match_operand:HI 0 "push_operand" "=<,<")
1270         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1271   "!TARGET_64BIT"
1272   "@
1273    push{w}\t{|WORD PTR }%1
1274    push{w}\t%1"
1275   [(set_attr "type" "push")
1276    (set_attr "mode" "HI")])
1278 ;; For 64BIT abi we always round up to 8 bytes.
1279 (define_insn "*pushhi2_rex64"
1280   [(set (match_operand:HI 0 "push_operand" "=X")
1281         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1282   "TARGET_64BIT"
1283   "push{q}\t%q1"
1284   [(set_attr "type" "push")
1285    (set_attr "mode" "QI")])
1287 (define_insn "*movhi_1"
1288   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1289         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1290   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1292   switch (get_attr_type (insn))
1293     {
1294     case TYPE_IMOVX:
1295       /* movzwl is faster than movw on p2 due to partial word stalls,
1296          though not as fast as an aligned movl.  */
1297       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1298     default:
1299       if (get_attr_mode (insn) == MODE_SI)
1300         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1301       else
1302         return "mov{w}\t{%1, %0|%0, %1}";
1303     }
1305   [(set (attr "type")
1306      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1307               (const_string "imov")
1308             (and (eq_attr "alternative" "0")
1309                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1310                           (const_int 0))
1311                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1312                           (const_int 0))))
1313               (const_string "imov")
1314             (and (eq_attr "alternative" "1,2")
1315                  (match_operand:HI 1 "aligned_operand" ""))
1316               (const_string "imov")
1317             (and (ne (symbol_ref "TARGET_MOVX")
1318                      (const_int 0))
1319                  (eq_attr "alternative" "0,2"))
1320               (const_string "imovx")
1321            ]
1322            (const_string "imov")))
1323     (set (attr "mode")
1324       (cond [(eq_attr "type" "imovx")
1325                (const_string "SI")
1326              (and (eq_attr "alternative" "1,2")
1327                   (match_operand:HI 1 "aligned_operand" ""))
1328                (const_string "SI")
1329              (and (eq_attr "alternative" "0")
1330                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1331                            (const_int 0))
1332                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1333                            (const_int 0))))
1334                (const_string "SI")
1335             ]
1336             (const_string "HI")))])
1338 ;; Stores and loads of ax to arbitrary constant address.
1339 ;; We fake an second form of instruction to force reload to load address
1340 ;; into register when rax is not available
1341 (define_insn "*movabshi_1_rex64"
1342   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1343         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1344   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1345   "@
1346    movabs{w}\t{%1, %P0|%P0, %1}
1347    mov{w}\t{%1, %a0|%a0, %1}"
1348   [(set_attr "type" "imov")
1349    (set_attr "modrm" "0,*")
1350    (set_attr "length_address" "8,0")
1351    (set_attr "length_immediate" "0,*")
1352    (set_attr "memory" "store")
1353    (set_attr "mode" "HI")])
1355 (define_insn "*movabshi_2_rex64"
1356   [(set (match_operand:HI 0 "register_operand" "=a,r")
1357         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1358   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1359   "@
1360    movabs{w}\t{%P1, %0|%0, %P1}
1361    mov{w}\t{%a1, %0|%0, %a1}"
1362   [(set_attr "type" "imov")
1363    (set_attr "modrm" "0,*")
1364    (set_attr "length_address" "8,0")
1365    (set_attr "length_immediate" "0")
1366    (set_attr "memory" "load")
1367    (set_attr "mode" "HI")])
1369 (define_insn "*swaphi_1"
1370   [(set (match_operand:HI 0 "register_operand" "+r")
1371         (match_operand:HI 1 "register_operand" "+r"))
1372    (set (match_dup 1)
1373         (match_dup 0))]
1374   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1375   "xchg{l}\t%k1, %k0"
1376   [(set_attr "type" "imov")
1377    (set_attr "mode" "SI")
1378    (set_attr "pent_pair" "np")
1379    (set_attr "athlon_decode" "vector")])
1381 (define_insn "*swaphi_2"
1382   [(set (match_operand:HI 0 "register_operand" "+r")
1383         (match_operand:HI 1 "register_operand" "+r"))
1384    (set (match_dup 1)
1385         (match_dup 0))]
1386   "TARGET_PARTIAL_REG_STALL"
1387   "xchg{w}\t%1, %0"
1388   [(set_attr "type" "imov")
1389    (set_attr "mode" "HI")
1390    (set_attr "pent_pair" "np")
1391    (set_attr "athlon_decode" "vector")])
1393 (define_expand "movstricthi"
1394   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1395         (match_operand:HI 1 "general_operand" ""))]
1396   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1398   /* Don't generate memory->memory moves, go through a register */
1399   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1400     operands[1] = force_reg (HImode, operands[1]);
1403 (define_insn "*movstricthi_1"
1404   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1405         (match_operand:HI 1 "general_operand" "rn,m"))]
1406   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1407    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1408   "mov{w}\t{%1, %0|%0, %1}"
1409   [(set_attr "type" "imov")
1410    (set_attr "mode" "HI")])
1412 (define_insn "*movstricthi_xor"
1413   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1414         (match_operand:HI 1 "const0_operand" "i"))
1415    (clobber (reg:CC FLAGS_REG))]
1416   "reload_completed
1417    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1418   "xor{w}\t{%0, %0|%0, %0}"
1419   [(set_attr "type" "alu1")
1420    (set_attr "mode" "HI")
1421    (set_attr "length_immediate" "0")])
1423 (define_expand "movqi"
1424   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1425         (match_operand:QI 1 "general_operand" ""))]
1426   ""
1427   "ix86_expand_move (QImode, operands); DONE;")
1429 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1430 ;; "push a byte".  But actually we use pushw, which has the effect
1431 ;; of rounding the amount pushed up to a halfword.
1433 (define_insn "*pushqi2"
1434   [(set (match_operand:QI 0 "push_operand" "=X,X")
1435         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1436   "!TARGET_64BIT"
1437   "@
1438    push{w}\t{|word ptr }%1
1439    push{w}\t%w1"
1440   [(set_attr "type" "push")
1441    (set_attr "mode" "HI")])
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" "QI")])
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       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1471         abort ();
1472       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1473     default:
1474       if (get_attr_mode (insn) == MODE_SI)
1475         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1476       else
1477         return "mov{b}\t{%1, %0|%0, %1}";
1478     }
1480   [(set (attr "type")
1481      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1482               (const_string "imov")
1483             (and (eq_attr "alternative" "3")
1484                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1485                           (const_int 0))
1486                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1487                           (const_int 0))))
1488               (const_string "imov")
1489             (eq_attr "alternative" "3,5")
1490               (const_string "imovx")
1491             (and (ne (symbol_ref "TARGET_MOVX")
1492                      (const_int 0))
1493                  (eq_attr "alternative" "2"))
1494               (const_string "imovx")
1495            ]
1496            (const_string "imov")))
1497    (set (attr "mode")
1498       (cond [(eq_attr "alternative" "3,4,5")
1499                (const_string "SI")
1500              (eq_attr "alternative" "6")
1501                (const_string "QI")
1502              (eq_attr "type" "imovx")
1503                (const_string "SI")
1504              (and (eq_attr "type" "imov")
1505                   (and (eq_attr "alternative" "0,1")
1506                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1507                            (const_int 0))))
1508                (const_string "SI")
1509              ;; Avoid partial register stalls when not using QImode arithmetic
1510              (and (eq_attr "type" "imov")
1511                   (and (eq_attr "alternative" "0,1")
1512                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1513                                 (const_int 0))
1514                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1515                                 (const_int 0)))))
1516                (const_string "SI")
1517            ]
1518            (const_string "QI")))])
1520 (define_expand "reload_outqi"
1521   [(parallel [(match_operand:QI 0 "" "=m")
1522               (match_operand:QI 1 "register_operand" "r")
1523               (match_operand:QI 2 "register_operand" "=&q")])]
1524   ""
1526   rtx op0, op1, op2;
1527   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1529   if (reg_overlap_mentioned_p (op2, op0))
1530     abort ();
1531   if (! q_regs_operand (op1, QImode))
1532     {
1533       emit_insn (gen_movqi (op2, op1));
1534       op1 = op2;
1535     }
1536   emit_insn (gen_movqi (op0, op1));
1537   DONE;
1540 (define_insn "*swapqi_1"
1541   [(set (match_operand:QI 0 "register_operand" "+r")
1542         (match_operand:QI 1 "register_operand" "+r"))
1543    (set (match_dup 1)
1544         (match_dup 0))]
1545   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1546   "xchg{l}\t%k1, %k0"
1547   [(set_attr "type" "imov")
1548    (set_attr "mode" "SI")
1549    (set_attr "pent_pair" "np")
1550    (set_attr "athlon_decode" "vector")])
1552 (define_insn "*swapqi_2"
1553   [(set (match_operand:QI 0 "register_operand" "+q")
1554         (match_operand:QI 1 "register_operand" "+q"))
1555    (set (match_dup 1)
1556         (match_dup 0))]
1557   "TARGET_PARTIAL_REG_STALL"
1558   "xchg{b}\t%1, %0"
1559   [(set_attr "type" "imov")
1560    (set_attr "mode" "QI")
1561    (set_attr "pent_pair" "np")
1562    (set_attr "athlon_decode" "vector")])
1564 (define_expand "movstrictqi"
1565   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1566         (match_operand:QI 1 "general_operand" ""))]
1567   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1569   /* Don't generate memory->memory moves, go through a register.  */
1570   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1571     operands[1] = force_reg (QImode, operands[1]);
1574 (define_insn "*movstrictqi_1"
1575   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1576         (match_operand:QI 1 "general_operand" "*qn,m"))]
1577   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1578    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1579   "mov{b}\t{%1, %0|%0, %1}"
1580   [(set_attr "type" "imov")
1581    (set_attr "mode" "QI")])
1583 (define_insn "*movstrictqi_xor"
1584   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1585         (match_operand:QI 1 "const0_operand" "i"))
1586    (clobber (reg:CC FLAGS_REG))]
1587   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1588   "xor{b}\t{%0, %0|%0, %0}"
1589   [(set_attr "type" "alu1")
1590    (set_attr "mode" "QI")
1591    (set_attr "length_immediate" "0")])
1593 (define_insn "*movsi_extv_1"
1594   [(set (match_operand:SI 0 "register_operand" "=R")
1595         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1596                          (const_int 8)
1597                          (const_int 8)))]
1598   ""
1599   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1600   [(set_attr "type" "imovx")
1601    (set_attr "mode" "SI")])
1603 (define_insn "*movhi_extv_1"
1604   [(set (match_operand:HI 0 "register_operand" "=R")
1605         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1606                          (const_int 8)
1607                          (const_int 8)))]
1608   ""
1609   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1610   [(set_attr "type" "imovx")
1611    (set_attr "mode" "SI")])
1613 (define_insn "*movqi_extv_1"
1614   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1615         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1616                          (const_int 8)
1617                          (const_int 8)))]
1618   "!TARGET_64BIT"
1620   switch (get_attr_type (insn))
1621     {
1622     case TYPE_IMOVX:
1623       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1624     default:
1625       return "mov{b}\t{%h1, %0|%0, %h1}";
1626     }
1628   [(set (attr "type")
1629      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1630                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1631                              (ne (symbol_ref "TARGET_MOVX")
1632                                  (const_int 0))))
1633         (const_string "imovx")
1634         (const_string "imov")))
1635    (set (attr "mode")
1636      (if_then_else (eq_attr "type" "imovx")
1637         (const_string "SI")
1638         (const_string "QI")))])
1640 (define_insn "*movqi_extv_1_rex64"
1641   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1642         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1643                          (const_int 8)
1644                          (const_int 8)))]
1645   "TARGET_64BIT"
1647   switch (get_attr_type (insn))
1648     {
1649     case TYPE_IMOVX:
1650       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1651     default:
1652       return "mov{b}\t{%h1, %0|%0, %h1}";
1653     }
1655   [(set (attr "type")
1656      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1657                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1658                              (ne (symbol_ref "TARGET_MOVX")
1659                                  (const_int 0))))
1660         (const_string "imovx")
1661         (const_string "imov")))
1662    (set (attr "mode")
1663      (if_then_else (eq_attr "type" "imovx")
1664         (const_string "SI")
1665         (const_string "QI")))])
1667 ;; Stores and loads of ax to arbitrary constant address.
1668 ;; We fake an second form of instruction to force reload to load address
1669 ;; into register when rax is not available
1670 (define_insn "*movabsqi_1_rex64"
1671   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1672         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1673   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1674   "@
1675    movabs{b}\t{%1, %P0|%P0, %1}
1676    mov{b}\t{%1, %a0|%a0, %1}"
1677   [(set_attr "type" "imov")
1678    (set_attr "modrm" "0,*")
1679    (set_attr "length_address" "8,0")
1680    (set_attr "length_immediate" "0,*")
1681    (set_attr "memory" "store")
1682    (set_attr "mode" "QI")])
1684 (define_insn "*movabsqi_2_rex64"
1685   [(set (match_operand:QI 0 "register_operand" "=a,r")
1686         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1687   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1688   "@
1689    movabs{b}\t{%P1, %0|%0, %P1}
1690    mov{b}\t{%a1, %0|%0, %a1}"
1691   [(set_attr "type" "imov")
1692    (set_attr "modrm" "0,*")
1693    (set_attr "length_address" "8,0")
1694    (set_attr "length_immediate" "0")
1695    (set_attr "memory" "load")
1696    (set_attr "mode" "QI")])
1698 (define_insn "*movsi_extzv_1"
1699   [(set (match_operand:SI 0 "register_operand" "=R")
1700         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1701                          (const_int 8)
1702                          (const_int 8)))]
1703   ""
1704   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1705   [(set_attr "type" "imovx")
1706    (set_attr "mode" "SI")])
1708 (define_insn "*movqi_extzv_2"
1709   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1710         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1711                                     (const_int 8)
1712                                     (const_int 8)) 0))]
1713   "!TARGET_64BIT"
1715   switch (get_attr_type (insn))
1716     {
1717     case TYPE_IMOVX:
1718       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1719     default:
1720       return "mov{b}\t{%h1, %0|%0, %h1}";
1721     }
1723   [(set (attr "type")
1724      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1725                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1726                              (ne (symbol_ref "TARGET_MOVX")
1727                                  (const_int 0))))
1728         (const_string "imovx")
1729         (const_string "imov")))
1730    (set (attr "mode")
1731      (if_then_else (eq_attr "type" "imovx")
1732         (const_string "SI")
1733         (const_string "QI")))])
1735 (define_insn "*movqi_extzv_2_rex64"
1736   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1737         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1738                                     (const_int 8)
1739                                     (const_int 8)) 0))]
1740   "TARGET_64BIT"
1742   switch (get_attr_type (insn))
1743     {
1744     case TYPE_IMOVX:
1745       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1746     default:
1747       return "mov{b}\t{%h1, %0|%0, %h1}";
1748     }
1750   [(set (attr "type")
1751      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1752                         (ne (symbol_ref "TARGET_MOVX")
1753                             (const_int 0)))
1754         (const_string "imovx")
1755         (const_string "imov")))
1756    (set (attr "mode")
1757      (if_then_else (eq_attr "type" "imovx")
1758         (const_string "SI")
1759         (const_string "QI")))])
1761 (define_insn "movsi_insv_1"
1762   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1763                          (const_int 8)
1764                          (const_int 8))
1765         (match_operand:SI 1 "general_operand" "Qmn"))]
1766   "!TARGET_64BIT"
1767   "mov{b}\t{%b1, %h0|%h0, %b1}"
1768   [(set_attr "type" "imov")
1769    (set_attr "mode" "QI")])
1771 (define_insn "movdi_insv_1_rex64"
1772   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1773                          (const_int 8)
1774                          (const_int 8))
1775         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1776   "TARGET_64BIT"
1777   "mov{b}\t{%b1, %h0|%h0, %b1}"
1778   [(set_attr "type" "imov")
1779    (set_attr "mode" "QI")])
1781 (define_insn "*movqi_insv_2"
1782   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1783                          (const_int 8)
1784                          (const_int 8))
1785         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1786                      (const_int 8)))]
1787   ""
1788   "mov{b}\t{%h1, %h0|%h0, %h1}"
1789   [(set_attr "type" "imov")
1790    (set_attr "mode" "QI")])
1792 (define_expand "movdi"
1793   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1794         (match_operand:DI 1 "general_operand" ""))]
1795   ""
1796   "ix86_expand_move (DImode, operands); DONE;")
1798 (define_insn "*pushdi"
1799   [(set (match_operand:DI 0 "push_operand" "=<")
1800         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1801   "!TARGET_64BIT"
1802   "#")
1804 (define_insn "*pushdi2_rex64"
1805   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1806         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1807   "TARGET_64BIT"
1808   "@
1809    push{q}\t%1
1810    #"
1811   [(set_attr "type" "push,multi")
1812    (set_attr "mode" "DI")])
1814 ;; Convert impossible pushes of immediate to existing instructions.
1815 ;; First try to get scratch register and go through it.  In case this
1816 ;; fails, push sign extended lower part first and then overwrite
1817 ;; upper part by 32bit move.
1818 (define_peephole2
1819   [(match_scratch:DI 2 "r")
1820    (set (match_operand:DI 0 "push_operand" "")
1821         (match_operand:DI 1 "immediate_operand" ""))]
1822   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1823    && !x86_64_immediate_operand (operands[1], DImode)"
1824   [(set (match_dup 2) (match_dup 1))
1825    (set (match_dup 0) (match_dup 2))]
1826   "")
1828 ;; We need to define this as both peepholer and splitter for case
1829 ;; peephole2 pass is not run.
1830 ;; "&& 1" is needed to keep it from matching the previous pattern.
1831 (define_peephole2
1832   [(set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1835    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1836   [(set (match_dup 0) (match_dup 1))
1837    (set (match_dup 2) (match_dup 3))]
1838   "split_di (operands + 1, 1, operands + 2, operands + 3);
1839    operands[1] = gen_lowpart (DImode, operands[2]);
1840    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1841                                                     GEN_INT (4)));
1842   ")
1844 (define_split
1845   [(set (match_operand:DI 0 "push_operand" "")
1846         (match_operand:DI 1 "immediate_operand" ""))]
1847   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1848    && !symbolic_operand (operands[1], DImode)
1849    && !x86_64_immediate_operand (operands[1], DImode)"
1850   [(set (match_dup 0) (match_dup 1))
1851    (set (match_dup 2) (match_dup 3))]
1852   "split_di (operands + 1, 1, operands + 2, operands + 3);
1853    operands[1] = gen_lowpart (DImode, operands[2]);
1854    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1855                                                     GEN_INT (4)));
1856   ")
1858 (define_insn "*pushdi2_prologue_rex64"
1859   [(set (match_operand:DI 0 "push_operand" "=<")
1860         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1861    (clobber (mem:BLK (scratch)))]
1862   "TARGET_64BIT"
1863   "push{q}\t%1"
1864   [(set_attr "type" "push")
1865    (set_attr "mode" "DI")])
1867 (define_insn "*popdi1_epilogue_rex64"
1868   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1869         (mem:DI (reg:DI SP_REG)))
1870    (set (reg:DI SP_REG)
1871         (plus:DI (reg:DI SP_REG) (const_int 8)))
1872    (clobber (mem:BLK (scratch)))]
1873   "TARGET_64BIT"
1874   "pop{q}\t%0"
1875   [(set_attr "type" "pop")
1876    (set_attr "mode" "DI")])
1878 (define_insn "popdi1"
1879   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1880         (mem:DI (reg:DI SP_REG)))
1881    (set (reg:DI SP_REG)
1882         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1883   "TARGET_64BIT"
1884   "pop{q}\t%0"
1885   [(set_attr "type" "pop")
1886    (set_attr "mode" "DI")])
1888 (define_insn "*movdi_xor_rex64"
1889   [(set (match_operand:DI 0 "register_operand" "=r")
1890         (match_operand:DI 1 "const0_operand" "i"))
1891    (clobber (reg:CC FLAGS_REG))]
1892   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1893    && reload_completed"
1894   "xor{l}\t{%k0, %k0|%k0, %k0}"
1895   [(set_attr "type" "alu1")
1896    (set_attr "mode" "SI")
1897    (set_attr "length_immediate" "0")])
1899 (define_insn "*movdi_or_rex64"
1900   [(set (match_operand:DI 0 "register_operand" "=r")
1901         (match_operand:DI 1 "const_int_operand" "i"))
1902    (clobber (reg:CC FLAGS_REG))]
1903   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1904    && reload_completed
1905    && operands[1] == constm1_rtx"
1907   operands[1] = constm1_rtx;
1908   return "or{q}\t{%1, %0|%0, %1}";
1910   [(set_attr "type" "alu1")
1911    (set_attr "mode" "DI")
1912    (set_attr "length_immediate" "1")])
1914 (define_insn "*movdi_2"
1915   [(set (match_operand:DI 0 "nonimmediate_operand"
1916                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1917         (match_operand:DI 1 "general_operand"
1918                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1919   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1920   "@
1921    #
1922    #
1923    pxor\t%0, %0
1924    movq\t{%1, %0|%0, %1}
1925    movq\t{%1, %0|%0, %1}
1926    pxor\t%0, %0
1927    movq\t{%1, %0|%0, %1}
1928    movdqa\t{%1, %0|%0, %1}
1929    movq\t{%1, %0|%0, %1}
1930    xorps\t%0, %0
1931    movlps\t{%1, %0|%0, %1}
1932    movaps\t{%1, %0|%0, %1}
1933    movlps\t{%1, %0|%0, %1}"
1934   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1935    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1937 (define_split
1938   [(set (match_operand:DI 0 "push_operand" "")
1939         (match_operand:DI 1 "general_operand" ""))]
1940   "!TARGET_64BIT && reload_completed
1941    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1942   [(const_int 0)]
1943   "ix86_split_long_move (operands); DONE;")
1945 ;; %%% This multiword shite has got to go.
1946 (define_split
1947   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1948         (match_operand:DI 1 "general_operand" ""))]
1949   "!TARGET_64BIT && reload_completed
1950    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1951    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1952   [(const_int 0)]
1953   "ix86_split_long_move (operands); DONE;")
1955 (define_insn "*movdi_1_rex64"
1956   [(set (match_operand:DI 0 "nonimmediate_operand"
1957                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1958         (match_operand:DI 1 "general_operand"
1959                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1960   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1962   switch (get_attr_type (insn))
1963     {
1964     case TYPE_SSECVT:
1965       if (which_alternative == 13)
1966         return "movq2dq\t{%1, %0|%0, %1}";
1967       else
1968         return "movdq2q\t{%1, %0|%0, %1}";
1969     case TYPE_SSEMOV:
1970       if (get_attr_mode (insn) == MODE_TI)
1971           return "movdqa\t{%1, %0|%0, %1}";
1972       /* FALLTHRU */
1973     case TYPE_MMXMOV:
1974       /* Moves from and into integer register is done using movd opcode with
1975          REX prefix.  */
1976       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1977           return "movd\t{%1, %0|%0, %1}";
1978       return "movq\t{%1, %0|%0, %1}";
1979     case TYPE_SSELOG1:
1980     case TYPE_MMXADD:
1981       return "pxor\t%0, %0";
1982     case TYPE_MULTI:
1983       return "#";
1984     case TYPE_LEA:
1985       return "lea{q}\t{%a1, %0|%0, %a1}";
1986     default:
1987       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1988         abort ();
1989       if (get_attr_mode (insn) == MODE_SI)
1990         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1991       else if (which_alternative == 2)
1992         return "movabs{q}\t{%1, %0|%0, %1}";
1993       else
1994         return "mov{q}\t{%1, %0|%0, %1}";
1995     }
1997   [(set (attr "type")
1998      (cond [(eq_attr "alternative" "5")
1999               (const_string "mmx")
2000             (eq_attr "alternative" "6,7,8")
2001               (const_string "mmxmov")
2002             (eq_attr "alternative" "9")
2003               (const_string "sselog1")
2004             (eq_attr "alternative" "10,11,12")
2005               (const_string "ssemov")
2006             (eq_attr "alternative" "13,14")
2007               (const_string "ssecvt")
2008             (eq_attr "alternative" "4")
2009               (const_string "multi")
2010             (and (ne (symbol_ref "flag_pic") (const_int 0))
2011                  (match_operand:DI 1 "symbolic_operand" ""))
2012               (const_string "lea")
2013            ]
2014            (const_string "imov")))
2015    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2016    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2017    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2019 ;; Stores and loads of ax to arbitrary constant address.
2020 ;; We fake an second form of instruction to force reload to load address
2021 ;; into register when rax is not available
2022 (define_insn "*movabsdi_1_rex64"
2023   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2024         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2025   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2026   "@
2027    movabs{q}\t{%1, %P0|%P0, %1}
2028    mov{q}\t{%1, %a0|%a0, %1}"
2029   [(set_attr "type" "imov")
2030    (set_attr "modrm" "0,*")
2031    (set_attr "length_address" "8,0")
2032    (set_attr "length_immediate" "0,*")
2033    (set_attr "memory" "store")
2034    (set_attr "mode" "DI")])
2036 (define_insn "*movabsdi_2_rex64"
2037   [(set (match_operand:DI 0 "register_operand" "=a,r")
2038         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2039   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2040   "@
2041    movabs{q}\t{%P1, %0|%0, %P1}
2042    mov{q}\t{%a1, %0|%0, %a1}"
2043   [(set_attr "type" "imov")
2044    (set_attr "modrm" "0,*")
2045    (set_attr "length_address" "8,0")
2046    (set_attr "length_immediate" "0")
2047    (set_attr "memory" "load")
2048    (set_attr "mode" "DI")])
2050 ;; Convert impossible stores of immediate to existing instructions.
2051 ;; First try to get scratch register and go through it.  In case this
2052 ;; fails, move by 32bit parts.
2053 (define_peephole2
2054   [(match_scratch:DI 2 "r")
2055    (set (match_operand:DI 0 "memory_operand" "")
2056         (match_operand:DI 1 "immediate_operand" ""))]
2057   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2058    && !x86_64_immediate_operand (operands[1], DImode)"
2059   [(set (match_dup 2) (match_dup 1))
2060    (set (match_dup 0) (match_dup 2))]
2061   "")
2063 ;; We need to define this as both peepholer and splitter for case
2064 ;; peephole2 pass is not run.
2065 ;; "&& 1" is needed to keep it from matching the previous pattern.
2066 (define_peephole2
2067   [(set (match_operand:DI 0 "memory_operand" "")
2068         (match_operand:DI 1 "immediate_operand" ""))]
2069   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2070    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2071   [(set (match_dup 2) (match_dup 3))
2072    (set (match_dup 4) (match_dup 5))]
2073   "split_di (operands, 2, operands + 2, operands + 4);")
2075 (define_split
2076   [(set (match_operand:DI 0 "memory_operand" "")
2077         (match_operand:DI 1 "immediate_operand" ""))]
2078   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2079    && !symbolic_operand (operands[1], DImode)
2080    && !x86_64_immediate_operand (operands[1], DImode)"
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_insn "*swapdi_rex64"
2086   [(set (match_operand:DI 0 "register_operand" "+r")
2087         (match_operand:DI 1 "register_operand" "+r"))
2088    (set (match_dup 1)
2089         (match_dup 0))]
2090   "TARGET_64BIT"
2091   "xchg{q}\t%1, %0"
2092   [(set_attr "type" "imov")
2093    (set_attr "mode" "DI")
2094    (set_attr "pent_pair" "np")
2095    (set_attr "athlon_decode" "vector")])
2097 (define_expand "movti"
2098   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2099         (match_operand:TI 1 "nonimmediate_operand" ""))]
2100   "TARGET_SSE || TARGET_64BIT"
2102   if (TARGET_64BIT)
2103     ix86_expand_move (TImode, operands);
2104   else
2105     ix86_expand_vector_move (TImode, operands);
2106   DONE;
2109 (define_insn "*movti_internal"
2110   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2111         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2112   "TARGET_SSE && !TARGET_64BIT
2113    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2115   switch (which_alternative)
2116     {
2117     case 0:
2118       if (get_attr_mode (insn) == MODE_V4SF)
2119         return "xorps\t%0, %0";
2120       else
2121         return "pxor\t%0, %0";
2122     case 1:
2123     case 2:
2124       if (get_attr_mode (insn) == MODE_V4SF)
2125         return "movaps\t{%1, %0|%0, %1}";
2126       else
2127         return "movdqa\t{%1, %0|%0, %1}";
2128     default:
2129       abort ();
2130     }
2132   [(set_attr "type" "ssemov,ssemov,ssemov")
2133    (set (attr "mode")
2134         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2135                  (const_string "V4SF")
2137                (eq_attr "alternative" "0,1")
2138                  (if_then_else
2139                    (ne (symbol_ref "optimize_size")
2140                        (const_int 0))
2141                    (const_string "V4SF")
2142                    (const_string "TI"))
2143                (eq_attr "alternative" "2")
2144                  (if_then_else
2145                    (ne (symbol_ref "optimize_size")
2146                        (const_int 0))
2147                    (const_string "V4SF")
2148                    (const_string "TI"))]
2149                (const_string "TI")))])
2151 (define_insn "*movti_rex64"
2152   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2153         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2154   "TARGET_64BIT
2155    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2157   switch (which_alternative)
2158     {
2159     case 0:
2160     case 1:
2161       return "#";
2162     case 2:
2163       if (get_attr_mode (insn) == MODE_V4SF)
2164         return "xorps\t%0, %0";
2165       else
2166         return "pxor\t%0, %0";
2167     case 3:
2168     case 4:
2169       if (get_attr_mode (insn) == MODE_V4SF)
2170         return "movaps\t{%1, %0|%0, %1}";
2171       else
2172         return "movdqa\t{%1, %0|%0, %1}";
2173     default:
2174       abort ();
2175     }
2177   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2178    (set (attr "mode")
2179         (cond [(eq_attr "alternative" "2,3")
2180                  (if_then_else
2181                    (ne (symbol_ref "optimize_size")
2182                        (const_int 0))
2183                    (const_string "V4SF")
2184                    (const_string "TI"))
2185                (eq_attr "alternative" "4")
2186                  (if_then_else
2187                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2188                             (const_int 0))
2189                         (ne (symbol_ref "optimize_size")
2190                             (const_int 0)))
2191                    (const_string "V4SF")
2192                    (const_string "TI"))]
2193                (const_string "DI")))])
2195 (define_split
2196   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2197         (match_operand:TI 1 "general_operand" ""))]
2198   "reload_completed && !SSE_REG_P (operands[0])
2199    && !SSE_REG_P (operands[1])"
2200   [(const_int 0)]
2201   "ix86_split_long_move (operands); DONE;")
2203 (define_expand "movsf"
2204   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2205         (match_operand:SF 1 "general_operand" ""))]
2206   ""
2207   "ix86_expand_move (SFmode, operands); DONE;")
2209 (define_insn "*pushsf"
2210   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2211         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2212   "!TARGET_64BIT"
2214   switch (which_alternative)
2215     {
2216     case 1:
2217       return "push{l}\t%1";
2219     default:
2220       /* This insn should be already split before reg-stack.  */
2221       abort ();
2222     }
2224   [(set_attr "type" "multi,push,multi")
2225    (set_attr "mode" "SF,SI,SF")])
2227 (define_insn "*pushsf_rex64"
2228   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2229         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2230   "TARGET_64BIT"
2232   switch (which_alternative)
2233     {
2234     case 1:
2235       return "push{q}\t%q1";
2237     default:
2238       /* This insn should be already split before reg-stack.  */
2239       abort ();
2240     }
2242   [(set_attr "type" "multi,push,multi")
2243    (set_attr "mode" "SF,DI,SF")])
2245 (define_split
2246   [(set (match_operand:SF 0 "push_operand" "")
2247         (match_operand:SF 1 "memory_operand" ""))]
2248   "reload_completed
2249    && GET_CODE (operands[1]) == MEM
2250    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2251    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2252   [(set (match_dup 0)
2253         (match_dup 1))]
2254   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
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       abort();
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   abort ();
2395   [(set_attr "type" "multi")
2396    (set_attr "mode" "DF,SI,SI,DF")])
2398 (define_insn "*pushdf_integer"
2399   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2400         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2401   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2403   /* This insn should be already split before reg-stack.  */
2404   abort ();
2406   [(set_attr "type" "multi")
2407    (set_attr "mode" "DF,SI,DF")])
2409 ;; %%% Kill this when call knows how to work this out.
2410 (define_split
2411   [(set (match_operand:DF 0 "push_operand" "")
2412         (match_operand:DF 1 "any_fp_register_operand" ""))]
2413   "!TARGET_64BIT && reload_completed"
2414   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2415    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2416   "")
2418 (define_split
2419   [(set (match_operand:DF 0 "push_operand" "")
2420         (match_operand:DF 1 "any_fp_register_operand" ""))]
2421   "TARGET_64BIT && reload_completed"
2422   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2423    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2424   "")
2426 (define_split
2427   [(set (match_operand:DF 0 "push_operand" "")
2428         (match_operand:DF 1 "general_operand" ""))]
2429   "reload_completed"
2430   [(const_int 0)]
2431   "ix86_split_long_move (operands); DONE;")
2433 ;; Moving is usually shorter when only FP registers are used. This separate
2434 ;; movdf pattern avoids the use of integer registers for FP operations
2435 ;; when optimizing for size.
2437 (define_insn "*movdf_nointeger"
2438   [(set (match_operand:DF 0 "nonimmediate_operand"
2439                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2440         (match_operand:DF 1 "general_operand"
2441                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2442   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2443    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2444    && (reload_in_progress || reload_completed
2445        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2446        || GET_CODE (operands[1]) != CONST_DOUBLE
2447        || memory_operand (operands[0], DFmode))" 
2449   switch (which_alternative)
2450     {
2451     case 0:
2452       return output_387_reg_move (insn, operands);
2454     case 1:
2455       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2456         return "fstp%z0\t%y0";
2457       else
2458         return "fst%z0\t%y0";
2460     case 2:
2461       return standard_80387_constant_opcode (operands[1]);
2463     case 3:
2464     case 4:
2465       return "#";
2466     case 5:
2467       switch (get_attr_mode (insn))
2468         {
2469         case MODE_V4SF:
2470           return "xorps\t%0, %0";
2471         case MODE_V2DF:
2472           return "xorpd\t%0, %0";
2473         case MODE_TI:
2474           return "pxor\t%0, %0";
2475         default:
2476           abort ();
2477         }
2478     case 6:
2479     case 7:
2480     case 8:
2481       switch (get_attr_mode (insn))
2482         {
2483         case MODE_V4SF:
2484           return "movaps\t{%1, %0|%0, %1}";
2485         case MODE_V2DF:
2486           return "movapd\t{%1, %0|%0, %1}";
2487         case MODE_TI:
2488           return "movdqa\t{%1, %0|%0, %1}";
2489         case MODE_DI:
2490           return "movq\t{%1, %0|%0, %1}";
2491         case MODE_DF:
2492           return "movsd\t{%1, %0|%0, %1}";
2493         case MODE_V1DF:
2494           return "movlpd\t{%1, %0|%0, %1}";
2495         case MODE_V2SF:
2496           return "movlps\t{%1, %0|%0, %1}";
2497         default:
2498           abort ();
2499         }
2501     default:
2502       abort();
2503     }
2505   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2506    (set (attr "mode")
2507         (cond [(eq_attr "alternative" "0,1,2")
2508                  (const_string "DF")
2509                (eq_attr "alternative" "3,4")
2510                  (const_string "SI")
2512                /* For SSE1, we have many fewer alternatives.  */
2513                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2514                  (cond [(eq_attr "alternative" "5,6")
2515                           (const_string "V4SF")
2516                        ]
2517                    (const_string "V2SF"))
2519                /* xorps is one byte shorter.  */
2520                (eq_attr "alternative" "5")
2521                  (cond [(ne (symbol_ref "optimize_size")
2522                             (const_int 0))
2523                           (const_string "V4SF")
2524                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2525                             (const_int 0))
2526                           (const_string "TI")
2527                        ]
2528                        (const_string "V2DF"))
2530                /* For architectures resolving dependencies on
2531                   whole SSE registers use APD move to break dependency
2532                   chains, otherwise use short move to avoid extra work.
2534                   movaps encodes one byte shorter.  */
2535                (eq_attr "alternative" "6")
2536                  (cond
2537                    [(ne (symbol_ref "optimize_size")
2538                         (const_int 0))
2539                       (const_string "V4SF")
2540                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2541                         (const_int 0))
2542                       (const_string "V2DF")
2543                    ]
2544                    (const_string "DF"))
2545                /* For architectures resolving dependencies on register
2546                   parts we may avoid extra work to zero out upper part
2547                   of register.  */
2548                (eq_attr "alternative" "7")
2549                  (if_then_else
2550                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2551                        (const_int 0))
2552                    (const_string "V1DF")
2553                    (const_string "DF"))
2554               ]
2555               (const_string "DF")))])
2557 (define_insn "*movdf_integer"
2558   [(set (match_operand:DF 0 "nonimmediate_operand"
2559                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2560         (match_operand:DF 1 "general_operand"
2561                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2562   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2563    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2564    && (reload_in_progress || reload_completed
2565        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2566        || GET_CODE (operands[1]) != CONST_DOUBLE
2567        || memory_operand (operands[0], DFmode))" 
2569   switch (which_alternative)
2570     {
2571     case 0:
2572       return output_387_reg_move (insn, operands);
2574     case 1:
2575       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2576         return "fstp%z0\t%y0";
2577       else
2578         return "fst%z0\t%y0";
2580     case 2:
2581       return standard_80387_constant_opcode (operands[1]);
2583     case 3:
2584     case 4:
2585       return "#";
2587     case 5:
2588       switch (get_attr_mode (insn))
2589         {
2590         case MODE_V4SF:
2591           return "xorps\t%0, %0";
2592         case MODE_V2DF:
2593           return "xorpd\t%0, %0";
2594         case MODE_TI:
2595           return "pxor\t%0, %0";
2596         default:
2597           abort ();
2598         }
2599     case 6:
2600     case 7:
2601     case 8:
2602       switch (get_attr_mode (insn))
2603         {
2604         case MODE_V4SF:
2605           return "movaps\t{%1, %0|%0, %1}";
2606         case MODE_V2DF:
2607           return "movapd\t{%1, %0|%0, %1}";
2608         case MODE_TI:
2609           return "movdqa\t{%1, %0|%0, %1}";
2610         case MODE_DI:
2611           return "movq\t{%1, %0|%0, %1}";
2612         case MODE_DF:
2613           return "movsd\t{%1, %0|%0, %1}";
2614         case MODE_V1DF:
2615           return "movlpd\t{%1, %0|%0, %1}";
2616         case MODE_V2SF:
2617           return "movlps\t{%1, %0|%0, %1}";
2618         default:
2619           abort ();
2620         }
2622     default:
2623       abort();
2624     }
2626   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2627    (set (attr "mode")
2628         (cond [(eq_attr "alternative" "0,1,2")
2629                  (const_string "DF")
2630                (eq_attr "alternative" "3,4")
2631                  (const_string "SI")
2633                /* For SSE1, we have many fewer alternatives.  */
2634                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2635                  (cond [(eq_attr "alternative" "5,6")
2636                           (const_string "V4SF")
2637                        ]
2638                    (const_string "V2SF"))
2640                /* xorps is one byte shorter.  */
2641                (eq_attr "alternative" "5")
2642                  (cond [(ne (symbol_ref "optimize_size")
2643                             (const_int 0))
2644                           (const_string "V4SF")
2645                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2646                             (const_int 0))
2647                           (const_string "TI")
2648                        ]
2649                        (const_string "V2DF"))
2651                /* For architectures resolving dependencies on
2652                   whole SSE registers use APD move to break dependency
2653                   chains, otherwise use short move to avoid extra work.
2655                   movaps encodes one byte shorter.  */
2656                (eq_attr "alternative" "6")
2657                  (cond
2658                    [(ne (symbol_ref "optimize_size")
2659                         (const_int 0))
2660                       (const_string "V4SF")
2661                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2662                         (const_int 0))
2663                       (const_string "V2DF")
2664                    ]
2665                    (const_string "DF"))
2666                /* For architectures resolving dependencies on register
2667                   parts we may avoid extra work to zero out upper part
2668                   of register.  */
2669                (eq_attr "alternative" "7")
2670                  (if_then_else
2671                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2672                        (const_int 0))
2673                    (const_string "V1DF")
2674                    (const_string "DF"))
2675               ]
2676               (const_string "DF")))])
2678 (define_split
2679   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2680         (match_operand:DF 1 "general_operand" ""))]
2681   "reload_completed
2682    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2683    && ! (ANY_FP_REG_P (operands[0]) || 
2684          (GET_CODE (operands[0]) == SUBREG
2685           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2686    && ! (ANY_FP_REG_P (operands[1]) || 
2687          (GET_CODE (operands[1]) == SUBREG
2688           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2689   [(const_int 0)]
2690   "ix86_split_long_move (operands); DONE;")
2692 (define_insn "*swapdf"
2693   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2694         (match_operand:DF 1 "fp_register_operand" "+f"))
2695    (set (match_dup 1)
2696         (match_dup 0))]
2697   "reload_completed || TARGET_80387"
2699   if (STACK_TOP_P (operands[0]))
2700     return "fxch\t%1";
2701   else
2702     return "fxch\t%0";
2704   [(set_attr "type" "fxch")
2705    (set_attr "mode" "DF")])
2707 (define_expand "movxf"
2708   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2709         (match_operand:XF 1 "general_operand" ""))]
2710   ""
2711   "ix86_expand_move (XFmode, operands); DONE;")
2713 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2714 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2715 ;; Pushing using integer instructions is longer except for constants
2716 ;; and direct memory references.
2717 ;; (assuming that any given constant is pushed only once, but this ought to be
2718 ;;  handled elsewhere).
2720 (define_insn "*pushxf_nointeger"
2721   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2722         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2723   "optimize_size"
2725   /* This insn should be already split before reg-stack.  */
2726   abort ();
2728   [(set_attr "type" "multi")
2729    (set_attr "mode" "XF,SI,SI")])
2731 (define_insn "*pushxf_integer"
2732   [(set (match_operand:XF 0 "push_operand" "=<,<")
2733         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2734   "!optimize_size"
2736   /* This insn should be already split before reg-stack.  */
2737   abort ();
2739   [(set_attr "type" "multi")
2740    (set_attr "mode" "XF,SI")])
2742 (define_split
2743   [(set (match_operand 0 "push_operand" "")
2744         (match_operand 1 "general_operand" ""))]
2745   "reload_completed
2746    && (GET_MODE (operands[0]) == XFmode
2747        || GET_MODE (operands[0]) == DFmode)
2748    && !ANY_FP_REG_P (operands[1])"
2749   [(const_int 0)]
2750   "ix86_split_long_move (operands); DONE;")
2752 (define_split
2753   [(set (match_operand:XF 0 "push_operand" "")
2754         (match_operand:XF 1 "any_fp_register_operand" ""))]
2755   "!TARGET_64BIT"
2756   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2757    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2758   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2760 (define_split
2761   [(set (match_operand:XF 0 "push_operand" "")
2762         (match_operand:XF 1 "any_fp_register_operand" ""))]
2763   "TARGET_64BIT"
2764   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2765    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2766   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2768 ;; Do not use integer registers when optimizing for size
2769 (define_insn "*movxf_nointeger"
2770   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2771         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2772   "optimize_size
2773    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2774    && (reload_in_progress || reload_completed
2775        || GET_CODE (operands[1]) != CONST_DOUBLE
2776        || memory_operand (operands[0], XFmode))" 
2778   switch (which_alternative)
2779     {
2780     case 0:
2781       return output_387_reg_move (insn, operands);
2783     case 1:
2784       /* There is no non-popping store to memory for XFmode.  So if
2785          we need one, follow the store with a load.  */
2786       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2787         return "fstp%z0\t%y0\;fld%z0\t%y0";
2788       else
2789         return "fstp%z0\t%y0";
2791     case 2:
2792       return standard_80387_constant_opcode (operands[1]);
2794     case 3: case 4:
2795       return "#";
2796     }
2797   abort();
2799   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2800    (set_attr "mode" "XF,XF,XF,SI,SI")])
2802 (define_insn "*movxf_integer"
2803   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2804         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2805   "!optimize_size
2806    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2807    && (reload_in_progress || reload_completed
2808        || GET_CODE (operands[1]) != CONST_DOUBLE
2809        || memory_operand (operands[0], XFmode))" 
2811   switch (which_alternative)
2812     {
2813     case 0:
2814       return output_387_reg_move (insn, operands);
2816     case 1:
2817       /* There is no non-popping store to memory for XFmode.  So if
2818          we need one, follow the store with a load.  */
2819       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2820         return "fstp%z0\t%y0\;fld%z0\t%y0";
2821       else
2822         return "fstp%z0\t%y0";
2824     case 2:
2825       return standard_80387_constant_opcode (operands[1]);
2827     case 3: case 4:
2828       return "#";
2829     }
2830   abort();
2832   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2833    (set_attr "mode" "XF,XF,XF,SI,SI")])
2835 (define_split
2836   [(set (match_operand 0 "nonimmediate_operand" "")
2837         (match_operand 1 "general_operand" ""))]
2838   "reload_completed
2839    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2840    && GET_MODE (operands[0]) == XFmode
2841    && ! (ANY_FP_REG_P (operands[0]) || 
2842          (GET_CODE (operands[0]) == SUBREG
2843           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2844    && ! (ANY_FP_REG_P (operands[1]) || 
2845          (GET_CODE (operands[1]) == SUBREG
2846           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2847   [(const_int 0)]
2848   "ix86_split_long_move (operands); DONE;")
2850 (define_split
2851   [(set (match_operand 0 "register_operand" "")
2852         (match_operand 1 "memory_operand" ""))]
2853   "reload_completed
2854    && GET_CODE (operands[1]) == MEM
2855    && (GET_MODE (operands[0]) == XFmode
2856        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2857    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2858    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2859   [(set (match_dup 0) (match_dup 1))]
2861   rtx c = get_pool_constant (XEXP (operands[1], 0));
2862   rtx r = operands[0];
2864   if (GET_CODE (r) == SUBREG)
2865     r = SUBREG_REG (r);
2867   if (SSE_REG_P (r))
2868     {
2869       if (!standard_sse_constant_p (c))
2870         FAIL;
2871     }
2872   else if (FP_REG_P (r))
2873     {
2874       if (!standard_80387_constant_p (c))
2875         FAIL;
2876     }
2877   else if (MMX_REG_P (r))
2878     FAIL;
2880   operands[1] = c;
2883 (define_insn "swapxf"
2884   [(set (match_operand:XF 0 "register_operand" "+f")
2885         (match_operand:XF 1 "register_operand" "+f"))
2886    (set (match_dup 1)
2887         (match_dup 0))]
2888   "TARGET_80387"
2890   if (STACK_TOP_P (operands[0]))
2891     return "fxch\t%1";
2892   else
2893     return "fxch\t%0";
2895   [(set_attr "type" "fxch")
2896    (set_attr "mode" "XF")])
2898 (define_expand "movtf"
2899   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2900         (match_operand:TF 1 "nonimmediate_operand" ""))]
2901   "TARGET_64BIT"
2903   ix86_expand_move (TFmode, operands);
2904   DONE;
2907 (define_insn "*movtf_internal"
2908   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2909         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2910   "TARGET_64BIT
2911    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2913   switch (which_alternative)
2914     {
2915     case 0:
2916     case 1:
2917       return "#";
2918     case 2:
2919       if (get_attr_mode (insn) == MODE_V4SF)
2920         return "xorps\t%0, %0";
2921       else
2922         return "pxor\t%0, %0";
2923     case 3:
2924     case 4:
2925       if (get_attr_mode (insn) == MODE_V4SF)
2926         return "movaps\t{%1, %0|%0, %1}";
2927       else
2928         return "movdqa\t{%1, %0|%0, %1}";
2929     default:
2930       abort ();
2931     }
2933   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2934    (set (attr "mode")
2935         (cond [(eq_attr "alternative" "2,3")
2936                  (if_then_else
2937                    (ne (symbol_ref "optimize_size")
2938                        (const_int 0))
2939                    (const_string "V4SF")
2940                    (const_string "TI"))
2941                (eq_attr "alternative" "4")
2942                  (if_then_else
2943                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2944                             (const_int 0))
2945                         (ne (symbol_ref "optimize_size")
2946                             (const_int 0)))
2947                    (const_string "V4SF")
2948                    (const_string "TI"))]
2949                (const_string "DI")))])
2951 (define_split
2952   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2953         (match_operand:TF 1 "general_operand" ""))]
2954   "reload_completed && !SSE_REG_P (operands[0])
2955    && !SSE_REG_P (operands[1])"
2956   [(const_int 0)]
2957   "ix86_split_long_move (operands); DONE;")
2959 ;; Zero extension instructions
2961 (define_expand "zero_extendhisi2"
2962   [(set (match_operand:SI 0 "register_operand" "")
2963      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2964   ""
2966   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2967     {
2968       operands[1] = force_reg (HImode, operands[1]);
2969       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2970       DONE;
2971     }
2974 (define_insn "zero_extendhisi2_and"
2975   [(set (match_operand:SI 0 "register_operand" "=r")
2976      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2977    (clobber (reg:CC FLAGS_REG))]
2978   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2979   "#"
2980   [(set_attr "type" "alu1")
2981    (set_attr "mode" "SI")])
2983 (define_split
2984   [(set (match_operand:SI 0 "register_operand" "")
2985         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2986    (clobber (reg:CC FLAGS_REG))]
2987   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2988   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2989               (clobber (reg:CC FLAGS_REG))])]
2990   "")
2992 (define_insn "*zero_extendhisi2_movzwl"
2993   [(set (match_operand:SI 0 "register_operand" "=r")
2994      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2995   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2996   "movz{wl|x}\t{%1, %0|%0, %1}"
2997   [(set_attr "type" "imovx")
2998    (set_attr "mode" "SI")])
3000 (define_expand "zero_extendqihi2"
3001   [(parallel
3002     [(set (match_operand:HI 0 "register_operand" "")
3003        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3004      (clobber (reg:CC FLAGS_REG))])]
3005   ""
3006   "")
3008 (define_insn "*zero_extendqihi2_and"
3009   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3010      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3011    (clobber (reg:CC FLAGS_REG))]
3012   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3013   "#"
3014   [(set_attr "type" "alu1")
3015    (set_attr "mode" "HI")])
3017 (define_insn "*zero_extendqihi2_movzbw_and"
3018   [(set (match_operand:HI 0 "register_operand" "=r,r")
3019      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3020    (clobber (reg:CC FLAGS_REG))]
3021   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3022   "#"
3023   [(set_attr "type" "imovx,alu1")
3024    (set_attr "mode" "HI")])
3026 (define_insn "*zero_extendqihi2_movzbw"
3027   [(set (match_operand:HI 0 "register_operand" "=r")
3028      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3029   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3030   "movz{bw|x}\t{%1, %0|%0, %1}"
3031   [(set_attr "type" "imovx")
3032    (set_attr "mode" "HI")])
3034 ;; For the movzbw case strip only the clobber
3035 (define_split
3036   [(set (match_operand:HI 0 "register_operand" "")
3037         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3038    (clobber (reg:CC FLAGS_REG))]
3039   "reload_completed 
3040    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3041    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3042   [(set (match_operand:HI 0 "register_operand" "")
3043         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3045 ;; When source and destination does not overlap, clear destination
3046 ;; first and then do the movb
3047 (define_split
3048   [(set (match_operand:HI 0 "register_operand" "")
3049         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3050    (clobber (reg:CC FLAGS_REG))]
3051   "reload_completed
3052    && ANY_QI_REG_P (operands[0])
3053    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3054    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3055   [(set (match_dup 0) (const_int 0))
3056    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3057   "operands[2] = gen_lowpart (QImode, operands[0]);")
3059 ;; Rest is handled by single and.
3060 (define_split
3061   [(set (match_operand:HI 0 "register_operand" "")
3062         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3063    (clobber (reg:CC FLAGS_REG))]
3064   "reload_completed
3065    && true_regnum (operands[0]) == true_regnum (operands[1])"
3066   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3067               (clobber (reg:CC FLAGS_REG))])]
3068   "")
3070 (define_expand "zero_extendqisi2"
3071   [(parallel
3072     [(set (match_operand:SI 0 "register_operand" "")
3073        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3074      (clobber (reg:CC FLAGS_REG))])]
3075   ""
3076   "")
3078 (define_insn "*zero_extendqisi2_and"
3079   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3080      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3081    (clobber (reg:CC FLAGS_REG))]
3082   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3083   "#"
3084   [(set_attr "type" "alu1")
3085    (set_attr "mode" "SI")])
3087 (define_insn "*zero_extendqisi2_movzbw_and"
3088   [(set (match_operand:SI 0 "register_operand" "=r,r")
3089      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3090    (clobber (reg:CC FLAGS_REG))]
3091   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3092   "#"
3093   [(set_attr "type" "imovx,alu1")
3094    (set_attr "mode" "SI")])
3096 (define_insn "*zero_extendqisi2_movzbw"
3097   [(set (match_operand:SI 0 "register_operand" "=r")
3098      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3099   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3100   "movz{bl|x}\t{%1, %0|%0, %1}"
3101   [(set_attr "type" "imovx")
3102    (set_attr "mode" "SI")])
3104 ;; For the movzbl case strip only the clobber
3105 (define_split
3106   [(set (match_operand:SI 0 "register_operand" "")
3107         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3108    (clobber (reg:CC FLAGS_REG))]
3109   "reload_completed 
3110    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3111    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3112   [(set (match_dup 0)
3113         (zero_extend:SI (match_dup 1)))])
3115 ;; When source and destination does not overlap, clear destination
3116 ;; first and then do the movb
3117 (define_split
3118   [(set (match_operand:SI 0 "register_operand" "")
3119         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3120    (clobber (reg:CC FLAGS_REG))]
3121   "reload_completed
3122    && ANY_QI_REG_P (operands[0])
3123    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3124    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3125    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3126   [(set (match_dup 0) (const_int 0))
3127    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3128   "operands[2] = gen_lowpart (QImode, operands[0]);")
3130 ;; Rest is handled by single and.
3131 (define_split
3132   [(set (match_operand:SI 0 "register_operand" "")
3133         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3134    (clobber (reg:CC FLAGS_REG))]
3135   "reload_completed
3136    && true_regnum (operands[0]) == true_regnum (operands[1])"
3137   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3138               (clobber (reg:CC FLAGS_REG))])]
3139   "")
3141 ;; %%% Kill me once multi-word ops are sane.
3142 (define_expand "zero_extendsidi2"
3143   [(set (match_operand:DI 0 "register_operand" "=r")
3144      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3145   ""
3146   "if (!TARGET_64BIT)
3147      {
3148        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3149        DONE;
3150      }
3151   ")
3153 (define_insn "zero_extendsidi2_32"
3154   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3155         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3156    (clobber (reg:CC FLAGS_REG))]
3157   "!TARGET_64BIT"
3158   "@
3159    #
3160    #
3161    #
3162    movd\t{%1, %0|%0, %1}
3163    movd\t{%1, %0|%0, %1}"
3164   [(set_attr "mode" "SI,SI,SI,DI,TI")
3165    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3167 (define_insn "zero_extendsidi2_rex64"
3168   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3169      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3170   "TARGET_64BIT"
3171   "@
3172    mov\t{%k1, %k0|%k0, %k1}
3173    #
3174    movd\t{%1, %0|%0, %1}
3175    movd\t{%1, %0|%0, %1}"
3176   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3177    (set_attr "mode" "SI,DI,SI,SI")])
3179 (define_split
3180   [(set (match_operand:DI 0 "memory_operand" "")
3181      (zero_extend:DI (match_dup 0)))]
3182   "TARGET_64BIT"
3183   [(set (match_dup 4) (const_int 0))]
3184   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3186 (define_split 
3187   [(set (match_operand:DI 0 "register_operand" "")
3188         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3189    (clobber (reg:CC FLAGS_REG))]
3190   "!TARGET_64BIT && reload_completed
3191    && true_regnum (operands[0]) == true_regnum (operands[1])"
3192   [(set (match_dup 4) (const_int 0))]
3193   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3195 (define_split 
3196   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3197         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3198    (clobber (reg:CC FLAGS_REG))]
3199   "!TARGET_64BIT && reload_completed
3200    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3201   [(set (match_dup 3) (match_dup 1))
3202    (set (match_dup 4) (const_int 0))]
3203   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205 (define_insn "zero_extendhidi2"
3206   [(set (match_operand:DI 0 "register_operand" "=r,r")
3207      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3208   "TARGET_64BIT"
3209   "@
3210    movz{wl|x}\t{%1, %k0|%k0, %1}
3211    movz{wq|x}\t{%1, %0|%0, %1}"
3212   [(set_attr "type" "imovx")
3213    (set_attr "mode" "SI,DI")])
3215 (define_insn "zero_extendqidi2"
3216   [(set (match_operand:DI 0 "register_operand" "=r,r")
3217      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3218   "TARGET_64BIT"
3219   "@
3220    movz{bl|x}\t{%1, %k0|%k0, %1}
3221    movz{bq|x}\t{%1, %0|%0, %1}"
3222   [(set_attr "type" "imovx")
3223    (set_attr "mode" "SI,DI")])
3225 ;; Sign extension instructions
3227 (define_expand "extendsidi2"
3228   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3229                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3230               (clobber (reg:CC FLAGS_REG))
3231               (clobber (match_scratch:SI 2 ""))])]
3232   ""
3234   if (TARGET_64BIT)
3235     {
3236       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3237       DONE;
3238     }
3241 (define_insn "*extendsidi2_1"
3242   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3243         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3244    (clobber (reg:CC FLAGS_REG))
3245    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3246   "!TARGET_64BIT"
3247   "#")
3249 (define_insn "extendsidi2_rex64"
3250   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3251         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3252   "TARGET_64BIT"
3253   "@
3254    {cltq|cdqe}
3255    movs{lq|x}\t{%1,%0|%0, %1}"
3256   [(set_attr "type" "imovx")
3257    (set_attr "mode" "DI")
3258    (set_attr "prefix_0f" "0")
3259    (set_attr "modrm" "0,1")])
3261 (define_insn "extendhidi2"
3262   [(set (match_operand:DI 0 "register_operand" "=r")
3263         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3264   "TARGET_64BIT"
3265   "movs{wq|x}\t{%1,%0|%0, %1}"
3266   [(set_attr "type" "imovx")
3267    (set_attr "mode" "DI")])
3269 (define_insn "extendqidi2"
3270   [(set (match_operand:DI 0 "register_operand" "=r")
3271         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3272   "TARGET_64BIT"
3273   "movs{bq|x}\t{%1,%0|%0, %1}"
3274    [(set_attr "type" "imovx")
3275     (set_attr "mode" "DI")])
3277 ;; Extend to memory case when source register does die.
3278 (define_split 
3279   [(set (match_operand:DI 0 "memory_operand" "")
3280         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3281    (clobber (reg:CC FLAGS_REG))
3282    (clobber (match_operand:SI 2 "register_operand" ""))]
3283   "(reload_completed
3284     && dead_or_set_p (insn, operands[1])
3285     && !reg_mentioned_p (operands[1], operands[0]))"
3286   [(set (match_dup 3) (match_dup 1))
3287    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3288               (clobber (reg:CC FLAGS_REG))])
3289    (set (match_dup 4) (match_dup 1))]
3290   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3292 ;; Extend to memory case when source register does not die.
3293 (define_split 
3294   [(set (match_operand:DI 0 "memory_operand" "")
3295         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3296    (clobber (reg:CC FLAGS_REG))
3297    (clobber (match_operand:SI 2 "register_operand" ""))]
3298   "reload_completed"
3299   [(const_int 0)]
3301   split_di (&operands[0], 1, &operands[3], &operands[4]);
3303   emit_move_insn (operands[3], operands[1]);
3305   /* Generate a cltd if possible and doing so it profitable.  */
3306   if (true_regnum (operands[1]) == 0
3307       && true_regnum (operands[2]) == 1
3308       && (optimize_size || TARGET_USE_CLTD))
3309     {
3310       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3311     }
3312   else
3313     {
3314       emit_move_insn (operands[2], operands[1]);
3315       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3316     }
3317   emit_move_insn (operands[4], operands[2]);
3318   DONE;
3321 ;; Extend to register case.  Optimize case where source and destination
3322 ;; registers match and cases where we can use cltd.
3323 (define_split 
3324   [(set (match_operand:DI 0 "register_operand" "")
3325         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3326    (clobber (reg:CC FLAGS_REG))
3327    (clobber (match_scratch:SI 2 ""))]
3328   "reload_completed"
3329   [(const_int 0)]
3331   split_di (&operands[0], 1, &operands[3], &operands[4]);
3333   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3334     emit_move_insn (operands[3], operands[1]);
3336   /* Generate a cltd if possible and doing so it profitable.  */
3337   if (true_regnum (operands[3]) == 0
3338       && (optimize_size || TARGET_USE_CLTD))
3339     {
3340       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3341       DONE;
3342     }
3344   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3345     emit_move_insn (operands[4], operands[1]);
3347   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3348   DONE;
3351 (define_insn "extendhisi2"
3352   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3353         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3354   ""
3356   switch (get_attr_prefix_0f (insn))
3357     {
3358     case 0:
3359       return "{cwtl|cwde}";
3360     default:
3361       return "movs{wl|x}\t{%1,%0|%0, %1}";
3362     }
3364   [(set_attr "type" "imovx")
3365    (set_attr "mode" "SI")
3366    (set (attr "prefix_0f")
3367      ;; movsx is short decodable while cwtl is vector decoded.
3368      (if_then_else (and (eq_attr "cpu" "!k6")
3369                         (eq_attr "alternative" "0"))
3370         (const_string "0")
3371         (const_string "1")))
3372    (set (attr "modrm")
3373      (if_then_else (eq_attr "prefix_0f" "0")
3374         (const_string "0")
3375         (const_string "1")))])
3377 (define_insn "*extendhisi2_zext"
3378   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3379         (zero_extend:DI
3380           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3381   "TARGET_64BIT"
3383   switch (get_attr_prefix_0f (insn))
3384     {
3385     case 0:
3386       return "{cwtl|cwde}";
3387     default:
3388       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3389     }
3391   [(set_attr "type" "imovx")
3392    (set_attr "mode" "SI")
3393    (set (attr "prefix_0f")
3394      ;; movsx is short decodable while cwtl is vector decoded.
3395      (if_then_else (and (eq_attr "cpu" "!k6")
3396                         (eq_attr "alternative" "0"))
3397         (const_string "0")
3398         (const_string "1")))
3399    (set (attr "modrm")
3400      (if_then_else (eq_attr "prefix_0f" "0")
3401         (const_string "0")
3402         (const_string "1")))])
3404 (define_insn "extendqihi2"
3405   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3406         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3407   ""
3409   switch (get_attr_prefix_0f (insn))
3410     {
3411     case 0:
3412       return "{cbtw|cbw}";
3413     default:
3414       return "movs{bw|x}\t{%1,%0|%0, %1}";
3415     }
3417   [(set_attr "type" "imovx")
3418    (set_attr "mode" "HI")
3419    (set (attr "prefix_0f")
3420      ;; movsx is short decodable while cwtl is vector decoded.
3421      (if_then_else (and (eq_attr "cpu" "!k6")
3422                         (eq_attr "alternative" "0"))
3423         (const_string "0")
3424         (const_string "1")))
3425    (set (attr "modrm")
3426      (if_then_else (eq_attr "prefix_0f" "0")
3427         (const_string "0")
3428         (const_string "1")))])
3430 (define_insn "extendqisi2"
3431   [(set (match_operand:SI 0 "register_operand" "=r")
3432         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3433   ""
3434   "movs{bl|x}\t{%1,%0|%0, %1}"
3435    [(set_attr "type" "imovx")
3436     (set_attr "mode" "SI")])
3438 (define_insn "*extendqisi2_zext"
3439   [(set (match_operand:DI 0 "register_operand" "=r")
3440         (zero_extend:DI
3441           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3442   "TARGET_64BIT"
3443   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3444    [(set_attr "type" "imovx")
3445     (set_attr "mode" "SI")])
3447 ;; Conversions between float and double.
3449 ;; These are all no-ops in the model used for the 80387.  So just
3450 ;; emit moves.
3452 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3453 (define_insn "*dummy_extendsfdf2"
3454   [(set (match_operand:DF 0 "push_operand" "=<")
3455         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3456   "0"
3457   "#")
3459 (define_split
3460   [(set (match_operand:DF 0 "push_operand" "")
3461         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3462   "!TARGET_64BIT"
3463   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3464    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3466 (define_split
3467   [(set (match_operand:DF 0 "push_operand" "")
3468         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3469   "TARGET_64BIT"
3470   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3471    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3473 (define_insn "*dummy_extendsfxf2"
3474   [(set (match_operand:XF 0 "push_operand" "=<")
3475         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3476   "0"
3477   "#")
3479 (define_split
3480   [(set (match_operand:XF 0 "push_operand" "")
3481         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3482   ""
3483   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3484    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3485   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3487 (define_split
3488   [(set (match_operand:XF 0 "push_operand" "")
3489         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3490   "TARGET_64BIT"
3491   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3492    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3493   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3495 (define_split
3496   [(set (match_operand:XF 0 "push_operand" "")
3497         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3498   ""
3499   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3500    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3501   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3503 (define_split
3504   [(set (match_operand:XF 0 "push_operand" "")
3505         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3506   "TARGET_64BIT"
3507   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3508    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3509   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3511 (define_expand "extendsfdf2"
3512   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3513         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3514   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3516   /* ??? Needed for compress_float_constant since all fp constants
3517      are LEGITIMATE_CONSTANT_P.  */
3518   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3519     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3520   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3521     operands[1] = force_reg (SFmode, operands[1]);
3524 (define_insn "*extendsfdf2_mixed"
3525   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3526         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3527   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3528    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3530   switch (which_alternative)
3531     {
3532     case 0:
3533       return output_387_reg_move (insn, operands);
3535     case 1:
3536       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3537         return "fstp%z0\t%y0";
3538       else
3539         return "fst%z0\t%y0";
3541     case 2:
3542       return "cvtss2sd\t{%1, %0|%0, %1}";
3544     default:
3545       abort ();
3546     }
3548   [(set_attr "type" "fmov,fmov,ssecvt")
3549    (set_attr "mode" "SF,XF,DF")])
3551 (define_insn "*extendsfdf2_sse"
3552   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3553         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3554   "TARGET_SSE2 && TARGET_SSE_MATH
3555    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3556   "cvtss2sd\t{%1, %0|%0, %1}"
3557   [(set_attr "type" "ssecvt")
3558    (set_attr "mode" "DF")])
3560 (define_insn "*extendsfdf2_i387"
3561   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3562         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3563   "TARGET_80387
3564    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3566   switch (which_alternative)
3567     {
3568     case 0:
3569       return output_387_reg_move (insn, operands);
3571     case 1:
3572       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3573         return "fstp%z0\t%y0";
3574       else
3575         return "fst%z0\t%y0";
3577     default:
3578       abort ();
3579     }
3581   [(set_attr "type" "fmov")
3582    (set_attr "mode" "SF,XF")])
3584 (define_expand "extendsfxf2"
3585   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3586         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3587   "TARGET_80387"
3589   /* ??? Needed for compress_float_constant since all fp constants
3590      are LEGITIMATE_CONSTANT_P.  */
3591   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3592     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3593   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3594     operands[1] = force_reg (SFmode, operands[1]);
3597 (define_insn "*extendsfxf2_i387"
3598   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3599         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3600   "TARGET_80387
3601    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3603   switch (which_alternative)
3604     {
3605     case 0:
3606       return output_387_reg_move (insn, operands);
3608     case 1:
3609       /* There is no non-popping store to memory for XFmode.  So if
3610          we need one, follow the store with a load.  */
3611       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3612         return "fstp%z0\t%y0";
3613       else
3614         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3616     default:
3617       abort ();
3618     }
3620   [(set_attr "type" "fmov")
3621    (set_attr "mode" "SF,XF")])
3623 (define_expand "extenddfxf2"
3624   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3625         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3626   "TARGET_80387"
3628   /* ??? Needed for compress_float_constant since all fp constants
3629      are LEGITIMATE_CONSTANT_P.  */
3630   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3631     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3632   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3633     operands[1] = force_reg (DFmode, operands[1]);
3636 (define_insn "*extenddfxf2_i387"
3637   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3638         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3639   "TARGET_80387
3640    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3642   switch (which_alternative)
3643     {
3644     case 0:
3645       return output_387_reg_move (insn, operands);
3647     case 1:
3648       /* There is no non-popping store to memory for XFmode.  So if
3649          we need one, follow the store with a load.  */
3650       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3651         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3652       else
3653         return "fstp%z0\t%y0";
3655     default:
3656       abort ();
3657     }
3659   [(set_attr "type" "fmov")
3660    (set_attr "mode" "DF,XF")])
3662 ;; %%% This seems bad bad news.
3663 ;; This cannot output into an f-reg because there is no way to be sure
3664 ;; of truncating in that case.  Otherwise this is just like a simple move
3665 ;; insn.  So we pretend we can output to a reg in order to get better
3666 ;; register preferencing, but we really use a stack slot.
3668 ;; Conversion from DFmode to SFmode.
3670 (define_expand "truncdfsf2"
3671   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3672         (float_truncate:SF
3673           (match_operand:DF 1 "nonimmediate_operand" "")))]
3674   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3676   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3677     operands[1] = force_reg (DFmode, operands[1]);
3679   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3680     ;
3681   else if (flag_unsafe_math_optimizations)
3682     ;
3683   else
3684     {
3685       rtx temp = assign_386_stack_local (SFmode, 0);
3686       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3687       DONE;
3688     }
3691 (define_expand "truncdfsf2_with_temp"
3692   [(parallel [(set (match_operand:SF 0 "" "")
3693                    (float_truncate:SF (match_operand:DF 1 "" "")))
3694               (clobber (match_operand:SF 2 "" ""))])]
3695   "")
3697 (define_insn "*truncdfsf_fast_mixed"
3698   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3699         (float_truncate:SF
3700           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3701   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3703   switch (which_alternative)
3704     {
3705     case 0:
3706       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3707         return "fstp%z0\t%y0";
3708       else
3709         return "fst%z0\t%y0";
3710     case 1:
3711       return output_387_reg_move (insn, operands);
3712     case 2:
3713       return "cvtsd2ss\t{%1, %0|%0, %1}";
3714     default:
3715       abort ();
3716     }
3718   [(set_attr "type" "fmov,fmov,ssecvt")
3719    (set_attr "mode" "SF")])
3721 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3722 ;; because nothing we do here is unsafe.
3723 (define_insn "*truncdfsf_fast_sse"
3724   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3725         (float_truncate:SF
3726           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3727   "TARGET_SSE2 && TARGET_SSE_MATH"
3728   "cvtsd2ss\t{%1, %0|%0, %1}"
3729   [(set_attr "type" "ssecvt")
3730    (set_attr "mode" "SF")])
3732 (define_insn "*truncdfsf_fast_i387"
3733   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3734         (float_truncate:SF
3735           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3736   "TARGET_80387 && flag_unsafe_math_optimizations"
3737   "* return output_387_reg_move (insn, operands);"
3738   [(set_attr "type" "fmov")
3739    (set_attr "mode" "SF")])
3741 (define_insn "*truncdfsf_mixed"
3742   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3743         (float_truncate:SF
3744           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3745    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3746   "TARGET_MIX_SSE_I387"
3748   switch (which_alternative)
3749     {
3750     case 0:
3751       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3752         return "fstp%z0\t%y0";
3753       else
3754         return "fst%z0\t%y0";
3755     case 1:
3756       return "#";
3757     case 2:
3758       return "cvtsd2ss\t{%1, %0|%0, %1}";
3759     default:
3760       abort ();
3761     }
3763   [(set_attr "type" "fmov,multi,ssecvt")
3764    (set_attr "mode" "SF")])
3766 (define_insn "*truncdfsf_i387"
3767   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3768         (float_truncate:SF
3769           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3770    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3771   "TARGET_80387"
3773   switch (which_alternative)
3774     {
3775     case 0:
3776       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3777         return "fstp%z0\t%y0";
3778       else
3779         return "fst%z0\t%y0";
3780     case 1:
3781       return "#";
3782     default:
3783       abort ();
3784     }
3786   [(set_attr "type" "fmov,multi")
3787    (set_attr "mode" "SF")])
3789 (define_split
3790   [(set (match_operand:SF 0 "register_operand" "")
3791         (float_truncate:SF
3792          (match_operand:DF 1 "fp_register_operand" "")))
3793    (clobber (match_operand 2 "" ""))]
3794   "reload_completed"
3795   [(set (match_dup 2) (match_dup 1))
3796    (set (match_dup 0) (match_dup 2))]
3798   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3801 ;; Conversion from XFmode to SFmode.
3803 (define_expand "truncxfsf2"
3804   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3805                    (float_truncate:SF
3806                     (match_operand:XF 1 "register_operand" "")))
3807               (clobber (match_dup 2))])]
3808   "TARGET_80387"
3810   if (flag_unsafe_math_optimizations)
3811     {
3812       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3813       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3814       if (reg != operands[0])
3815         emit_move_insn (operands[0], reg);
3816       DONE;
3817     }
3818   else
3819     operands[2] = assign_386_stack_local (SFmode, 0);
3822 (define_insn "*truncxfsf2_mixed"
3823   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3824         (float_truncate:SF
3825          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3826    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3827   "TARGET_MIX_SSE_I387"
3829   switch (which_alternative)
3830     {
3831     case 0:
3832       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3833         return "fstp%z0\t%y0";
3834       else
3835         return "fst%z0\t%y0";
3836     default:
3837       abort();
3838     }
3840   [(set_attr "type" "fmov,multi,multi,multi")
3841    (set_attr "mode" "SF")])
3843 (define_insn "truncxfsf2_i387_noop"
3844   [(set (match_operand:SF 0 "register_operand" "=f")
3845         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3846   "TARGET_80387 && flag_unsafe_math_optimizations"
3848   return output_387_reg_move (insn, operands);
3850   [(set_attr "type" "fmov")
3851    (set_attr "mode" "SF")])
3853 (define_insn "*truncxfsf2_i387"
3854   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3855         (float_truncate:SF
3856          (match_operand:XF 1 "register_operand" "f,f,f")))
3857    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3858   "TARGET_80387"
3860   switch (which_alternative)
3861     {
3862     case 0:
3863       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3864         return "fstp%z0\t%y0";
3865       else
3866         return "fst%z0\t%y0";
3867     default:
3868       abort ();
3869     }
3871   [(set_attr "type" "fmov,multi,multi")
3872    (set_attr "mode" "SF")])
3874 (define_insn "*truncxfsf2_i387_1"
3875   [(set (match_operand:SF 0 "memory_operand" "=m")
3876         (float_truncate:SF
3877          (match_operand:XF 1 "register_operand" "f")))]
3878   "TARGET_80387"
3880   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3881     return "fstp%z0\t%y0";
3882   else
3883     return "fst%z0\t%y0";
3885   [(set_attr "type" "fmov")
3886    (set_attr "mode" "SF")])
3888 (define_split
3889   [(set (match_operand:SF 0 "register_operand" "")
3890         (float_truncate:SF
3891          (match_operand:XF 1 "register_operand" "")))
3892    (clobber (match_operand:SF 2 "memory_operand" ""))]
3893   "TARGET_80387 && reload_completed"
3894   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3895    (set (match_dup 0) (match_dup 2))]
3896   "")
3898 (define_split
3899   [(set (match_operand:SF 0 "memory_operand" "")
3900         (float_truncate:SF
3901          (match_operand:XF 1 "register_operand" "")))
3902    (clobber (match_operand:SF 2 "memory_operand" ""))]
3903   "TARGET_80387"
3904   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3905   "")
3907 ;; Conversion from XFmode to DFmode.
3909 (define_expand "truncxfdf2"
3910   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3911                    (float_truncate:DF
3912                     (match_operand:XF 1 "register_operand" "")))
3913               (clobber (match_dup 2))])]
3914   "TARGET_80387"
3916   if (flag_unsafe_math_optimizations)
3917     {
3918       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3919       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3920       if (reg != operands[0])
3921         emit_move_insn (operands[0], reg);
3922       DONE;
3923     }
3924   else
3925     operands[2] = assign_386_stack_local (DFmode, 0);
3928 (define_insn "*truncxfdf2_mixed"
3929   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3930         (float_truncate:DF
3931          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3932    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3933   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3935   switch (which_alternative)
3936     {
3937     case 0:
3938       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3939         return "fstp%z0\t%y0";
3940       else
3941         return "fst%z0\t%y0";
3942     default:
3943       abort();
3944     }
3945   abort ();
3947   [(set_attr "type" "fmov,multi,multi,multi")
3948    (set_attr "mode" "DF")])
3950 (define_insn "truncxfdf2_i387_noop"
3951   [(set (match_operand:DF 0 "register_operand" "=f")
3952         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3953   "TARGET_80387 && flag_unsafe_math_optimizations"
3955   return output_387_reg_move (insn, operands);
3957   [(set_attr "type" "fmov")
3958    (set_attr "mode" "DF")])
3960 (define_insn "*truncxfdf2_i387"
3961   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3962         (float_truncate:DF
3963          (match_operand:XF 1 "register_operand" "f,f,f")))
3964    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3965   "TARGET_80387"
3967   switch (which_alternative)
3968     {
3969     case 0:
3970       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3971         return "fstp%z0\t%y0";
3972       else
3973         return "fst%z0\t%y0";
3974     default:
3975       abort ();
3976     }
3978   [(set_attr "type" "fmov,multi,multi")
3979    (set_attr "mode" "DF")])
3981 (define_insn "*truncxfdf2_i387_1"
3982   [(set (match_operand:DF 0 "memory_operand" "=m")
3983         (float_truncate:DF
3984           (match_operand:XF 1 "register_operand" "f")))]
3985   "TARGET_80387"
3987   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3988     return "fstp%z0\t%y0";
3989   else
3990     return "fst%z0\t%y0";
3992   [(set_attr "type" "fmov")
3993    (set_attr "mode" "DF")])
3995 (define_split
3996   [(set (match_operand:DF 0 "register_operand" "")
3997         (float_truncate:DF
3998          (match_operand:XF 1 "register_operand" "")))
3999    (clobber (match_operand:DF 2 "memory_operand" ""))]
4000   "TARGET_80387 && reload_completed"
4001   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4002    (set (match_dup 0) (match_dup 2))]
4003   "")
4005 (define_split
4006   [(set (match_operand:DF 0 "memory_operand" "")
4007         (float_truncate:DF
4008          (match_operand:XF 1 "register_operand" "")))
4009    (clobber (match_operand:DF 2 "memory_operand" ""))]
4010   "TARGET_80387"
4011   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4012   "")
4014 ;; Signed conversion to DImode.
4016 (define_expand "fix_truncxfdi2"
4017   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4018                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4019               (clobber (reg:CC FLAGS_REG))])]
4020   "TARGET_80387"
4022   if (TARGET_FISTTP)
4023    {
4024      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4025      DONE;
4026    }
4029 (define_expand "fix_trunc<mode>di2"
4030   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4031                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4032               (clobber (reg:CC FLAGS_REG))])]
4033   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4035   if (TARGET_FISTTP
4036       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4037    {
4038      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4039      DONE;
4040    }
4041   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4042    {
4043      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4044      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4045      if (out != operands[0])
4046         emit_move_insn (operands[0], out);
4047      DONE;
4048    }
4051 ;; Signed conversion to SImode.
4053 (define_expand "fix_truncxfsi2"
4054   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4055                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4056               (clobber (reg:CC FLAGS_REG))])]
4057   "TARGET_80387"
4059   if (TARGET_FISTTP)
4060    {
4061      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4062      DONE;
4063    }
4066 (define_expand "fix_trunc<mode>si2"
4067   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4068                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4069               (clobber (reg:CC FLAGS_REG))])]
4070   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4072   if (TARGET_FISTTP
4073       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4074    {
4075      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4076      DONE;
4077    }
4078   if (SSE_FLOAT_MODE_P (<MODE>mode))
4079    {
4080      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4081      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4082      if (out != operands[0])
4083         emit_move_insn (operands[0], out);
4084      DONE;
4085    }
4088 ;; Signed conversion to HImode.
4090 (define_expand "fix_trunc<mode>hi2"
4091   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4092                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4093               (clobber (reg:CC FLAGS_REG))])]
4094   "TARGET_80387
4095    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4097   if (TARGET_FISTTP)
4098    {
4099      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4100      DONE;
4101    }
4104 ;; When SSE is available, it is always faster to use it!
4105 (define_insn "fix_truncsfdi_sse"
4106   [(set (match_operand:DI 0 "register_operand" "=r,r")
4107         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4108   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4109   "cvttss2si{q}\t{%1, %0|%0, %1}"
4110   [(set_attr "type" "sseicvt")
4111    (set_attr "mode" "SF")
4112    (set_attr "athlon_decode" "double,vector")])
4114 (define_insn "fix_truncdfdi_sse"
4115   [(set (match_operand:DI 0 "register_operand" "=r,r")
4116         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4117   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4118   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4119   [(set_attr "type" "sseicvt")
4120    (set_attr "mode" "DF")
4121    (set_attr "athlon_decode" "double,vector")])
4123 (define_insn "fix_truncsfsi_sse"
4124   [(set (match_operand:SI 0 "register_operand" "=r,r")
4125         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4126   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4127   "cvttss2si\t{%1, %0|%0, %1}"
4128   [(set_attr "type" "sseicvt")
4129    (set_attr "mode" "DF")
4130    (set_attr "athlon_decode" "double,vector")])
4132 (define_insn "fix_truncdfsi_sse"
4133   [(set (match_operand:SI 0 "register_operand" "=r,r")
4134         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4135   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4136   "cvttsd2si\t{%1, %0|%0, %1}"
4137   [(set_attr "type" "sseicvt")
4138    (set_attr "mode" "DF")
4139    (set_attr "athlon_decode" "double,vector")])
4141 ;; Avoid vector decoded forms of the instruction.
4142 (define_peephole2
4143   [(match_scratch:DF 2 "Y")
4144    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4145         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4146   "TARGET_K8 && !optimize_size"
4147   [(set (match_dup 2) (match_dup 1))
4148    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4149   "")
4151 (define_peephole2
4152   [(match_scratch:SF 2 "x")
4153    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4154         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4155   "TARGET_K8 && !optimize_size"
4156   [(set (match_dup 2) (match_dup 1))
4157    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4158   "")
4160 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4161   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4162         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4163   "TARGET_80387 && TARGET_FISTTP
4164    && FLOAT_MODE_P (GET_MODE (operands[1]))
4165    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4166          && (TARGET_64BIT || <MODE>mode != DImode))
4167         && TARGET_SSE_MATH)
4168    && !(reload_completed || reload_in_progress)"
4169   "#"
4170   "&& 1"
4171   [(const_int 0)]
4173   if (memory_operand (operands[0], VOIDmode))
4174     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4175   else
4176     {
4177       operands[2] = assign_386_stack_local (<MODE>mode, 0);
4178       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4179                                                             operands[1],
4180                                                             operands[2]));
4181     }
4182   DONE;
4184   [(set_attr "type" "fisttp")
4185    (set_attr "mode" "<MODE>")])
4187 (define_insn "fix_trunc<mode>_i387_fisttp"
4188   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4189         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4190    (clobber (match_scratch:XF 2 "=&1f"))]
4191   "TARGET_80387 && TARGET_FISTTP
4192    && FLOAT_MODE_P (GET_MODE (operands[1]))
4193    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4194          && (TARGET_64BIT || <MODE>mode != DImode))
4195         && TARGET_SSE_MATH)"
4196   "* return output_fix_trunc (insn, operands, 1);"
4197   [(set_attr "type" "fisttp")
4198    (set_attr "mode" "<MODE>")])
4200 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4201   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4202         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4203    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4204    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4205   "TARGET_80387 && TARGET_FISTTP
4206    && FLOAT_MODE_P (GET_MODE (operands[1]))
4207    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4208         && (TARGET_64BIT || <MODE>mode != DImode))
4209         && TARGET_SSE_MATH)"
4210   "#"
4211   [(set_attr "type" "fisttp")
4212    (set_attr "mode" "<MODE>")])
4214 (define_split
4215   [(set (match_operand:X87MODEI 0 "register_operand" "")
4216         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4217    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4218    (clobber (match_scratch 3 ""))]
4219   "reload_completed"
4220   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4221               (clobber (match_dup 3))])
4222    (set (match_dup 0) (match_dup 2))]
4223   "")
4225 (define_split
4226   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4227         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4228    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4229    (clobber (match_scratch 3 ""))]
4230   "reload_completed"
4231   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4232               (clobber (match_dup 3))])]
4233   "")
4235 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4236 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4237 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4238 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4239 ;; function in i386.c.
4240 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4241   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4242         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4243    (clobber (reg:CC FLAGS_REG))]
4244   "TARGET_80387 && !TARGET_FISTTP
4245    && FLOAT_MODE_P (GET_MODE (operands[1]))
4246    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4247          && (TARGET_64BIT || <MODE>mode != DImode))
4248    && !(reload_completed || reload_in_progress)"
4249   "#"
4250   "&& 1"
4251   [(const_int 0)]
4253   ix86_optimize_mode_switching = 1;
4254   operands[2] = assign_386_stack_local (HImode, 1);
4255   operands[3] = assign_386_stack_local (HImode, 2);
4256   if (memory_operand (operands[0], VOIDmode))
4257     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4258                                          operands[2], operands[3]));
4259   else
4260     {
4261       operands[4] = assign_386_stack_local (<MODE>mode, 0);
4262       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4263                                                      operands[2], operands[3],
4264                                                      operands[4]));
4265     }
4266   DONE;
4268   [(set_attr "type" "fistp")
4269    (set_attr "i387_cw" "trunc")
4270    (set_attr "mode" "<MODE>")])
4272 (define_insn "fix_truncdi_i387"
4273   [(set (match_operand:DI 0 "memory_operand" "=m")
4274         (fix:DI (match_operand 1 "register_operand" "f")))
4275    (use (match_operand:HI 2 "memory_operand" "m"))
4276    (use (match_operand:HI 3 "memory_operand" "m"))
4277    (clobber (match_scratch:XF 4 "=&1f"))]
4278   "TARGET_80387 && !TARGET_FISTTP
4279    && FLOAT_MODE_P (GET_MODE (operands[1]))
4280    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4281   "* return output_fix_trunc (insn, operands, 0);"
4282   [(set_attr "type" "fistp")
4283    (set_attr "i387_cw" "trunc")
4284    (set_attr "mode" "DI")])
4286 (define_insn "fix_truncdi_i387_with_temp"
4287   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4288         (fix:DI (match_operand 1 "register_operand" "f,f")))
4289    (use (match_operand:HI 2 "memory_operand" "m,m"))
4290    (use (match_operand:HI 3 "memory_operand" "m,m"))
4291    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4292    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4293   "TARGET_80387 && !TARGET_FISTTP
4294    && FLOAT_MODE_P (GET_MODE (operands[1]))
4295    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4296   "#"
4297   [(set_attr "type" "fistp")
4298    (set_attr "i387_cw" "trunc")
4299    (set_attr "mode" "DI")])
4301 (define_split 
4302   [(set (match_operand:DI 0 "register_operand" "")
4303         (fix:DI (match_operand 1 "register_operand" "")))
4304    (use (match_operand:HI 2 "memory_operand" ""))
4305    (use (match_operand:HI 3 "memory_operand" ""))
4306    (clobber (match_operand:DI 4 "memory_operand" ""))
4307    (clobber (match_scratch 5 ""))]
4308   "reload_completed"
4309   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4310               (use (match_dup 2))
4311               (use (match_dup 3))
4312               (clobber (match_dup 5))])
4313    (set (match_dup 0) (match_dup 4))]
4314   "")
4316 (define_split 
4317   [(set (match_operand:DI 0 "memory_operand" "")
4318         (fix:DI (match_operand 1 "register_operand" "")))
4319    (use (match_operand:HI 2 "memory_operand" ""))
4320    (use (match_operand:HI 3 "memory_operand" ""))
4321    (clobber (match_operand:DI 4 "memory_operand" ""))
4322    (clobber (match_scratch 5 ""))]
4323   "reload_completed"
4324   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4325               (use (match_dup 2))
4326               (use (match_dup 3))
4327               (clobber (match_dup 5))])]
4328   "")
4330 (define_insn "fix_trunc<mode>_i387"
4331   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4332         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4333    (use (match_operand:HI 2 "memory_operand" "m"))
4334    (use (match_operand:HI 3 "memory_operand" "m"))]
4335   "TARGET_80387 && !TARGET_FISTTP
4336    && FLOAT_MODE_P (GET_MODE (operands[1]))
4337    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4338   "* return output_fix_trunc (insn, operands, 0);"
4339   [(set_attr "type" "fistp")
4340    (set_attr "i387_cw" "trunc")
4341    (set_attr "mode" "<MODE>")])
4343 (define_insn "fix_trunc<mode>_i387_with_temp"
4344   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4345         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4346    (use (match_operand:HI 2 "memory_operand" "m,m"))
4347    (use (match_operand:HI 3 "memory_operand" "m,m"))
4348    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4349   "TARGET_80387 && !TARGET_FISTTP
4350    && FLOAT_MODE_P (GET_MODE (operands[1]))
4351    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4352   "#"
4353   [(set_attr "type" "fistp")
4354    (set_attr "i387_cw" "trunc")
4355    (set_attr "mode" "<MODE>")])
4357 (define_split 
4358   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4359         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4360    (use (match_operand:HI 2 "memory_operand" ""))
4361    (use (match_operand:HI 3 "memory_operand" ""))
4362    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4363   "reload_completed"
4364   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4365               (use (match_dup 2))
4366               (use (match_dup 3))])
4367    (set (match_dup 0) (match_dup 4))]
4368   "")
4370 (define_split 
4371   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4372         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4373    (use (match_operand:HI 2 "memory_operand" ""))
4374    (use (match_operand:HI 3 "memory_operand" ""))
4375    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4376   "reload_completed"
4377   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4378               (use (match_dup 2))
4379               (use (match_dup 3))])]
4380   "")
4382 (define_insn "x86_fnstcw_1"
4383   [(set (match_operand:HI 0 "memory_operand" "=m")
4384         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4385   "TARGET_80387"
4386   "fnstcw\t%0"
4387   [(set_attr "length" "2")
4388    (set_attr "mode" "HI")
4389    (set_attr "unit" "i387")])
4391 (define_insn "x86_fldcw_1"
4392   [(set (reg:HI FPSR_REG)
4393         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4394   "TARGET_80387"
4395   "fldcw\t%0"
4396   [(set_attr "length" "2")
4397    (set_attr "mode" "HI")
4398    (set_attr "unit" "i387")
4399    (set_attr "athlon_decode" "vector")])
4401 ;; Conversion between fixed point and floating point.
4403 ;; Even though we only accept memory inputs, the backend _really_
4404 ;; wants to be able to do this between registers.
4406 (define_expand "floathisf2"
4407   [(set (match_operand:SF 0 "register_operand" "")
4408         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4409   "TARGET_80387 || TARGET_SSE_MATH"
4411   if (TARGET_SSE_MATH)
4412     {
4413       emit_insn (gen_floatsisf2 (operands[0],
4414                                  convert_to_mode (SImode, operands[1], 0)));
4415       DONE;
4416     }
4419 (define_insn "*floathisf2_i387"
4420   [(set (match_operand:SF 0 "register_operand" "=f,f")
4421         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4422   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4423   "@
4424    fild%z1\t%1
4425    #"
4426   [(set_attr "type" "fmov,multi")
4427    (set_attr "mode" "SF")
4428    (set_attr "fp_int_src" "true")])
4430 (define_expand "floatsisf2"
4431   [(set (match_operand:SF 0 "register_operand" "")
4432         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4433   "TARGET_80387 || TARGET_SSE_MATH"
4434   "")
4436 (define_insn "*floatsisf2_mixed"
4437   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4438         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4439   "TARGET_MIX_SSE_I387"
4440   "@
4441    fild%z1\t%1
4442    #
4443    cvtsi2ss\t{%1, %0|%0, %1}
4444    cvtsi2ss\t{%1, %0|%0, %1}"
4445   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4446    (set_attr "mode" "SF")
4447    (set_attr "athlon_decode" "*,*,vector,double")
4448    (set_attr "fp_int_src" "true")])
4450 (define_insn "*floatsisf2_sse"
4451   [(set (match_operand:SF 0 "register_operand" "=x,x")
4452         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4453   "TARGET_SSE_MATH"
4454   "cvtsi2ss\t{%1, %0|%0, %1}"
4455   [(set_attr "type" "sseicvt")
4456    (set_attr "mode" "SF")
4457    (set_attr "athlon_decode" "vector,double")
4458    (set_attr "fp_int_src" "true")])
4460 (define_insn "*floatsisf2_i387"
4461   [(set (match_operand:SF 0 "register_operand" "=f,f")
4462         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4463   "TARGET_80387"
4464   "@
4465    fild%z1\t%1
4466    #"
4467   [(set_attr "type" "fmov,multi")
4468    (set_attr "mode" "SF")
4469    (set_attr "fp_int_src" "true")])
4471 (define_expand "floatdisf2"
4472   [(set (match_operand:SF 0 "register_operand" "")
4473         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4474   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4475   "")
4477 (define_insn "*floatdisf2_mixed"
4478   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4479         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4480   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4481   "@
4482    fild%z1\t%1
4483    #
4484    cvtsi2ss{q}\t{%1, %0|%0, %1}
4485    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4486   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4487    (set_attr "mode" "SF")
4488    (set_attr "athlon_decode" "*,*,vector,double")
4489    (set_attr "fp_int_src" "true")])
4491 (define_insn "*floatdisf2_sse"
4492   [(set (match_operand:SF 0 "register_operand" "=x,x")
4493         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4494   "TARGET_64BIT && TARGET_SSE_MATH"
4495   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4496   [(set_attr "type" "sseicvt")
4497    (set_attr "mode" "SF")
4498    (set_attr "athlon_decode" "vector,double")
4499    (set_attr "fp_int_src" "true")])
4501 (define_insn "*floatdisf2_i387"
4502   [(set (match_operand:SF 0 "register_operand" "=f,f")
4503         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4504   "TARGET_80387"
4505   "@
4506    fild%z1\t%1
4507    #"
4508   [(set_attr "type" "fmov,multi")
4509    (set_attr "mode" "SF")
4510    (set_attr "fp_int_src" "true")])
4512 (define_expand "floathidf2"
4513   [(set (match_operand:DF 0 "register_operand" "")
4514         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4515   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4517   if (TARGET_SSE2 && TARGET_SSE_MATH)
4518     {
4519       emit_insn (gen_floatsidf2 (operands[0],
4520                                  convert_to_mode (SImode, operands[1], 0)));
4521       DONE;
4522     }
4525 (define_insn "*floathidf2_i387"
4526   [(set (match_operand:DF 0 "register_operand" "=f,f")
4527         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4528   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4529   "@
4530    fild%z1\t%1
4531    #"
4532   [(set_attr "type" "fmov,multi")
4533    (set_attr "mode" "DF")
4534    (set_attr "fp_int_src" "true")])
4536 (define_expand "floatsidf2"
4537   [(set (match_operand:DF 0 "register_operand" "")
4538         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4539   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4540   "")
4542 (define_insn "*floatsidf2_mixed"
4543   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4544         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4545   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4546   "@
4547    fild%z1\t%1
4548    #
4549    cvtsi2sd\t{%1, %0|%0, %1}
4550    cvtsi2sd\t{%1, %0|%0, %1}"
4551   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4552    (set_attr "mode" "DF")
4553    (set_attr "athlon_decode" "*,*,double,direct")
4554    (set_attr "fp_int_src" "true")])
4556 (define_insn "*floatsidf2_sse"
4557   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4558         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4559   "TARGET_SSE2 && TARGET_SSE_MATH"
4560   "cvtsi2sd\t{%1, %0|%0, %1}"
4561   [(set_attr "type" "sseicvt")
4562    (set_attr "mode" "DF")
4563    (set_attr "athlon_decode" "double,direct")
4564    (set_attr "fp_int_src" "true")])
4566 (define_insn "*floatsidf2_i387"
4567   [(set (match_operand:DF 0 "register_operand" "=f,f")
4568         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4569   "TARGET_80387"
4570   "@
4571    fild%z1\t%1
4572    #"
4573   [(set_attr "type" "fmov,multi")
4574    (set_attr "mode" "DF")
4575    (set_attr "fp_int_src" "true")])
4577 (define_expand "floatdidf2"
4578   [(set (match_operand:DF 0 "register_operand" "")
4579         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4580   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4581   "")
4583 (define_insn "*floatdidf2_mixed"
4584   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4585         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4586   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4587   "@
4588    fild%z1\t%1
4589    #
4590    cvtsi2sd{q}\t{%1, %0|%0, %1}
4591    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4592   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4593    (set_attr "mode" "DF")
4594    (set_attr "athlon_decode" "*,*,double,direct")
4595    (set_attr "fp_int_src" "true")])
4597 (define_insn "*floatdidf2_sse"
4598   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4599         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4600   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4601   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4602   [(set_attr "type" "sseicvt")
4603    (set_attr "mode" "DF")
4604    (set_attr "athlon_decode" "double,direct")
4605    (set_attr "fp_int_src" "true")])
4607 (define_insn "*floatdidf2_i387"
4608   [(set (match_operand:DF 0 "register_operand" "=f,f")
4609         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4610   "TARGET_80387"
4611   "@
4612    fild%z1\t%1
4613    #"
4614   [(set_attr "type" "fmov,multi")
4615    (set_attr "mode" "DF")
4616    (set_attr "fp_int_src" "true")])
4618 (define_insn "floathixf2"
4619   [(set (match_operand:XF 0 "register_operand" "=f,f")
4620         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4621   "TARGET_80387"
4622   "@
4623    fild%z1\t%1
4624    #"
4625   [(set_attr "type" "fmov,multi")
4626    (set_attr "mode" "XF")
4627    (set_attr "fp_int_src" "true")])
4629 (define_insn "floatsixf2"
4630   [(set (match_operand:XF 0 "register_operand" "=f,f")
4631         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4632   "TARGET_80387"
4633   "@
4634    fild%z1\t%1
4635    #"
4636   [(set_attr "type" "fmov,multi")
4637    (set_attr "mode" "XF")
4638    (set_attr "fp_int_src" "true")])
4640 (define_insn "floatdixf2"
4641   [(set (match_operand:XF 0 "register_operand" "=f,f")
4642         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4643   "TARGET_80387"
4644   "@
4645    fild%z1\t%1
4646    #"
4647   [(set_attr "type" "fmov,multi")
4648    (set_attr "mode" "XF")
4649    (set_attr "fp_int_src" "true")])
4651 ;; %%% Kill these when reload knows how to do it.
4652 (define_split
4653   [(set (match_operand 0 "fp_register_operand" "")
4654         (float (match_operand 1 "register_operand" "")))]
4655   "reload_completed
4656    && TARGET_80387
4657    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4658   [(const_int 0)]
4660   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4661   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4662   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4663   ix86_free_from_memory (GET_MODE (operands[1]));
4664   DONE;
4667 (define_expand "floatunssisf2"
4668   [(use (match_operand:SF 0 "register_operand" ""))
4669    (use (match_operand:SI 1 "register_operand" ""))]
4670   "!TARGET_64BIT && TARGET_SSE_MATH"
4671   "x86_emit_floatuns (operands); DONE;")
4673 (define_expand "floatunsdisf2"
4674   [(use (match_operand:SF 0 "register_operand" ""))
4675    (use (match_operand:DI 1 "register_operand" ""))]
4676   "TARGET_64BIT && TARGET_SSE_MATH"
4677   "x86_emit_floatuns (operands); DONE;")
4679 (define_expand "floatunsdidf2"
4680   [(use (match_operand:DF 0 "register_operand" ""))
4681    (use (match_operand:DI 1 "register_operand" ""))]
4682   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4683   "x86_emit_floatuns (operands); DONE;")
4685 ;; SSE extract/set expanders
4688 ;; Add instructions
4690 ;; %%% splits for addsidi3
4691 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4692 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4693 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4695 (define_expand "adddi3"
4696   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4697         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4698                  (match_operand:DI 2 "x86_64_general_operand" "")))
4699    (clobber (reg:CC FLAGS_REG))]
4700   ""
4701   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4703 (define_insn "*adddi3_1"
4704   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4705         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4706                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4707    (clobber (reg:CC FLAGS_REG))]
4708   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4709   "#")
4711 (define_split
4712   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4713         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4714                  (match_operand:DI 2 "general_operand" "")))
4715    (clobber (reg:CC FLAGS_REG))]
4716   "!TARGET_64BIT && reload_completed"
4717   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4718                                           UNSPEC_ADD_CARRY))
4719               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4720    (parallel [(set (match_dup 3)
4721                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4722                                      (match_dup 4))
4723                             (match_dup 5)))
4724               (clobber (reg:CC FLAGS_REG))])]
4725   "split_di (operands+0, 1, operands+0, operands+3);
4726    split_di (operands+1, 1, operands+1, operands+4);
4727    split_di (operands+2, 1, operands+2, operands+5);")
4729 (define_insn "adddi3_carry_rex64"
4730   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4731           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4732                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4733                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4734    (clobber (reg:CC FLAGS_REG))]
4735   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4736   "adc{q}\t{%2, %0|%0, %2}"
4737   [(set_attr "type" "alu")
4738    (set_attr "pent_pair" "pu")
4739    (set_attr "mode" "DI")])
4741 (define_insn "*adddi3_cc_rex64"
4742   [(set (reg:CC FLAGS_REG)
4743         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4744                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4745                    UNSPEC_ADD_CARRY))
4746    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4747         (plus:DI (match_dup 1) (match_dup 2)))]
4748   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4749   "add{q}\t{%2, %0|%0, %2}"
4750   [(set_attr "type" "alu")
4751    (set_attr "mode" "DI")])
4753 (define_insn "addqi3_carry"
4754   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4755           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4756                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4757                    (match_operand:QI 2 "general_operand" "qi,qm")))
4758    (clobber (reg:CC FLAGS_REG))]
4759   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4760   "adc{b}\t{%2, %0|%0, %2}"
4761   [(set_attr "type" "alu")
4762    (set_attr "pent_pair" "pu")
4763    (set_attr "mode" "QI")])
4765 (define_insn "addhi3_carry"
4766   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4767           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4768                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4769                    (match_operand:HI 2 "general_operand" "ri,rm")))
4770    (clobber (reg:CC FLAGS_REG))]
4771   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4772   "adc{w}\t{%2, %0|%0, %2}"
4773   [(set_attr "type" "alu")
4774    (set_attr "pent_pair" "pu")
4775    (set_attr "mode" "HI")])
4777 (define_insn "addsi3_carry"
4778   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4779           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4780                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4781                    (match_operand:SI 2 "general_operand" "ri,rm")))
4782    (clobber (reg:CC FLAGS_REG))]
4783   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4784   "adc{l}\t{%2, %0|%0, %2}"
4785   [(set_attr "type" "alu")
4786    (set_attr "pent_pair" "pu")
4787    (set_attr "mode" "SI")])
4789 (define_insn "*addsi3_carry_zext"
4790   [(set (match_operand:DI 0 "register_operand" "=r")
4791           (zero_extend:DI 
4792             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4793                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4794                      (match_operand:SI 2 "general_operand" "rim"))))
4795    (clobber (reg:CC FLAGS_REG))]
4796   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4797   "adc{l}\t{%2, %k0|%k0, %2}"
4798   [(set_attr "type" "alu")
4799    (set_attr "pent_pair" "pu")
4800    (set_attr "mode" "SI")])
4802 (define_insn "*addsi3_cc"
4803   [(set (reg:CC FLAGS_REG)
4804         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4805                     (match_operand:SI 2 "general_operand" "ri,rm")]
4806                    UNSPEC_ADD_CARRY))
4807    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4808         (plus:SI (match_dup 1) (match_dup 2)))]
4809   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4810   "add{l}\t{%2, %0|%0, %2}"
4811   [(set_attr "type" "alu")
4812    (set_attr "mode" "SI")])
4814 (define_insn "addqi3_cc"
4815   [(set (reg:CC FLAGS_REG)
4816         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4817                     (match_operand:QI 2 "general_operand" "qi,qm")]
4818                    UNSPEC_ADD_CARRY))
4819    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4820         (plus:QI (match_dup 1) (match_dup 2)))]
4821   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4822   "add{b}\t{%2, %0|%0, %2}"
4823   [(set_attr "type" "alu")
4824    (set_attr "mode" "QI")])
4826 (define_expand "addsi3"
4827   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4828                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4829                             (match_operand:SI 2 "general_operand" "")))
4830               (clobber (reg:CC FLAGS_REG))])]
4831   ""
4832   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4834 (define_insn "*lea_1"
4835   [(set (match_operand:SI 0 "register_operand" "=r")
4836         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4837   "!TARGET_64BIT"
4838   "lea{l}\t{%a1, %0|%0, %a1}"
4839   [(set_attr "type" "lea")
4840    (set_attr "mode" "SI")])
4842 (define_insn "*lea_1_rex64"
4843   [(set (match_operand:SI 0 "register_operand" "=r")
4844         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4845   "TARGET_64BIT"
4846   "lea{l}\t{%a1, %0|%0, %a1}"
4847   [(set_attr "type" "lea")
4848    (set_attr "mode" "SI")])
4850 (define_insn "*lea_1_zext"
4851   [(set (match_operand:DI 0 "register_operand" "=r")
4852         (zero_extend:DI
4853          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4854   "TARGET_64BIT"
4855   "lea{l}\t{%a1, %k0|%k0, %a1}"
4856   [(set_attr "type" "lea")
4857    (set_attr "mode" "SI")])
4859 (define_insn "*lea_2_rex64"
4860   [(set (match_operand:DI 0 "register_operand" "=r")
4861         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4862   "TARGET_64BIT"
4863   "lea{q}\t{%a1, %0|%0, %a1}"
4864   [(set_attr "type" "lea")
4865    (set_attr "mode" "DI")])
4867 ;; The lea patterns for non-Pmodes needs to be matched by several
4868 ;; insns converted to real lea by splitters.
4870 (define_insn_and_split "*lea_general_1"
4871   [(set (match_operand 0 "register_operand" "=r")
4872         (plus (plus (match_operand 1 "index_register_operand" "l")
4873                     (match_operand 2 "register_operand" "r"))
4874               (match_operand 3 "immediate_operand" "i")))]
4875   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4876     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4877    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4878    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4879    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4880    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4881        || GET_MODE (operands[3]) == VOIDmode)"
4882   "#"
4883   "&& reload_completed"
4884   [(const_int 0)]
4886   rtx pat;
4887   operands[0] = gen_lowpart (SImode, operands[0]);
4888   operands[1] = gen_lowpart (Pmode, operands[1]);
4889   operands[2] = gen_lowpart (Pmode, operands[2]);
4890   operands[3] = gen_lowpart (Pmode, operands[3]);
4891   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4892                       operands[3]);
4893   if (Pmode != SImode)
4894     pat = gen_rtx_SUBREG (SImode, pat, 0);
4895   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4896   DONE;
4898   [(set_attr "type" "lea")
4899    (set_attr "mode" "SI")])
4901 (define_insn_and_split "*lea_general_1_zext"
4902   [(set (match_operand:DI 0 "register_operand" "=r")
4903         (zero_extend:DI
4904           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4905                             (match_operand:SI 2 "register_operand" "r"))
4906                    (match_operand:SI 3 "immediate_operand" "i"))))]
4907   "TARGET_64BIT"
4908   "#"
4909   "&& reload_completed"
4910   [(set (match_dup 0)
4911         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4912                                                      (match_dup 2))
4913                                             (match_dup 3)) 0)))]
4915   operands[1] = gen_lowpart (Pmode, operands[1]);
4916   operands[2] = gen_lowpart (Pmode, operands[2]);
4917   operands[3] = gen_lowpart (Pmode, operands[3]);
4919   [(set_attr "type" "lea")
4920    (set_attr "mode" "SI")])
4922 (define_insn_and_split "*lea_general_2"
4923   [(set (match_operand 0 "register_operand" "=r")
4924         (plus (mult (match_operand 1 "index_register_operand" "l")
4925                     (match_operand 2 "const248_operand" "i"))
4926               (match_operand 3 "nonmemory_operand" "ri")))]
4927   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4928     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4929    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4930    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4931    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4932        || GET_MODE (operands[3]) == VOIDmode)"
4933   "#"
4934   "&& reload_completed"
4935   [(const_int 0)]
4937   rtx pat;
4938   operands[0] = gen_lowpart (SImode, operands[0]);
4939   operands[1] = gen_lowpart (Pmode, operands[1]);
4940   operands[3] = gen_lowpart (Pmode, operands[3]);
4941   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4942                       operands[3]);
4943   if (Pmode != SImode)
4944     pat = gen_rtx_SUBREG (SImode, pat, 0);
4945   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4946   DONE;
4948   [(set_attr "type" "lea")
4949    (set_attr "mode" "SI")])
4951 (define_insn_and_split "*lea_general_2_zext"
4952   [(set (match_operand:DI 0 "register_operand" "=r")
4953         (zero_extend:DI
4954           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4955                             (match_operand:SI 2 "const248_operand" "n"))
4956                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4957   "TARGET_64BIT"
4958   "#"
4959   "&& reload_completed"
4960   [(set (match_dup 0)
4961         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4962                                                      (match_dup 2))
4963                                             (match_dup 3)) 0)))]
4965   operands[1] = gen_lowpart (Pmode, operands[1]);
4966   operands[3] = gen_lowpart (Pmode, operands[3]);
4968   [(set_attr "type" "lea")
4969    (set_attr "mode" "SI")])
4971 (define_insn_and_split "*lea_general_3"
4972   [(set (match_operand 0 "register_operand" "=r")
4973         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4974                           (match_operand 2 "const248_operand" "i"))
4975                     (match_operand 3 "register_operand" "r"))
4976               (match_operand 4 "immediate_operand" "i")))]
4977   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4978     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4979    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4980    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4981    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4982   "#"
4983   "&& reload_completed"
4984   [(const_int 0)]
4986   rtx pat;
4987   operands[0] = gen_lowpart (SImode, operands[0]);
4988   operands[1] = gen_lowpart (Pmode, operands[1]);
4989   operands[3] = gen_lowpart (Pmode, operands[3]);
4990   operands[4] = gen_lowpart (Pmode, operands[4]);
4991   pat = gen_rtx_PLUS (Pmode,
4992                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4993                                                          operands[2]),
4994                                     operands[3]),
4995                       operands[4]);
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_3_zext"
5005   [(set (match_operand:DI 0 "register_operand" "=r")
5006         (zero_extend:DI
5007           (plus:SI (plus:SI (mult:SI
5008                               (match_operand:SI 1 "index_register_operand" "l")
5009                               (match_operand:SI 2 "const248_operand" "n"))
5010                             (match_operand:SI 3 "register_operand" "r"))
5011                    (match_operand:SI 4 "immediate_operand" "i"))))]
5012   "TARGET_64BIT"
5013   "#"
5014   "&& reload_completed"
5015   [(set (match_dup 0)
5016         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5017                                                               (match_dup 2))
5018                                                      (match_dup 3))
5019                                             (match_dup 4)) 0)))]
5021   operands[1] = gen_lowpart (Pmode, operands[1]);
5022   operands[3] = gen_lowpart (Pmode, operands[3]);
5023   operands[4] = gen_lowpart (Pmode, operands[4]);
5025   [(set_attr "type" "lea")
5026    (set_attr "mode" "SI")])
5028 (define_insn "*adddi_1_rex64"
5029   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5030         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5031                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5032    (clobber (reg:CC FLAGS_REG))]
5033   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5035   switch (get_attr_type (insn))
5036     {
5037     case TYPE_LEA:
5038       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5039       return "lea{q}\t{%a2, %0|%0, %a2}";
5041     case TYPE_INCDEC:
5042       if (! rtx_equal_p (operands[0], operands[1]))
5043         abort ();
5044       if (operands[2] == const1_rtx)
5045         return "inc{q}\t%0";
5046       else if (operands[2] == constm1_rtx)
5047         return "dec{q}\t%0";
5048       else
5049         abort ();
5051     default:
5052       if (! rtx_equal_p (operands[0], operands[1]))
5053         abort ();
5055       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5056          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5057       if (GET_CODE (operands[2]) == CONST_INT
5058           /* Avoid overflows.  */
5059           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5060           && (INTVAL (operands[2]) == 128
5061               || (INTVAL (operands[2]) < 0
5062                   && INTVAL (operands[2]) != -128)))
5063         {
5064           operands[2] = GEN_INT (-INTVAL (operands[2]));
5065           return "sub{q}\t{%2, %0|%0, %2}";
5066         }
5067       return "add{q}\t{%2, %0|%0, %2}";
5068     }
5070   [(set (attr "type")
5071      (cond [(eq_attr "alternative" "2")
5072               (const_string "lea")
5073             ; Current assemblers are broken and do not allow @GOTOFF in
5074             ; ought but a memory context.
5075             (match_operand:DI 2 "pic_symbolic_operand" "")
5076               (const_string "lea")
5077             (match_operand:DI 2 "incdec_operand" "")
5078               (const_string "incdec")
5079            ]
5080            (const_string "alu")))
5081    (set_attr "mode" "DI")])
5083 ;; Convert lea to the lea pattern to avoid flags dependency.
5084 (define_split
5085   [(set (match_operand:DI 0 "register_operand" "")
5086         (plus:DI (match_operand:DI 1 "register_operand" "")
5087                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5088    (clobber (reg:CC FLAGS_REG))]
5089   "TARGET_64BIT && reload_completed
5090    && true_regnum (operands[0]) != true_regnum (operands[1])"
5091   [(set (match_dup 0)
5092         (plus:DI (match_dup 1)
5093                  (match_dup 2)))]
5094   "")
5096 (define_insn "*adddi_2_rex64"
5097   [(set (reg FLAGS_REG)
5098         (compare
5099           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5100                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5101           (const_int 0)))                       
5102    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5103         (plus:DI (match_dup 1) (match_dup 2)))]
5104   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5105    && ix86_binary_operator_ok (PLUS, DImode, operands)
5106    /* Current assemblers are broken and do not allow @GOTOFF in
5107       ought but a memory context.  */
5108    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5110   switch (get_attr_type (insn))
5111     {
5112     case TYPE_INCDEC:
5113       if (! rtx_equal_p (operands[0], operands[1]))
5114         abort ();
5115       if (operands[2] == const1_rtx)
5116         return "inc{q}\t%0";
5117       else if (operands[2] == constm1_rtx)
5118         return "dec{q}\t%0";
5119       else
5120         abort ();
5122     default:
5123       if (! rtx_equal_p (operands[0], operands[1]))
5124         abort ();
5125       /* ???? We ought to handle there the 32bit case too
5126          - do we need new constraint?  */
5127       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5128          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5129       if (GET_CODE (operands[2]) == CONST_INT
5130           /* Avoid overflows.  */
5131           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5132           && (INTVAL (operands[2]) == 128
5133               || (INTVAL (operands[2]) < 0
5134                   && INTVAL (operands[2]) != -128)))
5135         {
5136           operands[2] = GEN_INT (-INTVAL (operands[2]));
5137           return "sub{q}\t{%2, %0|%0, %2}";
5138         }
5139       return "add{q}\t{%2, %0|%0, %2}";
5140     }
5142   [(set (attr "type")
5143      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5144         (const_string "incdec")
5145         (const_string "alu")))
5146    (set_attr "mode" "DI")])
5148 (define_insn "*adddi_3_rex64"
5149   [(set (reg FLAGS_REG)
5150         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5151                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5152    (clobber (match_scratch:DI 0 "=r"))]
5153   "TARGET_64BIT
5154    && ix86_match_ccmode (insn, CCZmode)
5155    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5156    /* Current assemblers are broken and do not allow @GOTOFF in
5157       ought but a memory context.  */
5158    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5160   switch (get_attr_type (insn))
5161     {
5162     case TYPE_INCDEC:
5163       if (! rtx_equal_p (operands[0], operands[1]))
5164         abort ();
5165       if (operands[2] == const1_rtx)
5166         return "inc{q}\t%0";
5167       else if (operands[2] == constm1_rtx)
5168         return "dec{q}\t%0";
5169       else
5170         abort ();
5172     default:
5173       if (! rtx_equal_p (operands[0], operands[1]))
5174         abort ();
5175       /* ???? We ought to handle there the 32bit case too
5176          - do we need new constraint?  */
5177       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5178          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5179       if (GET_CODE (operands[2]) == CONST_INT
5180           /* Avoid overflows.  */
5181           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5182           && (INTVAL (operands[2]) == 128
5183               || (INTVAL (operands[2]) < 0
5184                   && INTVAL (operands[2]) != -128)))
5185         {
5186           operands[2] = GEN_INT (-INTVAL (operands[2]));
5187           return "sub{q}\t{%2, %0|%0, %2}";
5188         }
5189       return "add{q}\t{%2, %0|%0, %2}";
5190     }
5192   [(set (attr "type")
5193      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5194         (const_string "incdec")
5195         (const_string "alu")))
5196    (set_attr "mode" "DI")])
5198 ; For comparisons against 1, -1 and 128, we may generate better code
5199 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5200 ; is matched then.  We can't accept general immediate, because for
5201 ; case of overflows,  the result is messed up.
5202 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5203 ; when negated.
5204 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5205 ; only for comparisons not depending on it.
5206 (define_insn "*adddi_4_rex64"
5207   [(set (reg FLAGS_REG)
5208         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5209                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5210    (clobber (match_scratch:DI 0 "=rm"))]
5211   "TARGET_64BIT
5212    &&  ix86_match_ccmode (insn, CCGCmode)"
5214   switch (get_attr_type (insn))
5215     {
5216     case TYPE_INCDEC:
5217       if (operands[2] == constm1_rtx)
5218         return "inc{q}\t%0";
5219       else if (operands[2] == const1_rtx)
5220         return "dec{q}\t%0";
5221       else
5222         abort();
5224     default:
5225       if (! rtx_equal_p (operands[0], operands[1]))
5226         abort ();
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 ((INTVAL (operands[2]) == -128
5230            || (INTVAL (operands[2]) > 0
5231                && INTVAL (operands[2]) != 128))
5232           /* Avoid overflows.  */
5233           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5234         return "sub{q}\t{%2, %0|%0, %2}";
5235       operands[2] = GEN_INT (-INTVAL (operands[2]));
5236       return "add{q}\t{%2, %0|%0, %2}";
5237     }
5239   [(set (attr "type")
5240      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5241         (const_string "incdec")
5242         (const_string "alu")))
5243    (set_attr "mode" "DI")])
5245 (define_insn "*adddi_5_rex64"
5246   [(set (reg FLAGS_REG)
5247         (compare
5248           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5249                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5250           (const_int 0)))                       
5251    (clobber (match_scratch:DI 0 "=r"))]
5252   "TARGET_64BIT
5253    && ix86_match_ccmode (insn, CCGOCmode)
5254    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5255    /* Current assemblers are broken and do not allow @GOTOFF in
5256       ought but a memory context.  */
5257    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5259   switch (get_attr_type (insn))
5260     {
5261     case TYPE_INCDEC:
5262       if (! rtx_equal_p (operands[0], operands[1]))
5263         abort ();
5264       if (operands[2] == const1_rtx)
5265         return "inc{q}\t%0";
5266       else if (operands[2] == constm1_rtx)
5267         return "dec{q}\t%0";
5268       else
5269         abort();
5271     default:
5272       if (! rtx_equal_p (operands[0], operands[1]))
5273         abort ();
5274       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5275          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5276       if (GET_CODE (operands[2]) == CONST_INT
5277           /* Avoid overflows.  */
5278           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5279           && (INTVAL (operands[2]) == 128
5280               || (INTVAL (operands[2]) < 0
5281                   && INTVAL (operands[2]) != -128)))
5282         {
5283           operands[2] = GEN_INT (-INTVAL (operands[2]));
5284           return "sub{q}\t{%2, %0|%0, %2}";
5285         }
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")])
5296 (define_insn "*addsi_1"
5297   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5298         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5299                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5300    (clobber (reg:CC FLAGS_REG))]
5301   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5303   switch (get_attr_type (insn))
5304     {
5305     case TYPE_LEA:
5306       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5307       return "lea{l}\t{%a2, %0|%0, %a2}";
5309     case TYPE_INCDEC:
5310       if (! rtx_equal_p (operands[0], operands[1]))
5311         abort ();
5312       if (operands[2] == const1_rtx)
5313         return "inc{l}\t%0";
5314       else if (operands[2] == constm1_rtx)
5315         return "dec{l}\t%0";
5316       else
5317         abort();
5319     default:
5320       if (! rtx_equal_p (operands[0], operands[1]))
5321         abort ();
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           && (INTVAL (operands[2]) == 128
5327               || (INTVAL (operands[2]) < 0
5328                   && INTVAL (operands[2]) != -128)))
5329         {
5330           operands[2] = GEN_INT (-INTVAL (operands[2]));
5331           return "sub{l}\t{%2, %0|%0, %2}";
5332         }
5333       return "add{l}\t{%2, %0|%0, %2}";
5334     }
5336   [(set (attr "type")
5337      (cond [(eq_attr "alternative" "2")
5338               (const_string "lea")
5339             ; Current assemblers are broken and do not allow @GOTOFF in
5340             ; ought but a memory context.
5341             (match_operand:SI 2 "pic_symbolic_operand" "")
5342               (const_string "lea")
5343             (match_operand:SI 2 "incdec_operand" "")
5344               (const_string "incdec")
5345            ]
5346            (const_string "alu")))
5347    (set_attr "mode" "SI")])
5349 ;; Convert lea to the lea pattern to avoid flags dependency.
5350 (define_split
5351   [(set (match_operand 0 "register_operand" "")
5352         (plus (match_operand 1 "register_operand" "")
5353               (match_operand 2 "nonmemory_operand" "")))
5354    (clobber (reg:CC FLAGS_REG))]
5355   "reload_completed
5356    && true_regnum (operands[0]) != true_regnum (operands[1])"
5357   [(const_int 0)]
5359   rtx pat;
5360   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5361      may confuse gen_lowpart.  */
5362   if (GET_MODE (operands[0]) != Pmode)
5363     {
5364       operands[1] = gen_lowpart (Pmode, operands[1]);
5365       operands[2] = gen_lowpart (Pmode, operands[2]);
5366     }
5367   operands[0] = gen_lowpart (SImode, operands[0]);
5368   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5369   if (Pmode != SImode)
5370     pat = gen_rtx_SUBREG (SImode, pat, 0);
5371   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5372   DONE;
5375 ;; It may seem that nonimmediate operand is proper one for operand 1.
5376 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5377 ;; we take care in ix86_binary_operator_ok to not allow two memory
5378 ;; operands so proper swapping will be done in reload.  This allow
5379 ;; patterns constructed from addsi_1 to match.
5380 (define_insn "addsi_1_zext"
5381   [(set (match_operand:DI 0 "register_operand" "=r,r")
5382         (zero_extend:DI
5383           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5384                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5385    (clobber (reg:CC FLAGS_REG))]
5386   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5388   switch (get_attr_type (insn))
5389     {
5390     case TYPE_LEA:
5391       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5392       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5394     case TYPE_INCDEC:
5395       if (operands[2] == const1_rtx)
5396         return "inc{l}\t%k0";
5397       else if (operands[2] == constm1_rtx)
5398         return "dec{l}\t%k0";
5399       else
5400         abort();
5402     default:
5403       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5404          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5405       if (GET_CODE (operands[2]) == CONST_INT
5406           && (INTVAL (operands[2]) == 128
5407               || (INTVAL (operands[2]) < 0
5408                   && INTVAL (operands[2]) != -128)))
5409         {
5410           operands[2] = GEN_INT (-INTVAL (operands[2]));
5411           return "sub{l}\t{%2, %k0|%k0, %2}";
5412         }
5413       return "add{l}\t{%2, %k0|%k0, %2}";
5414     }
5416   [(set (attr "type")
5417      (cond [(eq_attr "alternative" "1")
5418               (const_string "lea")
5419             ; Current assemblers are broken and do not allow @GOTOFF in
5420             ; ought but a memory context.
5421             (match_operand:SI 2 "pic_symbolic_operand" "")
5422               (const_string "lea")
5423             (match_operand:SI 2 "incdec_operand" "")
5424               (const_string "incdec")
5425            ]
5426            (const_string "alu")))
5427    (set_attr "mode" "SI")])
5429 ;; Convert lea to the lea pattern to avoid flags dependency.
5430 (define_split
5431   [(set (match_operand:DI 0 "register_operand" "")
5432         (zero_extend:DI
5433           (plus:SI (match_operand:SI 1 "register_operand" "")
5434                    (match_operand:SI 2 "nonmemory_operand" ""))))
5435    (clobber (reg:CC FLAGS_REG))]
5436   "TARGET_64BIT && reload_completed
5437    && true_regnum (operands[0]) != true_regnum (operands[1])"
5438   [(set (match_dup 0)
5439         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5441   operands[1] = gen_lowpart (Pmode, operands[1]);
5442   operands[2] = gen_lowpart (Pmode, operands[2]);
5445 (define_insn "*addsi_2"
5446   [(set (reg FLAGS_REG)
5447         (compare
5448           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5449                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5450           (const_int 0)))                       
5451    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5452         (plus:SI (match_dup 1) (match_dup 2)))]
5453   "ix86_match_ccmode (insn, CCGOCmode)
5454    && ix86_binary_operator_ok (PLUS, SImode, operands)
5455    /* Current assemblers are broken and do not allow @GOTOFF in
5456       ought but a memory context.  */
5457    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5459   switch (get_attr_type (insn))
5460     {
5461     case TYPE_INCDEC:
5462       if (! rtx_equal_p (operands[0], operands[1]))
5463         abort ();
5464       if (operands[2] == const1_rtx)
5465         return "inc{l}\t%0";
5466       else if (operands[2] == constm1_rtx)
5467         return "dec{l}\t%0";
5468       else
5469         abort();
5471     default:
5472       if (! rtx_equal_p (operands[0], operands[1]))
5473         abort ();
5474       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5475          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5476       if (GET_CODE (operands[2]) == CONST_INT
5477           && (INTVAL (operands[2]) == 128
5478               || (INTVAL (operands[2]) < 0
5479                   && INTVAL (operands[2]) != -128)))
5480         {
5481           operands[2] = GEN_INT (-INTVAL (operands[2]));
5482           return "sub{l}\t{%2, %0|%0, %2}";
5483         }
5484       return "add{l}\t{%2, %0|%0, %2}";
5485     }
5487   [(set (attr "type")
5488      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5489         (const_string "incdec")
5490         (const_string "alu")))
5491    (set_attr "mode" "SI")])
5493 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5494 (define_insn "*addsi_2_zext"
5495   [(set (reg FLAGS_REG)
5496         (compare
5497           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5498                    (match_operand:SI 2 "general_operand" "rmni"))
5499           (const_int 0)))                       
5500    (set (match_operand:DI 0 "register_operand" "=r")
5501         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5502   "TARGET_64BIT && 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       if (operands[2] == const1_rtx)
5512         return "inc{l}\t%k0";
5513       else if (operands[2] == constm1_rtx)
5514         return "dec{l}\t%k0";
5515       else
5516         abort();
5518     default:
5519       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5520          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5521       if (GET_CODE (operands[2]) == CONST_INT
5522           && (INTVAL (operands[2]) == 128
5523               || (INTVAL (operands[2]) < 0
5524                   && INTVAL (operands[2]) != -128)))
5525         {
5526           operands[2] = GEN_INT (-INTVAL (operands[2]));
5527           return "sub{l}\t{%2, %k0|%k0, %2}";
5528         }
5529       return "add{l}\t{%2, %k0|%k0, %2}";
5530     }
5532   [(set (attr "type")
5533      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5534         (const_string "incdec")
5535         (const_string "alu")))
5536    (set_attr "mode" "SI")])
5538 (define_insn "*addsi_3"
5539   [(set (reg FLAGS_REG)
5540         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5541                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5542    (clobber (match_scratch:SI 0 "=r"))]
5543   "ix86_match_ccmode (insn, CCZmode)
5544    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5545    /* Current assemblers are broken and do not allow @GOTOFF in
5546       ought but a memory context.  */
5547    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5549   switch (get_attr_type (insn))
5550     {
5551     case TYPE_INCDEC:
5552       if (! rtx_equal_p (operands[0], operands[1]))
5553         abort ();
5554       if (operands[2] == const1_rtx)
5555         return "inc{l}\t%0";
5556       else if (operands[2] == constm1_rtx)
5557         return "dec{l}\t%0";
5558       else
5559         abort();
5561     default:
5562       if (! rtx_equal_p (operands[0], operands[1]))
5563         abort ();
5564       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5565          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5566       if (GET_CODE (operands[2]) == CONST_INT
5567           && (INTVAL (operands[2]) == 128
5568               || (INTVAL (operands[2]) < 0
5569                   && INTVAL (operands[2]) != -128)))
5570         {
5571           operands[2] = GEN_INT (-INTVAL (operands[2]));
5572           return "sub{l}\t{%2, %0|%0, %2}";
5573         }
5574       return "add{l}\t{%2, %0|%0, %2}";
5575     }
5577   [(set (attr "type")
5578      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5579         (const_string "incdec")
5580         (const_string "alu")))
5581    (set_attr "mode" "SI")])
5583 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5584 (define_insn "*addsi_3_zext"
5585   [(set (reg FLAGS_REG)
5586         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5587                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5588    (set (match_operand:DI 0 "register_operand" "=r")
5589         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5590   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5591    && ix86_binary_operator_ok (PLUS, SImode, operands)
5592    /* Current assemblers are broken and do not allow @GOTOFF in
5593       ought but a memory context.  */
5594    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5596   switch (get_attr_type (insn))
5597     {
5598     case TYPE_INCDEC:
5599       if (operands[2] == const1_rtx)
5600         return "inc{l}\t%k0";
5601       else if (operands[2] == constm1_rtx)
5602         return "dec{l}\t%k0";
5603       else
5604         abort();
5606     default:
5607       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5608          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5609       if (GET_CODE (operands[2]) == CONST_INT
5610           && (INTVAL (operands[2]) == 128
5611               || (INTVAL (operands[2]) < 0
5612                   && INTVAL (operands[2]) != -128)))
5613         {
5614           operands[2] = GEN_INT (-INTVAL (operands[2]));
5615           return "sub{l}\t{%2, %k0|%k0, %2}";
5616         }
5617       return "add{l}\t{%2, %k0|%k0, %2}";
5618     }
5620   [(set (attr "type")
5621      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5622         (const_string "incdec")
5623         (const_string "alu")))
5624    (set_attr "mode" "SI")])
5626 ; For comparisons against 1, -1 and 128, we may generate better code
5627 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5628 ; is matched then.  We can't accept general immediate, because for
5629 ; case of overflows,  the result is messed up.
5630 ; This pattern also don't hold of 0x80000000, since the value overflows
5631 ; when negated.
5632 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5633 ; only for comparisons not depending on it.
5634 (define_insn "*addsi_4"
5635   [(set (reg FLAGS_REG)
5636         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5637                  (match_operand:SI 2 "const_int_operand" "n")))
5638    (clobber (match_scratch:SI 0 "=rm"))]
5639   "ix86_match_ccmode (insn, CCGCmode)
5640    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5642   switch (get_attr_type (insn))
5643     {
5644     case TYPE_INCDEC:
5645       if (operands[2] == constm1_rtx)
5646         return "inc{l}\t%0";
5647       else if (operands[2] == const1_rtx)
5648         return "dec{l}\t%0";
5649       else
5650         abort();
5652     default:
5653       if (! rtx_equal_p (operands[0], operands[1]))
5654         abort ();
5655       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5657       if ((INTVAL (operands[2]) == -128
5658            || (INTVAL (operands[2]) > 0
5659                && INTVAL (operands[2]) != 128)))
5660         return "sub{l}\t{%2, %0|%0, %2}";
5661       operands[2] = GEN_INT (-INTVAL (operands[2]));
5662       return "add{l}\t{%2, %0|%0, %2}";
5663     }
5665   [(set (attr "type")
5666      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5667         (const_string "incdec")
5668         (const_string "alu")))
5669    (set_attr "mode" "SI")])
5671 (define_insn "*addsi_5"
5672   [(set (reg FLAGS_REG)
5673         (compare
5674           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5675                    (match_operand:SI 2 "general_operand" "rmni"))
5676           (const_int 0)))                       
5677    (clobber (match_scratch:SI 0 "=r"))]
5678   "ix86_match_ccmode (insn, CCGOCmode)
5679    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5680    /* Current assemblers are broken and do not allow @GOTOFF in
5681       ought but a memory context.  */
5682    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5684   switch (get_attr_type (insn))
5685     {
5686     case TYPE_INCDEC:
5687       if (! rtx_equal_p (operands[0], operands[1]))
5688         abort ();
5689       if (operands[2] == const1_rtx)
5690         return "inc{l}\t%0";
5691       else if (operands[2] == constm1_rtx)
5692         return "dec{l}\t%0";
5693       else
5694         abort();
5696     default:
5697       if (! rtx_equal_p (operands[0], operands[1]))
5698         abort ();
5699       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5700          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5701       if (GET_CODE (operands[2]) == CONST_INT
5702           && (INTVAL (operands[2]) == 128
5703               || (INTVAL (operands[2]) < 0
5704                   && INTVAL (operands[2]) != -128)))
5705         {
5706           operands[2] = GEN_INT (-INTVAL (operands[2]));
5707           return "sub{l}\t{%2, %0|%0, %2}";
5708         }
5709       return "add{l}\t{%2, %0|%0, %2}";
5710     }
5712   [(set (attr "type")
5713      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5714         (const_string "incdec")
5715         (const_string "alu")))
5716    (set_attr "mode" "SI")])
5718 (define_expand "addhi3"
5719   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5720                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5721                             (match_operand:HI 2 "general_operand" "")))
5722               (clobber (reg:CC FLAGS_REG))])]
5723   "TARGET_HIMODE_MATH"
5724   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5726 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5727 ;; type optimizations enabled by define-splits.  This is not important
5728 ;; for PII, and in fact harmful because of partial register stalls.
5730 (define_insn "*addhi_1_lea"
5731   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5732         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5733                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5734    (clobber (reg:CC FLAGS_REG))]
5735   "!TARGET_PARTIAL_REG_STALL
5736    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5738   switch (get_attr_type (insn))
5739     {
5740     case TYPE_LEA:
5741       return "#";
5742     case TYPE_INCDEC:
5743       if (operands[2] == const1_rtx)
5744         return "inc{w}\t%0";
5745       else if (operands[2] == constm1_rtx)
5746         return "dec{w}\t%0";
5747       abort();
5749     default:
5750       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5751          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5752       if (GET_CODE (operands[2]) == CONST_INT
5753           && (INTVAL (operands[2]) == 128
5754               || (INTVAL (operands[2]) < 0
5755                   && INTVAL (operands[2]) != -128)))
5756         {
5757           operands[2] = GEN_INT (-INTVAL (operands[2]));
5758           return "sub{w}\t{%2, %0|%0, %2}";
5759         }
5760       return "add{w}\t{%2, %0|%0, %2}";
5761     }
5763   [(set (attr "type")
5764      (if_then_else (eq_attr "alternative" "2")
5765         (const_string "lea")
5766         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5767            (const_string "incdec")
5768            (const_string "alu"))))
5769    (set_attr "mode" "HI,HI,SI")])
5771 (define_insn "*addhi_1"
5772   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5773         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5774                  (match_operand:HI 2 "general_operand" "ri,rm")))
5775    (clobber (reg:CC FLAGS_REG))]
5776   "TARGET_PARTIAL_REG_STALL
5777    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5779   switch (get_attr_type (insn))
5780     {
5781     case TYPE_INCDEC:
5782       if (operands[2] == const1_rtx)
5783         return "inc{w}\t%0";
5784       else if (operands[2] == constm1_rtx)
5785         return "dec{w}\t%0";
5786       abort();
5788     default:
5789       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5790          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5791       if (GET_CODE (operands[2]) == CONST_INT
5792           && (INTVAL (operands[2]) == 128
5793               || (INTVAL (operands[2]) < 0
5794                   && INTVAL (operands[2]) != -128)))
5795         {
5796           operands[2] = GEN_INT (-INTVAL (operands[2]));
5797           return "sub{w}\t{%2, %0|%0, %2}";
5798         }
5799       return "add{w}\t{%2, %0|%0, %2}";
5800     }
5802   [(set (attr "type")
5803      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5804         (const_string "incdec")
5805         (const_string "alu")))
5806    (set_attr "mode" "HI")])
5808 (define_insn "*addhi_2"
5809   [(set (reg FLAGS_REG)
5810         (compare
5811           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5812                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5813           (const_int 0)))                       
5814    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5815         (plus:HI (match_dup 1) (match_dup 2)))]
5816   "ix86_match_ccmode (insn, CCGOCmode)
5817    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5819   switch (get_attr_type (insn))
5820     {
5821     case TYPE_INCDEC:
5822       if (operands[2] == const1_rtx)
5823         return "inc{w}\t%0";
5824       else if (operands[2] == constm1_rtx)
5825         return "dec{w}\t%0";
5826       abort();
5828     default:
5829       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5830          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5831       if (GET_CODE (operands[2]) == CONST_INT
5832           && (INTVAL (operands[2]) == 128
5833               || (INTVAL (operands[2]) < 0
5834                   && INTVAL (operands[2]) != -128)))
5835         {
5836           operands[2] = GEN_INT (-INTVAL (operands[2]));
5837           return "sub{w}\t{%2, %0|%0, %2}";
5838         }
5839       return "add{w}\t{%2, %0|%0, %2}";
5840     }
5842   [(set (attr "type")
5843      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5844         (const_string "incdec")
5845         (const_string "alu")))
5846    (set_attr "mode" "HI")])
5848 (define_insn "*addhi_3"
5849   [(set (reg FLAGS_REG)
5850         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5851                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5852    (clobber (match_scratch:HI 0 "=r"))]
5853   "ix86_match_ccmode (insn, CCZmode)
5854    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5856   switch (get_attr_type (insn))
5857     {
5858     case TYPE_INCDEC:
5859       if (operands[2] == const1_rtx)
5860         return "inc{w}\t%0";
5861       else if (operands[2] == constm1_rtx)
5862         return "dec{w}\t%0";
5863       abort();
5865     default:
5866       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5867          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5868       if (GET_CODE (operands[2]) == CONST_INT
5869           && (INTVAL (operands[2]) == 128
5870               || (INTVAL (operands[2]) < 0
5871                   && INTVAL (operands[2]) != -128)))
5872         {
5873           operands[2] = GEN_INT (-INTVAL (operands[2]));
5874           return "sub{w}\t{%2, %0|%0, %2}";
5875         }
5876       return "add{w}\t{%2, %0|%0, %2}";
5877     }
5879   [(set (attr "type")
5880      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5881         (const_string "incdec")
5882         (const_string "alu")))
5883    (set_attr "mode" "HI")])
5885 ; See comments above addsi_4 for details.
5886 (define_insn "*addhi_4"
5887   [(set (reg FLAGS_REG)
5888         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5889                  (match_operand:HI 2 "const_int_operand" "n")))
5890    (clobber (match_scratch:HI 0 "=rm"))]
5891   "ix86_match_ccmode (insn, CCGCmode)
5892    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5894   switch (get_attr_type (insn))
5895     {
5896     case TYPE_INCDEC:
5897       if (operands[2] == constm1_rtx)
5898         return "inc{w}\t%0";
5899       else if (operands[2] == const1_rtx)
5900         return "dec{w}\t%0";
5901       else
5902         abort();
5904     default:
5905       if (! rtx_equal_p (operands[0], operands[1]))
5906         abort ();
5907       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5908          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5909       if ((INTVAL (operands[2]) == -128
5910            || (INTVAL (operands[2]) > 0
5911                && INTVAL (operands[2]) != 128)))
5912         return "sub{w}\t{%2, %0|%0, %2}";
5913       operands[2] = GEN_INT (-INTVAL (operands[2]));
5914       return "add{w}\t{%2, %0|%0, %2}";
5915     }
5917   [(set (attr "type")
5918      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5919         (const_string "incdec")
5920         (const_string "alu")))
5921    (set_attr "mode" "SI")])
5924 (define_insn "*addhi_5"
5925   [(set (reg FLAGS_REG)
5926         (compare
5927           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5928                    (match_operand:HI 2 "general_operand" "rmni"))
5929           (const_int 0)))                       
5930    (clobber (match_scratch:HI 0 "=r"))]
5931   "ix86_match_ccmode (insn, CCGOCmode)
5932    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5934   switch (get_attr_type (insn))
5935     {
5936     case TYPE_INCDEC:
5937       if (operands[2] == const1_rtx)
5938         return "inc{w}\t%0";
5939       else if (operands[2] == constm1_rtx)
5940         return "dec{w}\t%0";
5941       abort();
5943     default:
5944       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5945          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5946       if (GET_CODE (operands[2]) == CONST_INT
5947           && (INTVAL (operands[2]) == 128
5948               || (INTVAL (operands[2]) < 0
5949                   && INTVAL (operands[2]) != -128)))
5950         {
5951           operands[2] = GEN_INT (-INTVAL (operands[2]));
5952           return "sub{w}\t{%2, %0|%0, %2}";
5953         }
5954       return "add{w}\t{%2, %0|%0, %2}";
5955     }
5957   [(set (attr "type")
5958      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5959         (const_string "incdec")
5960         (const_string "alu")))
5961    (set_attr "mode" "HI")])
5963 (define_expand "addqi3"
5964   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5965                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5966                             (match_operand:QI 2 "general_operand" "")))
5967               (clobber (reg:CC FLAGS_REG))])]
5968   "TARGET_QIMODE_MATH"
5969   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5971 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5972 (define_insn "*addqi_1_lea"
5973   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5974         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5975                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5976    (clobber (reg:CC FLAGS_REG))]
5977   "!TARGET_PARTIAL_REG_STALL
5978    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5980   int widen = (which_alternative == 2);
5981   switch (get_attr_type (insn))
5982     {
5983     case TYPE_LEA:
5984       return "#";
5985     case TYPE_INCDEC:
5986       if (operands[2] == const1_rtx)
5987         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5988       else if (operands[2] == constm1_rtx)
5989         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5990       abort();
5992     default:
5993       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5994          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5995       if (GET_CODE (operands[2]) == CONST_INT
5996           && (INTVAL (operands[2]) == 128
5997               || (INTVAL (operands[2]) < 0
5998                   && INTVAL (operands[2]) != -128)))
5999         {
6000           operands[2] = GEN_INT (-INTVAL (operands[2]));
6001           if (widen)
6002             return "sub{l}\t{%2, %k0|%k0, %2}";
6003           else
6004             return "sub{b}\t{%2, %0|%0, %2}";
6005         }
6006       if (widen)
6007         return "add{l}\t{%k2, %k0|%k0, %k2}";
6008       else
6009         return "add{b}\t{%2, %0|%0, %2}";
6010     }
6012   [(set (attr "type")
6013      (if_then_else (eq_attr "alternative" "3")
6014         (const_string "lea")
6015         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6016            (const_string "incdec")
6017            (const_string "alu"))))
6018    (set_attr "mode" "QI,QI,SI,SI")])
6020 (define_insn "*addqi_1"
6021   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6022         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6023                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6024    (clobber (reg:CC FLAGS_REG))]
6025   "TARGET_PARTIAL_REG_STALL
6026    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6028   int widen = (which_alternative == 2);
6029   switch (get_attr_type (insn))
6030     {
6031     case TYPE_INCDEC:
6032       if (operands[2] == const1_rtx)
6033         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6034       else if (operands[2] == constm1_rtx)
6035         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6036       abort();
6038     default:
6039       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6040          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6041       if (GET_CODE (operands[2]) == CONST_INT
6042           && (INTVAL (operands[2]) == 128
6043               || (INTVAL (operands[2]) < 0
6044                   && INTVAL (operands[2]) != -128)))
6045         {
6046           operands[2] = GEN_INT (-INTVAL (operands[2]));
6047           if (widen)
6048             return "sub{l}\t{%2, %k0|%k0, %2}";
6049           else
6050             return "sub{b}\t{%2, %0|%0, %2}";
6051         }
6052       if (widen)
6053         return "add{l}\t{%k2, %k0|%k0, %k2}";
6054       else
6055         return "add{b}\t{%2, %0|%0, %2}";
6056     }
6058   [(set (attr "type")
6059      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6060         (const_string "incdec")
6061         (const_string "alu")))
6062    (set_attr "mode" "QI,QI,SI")])
6064 (define_insn "*addqi_1_slp"
6065   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6066         (plus:QI (match_dup 0)
6067                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6068    (clobber (reg:CC FLAGS_REG))]
6069   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6070    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6072   switch (get_attr_type (insn))
6073     {
6074     case TYPE_INCDEC:
6075       if (operands[1] == const1_rtx)
6076         return "inc{b}\t%0";
6077       else if (operands[1] == constm1_rtx)
6078         return "dec{b}\t%0";
6079       abort();
6081     default:
6082       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6083       if (GET_CODE (operands[1]) == CONST_INT
6084           && INTVAL (operands[1]) < 0)
6085         {
6086           operands[1] = GEN_INT (-INTVAL (operands[1]));
6087           return "sub{b}\t{%1, %0|%0, %1}";
6088         }
6089       return "add{b}\t{%1, %0|%0, %1}";
6090     }
6092   [(set (attr "type")
6093      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6094         (const_string "incdec")
6095         (const_string "alu1")))
6096    (set (attr "memory")
6097      (if_then_else (match_operand 1 "memory_operand" "")
6098         (const_string "load")
6099         (const_string "none")))
6100    (set_attr "mode" "QI")])
6102 (define_insn "*addqi_2"
6103   [(set (reg FLAGS_REG)
6104         (compare
6105           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6106                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6107           (const_int 0)))
6108    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6109         (plus:QI (match_dup 1) (match_dup 2)))]
6110   "ix86_match_ccmode (insn, CCGOCmode)
6111    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6113   switch (get_attr_type (insn))
6114     {
6115     case TYPE_INCDEC:
6116       if (operands[2] == const1_rtx)
6117         return "inc{b}\t%0";
6118       else if (operands[2] == constm1_rtx
6119                || (GET_CODE (operands[2]) == CONST_INT
6120                    && INTVAL (operands[2]) == 255))
6121         return "dec{b}\t%0";
6122       abort();
6124     default:
6125       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6126       if (GET_CODE (operands[2]) == CONST_INT
6127           && INTVAL (operands[2]) < 0)
6128         {
6129           operands[2] = GEN_INT (-INTVAL (operands[2]));
6130           return "sub{b}\t{%2, %0|%0, %2}";
6131         }
6132       return "add{b}\t{%2, %0|%0, %2}";
6133     }
6135   [(set (attr "type")
6136      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6137         (const_string "incdec")
6138         (const_string "alu")))
6139    (set_attr "mode" "QI")])
6141 (define_insn "*addqi_3"
6142   [(set (reg FLAGS_REG)
6143         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6144                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6145    (clobber (match_scratch:QI 0 "=q"))]
6146   "ix86_match_ccmode (insn, CCZmode)
6147    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6149   switch (get_attr_type (insn))
6150     {
6151     case TYPE_INCDEC:
6152       if (operands[2] == const1_rtx)
6153         return "inc{b}\t%0";
6154       else if (operands[2] == constm1_rtx
6155                || (GET_CODE (operands[2]) == CONST_INT
6156                    && INTVAL (operands[2]) == 255))
6157         return "dec{b}\t%0";
6158       abort();
6160     default:
6161       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6162       if (GET_CODE (operands[2]) == CONST_INT
6163           && INTVAL (operands[2]) < 0)
6164         {
6165           operands[2] = GEN_INT (-INTVAL (operands[2]));
6166           return "sub{b}\t{%2, %0|%0, %2}";
6167         }
6168       return "add{b}\t{%2, %0|%0, %2}";
6169     }
6171   [(set (attr "type")
6172      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6173         (const_string "incdec")
6174         (const_string "alu")))
6175    (set_attr "mode" "QI")])
6177 ; See comments above addsi_4 for details.
6178 (define_insn "*addqi_4"
6179   [(set (reg FLAGS_REG)
6180         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6181                  (match_operand:QI 2 "const_int_operand" "n")))
6182    (clobber (match_scratch:QI 0 "=qm"))]
6183   "ix86_match_ccmode (insn, CCGCmode)
6184    && (INTVAL (operands[2]) & 0xff) != 0x80"
6186   switch (get_attr_type (insn))
6187     {
6188     case TYPE_INCDEC:
6189       if (operands[2] == constm1_rtx
6190           || (GET_CODE (operands[2]) == CONST_INT
6191               && INTVAL (operands[2]) == 255))
6192         return "inc{b}\t%0";
6193       else if (operands[2] == const1_rtx)
6194         return "dec{b}\t%0";
6195       else
6196         abort();
6198     default:
6199       if (! rtx_equal_p (operands[0], operands[1]))
6200         abort ();
6201       if (INTVAL (operands[2]) < 0)
6202         {
6203           operands[2] = GEN_INT (-INTVAL (operands[2]));
6204           return "add{b}\t{%2, %0|%0, %2}";
6205         }
6206       return "sub{b}\t{%2, %0|%0, %2}";
6207     }
6209   [(set (attr "type")
6210      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6211         (const_string "incdec")
6212         (const_string "alu")))
6213    (set_attr "mode" "QI")])
6216 (define_insn "*addqi_5"
6217   [(set (reg FLAGS_REG)
6218         (compare
6219           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6220                    (match_operand:QI 2 "general_operand" "qmni"))
6221           (const_int 0)))
6222    (clobber (match_scratch:QI 0 "=q"))]
6223   "ix86_match_ccmode (insn, CCGOCmode)
6224    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6226   switch (get_attr_type (insn))
6227     {
6228     case TYPE_INCDEC:
6229       if (operands[2] == const1_rtx)
6230         return "inc{b}\t%0";
6231       else if (operands[2] == constm1_rtx
6232                || (GET_CODE (operands[2]) == CONST_INT
6233                    && INTVAL (operands[2]) == 255))
6234         return "dec{b}\t%0";
6235       abort();
6237     default:
6238       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6239       if (GET_CODE (operands[2]) == CONST_INT
6240           && INTVAL (operands[2]) < 0)
6241         {
6242           operands[2] = GEN_INT (-INTVAL (operands[2]));
6243           return "sub{b}\t{%2, %0|%0, %2}";
6244         }
6245       return "add{b}\t{%2, %0|%0, %2}";
6246     }
6248   [(set (attr "type")
6249      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250         (const_string "incdec")
6251         (const_string "alu")))
6252    (set_attr "mode" "QI")])
6255 (define_insn "addqi_ext_1"
6256   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6257                          (const_int 8)
6258                          (const_int 8))
6259         (plus:SI
6260           (zero_extract:SI
6261             (match_operand 1 "ext_register_operand" "0")
6262             (const_int 8)
6263             (const_int 8))
6264           (match_operand:QI 2 "general_operand" "Qmn")))
6265    (clobber (reg:CC FLAGS_REG))]
6266   "!TARGET_64BIT"
6268   switch (get_attr_type (insn))
6269     {
6270     case TYPE_INCDEC:
6271       if (operands[2] == const1_rtx)
6272         return "inc{b}\t%h0";
6273       else if (operands[2] == constm1_rtx
6274                || (GET_CODE (operands[2]) == CONST_INT
6275                    && INTVAL (operands[2]) == 255))
6276         return "dec{b}\t%h0";
6277       abort();
6279     default:
6280       return "add{b}\t{%2, %h0|%h0, %2}";
6281     }
6283   [(set (attr "type")
6284      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6285         (const_string "incdec")
6286         (const_string "alu")))
6287    (set_attr "mode" "QI")])
6289 (define_insn "*addqi_ext_1_rex64"
6290   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6291                          (const_int 8)
6292                          (const_int 8))
6293         (plus:SI
6294           (zero_extract:SI
6295             (match_operand 1 "ext_register_operand" "0")
6296             (const_int 8)
6297             (const_int 8))
6298           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6299    (clobber (reg:CC FLAGS_REG))]
6300   "TARGET_64BIT"
6302   switch (get_attr_type (insn))
6303     {
6304     case TYPE_INCDEC:
6305       if (operands[2] == const1_rtx)
6306         return "inc{b}\t%h0";
6307       else if (operands[2] == constm1_rtx
6308                || (GET_CODE (operands[2]) == CONST_INT
6309                    && INTVAL (operands[2]) == 255))
6310         return "dec{b}\t%h0";
6311       abort();
6313     default:
6314       return "add{b}\t{%2, %h0|%h0, %2}";
6315     }
6317   [(set (attr "type")
6318      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6319         (const_string "incdec")
6320         (const_string "alu")))
6321    (set_attr "mode" "QI")])
6323 (define_insn "*addqi_ext_2"
6324   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6325                          (const_int 8)
6326                          (const_int 8))
6327         (plus:SI
6328           (zero_extract:SI
6329             (match_operand 1 "ext_register_operand" "%0")
6330             (const_int 8)
6331             (const_int 8))
6332           (zero_extract:SI
6333             (match_operand 2 "ext_register_operand" "Q")
6334             (const_int 8)
6335             (const_int 8))))
6336    (clobber (reg:CC FLAGS_REG))]
6337   ""
6338   "add{b}\t{%h2, %h0|%h0, %h2}"
6339   [(set_attr "type" "alu")
6340    (set_attr "mode" "QI")])
6342 ;; The patterns that match these are at the end of this file.
6344 (define_expand "addxf3"
6345   [(set (match_operand:XF 0 "register_operand" "")
6346         (plus:XF (match_operand:XF 1 "register_operand" "")
6347                  (match_operand:XF 2 "register_operand" "")))]
6348   "TARGET_80387"
6349   "")
6351 (define_expand "adddf3"
6352   [(set (match_operand:DF 0 "register_operand" "")
6353         (plus:DF (match_operand:DF 1 "register_operand" "")
6354                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6355   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6356   "")
6358 (define_expand "addsf3"
6359   [(set (match_operand:SF 0 "register_operand" "")
6360         (plus:SF (match_operand:SF 1 "register_operand" "")
6361                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6362   "TARGET_80387 || TARGET_SSE_MATH"
6363   "")
6365 ;; Subtract instructions
6367 ;; %%% splits for subsidi3
6369 (define_expand "subdi3"
6370   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6371                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6372                              (match_operand:DI 2 "x86_64_general_operand" "")))
6373               (clobber (reg:CC FLAGS_REG))])]
6374   ""
6375   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6377 (define_insn "*subdi3_1"
6378   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6379         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6380                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6381    (clobber (reg:CC FLAGS_REG))]
6382   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6383   "#")
6385 (define_split
6386   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6387         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6388                   (match_operand:DI 2 "general_operand" "")))
6389    (clobber (reg:CC FLAGS_REG))]
6390   "!TARGET_64BIT && reload_completed"
6391   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6392               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6393    (parallel [(set (match_dup 3)
6394                    (minus:SI (match_dup 4)
6395                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6396                                       (match_dup 5))))
6397               (clobber (reg:CC FLAGS_REG))])]
6398   "split_di (operands+0, 1, operands+0, operands+3);
6399    split_di (operands+1, 1, operands+1, operands+4);
6400    split_di (operands+2, 1, operands+2, operands+5);")
6402 (define_insn "subdi3_carry_rex64"
6403   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6404           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6405             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6406                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6407    (clobber (reg:CC FLAGS_REG))]
6408   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6409   "sbb{q}\t{%2, %0|%0, %2}"
6410   [(set_attr "type" "alu")
6411    (set_attr "pent_pair" "pu")
6412    (set_attr "mode" "DI")])
6414 (define_insn "*subdi_1_rex64"
6415   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6416         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6417                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6418    (clobber (reg:CC FLAGS_REG))]
6419   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6420   "sub{q}\t{%2, %0|%0, %2}"
6421   [(set_attr "type" "alu")
6422    (set_attr "mode" "DI")])
6424 (define_insn "*subdi_2_rex64"
6425   [(set (reg FLAGS_REG)
6426         (compare
6427           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6428                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6429           (const_int 0)))
6430    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6431         (minus:DI (match_dup 1) (match_dup 2)))]
6432   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6433    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6434   "sub{q}\t{%2, %0|%0, %2}"
6435   [(set_attr "type" "alu")
6436    (set_attr "mode" "DI")])
6438 (define_insn "*subdi_3_rex63"
6439   [(set (reg FLAGS_REG)
6440         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6441                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6442    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6443         (minus:DI (match_dup 1) (match_dup 2)))]
6444   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6445    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6446   "sub{q}\t{%2, %0|%0, %2}"
6447   [(set_attr "type" "alu")
6448    (set_attr "mode" "DI")])
6450 (define_insn "subqi3_carry"
6451   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6452           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6453             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6454                (match_operand:QI 2 "general_operand" "qi,qm"))))
6455    (clobber (reg:CC FLAGS_REG))]
6456   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6457   "sbb{b}\t{%2, %0|%0, %2}"
6458   [(set_attr "type" "alu")
6459    (set_attr "pent_pair" "pu")
6460    (set_attr "mode" "QI")])
6462 (define_insn "subhi3_carry"
6463   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6464           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6465             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6466                (match_operand:HI 2 "general_operand" "ri,rm"))))
6467    (clobber (reg:CC FLAGS_REG))]
6468   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6469   "sbb{w}\t{%2, %0|%0, %2}"
6470   [(set_attr "type" "alu")
6471    (set_attr "pent_pair" "pu")
6472    (set_attr "mode" "HI")])
6474 (define_insn "subsi3_carry"
6475   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6476           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6477             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6478                (match_operand:SI 2 "general_operand" "ri,rm"))))
6479    (clobber (reg:CC FLAGS_REG))]
6480   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6481   "sbb{l}\t{%2, %0|%0, %2}"
6482   [(set_attr "type" "alu")
6483    (set_attr "pent_pair" "pu")
6484    (set_attr "mode" "SI")])
6486 (define_insn "subsi3_carry_zext"
6487   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6488           (zero_extend:DI
6489             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6490               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6491                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6492    (clobber (reg:CC FLAGS_REG))]
6493   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6494   "sbb{l}\t{%2, %k0|%k0, %2}"
6495   [(set_attr "type" "alu")
6496    (set_attr "pent_pair" "pu")
6497    (set_attr "mode" "SI")])
6499 (define_expand "subsi3"
6500   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6501                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6502                              (match_operand:SI 2 "general_operand" "")))
6503               (clobber (reg:CC FLAGS_REG))])]
6504   ""
6505   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6507 (define_insn "*subsi_1"
6508   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6509         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6510                   (match_operand:SI 2 "general_operand" "ri,rm")))
6511    (clobber (reg:CC FLAGS_REG))]
6512   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6513   "sub{l}\t{%2, %0|%0, %2}"
6514   [(set_attr "type" "alu")
6515    (set_attr "mode" "SI")])
6517 (define_insn "*subsi_1_zext"
6518   [(set (match_operand:DI 0 "register_operand" "=r")
6519         (zero_extend:DI
6520           (minus:SI (match_operand:SI 1 "register_operand" "0")
6521                     (match_operand:SI 2 "general_operand" "rim"))))
6522    (clobber (reg:CC FLAGS_REG))]
6523   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6524   "sub{l}\t{%2, %k0|%k0, %2}"
6525   [(set_attr "type" "alu")
6526    (set_attr "mode" "SI")])
6528 (define_insn "*subsi_2"
6529   [(set (reg FLAGS_REG)
6530         (compare
6531           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6532                     (match_operand:SI 2 "general_operand" "ri,rm"))
6533           (const_int 0)))
6534    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6535         (minus:SI (match_dup 1) (match_dup 2)))]
6536   "ix86_match_ccmode (insn, CCGOCmode)
6537    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6538   "sub{l}\t{%2, %0|%0, %2}"
6539   [(set_attr "type" "alu")
6540    (set_attr "mode" "SI")])
6542 (define_insn "*subsi_2_zext"
6543   [(set (reg FLAGS_REG)
6544         (compare
6545           (minus:SI (match_operand:SI 1 "register_operand" "0")
6546                     (match_operand:SI 2 "general_operand" "rim"))
6547           (const_int 0)))
6548    (set (match_operand:DI 0 "register_operand" "=r")
6549         (zero_extend:DI
6550           (minus:SI (match_dup 1)
6551                     (match_dup 2))))]
6552   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6553    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554   "sub{l}\t{%2, %k0|%k0, %2}"
6555   [(set_attr "type" "alu")
6556    (set_attr "mode" "SI")])
6558 (define_insn "*subsi_3"
6559   [(set (reg FLAGS_REG)
6560         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6561                  (match_operand:SI 2 "general_operand" "ri,rm")))
6562    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6563         (minus:SI (match_dup 1) (match_dup 2)))]
6564   "ix86_match_ccmode (insn, CCmode)
6565    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6566   "sub{l}\t{%2, %0|%0, %2}"
6567   [(set_attr "type" "alu")
6568    (set_attr "mode" "SI")])
6570 (define_insn "*subsi_3_zext"
6571   [(set (reg FLAGS_REG)
6572         (compare (match_operand:SI 1 "register_operand" "0")
6573                  (match_operand:SI 2 "general_operand" "rim")))
6574    (set (match_operand:DI 0 "register_operand" "=r")
6575         (zero_extend:DI
6576           (minus:SI (match_dup 1)
6577                     (match_dup 2))))]
6578   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6579    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6580   "sub{q}\t{%2, %0|%0, %2}"
6581   [(set_attr "type" "alu")
6582    (set_attr "mode" "DI")])
6584 (define_expand "subhi3"
6585   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6586                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6587                              (match_operand:HI 2 "general_operand" "")))
6588               (clobber (reg:CC FLAGS_REG))])]
6589   "TARGET_HIMODE_MATH"
6590   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6592 (define_insn "*subhi_1"
6593   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6594         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6595                   (match_operand:HI 2 "general_operand" "ri,rm")))
6596    (clobber (reg:CC FLAGS_REG))]
6597   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6598   "sub{w}\t{%2, %0|%0, %2}"
6599   [(set_attr "type" "alu")
6600    (set_attr "mode" "HI")])
6602 (define_insn "*subhi_2"
6603   [(set (reg FLAGS_REG)
6604         (compare
6605           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6606                     (match_operand:HI 2 "general_operand" "ri,rm"))
6607           (const_int 0)))
6608    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6609         (minus:HI (match_dup 1) (match_dup 2)))]
6610   "ix86_match_ccmode (insn, CCGOCmode)
6611    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6612   "sub{w}\t{%2, %0|%0, %2}"
6613   [(set_attr "type" "alu")
6614    (set_attr "mode" "HI")])
6616 (define_insn "*subhi_3"
6617   [(set (reg FLAGS_REG)
6618         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6619                  (match_operand:HI 2 "general_operand" "ri,rm")))
6620    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6621         (minus:HI (match_dup 1) (match_dup 2)))]
6622   "ix86_match_ccmode (insn, CCmode)
6623    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6624   "sub{w}\t{%2, %0|%0, %2}"
6625   [(set_attr "type" "alu")
6626    (set_attr "mode" "HI")])
6628 (define_expand "subqi3"
6629   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6630                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6631                              (match_operand:QI 2 "general_operand" "")))
6632               (clobber (reg:CC FLAGS_REG))])]
6633   "TARGET_QIMODE_MATH"
6634   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6636 (define_insn "*subqi_1"
6637   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6638         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6639                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6640    (clobber (reg:CC FLAGS_REG))]
6641   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6642   "sub{b}\t{%2, %0|%0, %2}"
6643   [(set_attr "type" "alu")
6644    (set_attr "mode" "QI")])
6646 (define_insn "*subqi_1_slp"
6647   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6648         (minus:QI (match_dup 0)
6649                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6650    (clobber (reg:CC FLAGS_REG))]
6651   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6652    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6653   "sub{b}\t{%1, %0|%0, %1}"
6654   [(set_attr "type" "alu1")
6655    (set_attr "mode" "QI")])
6657 (define_insn "*subqi_2"
6658   [(set (reg FLAGS_REG)
6659         (compare
6660           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6661                     (match_operand:QI 2 "general_operand" "qi,qm"))
6662           (const_int 0)))
6663    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6664         (minus:HI (match_dup 1) (match_dup 2)))]
6665   "ix86_match_ccmode (insn, CCGOCmode)
6666    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6667   "sub{b}\t{%2, %0|%0, %2}"
6668   [(set_attr "type" "alu")
6669    (set_attr "mode" "QI")])
6671 (define_insn "*subqi_3"
6672   [(set (reg FLAGS_REG)
6673         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6674                  (match_operand:QI 2 "general_operand" "qi,qm")))
6675    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6676         (minus:HI (match_dup 1) (match_dup 2)))]
6677   "ix86_match_ccmode (insn, CCmode)
6678    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6679   "sub{b}\t{%2, %0|%0, %2}"
6680   [(set_attr "type" "alu")
6681    (set_attr "mode" "QI")])
6683 ;; The patterns that match these are at the end of this file.
6685 (define_expand "subxf3"
6686   [(set (match_operand:XF 0 "register_operand" "")
6687         (minus:XF (match_operand:XF 1 "register_operand" "")
6688                   (match_operand:XF 2 "register_operand" "")))]
6689   "TARGET_80387"
6690   "")
6692 (define_expand "subdf3"
6693   [(set (match_operand:DF 0 "register_operand" "")
6694         (minus:DF (match_operand:DF 1 "register_operand" "")
6695                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6696   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6697   "")
6699 (define_expand "subsf3"
6700   [(set (match_operand:SF 0 "register_operand" "")
6701         (minus:SF (match_operand:SF 1 "register_operand" "")
6702                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6703   "TARGET_80387 || TARGET_SSE_MATH"
6704   "")
6706 ;; Multiply instructions
6708 (define_expand "muldi3"
6709   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6710                    (mult:DI (match_operand:DI 1 "register_operand" "")
6711                             (match_operand:DI 2 "x86_64_general_operand" "")))
6712               (clobber (reg:CC FLAGS_REG))])]
6713   "TARGET_64BIT"
6714   "")
6716 (define_insn "*muldi3_1_rex64"
6717   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6718         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6719                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6720    (clobber (reg:CC FLAGS_REG))]
6721   "TARGET_64BIT
6722    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6723   "@
6724    imul{q}\t{%2, %1, %0|%0, %1, %2}
6725    imul{q}\t{%2, %1, %0|%0, %1, %2}
6726    imul{q}\t{%2, %0|%0, %2}"
6727   [(set_attr "type" "imul")
6728    (set_attr "prefix_0f" "0,0,1")
6729    (set (attr "athlon_decode")
6730         (cond [(eq_attr "cpu" "athlon")
6731                   (const_string "vector")
6732                (eq_attr "alternative" "1")
6733                   (const_string "vector")
6734                (and (eq_attr "alternative" "2")
6735                     (match_operand 1 "memory_operand" ""))
6736                   (const_string "vector")]
6737               (const_string "direct")))
6738    (set_attr "mode" "DI")])
6740 (define_expand "mulsi3"
6741   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6742                    (mult:SI (match_operand:SI 1 "register_operand" "")
6743                             (match_operand:SI 2 "general_operand" "")))
6744               (clobber (reg:CC FLAGS_REG))])]
6745   ""
6746   "")
6748 (define_insn "*mulsi3_1"
6749   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6750         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6751                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6752    (clobber (reg:CC FLAGS_REG))]
6753   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6754   "@
6755    imul{l}\t{%2, %1, %0|%0, %1, %2}
6756    imul{l}\t{%2, %1, %0|%0, %1, %2}
6757    imul{l}\t{%2, %0|%0, %2}"
6758   [(set_attr "type" "imul")
6759    (set_attr "prefix_0f" "0,0,1")
6760    (set (attr "athlon_decode")
6761         (cond [(eq_attr "cpu" "athlon")
6762                   (const_string "vector")
6763                (eq_attr "alternative" "1")
6764                   (const_string "vector")
6765                (and (eq_attr "alternative" "2")
6766                     (match_operand 1 "memory_operand" ""))
6767                   (const_string "vector")]
6768               (const_string "direct")))
6769    (set_attr "mode" "SI")])
6771 (define_insn "*mulsi3_1_zext"
6772   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6773         (zero_extend:DI
6774           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6775                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6776    (clobber (reg:CC FLAGS_REG))]
6777   "TARGET_64BIT
6778    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6779   "@
6780    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6781    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6782    imul{l}\t{%2, %k0|%k0, %2}"
6783   [(set_attr "type" "imul")
6784    (set_attr "prefix_0f" "0,0,1")
6785    (set (attr "athlon_decode")
6786         (cond [(eq_attr "cpu" "athlon")
6787                   (const_string "vector")
6788                (eq_attr "alternative" "1")
6789                   (const_string "vector")
6790                (and (eq_attr "alternative" "2")
6791                     (match_operand 1 "memory_operand" ""))
6792                   (const_string "vector")]
6793               (const_string "direct")))
6794    (set_attr "mode" "SI")])
6796 (define_expand "mulhi3"
6797   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6798                    (mult:HI (match_operand:HI 1 "register_operand" "")
6799                             (match_operand:HI 2 "general_operand" "")))
6800               (clobber (reg:CC FLAGS_REG))])]
6801   "TARGET_HIMODE_MATH"
6802   "")
6804 (define_insn "*mulhi3_1"
6805   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6806         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6807                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6808    (clobber (reg:CC FLAGS_REG))]
6809   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6810   "@
6811    imul{w}\t{%2, %1, %0|%0, %1, %2}
6812    imul{w}\t{%2, %1, %0|%0, %1, %2}
6813    imul{w}\t{%2, %0|%0, %2}"
6814   [(set_attr "type" "imul")
6815    (set_attr "prefix_0f" "0,0,1")
6816    (set (attr "athlon_decode")
6817         (cond [(eq_attr "cpu" "athlon")
6818                   (const_string "vector")
6819                (eq_attr "alternative" "1,2")
6820                   (const_string "vector")]
6821               (const_string "direct")))
6822    (set_attr "mode" "HI")])
6824 (define_expand "mulqi3"
6825   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6826                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6827                             (match_operand:QI 2 "register_operand" "")))
6828               (clobber (reg:CC FLAGS_REG))])]
6829   "TARGET_QIMODE_MATH"
6830   "")
6832 (define_insn "*mulqi3_1"
6833   [(set (match_operand:QI 0 "register_operand" "=a")
6834         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6835                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6836    (clobber (reg:CC FLAGS_REG))]
6837   "TARGET_QIMODE_MATH
6838    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6839   "mul{b}\t%2"
6840   [(set_attr "type" "imul")
6841    (set_attr "length_immediate" "0")
6842    (set (attr "athlon_decode")
6843      (if_then_else (eq_attr "cpu" "athlon")
6844         (const_string "vector")
6845         (const_string "direct")))
6846    (set_attr "mode" "QI")])
6848 (define_expand "umulqihi3"
6849   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6850                    (mult:HI (zero_extend:HI
6851                               (match_operand:QI 1 "nonimmediate_operand" ""))
6852                             (zero_extend:HI
6853                               (match_operand:QI 2 "register_operand" ""))))
6854               (clobber (reg:CC FLAGS_REG))])]
6855   "TARGET_QIMODE_MATH"
6856   "")
6858 (define_insn "*umulqihi3_1"
6859   [(set (match_operand:HI 0 "register_operand" "=a")
6860         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6861                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6862    (clobber (reg:CC FLAGS_REG))]
6863   "TARGET_QIMODE_MATH
6864    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6865   "mul{b}\t%2"
6866   [(set_attr "type" "imul")
6867    (set_attr "length_immediate" "0")
6868    (set (attr "athlon_decode")
6869      (if_then_else (eq_attr "cpu" "athlon")
6870         (const_string "vector")
6871         (const_string "direct")))
6872    (set_attr "mode" "QI")])
6874 (define_expand "mulqihi3"
6875   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6876                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6877                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6878               (clobber (reg:CC FLAGS_REG))])]
6879   "TARGET_QIMODE_MATH"
6880   "")
6882 (define_insn "*mulqihi3_insn"
6883   [(set (match_operand:HI 0 "register_operand" "=a")
6884         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6885                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6886    (clobber (reg:CC FLAGS_REG))]
6887   "TARGET_QIMODE_MATH
6888    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6889   "imul{b}\t%2"
6890   [(set_attr "type" "imul")
6891    (set_attr "length_immediate" "0")
6892    (set (attr "athlon_decode")
6893      (if_then_else (eq_attr "cpu" "athlon")
6894         (const_string "vector")
6895         (const_string "direct")))
6896    (set_attr "mode" "QI")])
6898 (define_expand "umulditi3"
6899   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6900                    (mult:TI (zero_extend:TI
6901                               (match_operand:DI 1 "nonimmediate_operand" ""))
6902                             (zero_extend:TI
6903                               (match_operand:DI 2 "register_operand" ""))))
6904               (clobber (reg:CC FLAGS_REG))])]
6905   "TARGET_64BIT"
6906   "")
6908 (define_insn "*umulditi3_insn"
6909   [(set (match_operand:TI 0 "register_operand" "=A")
6910         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6911                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6912    (clobber (reg:CC FLAGS_REG))]
6913   "TARGET_64BIT
6914    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6915   "mul{q}\t%2"
6916   [(set_attr "type" "imul")
6917    (set_attr "length_immediate" "0")
6918    (set (attr "athlon_decode")
6919      (if_then_else (eq_attr "cpu" "athlon")
6920         (const_string "vector")
6921         (const_string "double")))
6922    (set_attr "mode" "DI")])
6924 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6925 (define_expand "umulsidi3"
6926   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6927                    (mult:DI (zero_extend:DI
6928                               (match_operand:SI 1 "nonimmediate_operand" ""))
6929                             (zero_extend:DI
6930                               (match_operand:SI 2 "register_operand" ""))))
6931               (clobber (reg:CC FLAGS_REG))])]
6932   "!TARGET_64BIT"
6933   "")
6935 (define_insn "*umulsidi3_insn"
6936   [(set (match_operand:DI 0 "register_operand" "=A")
6937         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6938                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6939    (clobber (reg:CC FLAGS_REG))]
6940   "!TARGET_64BIT
6941    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6942   "mul{l}\t%2"
6943   [(set_attr "type" "imul")
6944    (set_attr "length_immediate" "0")
6945    (set (attr "athlon_decode")
6946      (if_then_else (eq_attr "cpu" "athlon")
6947         (const_string "vector")
6948         (const_string "double")))
6949    (set_attr "mode" "SI")])
6951 (define_expand "mulditi3"
6952   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6953                    (mult:TI (sign_extend:TI
6954                               (match_operand:DI 1 "nonimmediate_operand" ""))
6955                             (sign_extend:TI
6956                               (match_operand:DI 2 "register_operand" ""))))
6957               (clobber (reg:CC FLAGS_REG))])]
6958   "TARGET_64BIT"
6959   "")
6961 (define_insn "*mulditi3_insn"
6962   [(set (match_operand:TI 0 "register_operand" "=A")
6963         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6964                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6965    (clobber (reg:CC FLAGS_REG))]
6966   "TARGET_64BIT
6967    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6968   "imul{q}\t%2"
6969   [(set_attr "type" "imul")
6970    (set_attr "length_immediate" "0")
6971    (set (attr "athlon_decode")
6972      (if_then_else (eq_attr "cpu" "athlon")
6973         (const_string "vector")
6974         (const_string "double")))
6975    (set_attr "mode" "DI")])
6977 (define_expand "mulsidi3"
6978   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6979                    (mult:DI (sign_extend:DI
6980                               (match_operand:SI 1 "nonimmediate_operand" ""))
6981                             (sign_extend:DI
6982                               (match_operand:SI 2 "register_operand" ""))))
6983               (clobber (reg:CC FLAGS_REG))])]
6984   "!TARGET_64BIT"
6985   "")
6987 (define_insn "*mulsidi3_insn"
6988   [(set (match_operand:DI 0 "register_operand" "=A")
6989         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6990                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6991    (clobber (reg:CC FLAGS_REG))]
6992   "!TARGET_64BIT
6993    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6994   "imul{l}\t%2"
6995   [(set_attr "type" "imul")
6996    (set_attr "length_immediate" "0")
6997    (set (attr "athlon_decode")
6998      (if_then_else (eq_attr "cpu" "athlon")
6999         (const_string "vector")
7000         (const_string "double")))
7001    (set_attr "mode" "SI")])
7003 (define_expand "umuldi3_highpart"
7004   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7005                    (truncate:DI
7006                      (lshiftrt:TI
7007                        (mult:TI (zero_extend:TI
7008                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7009                                 (zero_extend:TI
7010                                   (match_operand:DI 2 "register_operand" "")))
7011                        (const_int 64))))
7012               (clobber (match_scratch:DI 3 ""))
7013               (clobber (reg:CC FLAGS_REG))])]
7014   "TARGET_64BIT"
7015   "")
7017 (define_insn "*umuldi3_highpart_rex64"
7018   [(set (match_operand:DI 0 "register_operand" "=d")
7019         (truncate:DI
7020           (lshiftrt:TI
7021             (mult:TI (zero_extend:TI
7022                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7023                      (zero_extend:TI
7024                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7025             (const_int 64))))
7026    (clobber (match_scratch:DI 3 "=1"))
7027    (clobber (reg:CC FLAGS_REG))]
7028   "TARGET_64BIT
7029    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7030   "mul{q}\t%2"
7031   [(set_attr "type" "imul")
7032    (set_attr "length_immediate" "0")
7033    (set (attr "athlon_decode")
7034      (if_then_else (eq_attr "cpu" "athlon")
7035         (const_string "vector")
7036         (const_string "double")))
7037    (set_attr "mode" "DI")])
7039 (define_expand "umulsi3_highpart"
7040   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7041                    (truncate:SI
7042                      (lshiftrt:DI
7043                        (mult:DI (zero_extend:DI
7044                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7045                                 (zero_extend:DI
7046                                   (match_operand:SI 2 "register_operand" "")))
7047                        (const_int 32))))
7048               (clobber (match_scratch:SI 3 ""))
7049               (clobber (reg:CC FLAGS_REG))])]
7050   ""
7051   "")
7053 (define_insn "*umulsi3_highpart_insn"
7054   [(set (match_operand:SI 0 "register_operand" "=d")
7055         (truncate:SI
7056           (lshiftrt:DI
7057             (mult:DI (zero_extend:DI
7058                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7059                      (zero_extend:DI
7060                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7061             (const_int 32))))
7062    (clobber (match_scratch:SI 3 "=1"))
7063    (clobber (reg:CC FLAGS_REG))]
7064   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7065   "mul{l}\t%2"
7066   [(set_attr "type" "imul")
7067    (set_attr "length_immediate" "0")
7068    (set (attr "athlon_decode")
7069      (if_then_else (eq_attr "cpu" "athlon")
7070         (const_string "vector")
7071         (const_string "double")))
7072    (set_attr "mode" "SI")])
7074 (define_insn "*umulsi3_highpart_zext"
7075   [(set (match_operand:DI 0 "register_operand" "=d")
7076         (zero_extend:DI (truncate:SI
7077           (lshiftrt:DI
7078             (mult:DI (zero_extend:DI
7079                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7080                      (zero_extend:DI
7081                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7082             (const_int 32)))))
7083    (clobber (match_scratch:SI 3 "=1"))
7084    (clobber (reg:CC FLAGS_REG))]
7085   "TARGET_64BIT
7086    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7087   "mul{l}\t%2"
7088   [(set_attr "type" "imul")
7089    (set_attr "length_immediate" "0")
7090    (set (attr "athlon_decode")
7091      (if_then_else (eq_attr "cpu" "athlon")
7092         (const_string "vector")
7093         (const_string "double")))
7094    (set_attr "mode" "SI")])
7096 (define_expand "smuldi3_highpart"
7097   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7098                    (truncate:DI
7099                      (lshiftrt:TI
7100                        (mult:TI (sign_extend:TI
7101                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7102                                 (sign_extend:TI
7103                                   (match_operand:DI 2 "register_operand" "")))
7104                        (const_int 64))))
7105               (clobber (match_scratch:DI 3 ""))
7106               (clobber (reg:CC FLAGS_REG))])]
7107   "TARGET_64BIT"
7108   "")
7110 (define_insn "*smuldi3_highpart_rex64"
7111   [(set (match_operand:DI 0 "register_operand" "=d")
7112         (truncate:DI
7113           (lshiftrt:TI
7114             (mult:TI (sign_extend:TI
7115                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7116                      (sign_extend:TI
7117                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7118             (const_int 64))))
7119    (clobber (match_scratch:DI 3 "=1"))
7120    (clobber (reg:CC FLAGS_REG))]
7121   "TARGET_64BIT
7122    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7123   "imul{q}\t%2"
7124   [(set_attr "type" "imul")
7125    (set (attr "athlon_decode")
7126      (if_then_else (eq_attr "cpu" "athlon")
7127         (const_string "vector")
7128         (const_string "double")))
7129    (set_attr "mode" "DI")])
7131 (define_expand "smulsi3_highpart"
7132   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7133                    (truncate:SI
7134                      (lshiftrt:DI
7135                        (mult:DI (sign_extend:DI
7136                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7137                                 (sign_extend:DI
7138                                   (match_operand:SI 2 "register_operand" "")))
7139                        (const_int 32))))
7140               (clobber (match_scratch:SI 3 ""))
7141               (clobber (reg:CC FLAGS_REG))])]
7142   ""
7143   "")
7145 (define_insn "*smulsi3_highpart_insn"
7146   [(set (match_operand:SI 0 "register_operand" "=d")
7147         (truncate:SI
7148           (lshiftrt:DI
7149             (mult:DI (sign_extend:DI
7150                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7151                      (sign_extend:DI
7152                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7153             (const_int 32))))
7154    (clobber (match_scratch:SI 3 "=1"))
7155    (clobber (reg:CC FLAGS_REG))]
7156   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7157   "imul{l}\t%2"
7158   [(set_attr "type" "imul")
7159    (set (attr "athlon_decode")
7160      (if_then_else (eq_attr "cpu" "athlon")
7161         (const_string "vector")
7162         (const_string "double")))
7163    (set_attr "mode" "SI")])
7165 (define_insn "*smulsi3_highpart_zext"
7166   [(set (match_operand:DI 0 "register_operand" "=d")
7167         (zero_extend:DI (truncate:SI
7168           (lshiftrt:DI
7169             (mult:DI (sign_extend:DI
7170                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7171                      (sign_extend:DI
7172                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7173             (const_int 32)))))
7174    (clobber (match_scratch:SI 3 "=1"))
7175    (clobber (reg:CC FLAGS_REG))]
7176   "TARGET_64BIT
7177    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7178   "imul{l}\t%2"
7179   [(set_attr "type" "imul")
7180    (set (attr "athlon_decode")
7181      (if_then_else (eq_attr "cpu" "athlon")
7182         (const_string "vector")
7183         (const_string "double")))
7184    (set_attr "mode" "SI")])
7186 ;; The patterns that match these are at the end of this file.
7188 (define_expand "mulxf3"
7189   [(set (match_operand:XF 0 "register_operand" "")
7190         (mult:XF (match_operand:XF 1 "register_operand" "")
7191                  (match_operand:XF 2 "register_operand" "")))]
7192   "TARGET_80387"
7193   "")
7195 (define_expand "muldf3"
7196   [(set (match_operand:DF 0 "register_operand" "")
7197         (mult:DF (match_operand:DF 1 "register_operand" "")
7198                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7199   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7200   "")
7202 (define_expand "mulsf3"
7203   [(set (match_operand:SF 0 "register_operand" "")
7204         (mult:SF (match_operand:SF 1 "register_operand" "")
7205                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7206   "TARGET_80387 || TARGET_SSE_MATH"
7207   "")
7209 ;; Divide instructions
7211 (define_insn "divqi3"
7212   [(set (match_operand:QI 0 "register_operand" "=a")
7213         (div:QI (match_operand:HI 1 "register_operand" "0")
7214                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7215    (clobber (reg:CC FLAGS_REG))]
7216   "TARGET_QIMODE_MATH"
7217   "idiv{b}\t%2"
7218   [(set_attr "type" "idiv")
7219    (set_attr "mode" "QI")])
7221 (define_insn "udivqi3"
7222   [(set (match_operand:QI 0 "register_operand" "=a")
7223         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7224                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7225    (clobber (reg:CC FLAGS_REG))]
7226   "TARGET_QIMODE_MATH"
7227   "div{b}\t%2"
7228   [(set_attr "type" "idiv")
7229    (set_attr "mode" "QI")])
7231 ;; The patterns that match these are at the end of this file.
7233 (define_expand "divxf3"
7234   [(set (match_operand:XF 0 "register_operand" "")
7235         (div:XF (match_operand:XF 1 "register_operand" "")
7236                 (match_operand:XF 2 "register_operand" "")))]
7237   "TARGET_80387"
7238   "")
7240 (define_expand "divdf3"
7241   [(set (match_operand:DF 0 "register_operand" "")
7242         (div:DF (match_operand:DF 1 "register_operand" "")
7243                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7244    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7245    "")
7247 (define_expand "divsf3"
7248   [(set (match_operand:SF 0 "register_operand" "")
7249         (div:SF (match_operand:SF 1 "register_operand" "")
7250                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7251   "TARGET_80387 || TARGET_SSE_MATH"
7252   "")
7254 ;; Remainder instructions.
7256 (define_expand "divmoddi4"
7257   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7258                    (div:DI (match_operand:DI 1 "register_operand" "")
7259                            (match_operand:DI 2 "nonimmediate_operand" "")))
7260               (set (match_operand:DI 3 "register_operand" "")
7261                    (mod:DI (match_dup 1) (match_dup 2)))
7262               (clobber (reg:CC FLAGS_REG))])]
7263   "TARGET_64BIT"
7264   "")
7266 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7267 ;; Penalize eax case slightly because it results in worse scheduling
7268 ;; of code.
7269 (define_insn "*divmoddi4_nocltd_rex64"
7270   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7271         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7272                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7273    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7274         (mod:DI (match_dup 2) (match_dup 3)))
7275    (clobber (reg:CC FLAGS_REG))]
7276   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7277   "#"
7278   [(set_attr "type" "multi")])
7280 (define_insn "*divmoddi4_cltd_rex64"
7281   [(set (match_operand:DI 0 "register_operand" "=a")
7282         (div:DI (match_operand:DI 2 "register_operand" "a")
7283                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7284    (set (match_operand:DI 1 "register_operand" "=&d")
7285         (mod:DI (match_dup 2) (match_dup 3)))
7286    (clobber (reg:CC FLAGS_REG))]
7287   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7288   "#"
7289   [(set_attr "type" "multi")])
7291 (define_insn "*divmoddi_noext_rex64"
7292   [(set (match_operand:DI 0 "register_operand" "=a")
7293         (div:DI (match_operand:DI 1 "register_operand" "0")
7294                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7295    (set (match_operand:DI 3 "register_operand" "=d")
7296         (mod:DI (match_dup 1) (match_dup 2)))
7297    (use (match_operand:DI 4 "register_operand" "3"))
7298    (clobber (reg:CC FLAGS_REG))]
7299   "TARGET_64BIT"
7300   "idiv{q}\t%2"
7301   [(set_attr "type" "idiv")
7302    (set_attr "mode" "DI")])
7304 (define_split
7305   [(set (match_operand:DI 0 "register_operand" "")
7306         (div:DI (match_operand:DI 1 "register_operand" "")
7307                 (match_operand:DI 2 "nonimmediate_operand" "")))
7308    (set (match_operand:DI 3 "register_operand" "")
7309         (mod:DI (match_dup 1) (match_dup 2)))
7310    (clobber (reg:CC FLAGS_REG))]
7311   "TARGET_64BIT && reload_completed"
7312   [(parallel [(set (match_dup 3)
7313                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7314               (clobber (reg:CC FLAGS_REG))])
7315    (parallel [(set (match_dup 0)
7316                    (div:DI (reg:DI 0) (match_dup 2)))
7317               (set (match_dup 3)
7318                    (mod:DI (reg:DI 0) (match_dup 2)))
7319               (use (match_dup 3))
7320               (clobber (reg:CC FLAGS_REG))])]
7322   /* Avoid use of cltd in favor of a mov+shift.  */
7323   if (!TARGET_USE_CLTD && !optimize_size)
7324     {
7325       if (true_regnum (operands[1]))
7326         emit_move_insn (operands[0], operands[1]);
7327       else
7328         emit_move_insn (operands[3], operands[1]);
7329       operands[4] = operands[3];
7330     }
7331   else
7332     {
7333       if (true_regnum (operands[1]))
7334         abort();
7335       operands[4] = operands[1];
7336     }
7340 (define_expand "divmodsi4"
7341   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7342                    (div:SI (match_operand:SI 1 "register_operand" "")
7343                            (match_operand:SI 2 "nonimmediate_operand" "")))
7344               (set (match_operand:SI 3 "register_operand" "")
7345                    (mod:SI (match_dup 1) (match_dup 2)))
7346               (clobber (reg:CC FLAGS_REG))])]
7347   ""
7348   "")
7350 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7351 ;; Penalize eax case slightly because it results in worse scheduling
7352 ;; of code.
7353 (define_insn "*divmodsi4_nocltd"
7354   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7355         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7356                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7357    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7358         (mod:SI (match_dup 2) (match_dup 3)))
7359    (clobber (reg:CC FLAGS_REG))]
7360   "!optimize_size && !TARGET_USE_CLTD"
7361   "#"
7362   [(set_attr "type" "multi")])
7364 (define_insn "*divmodsi4_cltd"
7365   [(set (match_operand:SI 0 "register_operand" "=a")
7366         (div:SI (match_operand:SI 2 "register_operand" "a")
7367                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7368    (set (match_operand:SI 1 "register_operand" "=&d")
7369         (mod:SI (match_dup 2) (match_dup 3)))
7370    (clobber (reg:CC FLAGS_REG))]
7371   "optimize_size || TARGET_USE_CLTD"
7372   "#"
7373   [(set_attr "type" "multi")])
7375 (define_insn "*divmodsi_noext"
7376   [(set (match_operand:SI 0 "register_operand" "=a")
7377         (div:SI (match_operand:SI 1 "register_operand" "0")
7378                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7379    (set (match_operand:SI 3 "register_operand" "=d")
7380         (mod:SI (match_dup 1) (match_dup 2)))
7381    (use (match_operand:SI 4 "register_operand" "3"))
7382    (clobber (reg:CC FLAGS_REG))]
7383   ""
7384   "idiv{l}\t%2"
7385   [(set_attr "type" "idiv")
7386    (set_attr "mode" "SI")])
7388 (define_split
7389   [(set (match_operand:SI 0 "register_operand" "")
7390         (div:SI (match_operand:SI 1 "register_operand" "")
7391                 (match_operand:SI 2 "nonimmediate_operand" "")))
7392    (set (match_operand:SI 3 "register_operand" "")
7393         (mod:SI (match_dup 1) (match_dup 2)))
7394    (clobber (reg:CC FLAGS_REG))]
7395   "reload_completed"
7396   [(parallel [(set (match_dup 3)
7397                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7398               (clobber (reg:CC FLAGS_REG))])
7399    (parallel [(set (match_dup 0)
7400                    (div:SI (reg:SI 0) (match_dup 2)))
7401               (set (match_dup 3)
7402                    (mod:SI (reg:SI 0) (match_dup 2)))
7403               (use (match_dup 3))
7404               (clobber (reg:CC FLAGS_REG))])]
7406   /* Avoid use of cltd in favor of a mov+shift.  */
7407   if (!TARGET_USE_CLTD && !optimize_size)
7408     {
7409       if (true_regnum (operands[1]))
7410         emit_move_insn (operands[0], operands[1]);
7411       else
7412         emit_move_insn (operands[3], operands[1]);
7413       operands[4] = operands[3];
7414     }
7415   else
7416     {
7417       if (true_regnum (operands[1]))
7418         abort();
7419       operands[4] = operands[1];
7420     }
7422 ;; %%% Split me.
7423 (define_insn "divmodhi4"
7424   [(set (match_operand:HI 0 "register_operand" "=a")
7425         (div:HI (match_operand:HI 1 "register_operand" "0")
7426                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7427    (set (match_operand:HI 3 "register_operand" "=&d")
7428         (mod:HI (match_dup 1) (match_dup 2)))
7429    (clobber (reg:CC FLAGS_REG))]
7430   "TARGET_HIMODE_MATH"
7431   "cwtd\;idiv{w}\t%2"
7432   [(set_attr "type" "multi")
7433    (set_attr "length_immediate" "0")
7434    (set_attr "mode" "SI")])
7436 (define_insn "udivmoddi4"
7437   [(set (match_operand:DI 0 "register_operand" "=a")
7438         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7439                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7440    (set (match_operand:DI 3 "register_operand" "=&d")
7441         (umod:DI (match_dup 1) (match_dup 2)))
7442    (clobber (reg:CC FLAGS_REG))]
7443   "TARGET_64BIT"
7444   "xor{q}\t%3, %3\;div{q}\t%2"
7445   [(set_attr "type" "multi")
7446    (set_attr "length_immediate" "0")
7447    (set_attr "mode" "DI")])
7449 (define_insn "*udivmoddi4_noext"
7450   [(set (match_operand:DI 0 "register_operand" "=a")
7451         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7452                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7453    (set (match_operand:DI 3 "register_operand" "=d")
7454         (umod:DI (match_dup 1) (match_dup 2)))
7455    (use (match_dup 3))
7456    (clobber (reg:CC FLAGS_REG))]
7457   "TARGET_64BIT"
7458   "div{q}\t%2"
7459   [(set_attr "type" "idiv")
7460    (set_attr "mode" "DI")])
7462 (define_split
7463   [(set (match_operand:DI 0 "register_operand" "")
7464         (udiv:DI (match_operand:DI 1 "register_operand" "")
7465                  (match_operand:DI 2 "nonimmediate_operand" "")))
7466    (set (match_operand:DI 3 "register_operand" "")
7467         (umod:DI (match_dup 1) (match_dup 2)))
7468    (clobber (reg:CC FLAGS_REG))]
7469   "TARGET_64BIT && reload_completed"
7470   [(set (match_dup 3) (const_int 0))
7471    (parallel [(set (match_dup 0)
7472                    (udiv:DI (match_dup 1) (match_dup 2)))
7473               (set (match_dup 3)
7474                    (umod:DI (match_dup 1) (match_dup 2)))
7475               (use (match_dup 3))
7476               (clobber (reg:CC FLAGS_REG))])]
7477   "")
7479 (define_insn "udivmodsi4"
7480   [(set (match_operand:SI 0 "register_operand" "=a")
7481         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7482                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7483    (set (match_operand:SI 3 "register_operand" "=&d")
7484         (umod:SI (match_dup 1) (match_dup 2)))
7485    (clobber (reg:CC FLAGS_REG))]
7486   ""
7487   "xor{l}\t%3, %3\;div{l}\t%2"
7488   [(set_attr "type" "multi")
7489    (set_attr "length_immediate" "0")
7490    (set_attr "mode" "SI")])
7492 (define_insn "*udivmodsi4_noext"
7493   [(set (match_operand:SI 0 "register_operand" "=a")
7494         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7495                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7496    (set (match_operand:SI 3 "register_operand" "=d")
7497         (umod:SI (match_dup 1) (match_dup 2)))
7498    (use (match_dup 3))
7499    (clobber (reg:CC FLAGS_REG))]
7500   ""
7501   "div{l}\t%2"
7502   [(set_attr "type" "idiv")
7503    (set_attr "mode" "SI")])
7505 (define_split
7506   [(set (match_operand:SI 0 "register_operand" "")
7507         (udiv:SI (match_operand:SI 1 "register_operand" "")
7508                  (match_operand:SI 2 "nonimmediate_operand" "")))
7509    (set (match_operand:SI 3 "register_operand" "")
7510         (umod:SI (match_dup 1) (match_dup 2)))
7511    (clobber (reg:CC FLAGS_REG))]
7512   "reload_completed"
7513   [(set (match_dup 3) (const_int 0))
7514    (parallel [(set (match_dup 0)
7515                    (udiv:SI (match_dup 1) (match_dup 2)))
7516               (set (match_dup 3)
7517                    (umod:SI (match_dup 1) (match_dup 2)))
7518               (use (match_dup 3))
7519               (clobber (reg:CC FLAGS_REG))])]
7520   "")
7522 (define_expand "udivmodhi4"
7523   [(set (match_dup 4) (const_int 0))
7524    (parallel [(set (match_operand:HI 0 "register_operand" "")
7525                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7526                             (match_operand:HI 2 "nonimmediate_operand" "")))
7527               (set (match_operand:HI 3 "register_operand" "")
7528                    (umod:HI (match_dup 1) (match_dup 2)))
7529               (use (match_dup 4))
7530               (clobber (reg:CC FLAGS_REG))])]
7531   "TARGET_HIMODE_MATH"
7532   "operands[4] = gen_reg_rtx (HImode);")
7534 (define_insn "*udivmodhi_noext"
7535   [(set (match_operand:HI 0 "register_operand" "=a")
7536         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7537                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7538    (set (match_operand:HI 3 "register_operand" "=d")
7539         (umod:HI (match_dup 1) (match_dup 2)))
7540    (use (match_operand:HI 4 "register_operand" "3"))
7541    (clobber (reg:CC FLAGS_REG))]
7542   ""
7543   "div{w}\t%2"
7544   [(set_attr "type" "idiv")
7545    (set_attr "mode" "HI")])
7547 ;; We cannot use div/idiv for double division, because it causes
7548 ;; "division by zero" on the overflow and that's not what we expect
7549 ;; from truncate.  Because true (non truncating) double division is
7550 ;; never generated, we can't create this insn anyway.
7552 ;(define_insn ""
7553 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7554 ;       (truncate:SI
7555 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7556 ;                  (zero_extend:DI
7557 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7558 ;   (set (match_operand:SI 3 "register_operand" "=d")
7559 ;       (truncate:SI
7560 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7561 ;   (clobber (reg:CC FLAGS_REG))]
7562 ;  ""
7563 ;  "div{l}\t{%2, %0|%0, %2}"
7564 ;  [(set_attr "type" "idiv")])
7566 ;;- Logical AND instructions
7568 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7569 ;; Note that this excludes ah.
7571 (define_insn "*testdi_1_rex64"
7572   [(set (reg FLAGS_REG)
7573         (compare
7574           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7575                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7576           (const_int 0)))]
7577   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7578    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7579   "@
7580    test{l}\t{%k1, %k0|%k0, %k1}
7581    test{l}\t{%k1, %k0|%k0, %k1}
7582    test{q}\t{%1, %0|%0, %1}
7583    test{q}\t{%1, %0|%0, %1}
7584    test{q}\t{%1, %0|%0, %1}"
7585   [(set_attr "type" "test")
7586    (set_attr "modrm" "0,1,0,1,1")
7587    (set_attr "mode" "SI,SI,DI,DI,DI")
7588    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7590 (define_insn "testsi_1"
7591   [(set (reg FLAGS_REG)
7592         (compare
7593           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7594                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7595           (const_int 0)))]
7596   "ix86_match_ccmode (insn, CCNOmode)
7597    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7598   "test{l}\t{%1, %0|%0, %1}"
7599   [(set_attr "type" "test")
7600    (set_attr "modrm" "0,1,1")
7601    (set_attr "mode" "SI")
7602    (set_attr "pent_pair" "uv,np,uv")])
7604 (define_expand "testsi_ccno_1"
7605   [(set (reg:CCNO FLAGS_REG)
7606         (compare:CCNO
7607           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7608                   (match_operand:SI 1 "nonmemory_operand" ""))
7609           (const_int 0)))]
7610   ""
7611   "")
7613 (define_insn "*testhi_1"
7614   [(set (reg FLAGS_REG)
7615         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7616                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7617                  (const_int 0)))]
7618   "ix86_match_ccmode (insn, CCNOmode)
7619    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7620   "test{w}\t{%1, %0|%0, %1}"
7621   [(set_attr "type" "test")
7622    (set_attr "modrm" "0,1,1")
7623    (set_attr "mode" "HI")
7624    (set_attr "pent_pair" "uv,np,uv")])
7626 (define_expand "testqi_ccz_1"
7627   [(set (reg:CCZ FLAGS_REG)
7628         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7629                              (match_operand:QI 1 "nonmemory_operand" ""))
7630                  (const_int 0)))]
7631   ""
7632   "")
7634 (define_insn "*testqi_1_maybe_si"
7635   [(set (reg FLAGS_REG)
7636         (compare
7637           (and:QI
7638             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7639             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7640           (const_int 0)))]
7641    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7642     && ix86_match_ccmode (insn,
7643                          GET_CODE (operands[1]) == CONST_INT
7644                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7646   if (which_alternative == 3)
7647     {
7648       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7649         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7650       return "test{l}\t{%1, %k0|%k0, %1}";
7651     }
7652   return "test{b}\t{%1, %0|%0, %1}";
7654   [(set_attr "type" "test")
7655    (set_attr "modrm" "0,1,1,1")
7656    (set_attr "mode" "QI,QI,QI,SI")
7657    (set_attr "pent_pair" "uv,np,uv,np")])
7659 (define_insn "*testqi_1"
7660   [(set (reg FLAGS_REG)
7661         (compare
7662           (and:QI
7663             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7664             (match_operand:QI 1 "general_operand" "n,n,qn"))
7665           (const_int 0)))]
7666   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7667    && ix86_match_ccmode (insn, CCNOmode)"
7668   "test{b}\t{%1, %0|%0, %1}"
7669   [(set_attr "type" "test")
7670    (set_attr "modrm" "0,1,1")
7671    (set_attr "mode" "QI")
7672    (set_attr "pent_pair" "uv,np,uv")])
7674 (define_expand "testqi_ext_ccno_0"
7675   [(set (reg:CCNO FLAGS_REG)
7676         (compare:CCNO
7677           (and:SI
7678             (zero_extract:SI
7679               (match_operand 0 "ext_register_operand" "")
7680               (const_int 8)
7681               (const_int 8))
7682             (match_operand 1 "const_int_operand" ""))
7683           (const_int 0)))]
7684   ""
7685   "")
7687 (define_insn "*testqi_ext_0"
7688   [(set (reg FLAGS_REG)
7689         (compare
7690           (and:SI
7691             (zero_extract:SI
7692               (match_operand 0 "ext_register_operand" "Q")
7693               (const_int 8)
7694               (const_int 8))
7695             (match_operand 1 "const_int_operand" "n"))
7696           (const_int 0)))]
7697   "ix86_match_ccmode (insn, CCNOmode)"
7698   "test{b}\t{%1, %h0|%h0, %1}"
7699   [(set_attr "type" "test")
7700    (set_attr "mode" "QI")
7701    (set_attr "length_immediate" "1")
7702    (set_attr "pent_pair" "np")])
7704 (define_insn "*testqi_ext_1"
7705   [(set (reg FLAGS_REG)
7706         (compare
7707           (and:SI
7708             (zero_extract:SI
7709               (match_operand 0 "ext_register_operand" "Q")
7710               (const_int 8)
7711               (const_int 8))
7712             (zero_extend:SI
7713               (match_operand:QI 1 "general_operand" "Qm")))
7714           (const_int 0)))]
7715   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7716    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7717   "test{b}\t{%1, %h0|%h0, %1}"
7718   [(set_attr "type" "test")
7719    (set_attr "mode" "QI")])
7721 (define_insn "*testqi_ext_1_rex64"
7722   [(set (reg FLAGS_REG)
7723         (compare
7724           (and:SI
7725             (zero_extract:SI
7726               (match_operand 0 "ext_register_operand" "Q")
7727               (const_int 8)
7728               (const_int 8))
7729             (zero_extend:SI
7730               (match_operand:QI 1 "register_operand" "Q")))
7731           (const_int 0)))]
7732   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7733   "test{b}\t{%1, %h0|%h0, %1}"
7734   [(set_attr "type" "test")
7735    (set_attr "mode" "QI")])
7737 (define_insn "*testqi_ext_2"
7738   [(set (reg FLAGS_REG)
7739         (compare
7740           (and:SI
7741             (zero_extract:SI
7742               (match_operand 0 "ext_register_operand" "Q")
7743               (const_int 8)
7744               (const_int 8))
7745             (zero_extract:SI
7746               (match_operand 1 "ext_register_operand" "Q")
7747               (const_int 8)
7748               (const_int 8)))
7749           (const_int 0)))]
7750   "ix86_match_ccmode (insn, CCNOmode)"
7751   "test{b}\t{%h1, %h0|%h0, %h1}"
7752   [(set_attr "type" "test")
7753    (set_attr "mode" "QI")])
7755 ;; Combine likes to form bit extractions for some tests.  Humor it.
7756 (define_insn "*testqi_ext_3"
7757   [(set (reg FLAGS_REG)
7758         (compare (zero_extract:SI
7759                    (match_operand 0 "nonimmediate_operand" "rm")
7760                    (match_operand:SI 1 "const_int_operand" "")
7761                    (match_operand:SI 2 "const_int_operand" ""))
7762                  (const_int 0)))]
7763   "ix86_match_ccmode (insn, CCNOmode)
7764    && (GET_MODE (operands[0]) == SImode
7765        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7766        || GET_MODE (operands[0]) == HImode
7767        || GET_MODE (operands[0]) == QImode)"
7768   "#")
7770 (define_insn "*testqi_ext_3_rex64"
7771   [(set (reg FLAGS_REG)
7772         (compare (zero_extract:DI
7773                    (match_operand 0 "nonimmediate_operand" "rm")
7774                    (match_operand:DI 1 "const_int_operand" "")
7775                    (match_operand:DI 2 "const_int_operand" ""))
7776                  (const_int 0)))]
7777   "TARGET_64BIT
7778    && ix86_match_ccmode (insn, CCNOmode)
7779    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7780    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7781    /* Ensure that resulting mask is zero or sign extended operand.  */
7782    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7783        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7784            && INTVAL (operands[1]) > 32))
7785    && (GET_MODE (operands[0]) == SImode
7786        || GET_MODE (operands[0]) == DImode
7787        || GET_MODE (operands[0]) == HImode
7788        || GET_MODE (operands[0]) == QImode)"
7789   "#")
7791 (define_split
7792   [(set (match_operand 0 "flags_reg_operand" "")
7793         (match_operator 1 "compare_operator"
7794           [(zero_extract
7795              (match_operand 2 "nonimmediate_operand" "")
7796              (match_operand 3 "const_int_operand" "")
7797              (match_operand 4 "const_int_operand" ""))
7798            (const_int 0)]))]
7799   "ix86_match_ccmode (insn, CCNOmode)"
7800   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7802   rtx val = operands[2];
7803   HOST_WIDE_INT len = INTVAL (operands[3]);
7804   HOST_WIDE_INT pos = INTVAL (operands[4]);
7805   HOST_WIDE_INT mask;
7806   enum machine_mode mode, submode;
7808   mode = GET_MODE (val);
7809   if (GET_CODE (val) == MEM)
7810     {
7811       /* ??? Combine likes to put non-volatile mem extractions in QImode
7812          no matter the size of the test.  So find a mode that works.  */
7813       if (! MEM_VOLATILE_P (val))
7814         {
7815           mode = smallest_mode_for_size (pos + len, MODE_INT);
7816           val = adjust_address (val, mode, 0);
7817         }
7818     }
7819   else if (GET_CODE (val) == SUBREG
7820            && (submode = GET_MODE (SUBREG_REG (val)),
7821                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7822            && pos + len <= GET_MODE_BITSIZE (submode))
7823     {
7824       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7825       mode = submode;
7826       val = SUBREG_REG (val);
7827     }
7828   else if (mode == HImode && pos + len <= 8)
7829     {
7830       /* Small HImode tests can be converted to QImode.  */
7831       mode = QImode;
7832       val = gen_lowpart (QImode, val);
7833     }
7835   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7836   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7838   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7841 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7842 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7843 ;; this is relatively important trick.
7844 ;; Do the conversion only post-reload to avoid limiting of the register class
7845 ;; to QI regs.
7846 (define_split
7847   [(set (match_operand 0 "flags_reg_operand" "")
7848         (match_operator 1 "compare_operator"
7849           [(and (match_operand 2 "register_operand" "")
7850                 (match_operand 3 "const_int_operand" ""))
7851            (const_int 0)]))]
7852    "reload_completed
7853     && QI_REG_P (operands[2])
7854     && GET_MODE (operands[2]) != QImode
7855     && ((ix86_match_ccmode (insn, CCZmode)
7856          && !(INTVAL (operands[3]) & ~(255 << 8)))
7857         || (ix86_match_ccmode (insn, CCNOmode)
7858             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7859   [(set (match_dup 0)
7860         (match_op_dup 1
7861           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7862                    (match_dup 3))
7863            (const_int 0)]))]
7864   "operands[2] = gen_lowpart (SImode, operands[2]);
7865    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7867 (define_split
7868   [(set (match_operand 0 "flags_reg_operand" "")
7869         (match_operator 1 "compare_operator"
7870           [(and (match_operand 2 "nonimmediate_operand" "")
7871                 (match_operand 3 "const_int_operand" ""))
7872            (const_int 0)]))]
7873    "reload_completed
7874     && GET_MODE (operands[2]) != QImode
7875     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7876     && ((ix86_match_ccmode (insn, CCZmode)
7877          && !(INTVAL (operands[3]) & ~255))
7878         || (ix86_match_ccmode (insn, CCNOmode)
7879             && !(INTVAL (operands[3]) & ~127)))"
7880   [(set (match_dup 0)
7881         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7882                          (const_int 0)]))]
7883   "operands[2] = gen_lowpart (QImode, operands[2]);
7884    operands[3] = gen_lowpart (QImode, operands[3]);")
7887 ;; %%% This used to optimize known byte-wide and operations to memory,
7888 ;; and sometimes to QImode registers.  If this is considered useful,
7889 ;; it should be done with splitters.
7891 (define_expand "anddi3"
7892   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7893         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7894                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7895    (clobber (reg:CC FLAGS_REG))]
7896   "TARGET_64BIT"
7897   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7899 (define_insn "*anddi_1_rex64"
7900   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7901         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7902                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7903    (clobber (reg:CC FLAGS_REG))]
7904   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7906   switch (get_attr_type (insn))
7907     {
7908     case TYPE_IMOVX:
7909       {
7910         enum machine_mode mode;
7912         if (GET_CODE (operands[2]) != CONST_INT)
7913           abort ();
7914         if (INTVAL (operands[2]) == 0xff)
7915           mode = QImode;
7916         else if (INTVAL (operands[2]) == 0xffff)
7917           mode = HImode;
7918         else
7919           abort ();
7920         
7921         operands[1] = gen_lowpart (mode, operands[1]);
7922         if (mode == QImode)
7923           return "movz{bq|x}\t{%1,%0|%0, %1}";
7924         else
7925           return "movz{wq|x}\t{%1,%0|%0, %1}";
7926       }
7928     default:
7929       if (! rtx_equal_p (operands[0], operands[1]))
7930         abort ();
7931       if (get_attr_mode (insn) == MODE_SI)
7932         return "and{l}\t{%k2, %k0|%k0, %k2}";
7933       else
7934         return "and{q}\t{%2, %0|%0, %2}";
7935     }
7937   [(set_attr "type" "alu,alu,alu,imovx")
7938    (set_attr "length_immediate" "*,*,*,0")
7939    (set_attr "mode" "SI,DI,DI,DI")])
7941 (define_insn "*anddi_2"
7942   [(set (reg FLAGS_REG)
7943         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7944                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7945                  (const_int 0)))
7946    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7947         (and:DI (match_dup 1) (match_dup 2)))]
7948   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7949    && ix86_binary_operator_ok (AND, DImode, operands)"
7950   "@
7951    and{l}\t{%k2, %k0|%k0, %k2}
7952    and{q}\t{%2, %0|%0, %2}
7953    and{q}\t{%2, %0|%0, %2}"
7954   [(set_attr "type" "alu")
7955    (set_attr "mode" "SI,DI,DI")])
7957 (define_expand "andsi3"
7958   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7959         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7960                 (match_operand:SI 2 "general_operand" "")))
7961    (clobber (reg:CC FLAGS_REG))]
7962   ""
7963   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7965 (define_insn "*andsi_1"
7966   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7967         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7968                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7969    (clobber (reg:CC FLAGS_REG))]
7970   "ix86_binary_operator_ok (AND, SImode, operands)"
7972   switch (get_attr_type (insn))
7973     {
7974     case TYPE_IMOVX:
7975       {
7976         enum machine_mode mode;
7978         if (GET_CODE (operands[2]) != CONST_INT)
7979           abort ();
7980         if (INTVAL (operands[2]) == 0xff)
7981           mode = QImode;
7982         else if (INTVAL (operands[2]) == 0xffff)
7983           mode = HImode;
7984         else
7985           abort ();
7986         
7987         operands[1] = gen_lowpart (mode, operands[1]);
7988         if (mode == QImode)
7989           return "movz{bl|x}\t{%1,%0|%0, %1}";
7990         else
7991           return "movz{wl|x}\t{%1,%0|%0, %1}";
7992       }
7994     default:
7995       if (! rtx_equal_p (operands[0], operands[1]))
7996         abort ();
7997       return "and{l}\t{%2, %0|%0, %2}";
7998     }
8000   [(set_attr "type" "alu,alu,imovx")
8001    (set_attr "length_immediate" "*,*,0")
8002    (set_attr "mode" "SI")])
8004 (define_split
8005   [(set (match_operand 0 "register_operand" "")
8006         (and (match_dup 0)
8007              (const_int -65536)))
8008    (clobber (reg:CC FLAGS_REG))]
8009   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8010   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8011   "operands[1] = gen_lowpart (HImode, operands[0]);")
8013 (define_split
8014   [(set (match_operand 0 "ext_register_operand" "")
8015         (and (match_dup 0)
8016              (const_int -256)))
8017    (clobber (reg:CC FLAGS_REG))]
8018   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8019   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8020   "operands[1] = gen_lowpart (QImode, operands[0]);")
8022 (define_split
8023   [(set (match_operand 0 "ext_register_operand" "")
8024         (and (match_dup 0)
8025              (const_int -65281)))
8026    (clobber (reg:CC FLAGS_REG))]
8027   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8028   [(parallel [(set (zero_extract:SI (match_dup 0)
8029                                     (const_int 8)
8030                                     (const_int 8))
8031                    (xor:SI 
8032                      (zero_extract:SI (match_dup 0)
8033                                       (const_int 8)
8034                                       (const_int 8))
8035                      (zero_extract:SI (match_dup 0)
8036                                       (const_int 8)
8037                                       (const_int 8))))
8038               (clobber (reg:CC FLAGS_REG))])]
8039   "operands[0] = gen_lowpart (SImode, operands[0]);")
8041 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8042 (define_insn "*andsi_1_zext"
8043   [(set (match_operand:DI 0 "register_operand" "=r")
8044         (zero_extend:DI
8045           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8046                   (match_operand:SI 2 "general_operand" "rim"))))
8047    (clobber (reg:CC FLAGS_REG))]
8048   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8049   "and{l}\t{%2, %k0|%k0, %2}"
8050   [(set_attr "type" "alu")
8051    (set_attr "mode" "SI")])
8053 (define_insn "*andsi_2"
8054   [(set (reg FLAGS_REG)
8055         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8056                          (match_operand:SI 2 "general_operand" "rim,ri"))
8057                  (const_int 0)))
8058    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8059         (and:SI (match_dup 1) (match_dup 2)))]
8060   "ix86_match_ccmode (insn, CCNOmode)
8061    && ix86_binary_operator_ok (AND, SImode, operands)"
8062   "and{l}\t{%2, %0|%0, %2}"
8063   [(set_attr "type" "alu")
8064    (set_attr "mode" "SI")])
8066 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8067 (define_insn "*andsi_2_zext"
8068   [(set (reg FLAGS_REG)
8069         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8070                          (match_operand:SI 2 "general_operand" "rim"))
8071                  (const_int 0)))
8072    (set (match_operand:DI 0 "register_operand" "=r")
8073         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8074   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8075    && ix86_binary_operator_ok (AND, SImode, operands)"
8076   "and{l}\t{%2, %k0|%k0, %2}"
8077   [(set_attr "type" "alu")
8078    (set_attr "mode" "SI")])
8080 (define_expand "andhi3"
8081   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8082         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8083                 (match_operand:HI 2 "general_operand" "")))
8084    (clobber (reg:CC FLAGS_REG))]
8085   "TARGET_HIMODE_MATH"
8086   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8088 (define_insn "*andhi_1"
8089   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8090         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8091                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8092    (clobber (reg:CC FLAGS_REG))]
8093   "ix86_binary_operator_ok (AND, HImode, operands)"
8095   switch (get_attr_type (insn))
8096     {
8097     case TYPE_IMOVX:
8098       if (GET_CODE (operands[2]) != CONST_INT)
8099         abort ();
8100       if (INTVAL (operands[2]) == 0xff)
8101         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8102       abort ();
8104     default:
8105       if (! rtx_equal_p (operands[0], operands[1]))
8106         abort ();
8108       return "and{w}\t{%2, %0|%0, %2}";
8109     }
8111   [(set_attr "type" "alu,alu,imovx")
8112    (set_attr "length_immediate" "*,*,0")
8113    (set_attr "mode" "HI,HI,SI")])
8115 (define_insn "*andhi_2"
8116   [(set (reg FLAGS_REG)
8117         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8118                          (match_operand:HI 2 "general_operand" "rim,ri"))
8119                  (const_int 0)))
8120    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8121         (and:HI (match_dup 1) (match_dup 2)))]
8122   "ix86_match_ccmode (insn, CCNOmode)
8123    && ix86_binary_operator_ok (AND, HImode, operands)"
8124   "and{w}\t{%2, %0|%0, %2}"
8125   [(set_attr "type" "alu")
8126    (set_attr "mode" "HI")])
8128 (define_expand "andqi3"
8129   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8130         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8131                 (match_operand:QI 2 "general_operand" "")))
8132    (clobber (reg:CC FLAGS_REG))]
8133   "TARGET_QIMODE_MATH"
8134   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8136 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8137 (define_insn "*andqi_1"
8138   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8139         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8140                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8141    (clobber (reg:CC FLAGS_REG))]
8142   "ix86_binary_operator_ok (AND, QImode, operands)"
8143   "@
8144    and{b}\t{%2, %0|%0, %2}
8145    and{b}\t{%2, %0|%0, %2}
8146    and{l}\t{%k2, %k0|%k0, %k2}"
8147   [(set_attr "type" "alu")
8148    (set_attr "mode" "QI,QI,SI")])
8150 (define_insn "*andqi_1_slp"
8151   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8152         (and:QI (match_dup 0)
8153                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8154    (clobber (reg:CC FLAGS_REG))]
8155   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8156    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8157   "and{b}\t{%1, %0|%0, %1}"
8158   [(set_attr "type" "alu1")
8159    (set_attr "mode" "QI")])
8161 (define_insn "*andqi_2_maybe_si"
8162   [(set (reg FLAGS_REG)
8163         (compare (and:QI
8164                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8165                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8166                  (const_int 0)))
8167    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8168         (and:QI (match_dup 1) (match_dup 2)))]
8169   "ix86_binary_operator_ok (AND, QImode, operands)
8170    && ix86_match_ccmode (insn,
8171                          GET_CODE (operands[2]) == CONST_INT
8172                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8174   if (which_alternative == 2)
8175     {
8176       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8177         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8178       return "and{l}\t{%2, %k0|%k0, %2}";
8179     }
8180   return "and{b}\t{%2, %0|%0, %2}";
8182   [(set_attr "type" "alu")
8183    (set_attr "mode" "QI,QI,SI")])
8185 (define_insn "*andqi_2"
8186   [(set (reg FLAGS_REG)
8187         (compare (and:QI
8188                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8189                    (match_operand:QI 2 "general_operand" "qim,qi"))
8190                  (const_int 0)))
8191    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8192         (and:QI (match_dup 1) (match_dup 2)))]
8193   "ix86_match_ccmode (insn, CCNOmode)
8194    && ix86_binary_operator_ok (AND, QImode, operands)"
8195   "and{b}\t{%2, %0|%0, %2}"
8196   [(set_attr "type" "alu")
8197    (set_attr "mode" "QI")])
8199 (define_insn "*andqi_2_slp"
8200   [(set (reg FLAGS_REG)
8201         (compare (and:QI
8202                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8203                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8204                  (const_int 0)))
8205    (set (strict_low_part (match_dup 0))
8206         (and:QI (match_dup 0) (match_dup 1)))]
8207   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8208    && ix86_match_ccmode (insn, CCNOmode)
8209    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8210   "and{b}\t{%1, %0|%0, %1}"
8211   [(set_attr "type" "alu1")
8212    (set_attr "mode" "QI")])
8214 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8215 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8216 ;; for a QImode operand, which of course failed.
8218 (define_insn "andqi_ext_0"
8219   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8220                          (const_int 8)
8221                          (const_int 8))
8222         (and:SI 
8223           (zero_extract:SI
8224             (match_operand 1 "ext_register_operand" "0")
8225             (const_int 8)
8226             (const_int 8))
8227           (match_operand 2 "const_int_operand" "n")))
8228    (clobber (reg:CC FLAGS_REG))]
8229   ""
8230   "and{b}\t{%2, %h0|%h0, %2}"
8231   [(set_attr "type" "alu")
8232    (set_attr "length_immediate" "1")
8233    (set_attr "mode" "QI")])
8235 ;; Generated by peephole translating test to and.  This shows up
8236 ;; often in fp comparisons.
8238 (define_insn "*andqi_ext_0_cc"
8239   [(set (reg FLAGS_REG)
8240         (compare
8241           (and:SI
8242             (zero_extract:SI
8243               (match_operand 1 "ext_register_operand" "0")
8244               (const_int 8)
8245               (const_int 8))
8246             (match_operand 2 "const_int_operand" "n"))
8247           (const_int 0)))
8248    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8249                          (const_int 8)
8250                          (const_int 8))
8251         (and:SI 
8252           (zero_extract:SI
8253             (match_dup 1)
8254             (const_int 8)
8255             (const_int 8))
8256           (match_dup 2)))]
8257   "ix86_match_ccmode (insn, CCNOmode)"
8258   "and{b}\t{%2, %h0|%h0, %2}"
8259   [(set_attr "type" "alu")
8260    (set_attr "length_immediate" "1")
8261    (set_attr "mode" "QI")])
8263 (define_insn "*andqi_ext_1"
8264   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8265                          (const_int 8)
8266                          (const_int 8))
8267         (and:SI 
8268           (zero_extract:SI
8269             (match_operand 1 "ext_register_operand" "0")
8270             (const_int 8)
8271             (const_int 8))
8272           (zero_extend:SI
8273             (match_operand:QI 2 "general_operand" "Qm"))))
8274    (clobber (reg:CC FLAGS_REG))]
8275   "!TARGET_64BIT"
8276   "and{b}\t{%2, %h0|%h0, %2}"
8277   [(set_attr "type" "alu")
8278    (set_attr "length_immediate" "0")
8279    (set_attr "mode" "QI")])
8281 (define_insn "*andqi_ext_1_rex64"
8282   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8283                          (const_int 8)
8284                          (const_int 8))
8285         (and:SI 
8286           (zero_extract:SI
8287             (match_operand 1 "ext_register_operand" "0")
8288             (const_int 8)
8289             (const_int 8))
8290           (zero_extend:SI
8291             (match_operand 2 "ext_register_operand" "Q"))))
8292    (clobber (reg:CC FLAGS_REG))]
8293   "TARGET_64BIT"
8294   "and{b}\t{%2, %h0|%h0, %2}"
8295   [(set_attr "type" "alu")
8296    (set_attr "length_immediate" "0")
8297    (set_attr "mode" "QI")])
8299 (define_insn "*andqi_ext_2"
8300   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8301                          (const_int 8)
8302                          (const_int 8))
8303         (and:SI
8304           (zero_extract:SI
8305             (match_operand 1 "ext_register_operand" "%0")
8306             (const_int 8)
8307             (const_int 8))
8308           (zero_extract:SI
8309             (match_operand 2 "ext_register_operand" "Q")
8310             (const_int 8)
8311             (const_int 8))))
8312    (clobber (reg:CC FLAGS_REG))]
8313   ""
8314   "and{b}\t{%h2, %h0|%h0, %h2}"
8315   [(set_attr "type" "alu")
8316    (set_attr "length_immediate" "0")
8317    (set_attr "mode" "QI")])
8319 ;; Convert wide AND instructions with immediate operand to shorter QImode
8320 ;; equivalents when possible.
8321 ;; Don't do the splitting with memory operands, since it introduces risk
8322 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8323 ;; for size, but that can (should?) be handled by generic code instead.
8324 (define_split
8325   [(set (match_operand 0 "register_operand" "")
8326         (and (match_operand 1 "register_operand" "")
8327              (match_operand 2 "const_int_operand" "")))
8328    (clobber (reg:CC FLAGS_REG))]
8329    "reload_completed
8330     && QI_REG_P (operands[0])
8331     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8332     && !(~INTVAL (operands[2]) & ~(255 << 8))
8333     && GET_MODE (operands[0]) != QImode"
8334   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8335                    (and:SI (zero_extract:SI (match_dup 1)
8336                                             (const_int 8) (const_int 8))
8337                            (match_dup 2)))
8338               (clobber (reg:CC FLAGS_REG))])]
8339   "operands[0] = gen_lowpart (SImode, operands[0]);
8340    operands[1] = gen_lowpart (SImode, operands[1]);
8341    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8343 ;; Since AND can be encoded with sign extended immediate, this is only
8344 ;; profitable when 7th bit is not set.
8345 (define_split
8346   [(set (match_operand 0 "register_operand" "")
8347         (and (match_operand 1 "general_operand" "")
8348              (match_operand 2 "const_int_operand" "")))
8349    (clobber (reg:CC FLAGS_REG))]
8350    "reload_completed
8351     && ANY_QI_REG_P (operands[0])
8352     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8353     && !(~INTVAL (operands[2]) & ~255)
8354     && !(INTVAL (operands[2]) & 128)
8355     && GET_MODE (operands[0]) != QImode"
8356   [(parallel [(set (strict_low_part (match_dup 0))
8357                    (and:QI (match_dup 1)
8358                            (match_dup 2)))
8359               (clobber (reg:CC FLAGS_REG))])]
8360   "operands[0] = gen_lowpart (QImode, operands[0]);
8361    operands[1] = gen_lowpart (QImode, operands[1]);
8362    operands[2] = gen_lowpart (QImode, operands[2]);")
8364 ;; Logical inclusive OR instructions
8366 ;; %%% This used to optimize known byte-wide and operations to memory.
8367 ;; If this is considered useful, it should be done with splitters.
8369 (define_expand "iordi3"
8370   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8371         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8372                 (match_operand:DI 2 "x86_64_general_operand" "")))
8373    (clobber (reg:CC FLAGS_REG))]
8374   "TARGET_64BIT"
8375   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8377 (define_insn "*iordi_1_rex64"
8378   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8379         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8380                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8381    (clobber (reg:CC FLAGS_REG))]
8382   "TARGET_64BIT
8383    && ix86_binary_operator_ok (IOR, DImode, operands)"
8384   "or{q}\t{%2, %0|%0, %2}"
8385   [(set_attr "type" "alu")
8386    (set_attr "mode" "DI")])
8388 (define_insn "*iordi_2_rex64"
8389   [(set (reg FLAGS_REG)
8390         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8391                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8392                  (const_int 0)))
8393    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8394         (ior:DI (match_dup 1) (match_dup 2)))]
8395   "TARGET_64BIT
8396    && ix86_match_ccmode (insn, CCNOmode)
8397    && ix86_binary_operator_ok (IOR, DImode, operands)"
8398   "or{q}\t{%2, %0|%0, %2}"
8399   [(set_attr "type" "alu")
8400    (set_attr "mode" "DI")])
8402 (define_insn "*iordi_3_rex64"
8403   [(set (reg FLAGS_REG)
8404         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8405                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8406                  (const_int 0)))
8407    (clobber (match_scratch:DI 0 "=r"))]
8408   "TARGET_64BIT
8409    && ix86_match_ccmode (insn, CCNOmode)
8410    && ix86_binary_operator_ok (IOR, DImode, operands)"
8411   "or{q}\t{%2, %0|%0, %2}"
8412   [(set_attr "type" "alu")
8413    (set_attr "mode" "DI")])
8416 (define_expand "iorsi3"
8417   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8418         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8419                 (match_operand:SI 2 "general_operand" "")))
8420    (clobber (reg:CC FLAGS_REG))]
8421   ""
8422   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8424 (define_insn "*iorsi_1"
8425   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8426         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8427                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8428    (clobber (reg:CC FLAGS_REG))]
8429   "ix86_binary_operator_ok (IOR, SImode, operands)"
8430   "or{l}\t{%2, %0|%0, %2}"
8431   [(set_attr "type" "alu")
8432    (set_attr "mode" "SI")])
8434 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8435 (define_insn "*iorsi_1_zext"
8436   [(set (match_operand:DI 0 "register_operand" "=rm")
8437         (zero_extend:DI
8438           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8439                   (match_operand:SI 2 "general_operand" "rim"))))
8440    (clobber (reg:CC FLAGS_REG))]
8441   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8442   "or{l}\t{%2, %k0|%k0, %2}"
8443   [(set_attr "type" "alu")
8444    (set_attr "mode" "SI")])
8446 (define_insn "*iorsi_1_zext_imm"
8447   [(set (match_operand:DI 0 "register_operand" "=rm")
8448         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8449                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8450    (clobber (reg:CC FLAGS_REG))]
8451   "TARGET_64BIT"
8452   "or{l}\t{%2, %k0|%k0, %2}"
8453   [(set_attr "type" "alu")
8454    (set_attr "mode" "SI")])
8456 (define_insn "*iorsi_2"
8457   [(set (reg FLAGS_REG)
8458         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8459                          (match_operand:SI 2 "general_operand" "rim,ri"))
8460                  (const_int 0)))
8461    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8462         (ior:SI (match_dup 1) (match_dup 2)))]
8463   "ix86_match_ccmode (insn, CCNOmode)
8464    && ix86_binary_operator_ok (IOR, SImode, operands)"
8465   "or{l}\t{%2, %0|%0, %2}"
8466   [(set_attr "type" "alu")
8467    (set_attr "mode" "SI")])
8469 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8470 ;; ??? Special case for immediate operand is missing - it is tricky.
8471 (define_insn "*iorsi_2_zext"
8472   [(set (reg FLAGS_REG)
8473         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8474                          (match_operand:SI 2 "general_operand" "rim"))
8475                  (const_int 0)))
8476    (set (match_operand:DI 0 "register_operand" "=r")
8477         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8478   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8479    && ix86_binary_operator_ok (IOR, SImode, operands)"
8480   "or{l}\t{%2, %k0|%k0, %2}"
8481   [(set_attr "type" "alu")
8482    (set_attr "mode" "SI")])
8484 (define_insn "*iorsi_2_zext_imm"
8485   [(set (reg FLAGS_REG)
8486         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8487                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8488                  (const_int 0)))
8489    (set (match_operand:DI 0 "register_operand" "=r")
8490         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8491   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8492    && ix86_binary_operator_ok (IOR, SImode, operands)"
8493   "or{l}\t{%2, %k0|%k0, %2}"
8494   [(set_attr "type" "alu")
8495    (set_attr "mode" "SI")])
8497 (define_insn "*iorsi_3"
8498   [(set (reg FLAGS_REG)
8499         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8500                          (match_operand:SI 2 "general_operand" "rim"))
8501                  (const_int 0)))
8502    (clobber (match_scratch:SI 0 "=r"))]
8503   "ix86_match_ccmode (insn, CCNOmode)
8504    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8505   "or{l}\t{%2, %0|%0, %2}"
8506   [(set_attr "type" "alu")
8507    (set_attr "mode" "SI")])
8509 (define_expand "iorhi3"
8510   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8511         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8512                 (match_operand:HI 2 "general_operand" "")))
8513    (clobber (reg:CC FLAGS_REG))]
8514   "TARGET_HIMODE_MATH"
8515   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8517 (define_insn "*iorhi_1"
8518   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8519         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8520                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8521    (clobber (reg:CC FLAGS_REG))]
8522   "ix86_binary_operator_ok (IOR, HImode, operands)"
8523   "or{w}\t{%2, %0|%0, %2}"
8524   [(set_attr "type" "alu")
8525    (set_attr "mode" "HI")])
8527 (define_insn "*iorhi_2"
8528   [(set (reg FLAGS_REG)
8529         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8530                          (match_operand:HI 2 "general_operand" "rim,ri"))
8531                  (const_int 0)))
8532    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8533         (ior:HI (match_dup 1) (match_dup 2)))]
8534   "ix86_match_ccmode (insn, CCNOmode)
8535    && ix86_binary_operator_ok (IOR, HImode, operands)"
8536   "or{w}\t{%2, %0|%0, %2}"
8537   [(set_attr "type" "alu")
8538    (set_attr "mode" "HI")])
8540 (define_insn "*iorhi_3"
8541   [(set (reg FLAGS_REG)
8542         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8543                          (match_operand:HI 2 "general_operand" "rim"))
8544                  (const_int 0)))
8545    (clobber (match_scratch:HI 0 "=r"))]
8546   "ix86_match_ccmode (insn, CCNOmode)
8547    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8548   "or{w}\t{%2, %0|%0, %2}"
8549   [(set_attr "type" "alu")
8550    (set_attr "mode" "HI")])
8552 (define_expand "iorqi3"
8553   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8554         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8555                 (match_operand:QI 2 "general_operand" "")))
8556    (clobber (reg:CC FLAGS_REG))]
8557   "TARGET_QIMODE_MATH"
8558   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8560 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8561 (define_insn "*iorqi_1"
8562   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8563         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8564                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8565    (clobber (reg:CC FLAGS_REG))]
8566   "ix86_binary_operator_ok (IOR, QImode, operands)"
8567   "@
8568    or{b}\t{%2, %0|%0, %2}
8569    or{b}\t{%2, %0|%0, %2}
8570    or{l}\t{%k2, %k0|%k0, %k2}"
8571   [(set_attr "type" "alu")
8572    (set_attr "mode" "QI,QI,SI")])
8574 (define_insn "*iorqi_1_slp"
8575   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8576         (ior:QI (match_dup 0)
8577                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8578    (clobber (reg:CC FLAGS_REG))]
8579   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8580    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8581   "or{b}\t{%1, %0|%0, %1}"
8582   [(set_attr "type" "alu1")
8583    (set_attr "mode" "QI")])
8585 (define_insn "*iorqi_2"
8586   [(set (reg FLAGS_REG)
8587         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8588                          (match_operand:QI 2 "general_operand" "qim,qi"))
8589                  (const_int 0)))
8590    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8591         (ior:QI (match_dup 1) (match_dup 2)))]
8592   "ix86_match_ccmode (insn, CCNOmode)
8593    && ix86_binary_operator_ok (IOR, QImode, operands)"
8594   "or{b}\t{%2, %0|%0, %2}"
8595   [(set_attr "type" "alu")
8596    (set_attr "mode" "QI")])
8598 (define_insn "*iorqi_2_slp"
8599   [(set (reg FLAGS_REG)
8600         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8601                          (match_operand:QI 1 "general_operand" "qim,qi"))
8602                  (const_int 0)))
8603    (set (strict_low_part (match_dup 0))
8604         (ior:QI (match_dup 0) (match_dup 1)))]
8605   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8606    && ix86_match_ccmode (insn, CCNOmode)
8607    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8608   "or{b}\t{%1, %0|%0, %1}"
8609   [(set_attr "type" "alu1")
8610    (set_attr "mode" "QI")])
8612 (define_insn "*iorqi_3"
8613   [(set (reg FLAGS_REG)
8614         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8615                          (match_operand:QI 2 "general_operand" "qim"))
8616                  (const_int 0)))
8617    (clobber (match_scratch:QI 0 "=q"))]
8618   "ix86_match_ccmode (insn, CCNOmode)
8619    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8620   "or{b}\t{%2, %0|%0, %2}"
8621   [(set_attr "type" "alu")
8622    (set_attr "mode" "QI")])
8624 (define_insn "iorqi_ext_0"
8625   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8626                          (const_int 8)
8627                          (const_int 8))
8628         (ior:SI 
8629           (zero_extract:SI
8630             (match_operand 1 "ext_register_operand" "0")
8631             (const_int 8)
8632             (const_int 8))
8633           (match_operand 2 "const_int_operand" "n")))
8634    (clobber (reg:CC FLAGS_REG))]
8635   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8636   "or{b}\t{%2, %h0|%h0, %2}"
8637   [(set_attr "type" "alu")
8638    (set_attr "length_immediate" "1")
8639    (set_attr "mode" "QI")])
8641 (define_insn "*iorqi_ext_1"
8642   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8643                          (const_int 8)
8644                          (const_int 8))
8645         (ior:SI 
8646           (zero_extract:SI
8647             (match_operand 1 "ext_register_operand" "0")
8648             (const_int 8)
8649             (const_int 8))
8650           (zero_extend:SI
8651             (match_operand:QI 2 "general_operand" "Qm"))))
8652    (clobber (reg:CC FLAGS_REG))]
8653   "!TARGET_64BIT
8654    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8655   "or{b}\t{%2, %h0|%h0, %2}"
8656   [(set_attr "type" "alu")
8657    (set_attr "length_immediate" "0")
8658    (set_attr "mode" "QI")])
8660 (define_insn "*iorqi_ext_1_rex64"
8661   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8662                          (const_int 8)
8663                          (const_int 8))
8664         (ior:SI 
8665           (zero_extract:SI
8666             (match_operand 1 "ext_register_operand" "0")
8667             (const_int 8)
8668             (const_int 8))
8669           (zero_extend:SI
8670             (match_operand 2 "ext_register_operand" "Q"))))
8671    (clobber (reg:CC FLAGS_REG))]
8672   "TARGET_64BIT
8673    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8674   "or{b}\t{%2, %h0|%h0, %2}"
8675   [(set_attr "type" "alu")
8676    (set_attr "length_immediate" "0")
8677    (set_attr "mode" "QI")])
8679 (define_insn "*iorqi_ext_2"
8680   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8681                          (const_int 8)
8682                          (const_int 8))
8683         (ior:SI 
8684           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8685                            (const_int 8)
8686                            (const_int 8))
8687           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8688                            (const_int 8)
8689                            (const_int 8))))
8690    (clobber (reg:CC FLAGS_REG))]
8691   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8692   "ior{b}\t{%h2, %h0|%h0, %h2}"
8693   [(set_attr "type" "alu")
8694    (set_attr "length_immediate" "0")
8695    (set_attr "mode" "QI")])
8697 (define_split
8698   [(set (match_operand 0 "register_operand" "")
8699         (ior (match_operand 1 "register_operand" "")
8700              (match_operand 2 "const_int_operand" "")))
8701    (clobber (reg:CC FLAGS_REG))]
8702    "reload_completed
8703     && QI_REG_P (operands[0])
8704     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8705     && !(INTVAL (operands[2]) & ~(255 << 8))
8706     && GET_MODE (operands[0]) != QImode"
8707   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8708                    (ior:SI (zero_extract:SI (match_dup 1)
8709                                             (const_int 8) (const_int 8))
8710                            (match_dup 2)))
8711               (clobber (reg:CC FLAGS_REG))])]
8712   "operands[0] = gen_lowpart (SImode, operands[0]);
8713    operands[1] = gen_lowpart (SImode, operands[1]);
8714    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8716 ;; Since OR can be encoded with sign extended immediate, this is only
8717 ;; profitable when 7th bit is set.
8718 (define_split
8719   [(set (match_operand 0 "register_operand" "")
8720         (ior (match_operand 1 "general_operand" "")
8721              (match_operand 2 "const_int_operand" "")))
8722    (clobber (reg:CC FLAGS_REG))]
8723    "reload_completed
8724     && ANY_QI_REG_P (operands[0])
8725     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8726     && !(INTVAL (operands[2]) & ~255)
8727     && (INTVAL (operands[2]) & 128)
8728     && GET_MODE (operands[0]) != QImode"
8729   [(parallel [(set (strict_low_part (match_dup 0))
8730                    (ior:QI (match_dup 1)
8731                            (match_dup 2)))
8732               (clobber (reg:CC FLAGS_REG))])]
8733   "operands[0] = gen_lowpart (QImode, operands[0]);
8734    operands[1] = gen_lowpart (QImode, operands[1]);
8735    operands[2] = gen_lowpart (QImode, operands[2]);")
8737 ;; Logical XOR instructions
8739 ;; %%% This used to optimize known byte-wide and operations to memory.
8740 ;; If this is considered useful, it should be done with splitters.
8742 (define_expand "xordi3"
8743   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8744         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8745                 (match_operand:DI 2 "x86_64_general_operand" "")))
8746    (clobber (reg:CC FLAGS_REG))]
8747   "TARGET_64BIT"
8748   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8750 (define_insn "*xordi_1_rex64"
8751   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8752         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8753                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8754    (clobber (reg:CC FLAGS_REG))]
8755   "TARGET_64BIT
8756    && ix86_binary_operator_ok (XOR, DImode, operands)"
8757   "@
8758    xor{q}\t{%2, %0|%0, %2}
8759    xor{q}\t{%2, %0|%0, %2}"
8760   [(set_attr "type" "alu")
8761    (set_attr "mode" "DI,DI")])
8763 (define_insn "*xordi_2_rex64"
8764   [(set (reg FLAGS_REG)
8765         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8766                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8767                  (const_int 0)))
8768    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8769         (xor:DI (match_dup 1) (match_dup 2)))]
8770   "TARGET_64BIT
8771    && ix86_match_ccmode (insn, CCNOmode)
8772    && ix86_binary_operator_ok (XOR, DImode, operands)"
8773   "@
8774    xor{q}\t{%2, %0|%0, %2}
8775    xor{q}\t{%2, %0|%0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "mode" "DI,DI")])
8779 (define_insn "*xordi_3_rex64"
8780   [(set (reg FLAGS_REG)
8781         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8782                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8783                  (const_int 0)))
8784    (clobber (match_scratch:DI 0 "=r"))]
8785   "TARGET_64BIT
8786    && ix86_match_ccmode (insn, CCNOmode)
8787    && ix86_binary_operator_ok (XOR, DImode, operands)"
8788   "xor{q}\t{%2, %0|%0, %2}"
8789   [(set_attr "type" "alu")
8790    (set_attr "mode" "DI")])
8792 (define_expand "xorsi3"
8793   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8794         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8795                 (match_operand:SI 2 "general_operand" "")))
8796    (clobber (reg:CC FLAGS_REG))]
8797   ""
8798   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8800 (define_insn "*xorsi_1"
8801   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8802         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8803                 (match_operand:SI 2 "general_operand" "ri,rm")))
8804    (clobber (reg:CC FLAGS_REG))]
8805   "ix86_binary_operator_ok (XOR, SImode, operands)"
8806   "xor{l}\t{%2, %0|%0, %2}"
8807   [(set_attr "type" "alu")
8808    (set_attr "mode" "SI")])
8810 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8811 ;; Add speccase for immediates
8812 (define_insn "*xorsi_1_zext"
8813   [(set (match_operand:DI 0 "register_operand" "=r")
8814         (zero_extend:DI
8815           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8816                   (match_operand:SI 2 "general_operand" "rim"))))
8817    (clobber (reg:CC FLAGS_REG))]
8818   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8819   "xor{l}\t{%2, %k0|%k0, %2}"
8820   [(set_attr "type" "alu")
8821    (set_attr "mode" "SI")])
8823 (define_insn "*xorsi_1_zext_imm"
8824   [(set (match_operand:DI 0 "register_operand" "=r")
8825         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8826                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8827    (clobber (reg:CC FLAGS_REG))]
8828   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8829   "xor{l}\t{%2, %k0|%k0, %2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "mode" "SI")])
8833 (define_insn "*xorsi_2"
8834   [(set (reg FLAGS_REG)
8835         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8836                          (match_operand:SI 2 "general_operand" "rim,ri"))
8837                  (const_int 0)))
8838    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8839         (xor:SI (match_dup 1) (match_dup 2)))]
8840   "ix86_match_ccmode (insn, CCNOmode)
8841    && ix86_binary_operator_ok (XOR, SImode, operands)"
8842   "xor{l}\t{%2, %0|%0, %2}"
8843   [(set_attr "type" "alu")
8844    (set_attr "mode" "SI")])
8846 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8847 ;; ??? Special case for immediate operand is missing - it is tricky.
8848 (define_insn "*xorsi_2_zext"
8849   [(set (reg FLAGS_REG)
8850         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8851                          (match_operand:SI 2 "general_operand" "rim"))
8852                  (const_int 0)))
8853    (set (match_operand:DI 0 "register_operand" "=r")
8854         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8855   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8856    && ix86_binary_operator_ok (XOR, SImode, operands)"
8857   "xor{l}\t{%2, %k0|%k0, %2}"
8858   [(set_attr "type" "alu")
8859    (set_attr "mode" "SI")])
8861 (define_insn "*xorsi_2_zext_imm"
8862   [(set (reg FLAGS_REG)
8863         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8864                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8865                  (const_int 0)))
8866    (set (match_operand:DI 0 "register_operand" "=r")
8867         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8868   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8869    && ix86_binary_operator_ok (XOR, SImode, operands)"
8870   "xor{l}\t{%2, %k0|%k0, %2}"
8871   [(set_attr "type" "alu")
8872    (set_attr "mode" "SI")])
8874 (define_insn "*xorsi_3"
8875   [(set (reg FLAGS_REG)
8876         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8877                          (match_operand:SI 2 "general_operand" "rim"))
8878                  (const_int 0)))
8879    (clobber (match_scratch:SI 0 "=r"))]
8880   "ix86_match_ccmode (insn, CCNOmode)
8881    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8882   "xor{l}\t{%2, %0|%0, %2}"
8883   [(set_attr "type" "alu")
8884    (set_attr "mode" "SI")])
8886 (define_expand "xorhi3"
8887   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8888         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8889                 (match_operand:HI 2 "general_operand" "")))
8890    (clobber (reg:CC FLAGS_REG))]
8891   "TARGET_HIMODE_MATH"
8892   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8894 (define_insn "*xorhi_1"
8895   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8896         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8897                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8898    (clobber (reg:CC FLAGS_REG))]
8899   "ix86_binary_operator_ok (XOR, HImode, operands)"
8900   "xor{w}\t{%2, %0|%0, %2}"
8901   [(set_attr "type" "alu")
8902    (set_attr "mode" "HI")])
8904 (define_insn "*xorhi_2"
8905   [(set (reg FLAGS_REG)
8906         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8907                          (match_operand:HI 2 "general_operand" "rim,ri"))
8908                  (const_int 0)))
8909    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8910         (xor:HI (match_dup 1) (match_dup 2)))]
8911   "ix86_match_ccmode (insn, CCNOmode)
8912    && ix86_binary_operator_ok (XOR, HImode, operands)"
8913   "xor{w}\t{%2, %0|%0, %2}"
8914   [(set_attr "type" "alu")
8915    (set_attr "mode" "HI")])
8917 (define_insn "*xorhi_3"
8918   [(set (reg FLAGS_REG)
8919         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8920                          (match_operand:HI 2 "general_operand" "rim"))
8921                  (const_int 0)))
8922    (clobber (match_scratch:HI 0 "=r"))]
8923   "ix86_match_ccmode (insn, CCNOmode)
8924    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8925   "xor{w}\t{%2, %0|%0, %2}"
8926   [(set_attr "type" "alu")
8927    (set_attr "mode" "HI")])
8929 (define_expand "xorqi3"
8930   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8931         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8932                 (match_operand:QI 2 "general_operand" "")))
8933    (clobber (reg:CC FLAGS_REG))]
8934   "TARGET_QIMODE_MATH"
8935   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8937 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8938 (define_insn "*xorqi_1"
8939   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8940         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8941                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8942    (clobber (reg:CC FLAGS_REG))]
8943   "ix86_binary_operator_ok (XOR, QImode, operands)"
8944   "@
8945    xor{b}\t{%2, %0|%0, %2}
8946    xor{b}\t{%2, %0|%0, %2}
8947    xor{l}\t{%k2, %k0|%k0, %k2}"
8948   [(set_attr "type" "alu")
8949    (set_attr "mode" "QI,QI,SI")])
8951 (define_insn "*xorqi_1_slp"
8952   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8953         (xor:QI (match_dup 0)
8954                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8955    (clobber (reg:CC FLAGS_REG))]
8956   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8957    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8958   "xor{b}\t{%1, %0|%0, %1}"
8959   [(set_attr "type" "alu1")
8960    (set_attr "mode" "QI")])
8962 (define_insn "xorqi_ext_0"
8963   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8964                          (const_int 8)
8965                          (const_int 8))
8966         (xor:SI 
8967           (zero_extract:SI
8968             (match_operand 1 "ext_register_operand" "0")
8969             (const_int 8)
8970             (const_int 8))
8971           (match_operand 2 "const_int_operand" "n")))
8972    (clobber (reg:CC FLAGS_REG))]
8973   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8974   "xor{b}\t{%2, %h0|%h0, %2}"
8975   [(set_attr "type" "alu")
8976    (set_attr "length_immediate" "1")
8977    (set_attr "mode" "QI")])
8979 (define_insn "*xorqi_ext_1"
8980   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8981                          (const_int 8)
8982                          (const_int 8))
8983         (xor:SI 
8984           (zero_extract:SI
8985             (match_operand 1 "ext_register_operand" "0")
8986             (const_int 8)
8987             (const_int 8))
8988           (zero_extend:SI
8989             (match_operand:QI 2 "general_operand" "Qm"))))
8990    (clobber (reg:CC FLAGS_REG))]
8991   "!TARGET_64BIT
8992    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8993   "xor{b}\t{%2, %h0|%h0, %2}"
8994   [(set_attr "type" "alu")
8995    (set_attr "length_immediate" "0")
8996    (set_attr "mode" "QI")])
8998 (define_insn "*xorqi_ext_1_rex64"
8999   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9000                          (const_int 8)
9001                          (const_int 8))
9002         (xor:SI 
9003           (zero_extract:SI
9004             (match_operand 1 "ext_register_operand" "0")
9005             (const_int 8)
9006             (const_int 8))
9007           (zero_extend:SI
9008             (match_operand 2 "ext_register_operand" "Q"))))
9009    (clobber (reg:CC FLAGS_REG))]
9010   "TARGET_64BIT
9011    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9012   "xor{b}\t{%2, %h0|%h0, %2}"
9013   [(set_attr "type" "alu")
9014    (set_attr "length_immediate" "0")
9015    (set_attr "mode" "QI")])
9017 (define_insn "*xorqi_ext_2"
9018   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9019                          (const_int 8)
9020                          (const_int 8))
9021         (xor:SI 
9022           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9023                            (const_int 8)
9024                            (const_int 8))
9025           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9026                            (const_int 8)
9027                            (const_int 8))))
9028    (clobber (reg:CC FLAGS_REG))]
9029   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9030   "xor{b}\t{%h2, %h0|%h0, %h2}"
9031   [(set_attr "type" "alu")
9032    (set_attr "length_immediate" "0")
9033    (set_attr "mode" "QI")])
9035 (define_insn "*xorqi_cc_1"
9036   [(set (reg FLAGS_REG)
9037         (compare
9038           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9039                   (match_operand:QI 2 "general_operand" "qim,qi"))
9040           (const_int 0)))
9041    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9042         (xor:QI (match_dup 1) (match_dup 2)))]
9043   "ix86_match_ccmode (insn, CCNOmode)
9044    && ix86_binary_operator_ok (XOR, QImode, operands)"
9045   "xor{b}\t{%2, %0|%0, %2}"
9046   [(set_attr "type" "alu")
9047    (set_attr "mode" "QI")])
9049 (define_insn "*xorqi_2_slp"
9050   [(set (reg FLAGS_REG)
9051         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9052                          (match_operand:QI 1 "general_operand" "qim,qi"))
9053                  (const_int 0)))
9054    (set (strict_low_part (match_dup 0))
9055         (xor:QI (match_dup 0) (match_dup 1)))]
9056   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9057    && ix86_match_ccmode (insn, CCNOmode)
9058    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9059   "xor{b}\t{%1, %0|%0, %1}"
9060   [(set_attr "type" "alu1")
9061    (set_attr "mode" "QI")])
9063 (define_insn "*xorqi_cc_2"
9064   [(set (reg FLAGS_REG)
9065         (compare
9066           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9067                   (match_operand:QI 2 "general_operand" "qim"))
9068           (const_int 0)))
9069    (clobber (match_scratch:QI 0 "=q"))]
9070   "ix86_match_ccmode (insn, CCNOmode)
9071    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9072   "xor{b}\t{%2, %0|%0, %2}"
9073   [(set_attr "type" "alu")
9074    (set_attr "mode" "QI")])
9076 (define_insn "*xorqi_cc_ext_1"
9077   [(set (reg FLAGS_REG)
9078         (compare
9079           (xor:SI
9080             (zero_extract:SI
9081               (match_operand 1 "ext_register_operand" "0")
9082               (const_int 8)
9083               (const_int 8))
9084             (match_operand:QI 2 "general_operand" "qmn"))
9085           (const_int 0)))
9086    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9087                          (const_int 8)
9088                          (const_int 8))
9089         (xor:SI 
9090           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9091           (match_dup 2)))]
9092   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9093   "xor{b}\t{%2, %h0|%h0, %2}"
9094   [(set_attr "type" "alu")
9095    (set_attr "mode" "QI")])
9097 (define_insn "*xorqi_cc_ext_1_rex64"
9098   [(set (reg FLAGS_REG)
9099         (compare
9100           (xor:SI
9101             (zero_extract:SI
9102               (match_operand 1 "ext_register_operand" "0")
9103               (const_int 8)
9104               (const_int 8))
9105             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9106           (const_int 0)))
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 (match_dup 1) (const_int 8) (const_int 8))
9112           (match_dup 2)))]
9113   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9114   "xor{b}\t{%2, %h0|%h0, %2}"
9115   [(set_attr "type" "alu")
9116    (set_attr "mode" "QI")])
9118 (define_expand "xorqi_cc_ext_1"
9119   [(parallel [
9120      (set (reg:CCNO FLAGS_REG)
9121           (compare:CCNO
9122             (xor:SI
9123               (zero_extract:SI
9124                 (match_operand 1 "ext_register_operand" "")
9125                 (const_int 8)
9126                 (const_int 8))
9127               (match_operand:QI 2 "general_operand" ""))
9128             (const_int 0)))
9129      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9130                            (const_int 8)
9131                            (const_int 8))
9132           (xor:SI 
9133             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9134             (match_dup 2)))])]
9135   ""
9136   "")
9138 (define_split
9139   [(set (match_operand 0 "register_operand" "")
9140         (xor (match_operand 1 "register_operand" "")
9141              (match_operand 2 "const_int_operand" "")))
9142    (clobber (reg:CC FLAGS_REG))]
9143    "reload_completed
9144     && QI_REG_P (operands[0])
9145     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9146     && !(INTVAL (operands[2]) & ~(255 << 8))
9147     && GET_MODE (operands[0]) != QImode"
9148   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9149                    (xor:SI (zero_extract:SI (match_dup 1)
9150                                             (const_int 8) (const_int 8))
9151                            (match_dup 2)))
9152               (clobber (reg:CC FLAGS_REG))])]
9153   "operands[0] = gen_lowpart (SImode, operands[0]);
9154    operands[1] = gen_lowpart (SImode, operands[1]);
9155    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9157 ;; Since XOR can be encoded with sign extended immediate, this is only
9158 ;; profitable when 7th bit is set.
9159 (define_split
9160   [(set (match_operand 0 "register_operand" "")
9161         (xor (match_operand 1 "general_operand" "")
9162              (match_operand 2 "const_int_operand" "")))
9163    (clobber (reg:CC FLAGS_REG))]
9164    "reload_completed
9165     && ANY_QI_REG_P (operands[0])
9166     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9167     && !(INTVAL (operands[2]) & ~255)
9168     && (INTVAL (operands[2]) & 128)
9169     && GET_MODE (operands[0]) != QImode"
9170   [(parallel [(set (strict_low_part (match_dup 0))
9171                    (xor:QI (match_dup 1)
9172                            (match_dup 2)))
9173               (clobber (reg:CC FLAGS_REG))])]
9174   "operands[0] = gen_lowpart (QImode, operands[0]);
9175    operands[1] = gen_lowpart (QImode, operands[1]);
9176    operands[2] = gen_lowpart (QImode, operands[2]);")
9178 ;; Negation instructions
9180 (define_expand "negdi2"
9181   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9182                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9183               (clobber (reg:CC FLAGS_REG))])]
9184   ""
9185   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9187 (define_insn "*negdi2_1"
9188   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9189         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9190    (clobber (reg:CC FLAGS_REG))]
9191   "!TARGET_64BIT
9192    && ix86_unary_operator_ok (NEG, DImode, operands)"
9193   "#")
9195 (define_split
9196   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9197         (neg:DI (match_operand:DI 1 "general_operand" "")))
9198    (clobber (reg:CC FLAGS_REG))]
9199   "!TARGET_64BIT && reload_completed"
9200   [(parallel
9201     [(set (reg:CCZ FLAGS_REG)
9202           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9203      (set (match_dup 0) (neg:SI (match_dup 2)))])
9204    (parallel
9205     [(set (match_dup 1)
9206           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9207                             (match_dup 3))
9208                    (const_int 0)))
9209      (clobber (reg:CC FLAGS_REG))])
9210    (parallel
9211     [(set (match_dup 1)
9212           (neg:SI (match_dup 1)))
9213      (clobber (reg:CC FLAGS_REG))])]
9214   "split_di (operands+1, 1, operands+2, operands+3);
9215    split_di (operands+0, 1, operands+0, operands+1);")
9217 (define_insn "*negdi2_1_rex64"
9218   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9219         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9220    (clobber (reg:CC FLAGS_REG))]
9221   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9222   "neg{q}\t%0"
9223   [(set_attr "type" "negnot")
9224    (set_attr "mode" "DI")])
9226 ;; The problem with neg is that it does not perform (compare x 0),
9227 ;; it really performs (compare 0 x), which leaves us with the zero
9228 ;; flag being the only useful item.
9230 (define_insn "*negdi2_cmpz_rex64"
9231   [(set (reg:CCZ FLAGS_REG)
9232         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9233                      (const_int 0)))
9234    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9235         (neg:DI (match_dup 1)))]
9236   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9237   "neg{q}\t%0"
9238   [(set_attr "type" "negnot")
9239    (set_attr "mode" "DI")])
9242 (define_expand "negsi2"
9243   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9244                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9245               (clobber (reg:CC FLAGS_REG))])]
9246   ""
9247   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9249 (define_insn "*negsi2_1"
9250   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9251         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9252    (clobber (reg:CC FLAGS_REG))]
9253   "ix86_unary_operator_ok (NEG, SImode, operands)"
9254   "neg{l}\t%0"
9255   [(set_attr "type" "negnot")
9256    (set_attr "mode" "SI")])
9258 ;; Combine is quite creative about this pattern.
9259 (define_insn "*negsi2_1_zext"
9260   [(set (match_operand:DI 0 "register_operand" "=r")
9261         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9262                                         (const_int 32)))
9263                      (const_int 32)))
9264    (clobber (reg:CC FLAGS_REG))]
9265   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9266   "neg{l}\t%k0"
9267   [(set_attr "type" "negnot")
9268    (set_attr "mode" "SI")])
9270 ;; The problem with neg is that it does not perform (compare x 0),
9271 ;; it really performs (compare 0 x), which leaves us with the zero
9272 ;; flag being the only useful item.
9274 (define_insn "*negsi2_cmpz"
9275   [(set (reg:CCZ FLAGS_REG)
9276         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9277                      (const_int 0)))
9278    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9279         (neg:SI (match_dup 1)))]
9280   "ix86_unary_operator_ok (NEG, SImode, operands)"
9281   "neg{l}\t%0"
9282   [(set_attr "type" "negnot")
9283    (set_attr "mode" "SI")])
9285 (define_insn "*negsi2_cmpz_zext"
9286   [(set (reg:CCZ FLAGS_REG)
9287         (compare:CCZ (lshiftrt:DI
9288                        (neg:DI (ashift:DI
9289                                  (match_operand:DI 1 "register_operand" "0")
9290                                  (const_int 32)))
9291                        (const_int 32))
9292                      (const_int 0)))
9293    (set (match_operand:DI 0 "register_operand" "=r")
9294         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9295                                         (const_int 32)))
9296                      (const_int 32)))]
9297   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9298   "neg{l}\t%k0"
9299   [(set_attr "type" "negnot")
9300    (set_attr "mode" "SI")])
9302 (define_expand "neghi2"
9303   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9304                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9305               (clobber (reg:CC FLAGS_REG))])]
9306   "TARGET_HIMODE_MATH"
9307   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9309 (define_insn "*neghi2_1"
9310   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9311         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9312    (clobber (reg:CC FLAGS_REG))]
9313   "ix86_unary_operator_ok (NEG, HImode, operands)"
9314   "neg{w}\t%0"
9315   [(set_attr "type" "negnot")
9316    (set_attr "mode" "HI")])
9318 (define_insn "*neghi2_cmpz"
9319   [(set (reg:CCZ FLAGS_REG)
9320         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9321                      (const_int 0)))
9322    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9323         (neg:HI (match_dup 1)))]
9324   "ix86_unary_operator_ok (NEG, HImode, operands)"
9325   "neg{w}\t%0"
9326   [(set_attr "type" "negnot")
9327    (set_attr "mode" "HI")])
9329 (define_expand "negqi2"
9330   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9331                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9332               (clobber (reg:CC FLAGS_REG))])]
9333   "TARGET_QIMODE_MATH"
9334   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9336 (define_insn "*negqi2_1"
9337   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9338         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9339    (clobber (reg:CC FLAGS_REG))]
9340   "ix86_unary_operator_ok (NEG, QImode, operands)"
9341   "neg{b}\t%0"
9342   [(set_attr "type" "negnot")
9343    (set_attr "mode" "QI")])
9345 (define_insn "*negqi2_cmpz"
9346   [(set (reg:CCZ FLAGS_REG)
9347         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9348                      (const_int 0)))
9349    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9350         (neg:QI (match_dup 1)))]
9351   "ix86_unary_operator_ok (NEG, QImode, operands)"
9352   "neg{b}\t%0"
9353   [(set_attr "type" "negnot")
9354    (set_attr "mode" "QI")])
9356 ;; Changing of sign for FP values is doable using integer unit too.
9358 (define_expand "negsf2"
9359   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9360         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9361   "TARGET_80387 || TARGET_SSE_MATH"
9362   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9364 (define_expand "abssf2"
9365   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9366         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9367   "TARGET_80387 || TARGET_SSE_MATH"
9368   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9370 (define_insn "*absnegsf2_mixed"
9371   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9372         (match_operator:SF 3 "absneg_operator"
9373           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9374    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9375    (clobber (reg:CC FLAGS_REG))]
9376   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9377    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9378   "#")
9380 (define_insn "*absnegsf2_sse"
9381   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9382         (match_operator:SF 3 "absneg_operator"
9383           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9384    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9385    (clobber (reg:CC FLAGS_REG))]
9386   "TARGET_SSE_MATH
9387    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9388   "#")
9390 (define_insn "*absnegsf2_i387"
9391   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9392         (match_operator:SF 3 "absneg_operator"
9393           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9394    (use (match_operand 2 "" ""))
9395    (clobber (reg:CC FLAGS_REG))]
9396   "TARGET_80387 && !TARGET_SSE_MATH
9397    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9398   "#")
9400 (define_expand "copysignsf3"
9401   [(match_operand:SF 0 "register_operand" "")
9402    (match_operand:SF 1 "nonmemory_operand" "")
9403    (match_operand:SF 2 "register_operand" "")]
9404   "TARGET_SSE_MATH"
9406   ix86_expand_copysign (operands);
9407   DONE;
9410 (define_insn_and_split "copysignsf3_const"
9411   [(set (match_operand:SF 0 "register_operand"          "=x")
9412         (unspec:SF
9413           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9414            (match_operand:SF 2 "register_operand"       "0")
9415            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9416           UNSPEC_COPYSIGN))]
9417   "TARGET_SSE_MATH"
9418   "#"
9419   "&& reload_completed"
9420   [(const_int 0)]
9422   ix86_split_copysign_const (operands);
9423   DONE;
9426 (define_insn "copysignsf3_var"
9427   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9428         (unspec:SF
9429           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9430            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9431            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9432            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9433           UNSPEC_COPYSIGN))
9434    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9435   "TARGET_SSE_MATH"
9436   "#")
9438 (define_split
9439   [(set (match_operand:SF 0 "register_operand" "")
9440         (unspec:SF
9441           [(match_operand:SF 2 "register_operand" "")
9442            (match_operand:SF 3 "register_operand" "")
9443            (match_operand:V4SF 4 "" "")
9444            (match_operand:V4SF 5 "" "")]
9445           UNSPEC_COPYSIGN))
9446    (clobber (match_scratch:V4SF 1 ""))]
9447   "TARGET_SSE_MATH && reload_completed"
9448   [(const_int 0)]
9450   ix86_split_copysign_var (operands);
9451   DONE;
9454 (define_expand "negdf2"
9455   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9456         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9457   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9458   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9460 (define_expand "absdf2"
9461   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9462         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9463   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9464   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9466 (define_insn "*absnegdf2_mixed"
9467   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9468         (match_operator:DF 3 "absneg_operator"
9469           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9470    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9471    (clobber (reg:CC FLAGS_REG))]
9472   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9473    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9474   "#")
9476 (define_insn "*absnegdf2_sse"
9477   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9478         (match_operator:DF 3 "absneg_operator"
9479           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9480    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9481    (clobber (reg:CC FLAGS_REG))]
9482   "TARGET_SSE2 && TARGET_SSE_MATH
9483    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9484   "#")
9486 (define_insn "*absnegdf2_i387"
9487   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9488         (match_operator:DF 3 "absneg_operator"
9489           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9490    (use (match_operand 2 "" ""))
9491    (clobber (reg:CC FLAGS_REG))]
9492   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9493    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9494   "#")
9496 (define_expand "copysigndf3"
9497   [(match_operand:DF 0 "register_operand" "")
9498    (match_operand:DF 1 "nonmemory_operand" "")
9499    (match_operand:DF 2 "register_operand" "")]
9500   "TARGET_SSE2 && TARGET_SSE_MATH"
9502   ix86_expand_copysign (operands);
9503   DONE;
9506 (define_insn_and_split "copysigndf3_const"
9507   [(set (match_operand:DF 0 "register_operand"          "=x")
9508         (unspec:DF
9509           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9510            (match_operand:DF 2 "register_operand"       "0")
9511            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9512           UNSPEC_COPYSIGN))]
9513   "TARGET_SSE2 && TARGET_SSE_MATH"
9514   "#"
9515   "&& reload_completed"
9516   [(const_int 0)]
9518   ix86_split_copysign_const (operands);
9519   DONE;
9522 (define_insn "copysigndf3_var"
9523   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9524         (unspec:DF
9525           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9526            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9527            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9528            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9529           UNSPEC_COPYSIGN))
9530    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9531   "TARGET_SSE2 && TARGET_SSE_MATH"
9532   "#")
9534 (define_split
9535   [(set (match_operand:DF 0 "register_operand" "")
9536         (unspec:DF
9537           [(match_operand:DF 2 "register_operand" "")
9538            (match_operand:DF 3 "register_operand" "")
9539            (match_operand:V2DF 4 "" "")
9540            (match_operand:V2DF 5 "" "")]
9541           UNSPEC_COPYSIGN))
9542    (clobber (match_scratch:V2DF 1 ""))]
9543   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9544   [(const_int 0)]
9546   ix86_split_copysign_var (operands);
9547   DONE;
9550 (define_expand "negxf2"
9551   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9552         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9553   "TARGET_80387"
9554   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9556 (define_expand "absxf2"
9557   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9558         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9559   "TARGET_80387"
9560   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9562 (define_insn "*absnegxf2_i387"
9563   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9564         (match_operator:XF 3 "absneg_operator"
9565           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9566    (use (match_operand 2 "" ""))
9567    (clobber (reg:CC FLAGS_REG))]
9568   "TARGET_80387
9569    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9570   "#")
9572 ;; Splitters for fp abs and neg.
9574 (define_split
9575   [(set (match_operand 0 "fp_register_operand" "")
9576         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9577    (use (match_operand 2 "" ""))
9578    (clobber (reg:CC FLAGS_REG))]
9579   "reload_completed"
9580   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9582 (define_split
9583   [(set (match_operand 0 "register_operand" "")
9584         (match_operator 3 "absneg_operator"
9585           [(match_operand 1 "register_operand" "")]))
9586    (use (match_operand 2 "nonimmediate_operand" ""))
9587    (clobber (reg:CC FLAGS_REG))]
9588   "reload_completed && SSE_REG_P (operands[0])"
9589   [(set (match_dup 0) (match_dup 3))]
9591   enum machine_mode mode = GET_MODE (operands[0]);
9592   enum machine_mode vmode = GET_MODE (operands[2]);
9593   rtx tmp;
9594   
9595   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9596   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9597   if (operands_match_p (operands[0], operands[2]))
9598     {
9599       tmp = operands[1];
9600       operands[1] = operands[2];
9601       operands[2] = tmp;
9602     }
9603   if (GET_CODE (operands[3]) == ABS)
9604     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9605   else
9606     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9607   operands[3] = tmp;
9610 (define_split
9611   [(set (match_operand:SF 0 "register_operand" "")
9612         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9613    (use (match_operand:V4SF 2 "" ""))
9614    (clobber (reg:CC FLAGS_REG))]
9615   "reload_completed"
9616   [(parallel [(set (match_dup 0) (match_dup 1))
9617               (clobber (reg:CC FLAGS_REG))])]
9619   rtx tmp;
9620   operands[0] = gen_lowpart (SImode, operands[0]);
9621   if (GET_CODE (operands[1]) == ABS)
9622     {
9623       tmp = gen_int_mode (0x7fffffff, SImode);
9624       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9625     }
9626   else
9627     {
9628       tmp = gen_int_mode (0x80000000, SImode);
9629       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9630     }
9631   operands[1] = tmp;
9634 (define_split
9635   [(set (match_operand:DF 0 "register_operand" "")
9636         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9637    (use (match_operand 2 "" ""))
9638    (clobber (reg:CC FLAGS_REG))]
9639   "reload_completed"
9640   [(parallel [(set (match_dup 0) (match_dup 1))
9641               (clobber (reg:CC FLAGS_REG))])]
9643   rtx tmp;
9644   if (TARGET_64BIT)
9645     {
9646       tmp = gen_lowpart (DImode, operands[0]);
9647       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9648       operands[0] = tmp;
9650       if (GET_CODE (operands[1]) == ABS)
9651         tmp = const0_rtx;
9652       else
9653         tmp = gen_rtx_NOT (DImode, tmp);
9654     }
9655   else
9656     {
9657       operands[0] = gen_highpart (SImode, operands[0]);
9658       if (GET_CODE (operands[1]) == ABS)
9659         {
9660           tmp = gen_int_mode (0x7fffffff, SImode);
9661           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9662         }
9663       else
9664         {
9665           tmp = gen_int_mode (0x80000000, SImode);
9666           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9667         }
9668     }
9669   operands[1] = tmp;
9672 (define_split
9673   [(set (match_operand:XF 0 "register_operand" "")
9674         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9675    (use (match_operand 2 "" ""))
9676    (clobber (reg:CC FLAGS_REG))]
9677   "reload_completed"
9678   [(parallel [(set (match_dup 0) (match_dup 1))
9679               (clobber (reg:CC FLAGS_REG))])]
9681   rtx tmp;
9682   operands[0] = gen_rtx_REG (SImode,
9683                              true_regnum (operands[0])
9684                              + (TARGET_64BIT ? 1 : 2));
9685   if (GET_CODE (operands[1]) == ABS)
9686     {
9687       tmp = GEN_INT (0x7fff);
9688       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9689     }
9690   else
9691     {
9692       tmp = GEN_INT (0x8000);
9693       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9694     }
9695   operands[1] = tmp;
9698 (define_split
9699   [(set (match_operand 0 "memory_operand" "")
9700         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9701    (use (match_operand 2 "" ""))
9702    (clobber (reg:CC FLAGS_REG))]
9703   "reload_completed"
9704   [(parallel [(set (match_dup 0) (match_dup 1))
9705               (clobber (reg:CC FLAGS_REG))])]
9707   enum machine_mode mode = GET_MODE (operands[0]);
9708   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9709   rtx tmp;
9711   operands[0] = adjust_address (operands[0], QImode, size - 1);
9712   if (GET_CODE (operands[1]) == ABS)
9713     {
9714       tmp = gen_int_mode (0x7f, QImode);
9715       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9716     }
9717   else
9718     {
9719       tmp = gen_int_mode (0x80, QImode);
9720       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9721     }
9722   operands[1] = tmp;
9725 ;; Conditionalize these after reload. If they match before reload, we 
9726 ;; lose the clobber and ability to use integer instructions.
9728 (define_insn "*negsf2_1"
9729   [(set (match_operand:SF 0 "register_operand" "=f")
9730         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9731   "TARGET_80387 && reload_completed"
9732   "fchs"
9733   [(set_attr "type" "fsgn")
9734    (set_attr "mode" "SF")])
9736 (define_insn "*negdf2_1"
9737   [(set (match_operand:DF 0 "register_operand" "=f")
9738         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9739   "TARGET_80387 && reload_completed"
9740   "fchs"
9741   [(set_attr "type" "fsgn")
9742    (set_attr "mode" "DF")])
9744 (define_insn "*negxf2_1"
9745   [(set (match_operand:XF 0 "register_operand" "=f")
9746         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9747   "TARGET_80387 && reload_completed"
9748   "fchs"
9749   [(set_attr "type" "fsgn")
9750    (set_attr "mode" "XF")])
9752 (define_insn "*abssf2_1"
9753   [(set (match_operand:SF 0 "register_operand" "=f")
9754         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9755   "TARGET_80387 && reload_completed"
9756   "fabs"
9757   [(set_attr "type" "fsgn")
9758    (set_attr "mode" "SF")])
9760 (define_insn "*absdf2_1"
9761   [(set (match_operand:DF 0 "register_operand" "=f")
9762         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9763   "TARGET_80387 && reload_completed"
9764   "fabs"
9765   [(set_attr "type" "fsgn")
9766    (set_attr "mode" "DF")])
9768 (define_insn "*absxf2_1"
9769   [(set (match_operand:XF 0 "register_operand" "=f")
9770         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9771   "TARGET_80387 && reload_completed"
9772   "fabs"
9773   [(set_attr "type" "fsgn")
9774    (set_attr "mode" "DF")])
9776 (define_insn "*negextendsfdf2"
9777   [(set (match_operand:DF 0 "register_operand" "=f")
9778         (neg:DF (float_extend:DF
9779                   (match_operand:SF 1 "register_operand" "0"))))]
9780   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9781   "fchs"
9782   [(set_attr "type" "fsgn")
9783    (set_attr "mode" "DF")])
9785 (define_insn "*negextenddfxf2"
9786   [(set (match_operand:XF 0 "register_operand" "=f")
9787         (neg:XF (float_extend:XF
9788                   (match_operand:DF 1 "register_operand" "0"))))]
9789   "TARGET_80387"
9790   "fchs"
9791   [(set_attr "type" "fsgn")
9792    (set_attr "mode" "XF")])
9794 (define_insn "*negextendsfxf2"
9795   [(set (match_operand:XF 0 "register_operand" "=f")
9796         (neg:XF (float_extend:XF
9797                   (match_operand:SF 1 "register_operand" "0"))))]
9798   "TARGET_80387"
9799   "fchs"
9800   [(set_attr "type" "fsgn")
9801    (set_attr "mode" "XF")])
9803 (define_insn "*absextendsfdf2"
9804   [(set (match_operand:DF 0 "register_operand" "=f")
9805         (abs:DF (float_extend:DF
9806                   (match_operand:SF 1 "register_operand" "0"))))]
9807   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9808   "fabs"
9809   [(set_attr "type" "fsgn")
9810    (set_attr "mode" "DF")])
9812 (define_insn "*absextenddfxf2"
9813   [(set (match_operand:XF 0 "register_operand" "=f")
9814         (abs:XF (float_extend:XF
9815           (match_operand:DF 1 "register_operand" "0"))))]
9816   "TARGET_80387"
9817   "fabs"
9818   [(set_attr "type" "fsgn")
9819    (set_attr "mode" "XF")])
9821 (define_insn "*absextendsfxf2"
9822   [(set (match_operand:XF 0 "register_operand" "=f")
9823         (abs:XF (float_extend:XF
9824           (match_operand:SF 1 "register_operand" "0"))))]
9825   "TARGET_80387"
9826   "fabs"
9827   [(set_attr "type" "fsgn")
9828    (set_attr "mode" "XF")])
9830 ;; One complement instructions
9832 (define_expand "one_cmpldi2"
9833   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9834         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9835   "TARGET_64BIT"
9836   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9838 (define_insn "*one_cmpldi2_1_rex64"
9839   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9840         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9841   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9842   "not{q}\t%0"
9843   [(set_attr "type" "negnot")
9844    (set_attr "mode" "DI")])
9846 (define_insn "*one_cmpldi2_2_rex64"
9847   [(set (reg FLAGS_REG)
9848         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9849                  (const_int 0)))
9850    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9851         (not:DI (match_dup 1)))]
9852   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9853    && ix86_unary_operator_ok (NOT, DImode, operands)"
9854   "#"
9855   [(set_attr "type" "alu1")
9856    (set_attr "mode" "DI")])
9858 (define_split
9859   [(set (match_operand 0 "flags_reg_operand" "")
9860         (match_operator 2 "compare_operator"
9861           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9862            (const_int 0)]))
9863    (set (match_operand:DI 1 "nonimmediate_operand" "")
9864         (not:DI (match_dup 3)))]
9865   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9866   [(parallel [(set (match_dup 0)
9867                    (match_op_dup 2
9868                      [(xor:DI (match_dup 3) (const_int -1))
9869                       (const_int 0)]))
9870               (set (match_dup 1)
9871                    (xor:DI (match_dup 3) (const_int -1)))])]
9872   "")
9874 (define_expand "one_cmplsi2"
9875   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9876         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9877   ""
9878   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9880 (define_insn "*one_cmplsi2_1"
9881   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9882         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9883   "ix86_unary_operator_ok (NOT, SImode, operands)"
9884   "not{l}\t%0"
9885   [(set_attr "type" "negnot")
9886    (set_attr "mode" "SI")])
9888 ;; ??? Currently never generated - xor is used instead.
9889 (define_insn "*one_cmplsi2_1_zext"
9890   [(set (match_operand:DI 0 "register_operand" "=r")
9891         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9892   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9893   "not{l}\t%k0"
9894   [(set_attr "type" "negnot")
9895    (set_attr "mode" "SI")])
9897 (define_insn "*one_cmplsi2_2"
9898   [(set (reg FLAGS_REG)
9899         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9900                  (const_int 0)))
9901    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9902         (not:SI (match_dup 1)))]
9903   "ix86_match_ccmode (insn, CCNOmode)
9904    && ix86_unary_operator_ok (NOT, SImode, operands)"
9905   "#"
9906   [(set_attr "type" "alu1")
9907    (set_attr "mode" "SI")])
9909 (define_split
9910   [(set (match_operand 0 "flags_reg_operand" "")
9911         (match_operator 2 "compare_operator"
9912           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9913            (const_int 0)]))
9914    (set (match_operand:SI 1 "nonimmediate_operand" "")
9915         (not:SI (match_dup 3)))]
9916   "ix86_match_ccmode (insn, CCNOmode)"
9917   [(parallel [(set (match_dup 0)
9918                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9919                                     (const_int 0)]))
9920               (set (match_dup 1)
9921                    (xor:SI (match_dup 3) (const_int -1)))])]
9922   "")
9924 ;; ??? Currently never generated - xor is used instead.
9925 (define_insn "*one_cmplsi2_2_zext"
9926   [(set (reg FLAGS_REG)
9927         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9928                  (const_int 0)))
9929    (set (match_operand:DI 0 "register_operand" "=r")
9930         (zero_extend:DI (not:SI (match_dup 1))))]
9931   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9932    && ix86_unary_operator_ok (NOT, SImode, operands)"
9933   "#"
9934   [(set_attr "type" "alu1")
9935    (set_attr "mode" "SI")])
9937 (define_split
9938   [(set (match_operand 0 "flags_reg_operand" "")
9939         (match_operator 2 "compare_operator"
9940           [(not:SI (match_operand:SI 3 "register_operand" ""))
9941            (const_int 0)]))
9942    (set (match_operand:DI 1 "register_operand" "")
9943         (zero_extend:DI (not:SI (match_dup 3))))]
9944   "ix86_match_ccmode (insn, CCNOmode)"
9945   [(parallel [(set (match_dup 0)
9946                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9947                                     (const_int 0)]))
9948               (set (match_dup 1)
9949                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9950   "")
9952 (define_expand "one_cmplhi2"
9953   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9954         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9955   "TARGET_HIMODE_MATH"
9956   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9958 (define_insn "*one_cmplhi2_1"
9959   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9960         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9961   "ix86_unary_operator_ok (NOT, HImode, operands)"
9962   "not{w}\t%0"
9963   [(set_attr "type" "negnot")
9964    (set_attr "mode" "HI")])
9966 (define_insn "*one_cmplhi2_2"
9967   [(set (reg FLAGS_REG)
9968         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9969                  (const_int 0)))
9970    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9971         (not:HI (match_dup 1)))]
9972   "ix86_match_ccmode (insn, CCNOmode)
9973    && ix86_unary_operator_ok (NEG, HImode, operands)"
9974   "#"
9975   [(set_attr "type" "alu1")
9976    (set_attr "mode" "HI")])
9978 (define_split
9979   [(set (match_operand 0 "flags_reg_operand" "")
9980         (match_operator 2 "compare_operator"
9981           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9982            (const_int 0)]))
9983    (set (match_operand:HI 1 "nonimmediate_operand" "")
9984         (not:HI (match_dup 3)))]
9985   "ix86_match_ccmode (insn, CCNOmode)"
9986   [(parallel [(set (match_dup 0)
9987                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
9988                                     (const_int 0)]))
9989               (set (match_dup 1)
9990                    (xor:HI (match_dup 3) (const_int -1)))])]
9991   "")
9993 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9994 (define_expand "one_cmplqi2"
9995   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9996         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
9997   "TARGET_QIMODE_MATH"
9998   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10000 (define_insn "*one_cmplqi2_1"
10001   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10002         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10003   "ix86_unary_operator_ok (NOT, QImode, operands)"
10004   "@
10005    not{b}\t%0
10006    not{l}\t%k0"
10007   [(set_attr "type" "negnot")
10008    (set_attr "mode" "QI,SI")])
10010 (define_insn "*one_cmplqi2_2"
10011   [(set (reg FLAGS_REG)
10012         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10013                  (const_int 0)))
10014    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10015         (not:QI (match_dup 1)))]
10016   "ix86_match_ccmode (insn, CCNOmode)
10017    && ix86_unary_operator_ok (NOT, QImode, operands)"
10018   "#"
10019   [(set_attr "type" "alu1")
10020    (set_attr "mode" "QI")])
10022 (define_split
10023   [(set (match_operand 0 "flags_reg_operand" "")
10024         (match_operator 2 "compare_operator"
10025           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10026            (const_int 0)]))
10027    (set (match_operand:QI 1 "nonimmediate_operand" "")
10028         (not:QI (match_dup 3)))]
10029   "ix86_match_ccmode (insn, CCNOmode)"
10030   [(parallel [(set (match_dup 0)
10031                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10032                                     (const_int 0)]))
10033               (set (match_dup 1)
10034                    (xor:QI (match_dup 3) (const_int -1)))])]
10035   "")
10037 ;; Arithmetic shift instructions
10039 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10040 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10041 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10042 ;; from the assembler input.
10044 ;; This instruction shifts the target reg/mem as usual, but instead of
10045 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10046 ;; is a left shift double, bits are taken from the high order bits of
10047 ;; reg, else if the insn is a shift right double, bits are taken from the
10048 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10049 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10051 ;; Since sh[lr]d does not change the `reg' operand, that is done
10052 ;; separately, making all shifts emit pairs of shift double and normal
10053 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10054 ;; support a 63 bit shift, each shift where the count is in a reg expands
10055 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10057 ;; If the shift count is a constant, we need never emit more than one
10058 ;; shift pair, instead using moves and sign extension for counts greater
10059 ;; than 31.
10061 (define_expand "ashldi3"
10062   [(set (match_operand:DI 0 "shiftdi_operand" "")
10063         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10064                    (match_operand:QI 2 "nonmemory_operand" "")))]
10065   ""
10066   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10068 (define_insn "*ashldi3_1_rex64"
10069   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10070         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10071                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10072    (clobber (reg:CC FLAGS_REG))]
10073   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10075   switch (get_attr_type (insn))
10076     {
10077     case TYPE_ALU:
10078       if (operands[2] != const1_rtx)
10079         abort ();
10080       if (!rtx_equal_p (operands[0], operands[1]))
10081         abort ();
10082       return "add{q}\t{%0, %0|%0, %0}";
10084     case TYPE_LEA:
10085       if (GET_CODE (operands[2]) != CONST_INT
10086           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10087         abort ();
10088       operands[1] = gen_rtx_MULT (DImode, operands[1],
10089                                   GEN_INT (1 << INTVAL (operands[2])));
10090       return "lea{q}\t{%a1, %0|%0, %a1}";
10092     default:
10093       if (REG_P (operands[2]))
10094         return "sal{q}\t{%b2, %0|%0, %b2}";
10095       else if (operands[2] == const1_rtx
10096                && (TARGET_SHIFT1 || optimize_size))
10097         return "sal{q}\t%0";
10098       else
10099         return "sal{q}\t{%2, %0|%0, %2}";
10100     }
10102   [(set (attr "type")
10103      (cond [(eq_attr "alternative" "1")
10104               (const_string "lea")
10105             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10106                           (const_int 0))
10107                       (match_operand 0 "register_operand" ""))
10108                  (match_operand 2 "const1_operand" ""))
10109               (const_string "alu")
10110            ]
10111            (const_string "ishift")))
10112    (set_attr "mode" "DI")])
10114 ;; Convert lea to the lea pattern to avoid flags dependency.
10115 (define_split
10116   [(set (match_operand:DI 0 "register_operand" "")
10117         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10118                    (match_operand:QI 2 "immediate_operand" "")))
10119    (clobber (reg:CC FLAGS_REG))]
10120   "TARGET_64BIT && reload_completed
10121    && true_regnum (operands[0]) != true_regnum (operands[1])"
10122   [(set (match_dup 0)
10123         (mult:DI (match_dup 1)
10124                  (match_dup 2)))]
10125   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10127 ;; This pattern can't accept a variable shift count, since shifts by
10128 ;; zero don't affect the flags.  We assume that shifts by constant
10129 ;; zero are optimized away.
10130 (define_insn "*ashldi3_cmp_rex64"
10131   [(set (reg FLAGS_REG)
10132         (compare
10133           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10134                      (match_operand:QI 2 "immediate_operand" "e"))
10135           (const_int 0)))
10136    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10137         (ashift:DI (match_dup 1) (match_dup 2)))]
10138   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10139    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10141   switch (get_attr_type (insn))
10142     {
10143     case TYPE_ALU:
10144       if (operands[2] != const1_rtx)
10145         abort ();
10146       return "add{q}\t{%0, %0|%0, %0}";
10148     default:
10149       if (REG_P (operands[2]))
10150         return "sal{q}\t{%b2, %0|%0, %b2}";
10151       else if (operands[2] == const1_rtx
10152                && (TARGET_SHIFT1 || optimize_size))
10153         return "sal{q}\t%0";
10154       else
10155         return "sal{q}\t{%2, %0|%0, %2}";
10156     }
10158   [(set (attr "type")
10159      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10160                           (const_int 0))
10161                       (match_operand 0 "register_operand" ""))
10162                  (match_operand 2 "const1_operand" ""))
10163               (const_string "alu")
10164            ]
10165            (const_string "ishift")))
10166    (set_attr "mode" "DI")])
10168 (define_insn "*ashldi3_1"
10169   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10170         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10171                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10172    (clobber (reg:CC FLAGS_REG))]
10173   "!TARGET_64BIT"
10174   "#"
10175   [(set_attr "type" "multi")])
10177 ;; By default we don't ask for a scratch register, because when DImode
10178 ;; values are manipulated, registers are already at a premium.  But if
10179 ;; we have one handy, we won't turn it away.
10180 (define_peephole2
10181   [(match_scratch:SI 3 "r")
10182    (parallel [(set (match_operand:DI 0 "register_operand" "")
10183                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10184                               (match_operand:QI 2 "nonmemory_operand" "")))
10185               (clobber (reg:CC FLAGS_REG))])
10186    (match_dup 3)]
10187   "!TARGET_64BIT && TARGET_CMOVE"
10188   [(const_int 0)]
10189   "ix86_split_ashldi (operands, operands[3]); DONE;")
10191 (define_split
10192   [(set (match_operand:DI 0 "register_operand" "")
10193         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10194                    (match_operand:QI 2 "nonmemory_operand" "")))
10195    (clobber (reg:CC FLAGS_REG))]
10196   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10197   [(const_int 0)]
10198   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10200 (define_insn "x86_shld_1"
10201   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10202         (ior:SI (ashift:SI (match_dup 0)
10203                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10204                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10205                   (minus:QI (const_int 32) (match_dup 2)))))
10206    (clobber (reg:CC FLAGS_REG))]
10207   ""
10208   "@
10209    shld{l}\t{%2, %1, %0|%0, %1, %2}
10210    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10211   [(set_attr "type" "ishift")
10212    (set_attr "prefix_0f" "1")
10213    (set_attr "mode" "SI")
10214    (set_attr "pent_pair" "np")
10215    (set_attr "athlon_decode" "vector")])
10217 (define_expand "x86_shift_adj_1"
10218   [(set (reg:CCZ FLAGS_REG)
10219         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10220                              (const_int 32))
10221                      (const_int 0)))
10222    (set (match_operand:SI 0 "register_operand" "")
10223         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10224                          (match_operand:SI 1 "register_operand" "")
10225                          (match_dup 0)))
10226    (set (match_dup 1)
10227         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10228                          (match_operand:SI 3 "register_operand" "r")
10229                          (match_dup 1)))]
10230   "TARGET_CMOVE"
10231   "")
10233 (define_expand "x86_shift_adj_2"
10234   [(use (match_operand:SI 0 "register_operand" ""))
10235    (use (match_operand:SI 1 "register_operand" ""))
10236    (use (match_operand:QI 2 "register_operand" ""))]
10237   ""
10239   rtx label = gen_label_rtx ();
10240   rtx tmp;
10242   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10244   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10245   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10246   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10247                               gen_rtx_LABEL_REF (VOIDmode, label),
10248                               pc_rtx);
10249   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10250   JUMP_LABEL (tmp) = label;
10252   emit_move_insn (operands[0], operands[1]);
10253   ix86_expand_clear (operands[1]);
10255   emit_label (label);
10256   LABEL_NUSES (label) = 1;
10258   DONE;
10261 (define_expand "ashlsi3"
10262   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10263         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10264                    (match_operand:QI 2 "nonmemory_operand" "")))
10265    (clobber (reg:CC FLAGS_REG))]
10266   ""
10267   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10269 (define_insn "*ashlsi3_1"
10270   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10271         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10272                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10273    (clobber (reg:CC FLAGS_REG))]
10274   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10276   switch (get_attr_type (insn))
10277     {
10278     case TYPE_ALU:
10279       if (operands[2] != const1_rtx)
10280         abort ();
10281       if (!rtx_equal_p (operands[0], operands[1]))
10282         abort ();
10283       return "add{l}\t{%0, %0|%0, %0}";
10285     case TYPE_LEA:
10286       return "#";
10288     default:
10289       if (REG_P (operands[2]))
10290         return "sal{l}\t{%b2, %0|%0, %b2}";
10291       else if (operands[2] == const1_rtx
10292                && (TARGET_SHIFT1 || optimize_size))
10293         return "sal{l}\t%0";
10294       else
10295         return "sal{l}\t{%2, %0|%0, %2}";
10296     }
10298   [(set (attr "type")
10299      (cond [(eq_attr "alternative" "1")
10300               (const_string "lea")
10301             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10302                           (const_int 0))
10303                       (match_operand 0 "register_operand" ""))
10304                  (match_operand 2 "const1_operand" ""))
10305               (const_string "alu")
10306            ]
10307            (const_string "ishift")))
10308    (set_attr "mode" "SI")])
10310 ;; Convert lea to the lea pattern to avoid flags dependency.
10311 (define_split
10312   [(set (match_operand 0 "register_operand" "")
10313         (ashift (match_operand 1 "index_register_operand" "")
10314                 (match_operand:QI 2 "const_int_operand" "")))
10315    (clobber (reg:CC FLAGS_REG))]
10316   "reload_completed
10317    && true_regnum (operands[0]) != true_regnum (operands[1])
10318    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10319   [(const_int 0)]
10321   rtx pat;
10322   enum machine_mode mode = GET_MODE (operands[0]);
10324   if (GET_MODE_SIZE (mode) < 4)
10325     operands[0] = gen_lowpart (SImode, operands[0]);
10326   if (mode != Pmode)
10327     operands[1] = gen_lowpart (Pmode, operands[1]);
10328   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10330   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10331   if (Pmode != SImode)
10332     pat = gen_rtx_SUBREG (SImode, pat, 0);
10333   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10334   DONE;
10337 ;; Rare case of shifting RSP is handled by generating move and shift
10338 (define_split
10339   [(set (match_operand 0 "register_operand" "")
10340         (ashift (match_operand 1 "register_operand" "")
10341                 (match_operand:QI 2 "const_int_operand" "")))
10342    (clobber (reg:CC FLAGS_REG))]
10343   "reload_completed
10344    && true_regnum (operands[0]) != true_regnum (operands[1])"
10345   [(const_int 0)]
10347   rtx pat, clob;
10348   emit_move_insn (operands[1], operands[0]);
10349   pat = gen_rtx_SET (VOIDmode, operands[0],
10350                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10351                                      operands[0], operands[2]));
10352   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10353   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10354   DONE;
10357 (define_insn "*ashlsi3_1_zext"
10358   [(set (match_operand:DI 0 "register_operand" "=r,r")
10359         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10360                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10361    (clobber (reg:CC FLAGS_REG))]
10362   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10364   switch (get_attr_type (insn))
10365     {
10366     case TYPE_ALU:
10367       if (operands[2] != const1_rtx)
10368         abort ();
10369       return "add{l}\t{%k0, %k0|%k0, %k0}";
10371     case TYPE_LEA:
10372       return "#";
10374     default:
10375       if (REG_P (operands[2]))
10376         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10377       else if (operands[2] == const1_rtx
10378                && (TARGET_SHIFT1 || optimize_size))
10379         return "sal{l}\t%k0";
10380       else
10381         return "sal{l}\t{%2, %k0|%k0, %2}";
10382     }
10384   [(set (attr "type")
10385      (cond [(eq_attr "alternative" "1")
10386               (const_string "lea")
10387             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10388                      (const_int 0))
10389                  (match_operand 2 "const1_operand" ""))
10390               (const_string "alu")
10391            ]
10392            (const_string "ishift")))
10393    (set_attr "mode" "SI")])
10395 ;; Convert lea to the lea pattern to avoid flags dependency.
10396 (define_split
10397   [(set (match_operand:DI 0 "register_operand" "")
10398         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10399                                 (match_operand:QI 2 "const_int_operand" ""))))
10400    (clobber (reg:CC FLAGS_REG))]
10401   "TARGET_64BIT && reload_completed
10402    && true_regnum (operands[0]) != true_regnum (operands[1])"
10403   [(set (match_dup 0) (zero_extend:DI
10404                         (subreg:SI (mult:SI (match_dup 1)
10405                                             (match_dup 2)) 0)))]
10407   operands[1] = gen_lowpart (Pmode, operands[1]);
10408   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10411 ;; This pattern can't accept a variable shift count, since shifts by
10412 ;; zero don't affect the flags.  We assume that shifts by constant
10413 ;; zero are optimized away.
10414 (define_insn "*ashlsi3_cmp"
10415   [(set (reg FLAGS_REG)
10416         (compare
10417           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10418                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10419           (const_int 0)))
10420    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10421         (ashift:SI (match_dup 1) (match_dup 2)))]
10422   "ix86_match_ccmode (insn, CCGOCmode)
10423    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10425   switch (get_attr_type (insn))
10426     {
10427     case TYPE_ALU:
10428       if (operands[2] != const1_rtx)
10429         abort ();
10430       return "add{l}\t{%0, %0|%0, %0}";
10432     default:
10433       if (REG_P (operands[2]))
10434         return "sal{l}\t{%b2, %0|%0, %b2}";
10435       else if (operands[2] == const1_rtx
10436                && (TARGET_SHIFT1 || optimize_size))
10437         return "sal{l}\t%0";
10438       else
10439         return "sal{l}\t{%2, %0|%0, %2}";
10440     }
10442   [(set (attr "type")
10443      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10444                           (const_int 0))
10445                       (match_operand 0 "register_operand" ""))
10446                  (match_operand 2 "const1_operand" ""))
10447               (const_string "alu")
10448            ]
10449            (const_string "ishift")))
10450    (set_attr "mode" "SI")])
10452 (define_insn "*ashlsi3_cmp_zext"
10453   [(set (reg FLAGS_REG)
10454         (compare
10455           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10456                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10457           (const_int 0)))
10458    (set (match_operand:DI 0 "register_operand" "=r")
10459         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10460   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10461    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10463   switch (get_attr_type (insn))
10464     {
10465     case TYPE_ALU:
10466       if (operands[2] != const1_rtx)
10467         abort ();
10468       return "add{l}\t{%k0, %k0|%k0, %k0}";
10470     default:
10471       if (REG_P (operands[2]))
10472         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10473       else if (operands[2] == const1_rtx
10474                && (TARGET_SHIFT1 || optimize_size))
10475         return "sal{l}\t%k0";
10476       else
10477         return "sal{l}\t{%2, %k0|%k0, %2}";
10478     }
10480   [(set (attr "type")
10481      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10482                      (const_int 0))
10483                  (match_operand 2 "const1_operand" ""))
10484               (const_string "alu")
10485            ]
10486            (const_string "ishift")))
10487    (set_attr "mode" "SI")])
10489 (define_expand "ashlhi3"
10490   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10491         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10492                    (match_operand:QI 2 "nonmemory_operand" "")))
10493    (clobber (reg:CC FLAGS_REG))]
10494   "TARGET_HIMODE_MATH"
10495   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10497 (define_insn "*ashlhi3_1_lea"
10498   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10499         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10500                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10501    (clobber (reg:CC FLAGS_REG))]
10502   "!TARGET_PARTIAL_REG_STALL
10503    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10505   switch (get_attr_type (insn))
10506     {
10507     case TYPE_LEA:
10508       return "#";
10509     case TYPE_ALU:
10510       if (operands[2] != const1_rtx)
10511         abort ();
10512       return "add{w}\t{%0, %0|%0, %0}";
10514     default:
10515       if (REG_P (operands[2]))
10516         return "sal{w}\t{%b2, %0|%0, %b2}";
10517       else if (operands[2] == const1_rtx
10518                && (TARGET_SHIFT1 || optimize_size))
10519         return "sal{w}\t%0";
10520       else
10521         return "sal{w}\t{%2, %0|%0, %2}";
10522     }
10524   [(set (attr "type")
10525      (cond [(eq_attr "alternative" "1")
10526               (const_string "lea")
10527             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10528                           (const_int 0))
10529                       (match_operand 0 "register_operand" ""))
10530                  (match_operand 2 "const1_operand" ""))
10531               (const_string "alu")
10532            ]
10533            (const_string "ishift")))
10534    (set_attr "mode" "HI,SI")])
10536 (define_insn "*ashlhi3_1"
10537   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10538         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10539                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10540    (clobber (reg:CC FLAGS_REG))]
10541   "TARGET_PARTIAL_REG_STALL
10542    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10544   switch (get_attr_type (insn))
10545     {
10546     case TYPE_ALU:
10547       if (operands[2] != const1_rtx)
10548         abort ();
10549       return "add{w}\t{%0, %0|%0, %0}";
10551     default:
10552       if (REG_P (operands[2]))
10553         return "sal{w}\t{%b2, %0|%0, %b2}";
10554       else if (operands[2] == const1_rtx
10555                && (TARGET_SHIFT1 || optimize_size))
10556         return "sal{w}\t%0";
10557       else
10558         return "sal{w}\t{%2, %0|%0, %2}";
10559     }
10561   [(set (attr "type")
10562      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10563                           (const_int 0))
10564                       (match_operand 0 "register_operand" ""))
10565                  (match_operand 2 "const1_operand" ""))
10566               (const_string "alu")
10567            ]
10568            (const_string "ishift")))
10569    (set_attr "mode" "HI")])
10571 ;; This pattern can't accept a variable shift count, since shifts by
10572 ;; zero don't affect the flags.  We assume that shifts by constant
10573 ;; zero are optimized away.
10574 (define_insn "*ashlhi3_cmp"
10575   [(set (reg FLAGS_REG)
10576         (compare
10577           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10578                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10579           (const_int 0)))
10580    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10581         (ashift:HI (match_dup 1) (match_dup 2)))]
10582   "ix86_match_ccmode (insn, CCGOCmode)
10583    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10585   switch (get_attr_type (insn))
10586     {
10587     case TYPE_ALU:
10588       if (operands[2] != const1_rtx)
10589         abort ();
10590       return "add{w}\t{%0, %0|%0, %0}";
10592     default:
10593       if (REG_P (operands[2]))
10594         return "sal{w}\t{%b2, %0|%0, %b2}";
10595       else if (operands[2] == const1_rtx
10596                && (TARGET_SHIFT1 || optimize_size))
10597         return "sal{w}\t%0";
10598       else
10599         return "sal{w}\t{%2, %0|%0, %2}";
10600     }
10602   [(set (attr "type")
10603      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10604                           (const_int 0))
10605                       (match_operand 0 "register_operand" ""))
10606                  (match_operand 2 "const1_operand" ""))
10607               (const_string "alu")
10608            ]
10609            (const_string "ishift")))
10610    (set_attr "mode" "HI")])
10612 (define_expand "ashlqi3"
10613   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10614         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10615                    (match_operand:QI 2 "nonmemory_operand" "")))
10616    (clobber (reg:CC FLAGS_REG))]
10617   "TARGET_QIMODE_MATH"
10618   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10620 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10622 (define_insn "*ashlqi3_1_lea"
10623   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10624         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10625                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10626    (clobber (reg:CC FLAGS_REG))]
10627   "!TARGET_PARTIAL_REG_STALL
10628    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10630   switch (get_attr_type (insn))
10631     {
10632     case TYPE_LEA:
10633       return "#";
10634     case TYPE_ALU:
10635       if (operands[2] != const1_rtx)
10636         abort ();
10637       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10638         return "add{l}\t{%k0, %k0|%k0, %k0}";
10639       else
10640         return "add{b}\t{%0, %0|%0, %0}";
10642     default:
10643       if (REG_P (operands[2]))
10644         {
10645           if (get_attr_mode (insn) == MODE_SI)
10646             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10647           else
10648             return "sal{b}\t{%b2, %0|%0, %b2}";
10649         }
10650       else if (operands[2] == const1_rtx
10651                && (TARGET_SHIFT1 || optimize_size))
10652         {
10653           if (get_attr_mode (insn) == MODE_SI)
10654             return "sal{l}\t%0";
10655           else
10656             return "sal{b}\t%0";
10657         }
10658       else
10659         {
10660           if (get_attr_mode (insn) == MODE_SI)
10661             return "sal{l}\t{%2, %k0|%k0, %2}";
10662           else
10663             return "sal{b}\t{%2, %0|%0, %2}";
10664         }
10665     }
10667   [(set (attr "type")
10668      (cond [(eq_attr "alternative" "2")
10669               (const_string "lea")
10670             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10671                           (const_int 0))
10672                       (match_operand 0 "register_operand" ""))
10673                  (match_operand 2 "const1_operand" ""))
10674               (const_string "alu")
10675            ]
10676            (const_string "ishift")))
10677    (set_attr "mode" "QI,SI,SI")])
10679 (define_insn "*ashlqi3_1"
10680   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10681         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10682                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10683    (clobber (reg:CC FLAGS_REG))]
10684   "TARGET_PARTIAL_REG_STALL
10685    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10687   switch (get_attr_type (insn))
10688     {
10689     case TYPE_ALU:
10690       if (operands[2] != const1_rtx)
10691         abort ();
10692       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10693         return "add{l}\t{%k0, %k0|%k0, %k0}";
10694       else
10695         return "add{b}\t{%0, %0|%0, %0}";
10697     default:
10698       if (REG_P (operands[2]))
10699         {
10700           if (get_attr_mode (insn) == MODE_SI)
10701             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10702           else
10703             return "sal{b}\t{%b2, %0|%0, %b2}";
10704         }
10705       else if (operands[2] == const1_rtx
10706                && (TARGET_SHIFT1 || optimize_size))
10707         {
10708           if (get_attr_mode (insn) == MODE_SI)
10709             return "sal{l}\t%0";
10710           else
10711             return "sal{b}\t%0";
10712         }
10713       else
10714         {
10715           if (get_attr_mode (insn) == MODE_SI)
10716             return "sal{l}\t{%2, %k0|%k0, %2}";
10717           else
10718             return "sal{b}\t{%2, %0|%0, %2}";
10719         }
10720     }
10722   [(set (attr "type")
10723      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10724                           (const_int 0))
10725                       (match_operand 0 "register_operand" ""))
10726                  (match_operand 2 "const1_operand" ""))
10727               (const_string "alu")
10728            ]
10729            (const_string "ishift")))
10730    (set_attr "mode" "QI,SI")])
10732 ;; This pattern can't accept a variable shift count, since shifts by
10733 ;; zero don't affect the flags.  We assume that shifts by constant
10734 ;; zero are optimized away.
10735 (define_insn "*ashlqi3_cmp"
10736   [(set (reg FLAGS_REG)
10737         (compare
10738           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10739                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10740           (const_int 0)))
10741    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10742         (ashift:QI (match_dup 1) (match_dup 2)))]
10743   "ix86_match_ccmode (insn, CCGOCmode)
10744    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10746   switch (get_attr_type (insn))
10747     {
10748     case TYPE_ALU:
10749       if (operands[2] != const1_rtx)
10750         abort ();
10751       return "add{b}\t{%0, %0|%0, %0}";
10753     default:
10754       if (REG_P (operands[2]))
10755         return "sal{b}\t{%b2, %0|%0, %b2}";
10756       else if (operands[2] == const1_rtx
10757                && (TARGET_SHIFT1 || optimize_size))
10758         return "sal{b}\t%0";
10759       else
10760         return "sal{b}\t{%2, %0|%0, %2}";
10761     }
10763   [(set (attr "type")
10764      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10765                           (const_int 0))
10766                       (match_operand 0 "register_operand" ""))
10767                  (match_operand 2 "const1_operand" ""))
10768               (const_string "alu")
10769            ]
10770            (const_string "ishift")))
10771    (set_attr "mode" "QI")])
10773 ;; See comment above `ashldi3' about how this works.
10775 (define_expand "ashrdi3"
10776   [(set (match_operand:DI 0 "shiftdi_operand" "")
10777         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10778                      (match_operand:QI 2 "nonmemory_operand" "")))]
10779   ""
10780   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10782 (define_insn "*ashrdi3_63_rex64"
10783   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10784         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10785                      (match_operand:DI 2 "const_int_operand" "i,i")))
10786    (clobber (reg:CC FLAGS_REG))]
10787   "TARGET_64BIT && INTVAL (operands[2]) == 63
10788    && (TARGET_USE_CLTD || optimize_size)
10789    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10790   "@
10791    {cqto|cqo}
10792    sar{q}\t{%2, %0|%0, %2}"
10793   [(set_attr "type" "imovx,ishift")
10794    (set_attr "prefix_0f" "0,*")
10795    (set_attr "length_immediate" "0,*")
10796    (set_attr "modrm" "0,1")
10797    (set_attr "mode" "DI")])
10799 (define_insn "*ashrdi3_1_one_bit_rex64"
10800   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10801         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10802                      (match_operand:QI 2 "const1_operand" "")))
10803    (clobber (reg:CC FLAGS_REG))]
10804   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10805    && (TARGET_SHIFT1 || optimize_size)"
10806   "sar{q}\t%0"
10807   [(set_attr "type" "ishift")
10808    (set (attr "length") 
10809      (if_then_else (match_operand:DI 0 "register_operand" "") 
10810         (const_string "2")
10811         (const_string "*")))])
10813 (define_insn "*ashrdi3_1_rex64"
10814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10815         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10816                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10817    (clobber (reg:CC FLAGS_REG))]
10818   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10819   "@
10820    sar{q}\t{%2, %0|%0, %2}
10821    sar{q}\t{%b2, %0|%0, %b2}"
10822   [(set_attr "type" "ishift")
10823    (set_attr "mode" "DI")])
10825 ;; This pattern can't accept a variable shift count, since shifts by
10826 ;; zero don't affect the flags.  We assume that shifts by constant
10827 ;; zero are optimized away.
10828 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10829   [(set (reg FLAGS_REG)
10830         (compare
10831           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10832                        (match_operand:QI 2 "const1_operand" ""))
10833           (const_int 0)))
10834    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10835         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10836   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10837    && (TARGET_SHIFT1 || optimize_size)
10838    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10839   "sar{q}\t%0"
10840   [(set_attr "type" "ishift")
10841    (set (attr "length") 
10842      (if_then_else (match_operand:DI 0 "register_operand" "") 
10843         (const_string "2")
10844         (const_string "*")))])
10846 ;; This pattern can't accept a variable shift count, since shifts by
10847 ;; zero don't affect the flags.  We assume that shifts by constant
10848 ;; zero are optimized away.
10849 (define_insn "*ashrdi3_cmp_rex64"
10850   [(set (reg FLAGS_REG)
10851         (compare
10852           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10853                        (match_operand:QI 2 "const_int_operand" "n"))
10854           (const_int 0)))
10855    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10856         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10857   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10858    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10859   "sar{q}\t{%2, %0|%0, %2}"
10860   [(set_attr "type" "ishift")
10861    (set_attr "mode" "DI")])
10863 (define_insn "*ashrdi3_1"
10864   [(set (match_operand:DI 0 "register_operand" "=r")
10865         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10866                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10867    (clobber (reg:CC FLAGS_REG))]
10868   "!TARGET_64BIT"
10869   "#"
10870   [(set_attr "type" "multi")])
10872 ;; By default we don't ask for a scratch register, because when DImode
10873 ;; values are manipulated, registers are already at a premium.  But if
10874 ;; we have one handy, we won't turn it away.
10875 (define_peephole2
10876   [(match_scratch:SI 3 "r")
10877    (parallel [(set (match_operand:DI 0 "register_operand" "")
10878                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10879                                 (match_operand:QI 2 "nonmemory_operand" "")))
10880               (clobber (reg:CC FLAGS_REG))])
10881    (match_dup 3)]
10882   "!TARGET_64BIT && TARGET_CMOVE"
10883   [(const_int 0)]
10884   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10886 (define_split
10887   [(set (match_operand:DI 0 "register_operand" "")
10888         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10889                      (match_operand:QI 2 "nonmemory_operand" "")))
10890    (clobber (reg:CC FLAGS_REG))]
10891   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10892   [(const_int 0)]
10893   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10895 (define_insn "x86_shrd_1"
10896   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10897         (ior:SI (ashiftrt:SI (match_dup 0)
10898                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10899                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10900                   (minus:QI (const_int 32) (match_dup 2)))))
10901    (clobber (reg:CC FLAGS_REG))]
10902   ""
10903   "@
10904    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10905    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10906   [(set_attr "type" "ishift")
10907    (set_attr "prefix_0f" "1")
10908    (set_attr "pent_pair" "np")
10909    (set_attr "mode" "SI")])
10911 (define_expand "x86_shift_adj_3"
10912   [(use (match_operand:SI 0 "register_operand" ""))
10913    (use (match_operand:SI 1 "register_operand" ""))
10914    (use (match_operand:QI 2 "register_operand" ""))]
10915   ""
10917   rtx label = gen_label_rtx ();
10918   rtx tmp;
10920   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10922   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10923   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10924   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10925                               gen_rtx_LABEL_REF (VOIDmode, label),
10926                               pc_rtx);
10927   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10928   JUMP_LABEL (tmp) = label;
10930   emit_move_insn (operands[0], operands[1]);
10931   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10933   emit_label (label);
10934   LABEL_NUSES (label) = 1;
10936   DONE;
10939 (define_insn "ashrsi3_31"
10940   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10941         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10942                      (match_operand:SI 2 "const_int_operand" "i,i")))
10943    (clobber (reg:CC FLAGS_REG))]
10944   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10945    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10946   "@
10947    {cltd|cdq}
10948    sar{l}\t{%2, %0|%0, %2}"
10949   [(set_attr "type" "imovx,ishift")
10950    (set_attr "prefix_0f" "0,*")
10951    (set_attr "length_immediate" "0,*")
10952    (set_attr "modrm" "0,1")
10953    (set_attr "mode" "SI")])
10955 (define_insn "*ashrsi3_31_zext"
10956   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10957         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10958                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10959    (clobber (reg:CC FLAGS_REG))]
10960   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10961    && INTVAL (operands[2]) == 31
10962    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10963   "@
10964    {cltd|cdq}
10965    sar{l}\t{%2, %k0|%k0, %2}"
10966   [(set_attr "type" "imovx,ishift")
10967    (set_attr "prefix_0f" "0,*")
10968    (set_attr "length_immediate" "0,*")
10969    (set_attr "modrm" "0,1")
10970    (set_attr "mode" "SI")])
10972 (define_expand "ashrsi3"
10973   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10974         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10975                      (match_operand:QI 2 "nonmemory_operand" "")))
10976    (clobber (reg:CC FLAGS_REG))]
10977   ""
10978   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10980 (define_insn "*ashrsi3_1_one_bit"
10981   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10982         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10983                      (match_operand:QI 2 "const1_operand" "")))
10984    (clobber (reg:CC FLAGS_REG))]
10985   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10986    && (TARGET_SHIFT1 || optimize_size)"
10987   "sar{l}\t%0"
10988   [(set_attr "type" "ishift")
10989    (set (attr "length") 
10990      (if_then_else (match_operand:SI 0 "register_operand" "") 
10991         (const_string "2")
10992         (const_string "*")))])
10994 (define_insn "*ashrsi3_1_one_bit_zext"
10995   [(set (match_operand:DI 0 "register_operand" "=r")
10996         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10997                                      (match_operand:QI 2 "const1_operand" ""))))
10998    (clobber (reg:CC FLAGS_REG))]
10999   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11000    && (TARGET_SHIFT1 || optimize_size)"
11001   "sar{l}\t%k0"
11002   [(set_attr "type" "ishift")
11003    (set_attr "length" "2")])
11005 (define_insn "*ashrsi3_1"
11006   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11007         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11008                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11009    (clobber (reg:CC FLAGS_REG))]
11010   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11011   "@
11012    sar{l}\t{%2, %0|%0, %2}
11013    sar{l}\t{%b2, %0|%0, %b2}"
11014   [(set_attr "type" "ishift")
11015    (set_attr "mode" "SI")])
11017 (define_insn "*ashrsi3_1_zext"
11018   [(set (match_operand:DI 0 "register_operand" "=r,r")
11019         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11020                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11021    (clobber (reg:CC FLAGS_REG))]
11022   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11023   "@
11024    sar{l}\t{%2, %k0|%k0, %2}
11025    sar{l}\t{%b2, %k0|%k0, %b2}"
11026   [(set_attr "type" "ishift")
11027    (set_attr "mode" "SI")])
11029 ;; This pattern can't accept a variable shift count, since shifts by
11030 ;; zero don't affect the flags.  We assume that shifts by constant
11031 ;; zero are optimized away.
11032 (define_insn "*ashrsi3_one_bit_cmp"
11033   [(set (reg FLAGS_REG)
11034         (compare
11035           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11036                        (match_operand:QI 2 "const1_operand" ""))
11037           (const_int 0)))
11038    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11039         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11040   "ix86_match_ccmode (insn, CCGOCmode)
11041    && (TARGET_SHIFT1 || optimize_size)
11042    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11043   "sar{l}\t%0"
11044   [(set_attr "type" "ishift")
11045    (set (attr "length") 
11046      (if_then_else (match_operand:SI 0 "register_operand" "") 
11047         (const_string "2")
11048         (const_string "*")))])
11050 (define_insn "*ashrsi3_one_bit_cmp_zext"
11051   [(set (reg FLAGS_REG)
11052         (compare
11053           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11054                        (match_operand:QI 2 "const1_operand" ""))
11055           (const_int 0)))
11056    (set (match_operand:DI 0 "register_operand" "=r")
11057         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11058   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11059    && (TARGET_SHIFT1 || optimize_size)
11060    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11061   "sar{l}\t%k0"
11062   [(set_attr "type" "ishift")
11063    (set_attr "length" "2")])
11065 ;; This pattern can't accept a variable shift count, since shifts by
11066 ;; zero don't affect the flags.  We assume that shifts by constant
11067 ;; zero are optimized away.
11068 (define_insn "*ashrsi3_cmp"
11069   [(set (reg FLAGS_REG)
11070         (compare
11071           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11072                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11073           (const_int 0)))
11074    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11075         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11076   "ix86_match_ccmode (insn, CCGOCmode)
11077    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11078   "sar{l}\t{%2, %0|%0, %2}"
11079   [(set_attr "type" "ishift")
11080    (set_attr "mode" "SI")])
11082 (define_insn "*ashrsi3_cmp_zext"
11083   [(set (reg FLAGS_REG)
11084         (compare
11085           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11086                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11087           (const_int 0)))
11088    (set (match_operand:DI 0 "register_operand" "=r")
11089         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11090   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11091    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11092   "sar{l}\t{%2, %k0|%k0, %2}"
11093   [(set_attr "type" "ishift")
11094    (set_attr "mode" "SI")])
11096 (define_expand "ashrhi3"
11097   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11098         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11099                      (match_operand:QI 2 "nonmemory_operand" "")))
11100    (clobber (reg:CC FLAGS_REG))]
11101   "TARGET_HIMODE_MATH"
11102   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11104 (define_insn "*ashrhi3_1_one_bit"
11105   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11106         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11107                      (match_operand:QI 2 "const1_operand" "")))
11108    (clobber (reg:CC FLAGS_REG))]
11109   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11110    && (TARGET_SHIFT1 || optimize_size)"
11111   "sar{w}\t%0"
11112   [(set_attr "type" "ishift")
11113    (set (attr "length") 
11114      (if_then_else (match_operand 0 "register_operand" "") 
11115         (const_string "2")
11116         (const_string "*")))])
11118 (define_insn "*ashrhi3_1"
11119   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11120         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11121                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11122    (clobber (reg:CC FLAGS_REG))]
11123   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11124   "@
11125    sar{w}\t{%2, %0|%0, %2}
11126    sar{w}\t{%b2, %0|%0, %b2}"
11127   [(set_attr "type" "ishift")
11128    (set_attr "mode" "HI")])
11130 ;; This pattern can't accept a variable shift count, since shifts by
11131 ;; zero don't affect the flags.  We assume that shifts by constant
11132 ;; zero are optimized away.
11133 (define_insn "*ashrhi3_one_bit_cmp"
11134   [(set (reg FLAGS_REG)
11135         (compare
11136           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11137                        (match_operand:QI 2 "const1_operand" ""))
11138           (const_int 0)))
11139    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11140         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11141   "ix86_match_ccmode (insn, CCGOCmode)
11142    && (TARGET_SHIFT1 || optimize_size)
11143    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11144   "sar{w}\t%0"
11145   [(set_attr "type" "ishift")
11146    (set (attr "length") 
11147      (if_then_else (match_operand 0 "register_operand" "") 
11148         (const_string "2")
11149         (const_string "*")))])
11151 ;; This pattern can't accept a variable shift count, since shifts by
11152 ;; zero don't affect the flags.  We assume that shifts by constant
11153 ;; zero are optimized away.
11154 (define_insn "*ashrhi3_cmp"
11155   [(set (reg FLAGS_REG)
11156         (compare
11157           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11158                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11159           (const_int 0)))
11160    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11161         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11162   "ix86_match_ccmode (insn, CCGOCmode)
11163    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11164   "sar{w}\t{%2, %0|%0, %2}"
11165   [(set_attr "type" "ishift")
11166    (set_attr "mode" "HI")])
11168 (define_expand "ashrqi3"
11169   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11170         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11171                      (match_operand:QI 2 "nonmemory_operand" "")))
11172    (clobber (reg:CC FLAGS_REG))]
11173   "TARGET_QIMODE_MATH"
11174   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11176 (define_insn "*ashrqi3_1_one_bit"
11177   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11178         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11179                      (match_operand:QI 2 "const1_operand" "")))
11180    (clobber (reg:CC FLAGS_REG))]
11181   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11182    && (TARGET_SHIFT1 || optimize_size)"
11183   "sar{b}\t%0"
11184   [(set_attr "type" "ishift")
11185    (set (attr "length") 
11186      (if_then_else (match_operand 0 "register_operand" "") 
11187         (const_string "2")
11188         (const_string "*")))])
11190 (define_insn "*ashrqi3_1_one_bit_slp"
11191   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11192         (ashiftrt:QI (match_dup 0)
11193                      (match_operand:QI 1 "const1_operand" "")))
11194    (clobber (reg:CC FLAGS_REG))]
11195   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11196    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11197    && (TARGET_SHIFT1 || optimize_size)"
11198   "sar{b}\t%0"
11199   [(set_attr "type" "ishift1")
11200    (set (attr "length") 
11201      (if_then_else (match_operand 0 "register_operand" "") 
11202         (const_string "2")
11203         (const_string "*")))])
11205 (define_insn "*ashrqi3_1"
11206   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11207         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11208                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11209    (clobber (reg:CC FLAGS_REG))]
11210   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11211   "@
11212    sar{b}\t{%2, %0|%0, %2}
11213    sar{b}\t{%b2, %0|%0, %b2}"
11214   [(set_attr "type" "ishift")
11215    (set_attr "mode" "QI")])
11217 (define_insn "*ashrqi3_1_slp"
11218   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11219         (ashiftrt:QI (match_dup 0)
11220                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11221    (clobber (reg:CC FLAGS_REG))]
11222   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11223    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11224   "@
11225    sar{b}\t{%1, %0|%0, %1}
11226    sar{b}\t{%b1, %0|%0, %b1}"
11227   [(set_attr "type" "ishift1")
11228    (set_attr "mode" "QI")])
11230 ;; This pattern can't accept a variable shift count, since shifts by
11231 ;; zero don't affect the flags.  We assume that shifts by constant
11232 ;; zero are optimized away.
11233 (define_insn "*ashrqi3_one_bit_cmp"
11234   [(set (reg FLAGS_REG)
11235         (compare
11236           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11237                        (match_operand:QI 2 "const1_operand" "I"))
11238           (const_int 0)))
11239    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11240         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11241   "ix86_match_ccmode (insn, CCGOCmode)
11242    && (TARGET_SHIFT1 || optimize_size)
11243    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11244   "sar{b}\t%0"
11245   [(set_attr "type" "ishift")
11246    (set (attr "length") 
11247      (if_then_else (match_operand 0 "register_operand" "") 
11248         (const_string "2")
11249         (const_string "*")))])
11251 ;; This pattern can't accept a variable shift count, since shifts by
11252 ;; zero don't affect the flags.  We assume that shifts by constant
11253 ;; zero are optimized away.
11254 (define_insn "*ashrqi3_cmp"
11255   [(set (reg FLAGS_REG)
11256         (compare
11257           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11258                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11259           (const_int 0)))
11260    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11261         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11262   "ix86_match_ccmode (insn, CCGOCmode)
11263    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11264   "sar{b}\t{%2, %0|%0, %2}"
11265   [(set_attr "type" "ishift")
11266    (set_attr "mode" "QI")])
11268 ;; Logical shift instructions
11270 ;; See comment above `ashldi3' about how this works.
11272 (define_expand "lshrdi3"
11273   [(set (match_operand:DI 0 "shiftdi_operand" "")
11274         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11275                      (match_operand:QI 2 "nonmemory_operand" "")))]
11276   ""
11277   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11279 (define_insn "*lshrdi3_1_one_bit_rex64"
11280   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11281         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11282                      (match_operand:QI 2 "const1_operand" "")))
11283    (clobber (reg:CC FLAGS_REG))]
11284   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11285    && (TARGET_SHIFT1 || optimize_size)"
11286   "shr{q}\t%0"
11287   [(set_attr "type" "ishift")
11288    (set (attr "length") 
11289      (if_then_else (match_operand:DI 0 "register_operand" "") 
11290         (const_string "2")
11291         (const_string "*")))])
11293 (define_insn "*lshrdi3_1_rex64"
11294   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11295         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11296                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11297    (clobber (reg:CC FLAGS_REG))]
11298   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11299   "@
11300    shr{q}\t{%2, %0|%0, %2}
11301    shr{q}\t{%b2, %0|%0, %b2}"
11302   [(set_attr "type" "ishift")
11303    (set_attr "mode" "DI")])
11305 ;; This pattern can't accept a variable shift count, since shifts by
11306 ;; zero don't affect the flags.  We assume that shifts by constant
11307 ;; zero are optimized away.
11308 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11309   [(set (reg FLAGS_REG)
11310         (compare
11311           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11312                        (match_operand:QI 2 "const1_operand" ""))
11313           (const_int 0)))
11314    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11315         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11316   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11317    && (TARGET_SHIFT1 || optimize_size)
11318    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11319   "shr{q}\t%0"
11320   [(set_attr "type" "ishift")
11321    (set (attr "length") 
11322      (if_then_else (match_operand:DI 0 "register_operand" "") 
11323         (const_string "2")
11324         (const_string "*")))])
11326 ;; This pattern can't accept a variable shift count, since shifts by
11327 ;; zero don't affect the flags.  We assume that shifts by constant
11328 ;; zero are optimized away.
11329 (define_insn "*lshrdi3_cmp_rex64"
11330   [(set (reg FLAGS_REG)
11331         (compare
11332           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11333                        (match_operand:QI 2 "const_int_operand" "e"))
11334           (const_int 0)))
11335    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11336         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11337   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11338    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11339   "shr{q}\t{%2, %0|%0, %2}"
11340   [(set_attr "type" "ishift")
11341    (set_attr "mode" "DI")])
11343 (define_insn "*lshrdi3_1"
11344   [(set (match_operand:DI 0 "register_operand" "=r")
11345         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11346                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11347    (clobber (reg:CC FLAGS_REG))]
11348   "!TARGET_64BIT"
11349   "#"
11350   [(set_attr "type" "multi")])
11352 ;; By default we don't ask for a scratch register, because when DImode
11353 ;; values are manipulated, registers are already at a premium.  But if
11354 ;; we have one handy, we won't turn it away.
11355 (define_peephole2
11356   [(match_scratch:SI 3 "r")
11357    (parallel [(set (match_operand:DI 0 "register_operand" "")
11358                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11359                                 (match_operand:QI 2 "nonmemory_operand" "")))
11360               (clobber (reg:CC FLAGS_REG))])
11361    (match_dup 3)]
11362   "!TARGET_64BIT && TARGET_CMOVE"
11363   [(const_int 0)]
11364   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11366 (define_split 
11367   [(set (match_operand:DI 0 "register_operand" "")
11368         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11369                      (match_operand:QI 2 "nonmemory_operand" "")))
11370    (clobber (reg:CC FLAGS_REG))]
11371   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11372   [(const_int 0)]
11373   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11375 (define_expand "lshrsi3"
11376   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11377         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11378                      (match_operand:QI 2 "nonmemory_operand" "")))
11379    (clobber (reg:CC FLAGS_REG))]
11380   ""
11381   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11383 (define_insn "*lshrsi3_1_one_bit"
11384   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11385         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11386                      (match_operand:QI 2 "const1_operand" "")))
11387    (clobber (reg:CC FLAGS_REG))]
11388   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11389    && (TARGET_SHIFT1 || optimize_size)"
11390   "shr{l}\t%0"
11391   [(set_attr "type" "ishift")
11392    (set (attr "length") 
11393      (if_then_else (match_operand:SI 0 "register_operand" "") 
11394         (const_string "2")
11395         (const_string "*")))])
11397 (define_insn "*lshrsi3_1_one_bit_zext"
11398   [(set (match_operand:DI 0 "register_operand" "=r")
11399         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11400                      (match_operand:QI 2 "const1_operand" "")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11403    && (TARGET_SHIFT1 || optimize_size)"
11404   "shr{l}\t%k0"
11405   [(set_attr "type" "ishift")
11406    (set_attr "length" "2")])
11408 (define_insn "*lshrsi3_1"
11409   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11410         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11411                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11412    (clobber (reg:CC FLAGS_REG))]
11413   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11414   "@
11415    shr{l}\t{%2, %0|%0, %2}
11416    shr{l}\t{%b2, %0|%0, %b2}"
11417   [(set_attr "type" "ishift")
11418    (set_attr "mode" "SI")])
11420 (define_insn "*lshrsi3_1_zext"
11421   [(set (match_operand:DI 0 "register_operand" "=r,r")
11422         (zero_extend:DI
11423           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11424                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11425    (clobber (reg:CC FLAGS_REG))]
11426   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11427   "@
11428    shr{l}\t{%2, %k0|%k0, %2}
11429    shr{l}\t{%b2, %k0|%k0, %b2}"
11430   [(set_attr "type" "ishift")
11431    (set_attr "mode" "SI")])
11433 ;; This pattern can't accept a variable shift count, since shifts by
11434 ;; zero don't affect the flags.  We assume that shifts by constant
11435 ;; zero are optimized away.
11436 (define_insn "*lshrsi3_one_bit_cmp"
11437   [(set (reg FLAGS_REG)
11438         (compare
11439           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11440                        (match_operand:QI 2 "const1_operand" ""))
11441           (const_int 0)))
11442    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11443         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11444   "ix86_match_ccmode (insn, CCGOCmode)
11445    && (TARGET_SHIFT1 || optimize_size)
11446    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11447   "shr{l}\t%0"
11448   [(set_attr "type" "ishift")
11449    (set (attr "length") 
11450      (if_then_else (match_operand:SI 0 "register_operand" "") 
11451         (const_string "2")
11452         (const_string "*")))])
11454 (define_insn "*lshrsi3_cmp_one_bit_zext"
11455   [(set (reg FLAGS_REG)
11456         (compare
11457           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11458                        (match_operand:QI 2 "const1_operand" ""))
11459           (const_int 0)))
11460    (set (match_operand:DI 0 "register_operand" "=r")
11461         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11462   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11463    && (TARGET_SHIFT1 || optimize_size)
11464    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11465   "shr{l}\t%k0"
11466   [(set_attr "type" "ishift")
11467    (set_attr "length" "2")])
11469 ;; This pattern can't accept a variable shift count, since shifts by
11470 ;; zero don't affect the flags.  We assume that shifts by constant
11471 ;; zero are optimized away.
11472 (define_insn "*lshrsi3_cmp"
11473   [(set (reg FLAGS_REG)
11474         (compare
11475           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11476                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11477           (const_int 0)))
11478    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11479         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11480   "ix86_match_ccmode (insn, CCGOCmode)
11481    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11482   "shr{l}\t{%2, %0|%0, %2}"
11483   [(set_attr "type" "ishift")
11484    (set_attr "mode" "SI")])
11486 (define_insn "*lshrsi3_cmp_zext"
11487   [(set (reg FLAGS_REG)
11488         (compare
11489           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11490                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11491           (const_int 0)))
11492    (set (match_operand:DI 0 "register_operand" "=r")
11493         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11494   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11495    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11496   "shr{l}\t{%2, %k0|%k0, %2}"
11497   [(set_attr "type" "ishift")
11498    (set_attr "mode" "SI")])
11500 (define_expand "lshrhi3"
11501   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11502         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11503                      (match_operand:QI 2 "nonmemory_operand" "")))
11504    (clobber (reg:CC FLAGS_REG))]
11505   "TARGET_HIMODE_MATH"
11506   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11508 (define_insn "*lshrhi3_1_one_bit"
11509   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11510         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11511                      (match_operand:QI 2 "const1_operand" "")))
11512    (clobber (reg:CC FLAGS_REG))]
11513   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11514    && (TARGET_SHIFT1 || optimize_size)"
11515   "shr{w}\t%0"
11516   [(set_attr "type" "ishift")
11517    (set (attr "length") 
11518      (if_then_else (match_operand 0 "register_operand" "") 
11519         (const_string "2")
11520         (const_string "*")))])
11522 (define_insn "*lshrhi3_1"
11523   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11524         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11525                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11526    (clobber (reg:CC FLAGS_REG))]
11527   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11528   "@
11529    shr{w}\t{%2, %0|%0, %2}
11530    shr{w}\t{%b2, %0|%0, %b2}"
11531   [(set_attr "type" "ishift")
11532    (set_attr "mode" "HI")])
11534 ;; This pattern can't accept a variable shift count, since shifts by
11535 ;; zero don't affect the flags.  We assume that shifts by constant
11536 ;; zero are optimized away.
11537 (define_insn "*lshrhi3_one_bit_cmp"
11538   [(set (reg FLAGS_REG)
11539         (compare
11540           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11541                        (match_operand:QI 2 "const1_operand" ""))
11542           (const_int 0)))
11543    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11544         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11545   "ix86_match_ccmode (insn, CCGOCmode)
11546    && (TARGET_SHIFT1 || optimize_size)
11547    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11548   "shr{w}\t%0"
11549   [(set_attr "type" "ishift")
11550    (set (attr "length") 
11551      (if_then_else (match_operand:SI 0 "register_operand" "") 
11552         (const_string "2")
11553         (const_string "*")))])
11555 ;; This pattern can't accept a variable shift count, since shifts by
11556 ;; zero don't affect the flags.  We assume that shifts by constant
11557 ;; zero are optimized away.
11558 (define_insn "*lshrhi3_cmp"
11559   [(set (reg FLAGS_REG)
11560         (compare
11561           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11562                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11563           (const_int 0)))
11564    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11565         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11566   "ix86_match_ccmode (insn, CCGOCmode)
11567    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11568   "shr{w}\t{%2, %0|%0, %2}"
11569   [(set_attr "type" "ishift")
11570    (set_attr "mode" "HI")])
11572 (define_expand "lshrqi3"
11573   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11574         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11575                      (match_operand:QI 2 "nonmemory_operand" "")))
11576    (clobber (reg:CC FLAGS_REG))]
11577   "TARGET_QIMODE_MATH"
11578   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11580 (define_insn "*lshrqi3_1_one_bit"
11581   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11582         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11583                      (match_operand:QI 2 "const1_operand" "")))
11584    (clobber (reg:CC FLAGS_REG))]
11585   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11586    && (TARGET_SHIFT1 || optimize_size)"
11587   "shr{b}\t%0"
11588   [(set_attr "type" "ishift")
11589    (set (attr "length") 
11590      (if_then_else (match_operand 0 "register_operand" "") 
11591         (const_string "2")
11592         (const_string "*")))])
11594 (define_insn "*lshrqi3_1_one_bit_slp"
11595   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11596         (lshiftrt:QI (match_dup 0)
11597                      (match_operand:QI 1 "const1_operand" "")))
11598    (clobber (reg:CC FLAGS_REG))]
11599   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11600    && (TARGET_SHIFT1 || optimize_size)"
11601   "shr{b}\t%0"
11602   [(set_attr "type" "ishift1")
11603    (set (attr "length") 
11604      (if_then_else (match_operand 0 "register_operand" "") 
11605         (const_string "2")
11606         (const_string "*")))])
11608 (define_insn "*lshrqi3_1"
11609   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11610         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11611                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11612    (clobber (reg:CC FLAGS_REG))]
11613   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11614   "@
11615    shr{b}\t{%2, %0|%0, %2}
11616    shr{b}\t{%b2, %0|%0, %b2}"
11617   [(set_attr "type" "ishift")
11618    (set_attr "mode" "QI")])
11620 (define_insn "*lshrqi3_1_slp"
11621   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11622         (lshiftrt:QI (match_dup 0)
11623                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11624    (clobber (reg:CC FLAGS_REG))]
11625   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11626    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11627   "@
11628    shr{b}\t{%1, %0|%0, %1}
11629    shr{b}\t{%b1, %0|%0, %b1}"
11630   [(set_attr "type" "ishift1")
11631    (set_attr "mode" "QI")])
11633 ;; This pattern can't accept a variable shift count, since shifts by
11634 ;; zero don't affect the flags.  We assume that shifts by constant
11635 ;; zero are optimized away.
11636 (define_insn "*lshrqi2_one_bit_cmp"
11637   [(set (reg FLAGS_REG)
11638         (compare
11639           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11640                        (match_operand:QI 2 "const1_operand" ""))
11641           (const_int 0)))
11642    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11643         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11644   "ix86_match_ccmode (insn, CCGOCmode)
11645    && (TARGET_SHIFT1 || optimize_size)
11646    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11647   "shr{b}\t%0"
11648   [(set_attr "type" "ishift")
11649    (set (attr "length") 
11650      (if_then_else (match_operand:SI 0 "register_operand" "") 
11651         (const_string "2")
11652         (const_string "*")))])
11654 ;; This pattern can't accept a variable shift count, since shifts by
11655 ;; zero don't affect the flags.  We assume that shifts by constant
11656 ;; zero are optimized away.
11657 (define_insn "*lshrqi2_cmp"
11658   [(set (reg FLAGS_REG)
11659         (compare
11660           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11661                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11662           (const_int 0)))
11663    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11664         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11665   "ix86_match_ccmode (insn, CCGOCmode)
11666    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11667   "shr{b}\t{%2, %0|%0, %2}"
11668   [(set_attr "type" "ishift")
11669    (set_attr "mode" "QI")])
11671 ;; Rotate instructions
11673 (define_expand "rotldi3"
11674   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11675         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11676                    (match_operand:QI 2 "nonmemory_operand" "")))
11677    (clobber (reg:CC FLAGS_REG))]
11678   "TARGET_64BIT"
11679   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11681 (define_insn "*rotlsi3_1_one_bit_rex64"
11682   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11683         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11684                    (match_operand:QI 2 "const1_operand" "")))
11685    (clobber (reg:CC FLAGS_REG))]
11686   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11687    && (TARGET_SHIFT1 || optimize_size)"
11688   "rol{q}\t%0"
11689   [(set_attr "type" "rotate")
11690    (set (attr "length") 
11691      (if_then_else (match_operand:DI 0 "register_operand" "") 
11692         (const_string "2")
11693         (const_string "*")))])
11695 (define_insn "*rotldi3_1_rex64"
11696   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11697         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11698                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11699    (clobber (reg:CC FLAGS_REG))]
11700   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11701   "@
11702    rol{q}\t{%2, %0|%0, %2}
11703    rol{q}\t{%b2, %0|%0, %b2}"
11704   [(set_attr "type" "rotate")
11705    (set_attr "mode" "DI")])
11707 (define_expand "rotlsi3"
11708   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11709         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11710                    (match_operand:QI 2 "nonmemory_operand" "")))
11711    (clobber (reg:CC FLAGS_REG))]
11712   ""
11713   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11715 (define_insn "*rotlsi3_1_one_bit"
11716   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11717         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11718                    (match_operand:QI 2 "const1_operand" "")))
11719    (clobber (reg:CC FLAGS_REG))]
11720   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11721    && (TARGET_SHIFT1 || optimize_size)"
11722   "rol{l}\t%0"
11723   [(set_attr "type" "rotate")
11724    (set (attr "length") 
11725      (if_then_else (match_operand:SI 0 "register_operand" "") 
11726         (const_string "2")
11727         (const_string "*")))])
11729 (define_insn "*rotlsi3_1_one_bit_zext"
11730   [(set (match_operand:DI 0 "register_operand" "=r")
11731         (zero_extend:DI
11732           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11733                      (match_operand:QI 2 "const1_operand" ""))))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11736    && (TARGET_SHIFT1 || optimize_size)"
11737   "rol{l}\t%k0"
11738   [(set_attr "type" "rotate")
11739    (set_attr "length" "2")])
11741 (define_insn "*rotlsi3_1"
11742   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11743         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11744                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11745    (clobber (reg:CC FLAGS_REG))]
11746   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11747   "@
11748    rol{l}\t{%2, %0|%0, %2}
11749    rol{l}\t{%b2, %0|%0, %b2}"
11750   [(set_attr "type" "rotate")
11751    (set_attr "mode" "SI")])
11753 (define_insn "*rotlsi3_1_zext"
11754   [(set (match_operand:DI 0 "register_operand" "=r,r")
11755         (zero_extend:DI
11756           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11757                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11758    (clobber (reg:CC FLAGS_REG))]
11759   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11760   "@
11761    rol{l}\t{%2, %k0|%k0, %2}
11762    rol{l}\t{%b2, %k0|%k0, %b2}"
11763   [(set_attr "type" "rotate")
11764    (set_attr "mode" "SI")])
11766 (define_expand "rotlhi3"
11767   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11768         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11769                    (match_operand:QI 2 "nonmemory_operand" "")))
11770    (clobber (reg:CC FLAGS_REG))]
11771   "TARGET_HIMODE_MATH"
11772   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11774 (define_insn "*rotlhi3_1_one_bit"
11775   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11776         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11777                    (match_operand:QI 2 "const1_operand" "")))
11778    (clobber (reg:CC FLAGS_REG))]
11779   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11780    && (TARGET_SHIFT1 || optimize_size)"
11781   "rol{w}\t%0"
11782   [(set_attr "type" "rotate")
11783    (set (attr "length") 
11784      (if_then_else (match_operand 0 "register_operand" "") 
11785         (const_string "2")
11786         (const_string "*")))])
11788 (define_insn "*rotlhi3_1"
11789   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11790         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11791                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11792    (clobber (reg:CC FLAGS_REG))]
11793   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11794   "@
11795    rol{w}\t{%2, %0|%0, %2}
11796    rol{w}\t{%b2, %0|%0, %b2}"
11797   [(set_attr "type" "rotate")
11798    (set_attr "mode" "HI")])
11800 (define_expand "rotlqi3"
11801   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11802         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11803                    (match_operand:QI 2 "nonmemory_operand" "")))
11804    (clobber (reg:CC FLAGS_REG))]
11805   "TARGET_QIMODE_MATH"
11806   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11808 (define_insn "*rotlqi3_1_one_bit_slp"
11809   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11810         (rotate:QI (match_dup 0)
11811                    (match_operand:QI 1 "const1_operand" "")))
11812    (clobber (reg:CC FLAGS_REG))]
11813   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11814    && (TARGET_SHIFT1 || optimize_size)"
11815   "rol{b}\t%0"
11816   [(set_attr "type" "rotate1")
11817    (set (attr "length") 
11818      (if_then_else (match_operand 0 "register_operand" "") 
11819         (const_string "2")
11820         (const_string "*")))])
11822 (define_insn "*rotlqi3_1_one_bit"
11823   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11824         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11825                    (match_operand:QI 2 "const1_operand" "")))
11826    (clobber (reg:CC FLAGS_REG))]
11827   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11828    && (TARGET_SHIFT1 || optimize_size)"
11829   "rol{b}\t%0"
11830   [(set_attr "type" "rotate")
11831    (set (attr "length") 
11832      (if_then_else (match_operand 0 "register_operand" "") 
11833         (const_string "2")
11834         (const_string "*")))])
11836 (define_insn "*rotlqi3_1_slp"
11837   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11838         (rotate:QI (match_dup 0)
11839                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11840    (clobber (reg:CC FLAGS_REG))]
11841   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11842    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11843   "@
11844    rol{b}\t{%1, %0|%0, %1}
11845    rol{b}\t{%b1, %0|%0, %b1}"
11846   [(set_attr "type" "rotate1")
11847    (set_attr "mode" "QI")])
11849 (define_insn "*rotlqi3_1"
11850   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11851         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11852                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11855   "@
11856    rol{b}\t{%2, %0|%0, %2}
11857    rol{b}\t{%b2, %0|%0, %b2}"
11858   [(set_attr "type" "rotate")
11859    (set_attr "mode" "QI")])
11861 (define_expand "rotrdi3"
11862   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11863         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11864                      (match_operand:QI 2 "nonmemory_operand" "")))
11865    (clobber (reg:CC FLAGS_REG))]
11866   "TARGET_64BIT"
11867   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11869 (define_insn "*rotrdi3_1_one_bit_rex64"
11870   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11871         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11872                      (match_operand:QI 2 "const1_operand" "")))
11873    (clobber (reg:CC FLAGS_REG))]
11874   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11875    && (TARGET_SHIFT1 || optimize_size)"
11876   "ror{q}\t%0"
11877   [(set_attr "type" "rotate")
11878    (set (attr "length") 
11879      (if_then_else (match_operand:DI 0 "register_operand" "") 
11880         (const_string "2")
11881         (const_string "*")))])
11883 (define_insn "*rotrdi3_1_rex64"
11884   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11885         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11886                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11887    (clobber (reg:CC FLAGS_REG))]
11888   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11889   "@
11890    ror{q}\t{%2, %0|%0, %2}
11891    ror{q}\t{%b2, %0|%0, %b2}"
11892   [(set_attr "type" "rotate")
11893    (set_attr "mode" "DI")])
11895 (define_expand "rotrsi3"
11896   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11897         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11898                      (match_operand:QI 2 "nonmemory_operand" "")))
11899    (clobber (reg:CC FLAGS_REG))]
11900   ""
11901   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11903 (define_insn "*rotrsi3_1_one_bit"
11904   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11905         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11906                      (match_operand:QI 2 "const1_operand" "")))
11907    (clobber (reg:CC FLAGS_REG))]
11908   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11909    && (TARGET_SHIFT1 || optimize_size)"
11910   "ror{l}\t%0"
11911   [(set_attr "type" "rotate")
11912    (set (attr "length") 
11913      (if_then_else (match_operand:SI 0 "register_operand" "") 
11914         (const_string "2")
11915         (const_string "*")))])
11917 (define_insn "*rotrsi3_1_one_bit_zext"
11918   [(set (match_operand:DI 0 "register_operand" "=r")
11919         (zero_extend:DI
11920           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11921                        (match_operand:QI 2 "const1_operand" ""))))
11922    (clobber (reg:CC FLAGS_REG))]
11923   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11924    && (TARGET_SHIFT1 || optimize_size)"
11925   "ror{l}\t%k0"
11926   [(set_attr "type" "rotate")
11927    (set (attr "length") 
11928      (if_then_else (match_operand:SI 0 "register_operand" "") 
11929         (const_string "2")
11930         (const_string "*")))])
11932 (define_insn "*rotrsi3_1"
11933   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11934         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11935                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11936    (clobber (reg:CC FLAGS_REG))]
11937   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11938   "@
11939    ror{l}\t{%2, %0|%0, %2}
11940    ror{l}\t{%b2, %0|%0, %b2}"
11941   [(set_attr "type" "rotate")
11942    (set_attr "mode" "SI")])
11944 (define_insn "*rotrsi3_1_zext"
11945   [(set (match_operand:DI 0 "register_operand" "=r,r")
11946         (zero_extend:DI
11947           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11948                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11949    (clobber (reg:CC FLAGS_REG))]
11950   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11951   "@
11952    ror{l}\t{%2, %k0|%k0, %2}
11953    ror{l}\t{%b2, %k0|%k0, %b2}"
11954   [(set_attr "type" "rotate")
11955    (set_attr "mode" "SI")])
11957 (define_expand "rotrhi3"
11958   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11959         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11960                      (match_operand:QI 2 "nonmemory_operand" "")))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "TARGET_HIMODE_MATH"
11963   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11965 (define_insn "*rotrhi3_one_bit"
11966   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11967         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11968                      (match_operand:QI 2 "const1_operand" "")))
11969    (clobber (reg:CC FLAGS_REG))]
11970   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11971    && (TARGET_SHIFT1 || optimize_size)"
11972   "ror{w}\t%0"
11973   [(set_attr "type" "rotate")
11974    (set (attr "length") 
11975      (if_then_else (match_operand 0 "register_operand" "") 
11976         (const_string "2")
11977         (const_string "*")))])
11979 (define_insn "*rotrhi3"
11980   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11981         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11982                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11983    (clobber (reg:CC FLAGS_REG))]
11984   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11985   "@
11986    ror{w}\t{%2, %0|%0, %2}
11987    ror{w}\t{%b2, %0|%0, %b2}"
11988   [(set_attr "type" "rotate")
11989    (set_attr "mode" "HI")])
11991 (define_expand "rotrqi3"
11992   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11993         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11994                      (match_operand:QI 2 "nonmemory_operand" "")))
11995    (clobber (reg:CC FLAGS_REG))]
11996   "TARGET_QIMODE_MATH"
11997   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
11999 (define_insn "*rotrqi3_1_one_bit"
12000   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12001         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12002                      (match_operand:QI 2 "const1_operand" "")))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12005    && (TARGET_SHIFT1 || optimize_size)"
12006   "ror{b}\t%0"
12007   [(set_attr "type" "rotate")
12008    (set (attr "length") 
12009      (if_then_else (match_operand 0 "register_operand" "") 
12010         (const_string "2")
12011         (const_string "*")))])
12013 (define_insn "*rotrqi3_1_one_bit_slp"
12014   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12015         (rotatert:QI (match_dup 0)
12016                      (match_operand:QI 1 "const1_operand" "")))
12017    (clobber (reg:CC FLAGS_REG))]
12018   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12019    && (TARGET_SHIFT1 || optimize_size)"
12020   "ror{b}\t%0"
12021   [(set_attr "type" "rotate1")
12022    (set (attr "length") 
12023      (if_then_else (match_operand 0 "register_operand" "") 
12024         (const_string "2")
12025         (const_string "*")))])
12027 (define_insn "*rotrqi3_1"
12028   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12029         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12030                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12031    (clobber (reg:CC FLAGS_REG))]
12032   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12033   "@
12034    ror{b}\t{%2, %0|%0, %2}
12035    ror{b}\t{%b2, %0|%0, %b2}"
12036   [(set_attr "type" "rotate")
12037    (set_attr "mode" "QI")])
12039 (define_insn "*rotrqi3_1_slp"
12040   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12041         (rotatert:QI (match_dup 0)
12042                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12043    (clobber (reg:CC FLAGS_REG))]
12044   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12045    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12046   "@
12047    ror{b}\t{%1, %0|%0, %1}
12048    ror{b}\t{%b1, %0|%0, %b1}"
12049   [(set_attr "type" "rotate1")
12050    (set_attr "mode" "QI")])
12052 ;; Bit set / bit test instructions
12054 (define_expand "extv"
12055   [(set (match_operand:SI 0 "register_operand" "")
12056         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12057                          (match_operand:SI 2 "immediate_operand" "")
12058                          (match_operand:SI 3 "immediate_operand" "")))]
12059   ""
12061   /* Handle extractions from %ah et al.  */
12062   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12063     FAIL;
12065   /* From mips.md: extract_bit_field doesn't verify that our source
12066      matches the predicate, so check it again here.  */
12067   if (! ext_register_operand (operands[1], VOIDmode))
12068     FAIL;
12071 (define_expand "extzv"
12072   [(set (match_operand:SI 0 "register_operand" "")
12073         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12074                          (match_operand:SI 2 "immediate_operand" "")
12075                          (match_operand:SI 3 "immediate_operand" "")))]
12076   ""
12078   /* Handle extractions from %ah et al.  */
12079   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12080     FAIL;
12082   /* From mips.md: extract_bit_field doesn't verify that our source
12083      matches the predicate, so check it again here.  */
12084   if (! ext_register_operand (operands[1], VOIDmode))
12085     FAIL;
12088 (define_expand "insv"
12089   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12090                       (match_operand 1 "immediate_operand" "")
12091                       (match_operand 2 "immediate_operand" ""))
12092         (match_operand 3 "register_operand" ""))]
12093   ""
12095   /* Handle extractions from %ah et al.  */
12096   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12097     FAIL;
12099   /* From mips.md: insert_bit_field doesn't verify that our source
12100      matches the predicate, so check it again here.  */
12101   if (! ext_register_operand (operands[0], VOIDmode))
12102     FAIL;
12104   if (TARGET_64BIT)
12105     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12106   else
12107     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12109   DONE;
12112 ;; %%% bts, btr, btc, bt.
12113 ;; In general these instructions are *slow* when applied to memory,
12114 ;; since they enforce atomic operation.  When applied to registers,
12115 ;; it depends on the cpu implementation.  They're never faster than
12116 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12117 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12118 ;; within the instruction itself, so operating on bits in the high
12119 ;; 32-bits of a register becomes easier.
12121 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12122 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12123 ;; negdf respectively, so they can never be disabled entirely.
12125 (define_insn "*btsq"
12126   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12127                          (const_int 1)
12128                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12129         (const_int 1))
12130    (clobber (reg:CC FLAGS_REG))]
12131   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12132   "bts{q} %1,%0"
12133   [(set_attr "type" "alu1")])
12135 (define_insn "*btrq"
12136   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12137                          (const_int 1)
12138                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12139         (const_int 0))
12140    (clobber (reg:CC FLAGS_REG))]
12141   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12142   "btr{q} %1,%0"
12143   [(set_attr "type" "alu1")])
12145 (define_insn "*btcq"
12146   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12147                          (const_int 1)
12148                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12149         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12150    (clobber (reg:CC FLAGS_REG))]
12151   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12152   "btc{q} %1,%0"
12153   [(set_attr "type" "alu1")])
12155 ;; Allow Nocona to avoid these instructions if a register is available.
12157 (define_peephole2
12158   [(match_scratch:DI 2 "r")
12159    (parallel [(set (zero_extract:DI
12160                      (match_operand:DI 0 "register_operand" "")
12161                      (const_int 1)
12162                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12163                    (const_int 1))
12164               (clobber (reg:CC FLAGS_REG))])]
12165   "TARGET_64BIT && !TARGET_USE_BT"
12166   [(const_int 0)]
12168   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12169   rtx op1;
12171   if (HOST_BITS_PER_WIDE_INT >= 64)
12172     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12173   else if (i < HOST_BITS_PER_WIDE_INT)
12174     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12175   else
12176     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12178   op1 = immed_double_const (lo, hi, DImode);
12179   if (i >= 31)
12180     {
12181       emit_move_insn (operands[2], op1);
12182       op1 = operands[2];
12183     }
12185   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12186   DONE;
12189 (define_peephole2
12190   [(match_scratch:DI 2 "r")
12191    (parallel [(set (zero_extract:DI
12192                      (match_operand:DI 0 "register_operand" "")
12193                      (const_int 1)
12194                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12195                    (const_int 0))
12196               (clobber (reg:CC FLAGS_REG))])]
12197   "TARGET_64BIT && !TARGET_USE_BT"
12198   [(const_int 0)]
12200   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12201   rtx op1;
12203   if (HOST_BITS_PER_WIDE_INT >= 64)
12204     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12205   else if (i < HOST_BITS_PER_WIDE_INT)
12206     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12207   else
12208     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12210   op1 = immed_double_const (~lo, ~hi, DImode);
12211   if (i >= 32)
12212     {
12213       emit_move_insn (operands[2], op1);
12214       op1 = operands[2];
12215     }
12217   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12218   DONE;
12221 (define_peephole2
12222   [(match_scratch:DI 2 "r")
12223    (parallel [(set (zero_extract:DI
12224                      (match_operand:DI 0 "register_operand" "")
12225                      (const_int 1)
12226                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12227               (not:DI (zero_extract:DI
12228                         (match_dup 0) (const_int 1) (match_dup 1))))
12229               (clobber (reg:CC FLAGS_REG))])]
12230   "TARGET_64BIT && !TARGET_USE_BT"
12231   [(const_int 0)]
12233   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12234   rtx op1;
12236   if (HOST_BITS_PER_WIDE_INT >= 64)
12237     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12238   else if (i < HOST_BITS_PER_WIDE_INT)
12239     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12240   else
12241     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12243   op1 = immed_double_const (lo, hi, DImode);
12244   if (i >= 31)
12245     {
12246       emit_move_insn (operands[2], op1);
12247       op1 = operands[2];
12248     }
12250   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12251   DONE;
12254 ;; Store-flag instructions.
12256 ;; For all sCOND expanders, also expand the compare or test insn that
12257 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12259 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12260 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12261 ;; way, which can later delete the movzx if only QImode is needed.
12263 (define_expand "seq"
12264   [(set (match_operand:QI 0 "register_operand" "")
12265         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12266   ""
12267   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12269 (define_expand "sne"
12270   [(set (match_operand:QI 0 "register_operand" "")
12271         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12272   ""
12273   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12275 (define_expand "sgt"
12276   [(set (match_operand:QI 0 "register_operand" "")
12277         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12278   ""
12279   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12281 (define_expand "sgtu"
12282   [(set (match_operand:QI 0 "register_operand" "")
12283         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12284   ""
12285   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12287 (define_expand "slt"
12288   [(set (match_operand:QI 0 "register_operand" "")
12289         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12290   ""
12291   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12293 (define_expand "sltu"
12294   [(set (match_operand:QI 0 "register_operand" "")
12295         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12296   ""
12297   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12299 (define_expand "sge"
12300   [(set (match_operand:QI 0 "register_operand" "")
12301         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12302   ""
12303   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12305 (define_expand "sgeu"
12306   [(set (match_operand:QI 0 "register_operand" "")
12307         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12308   ""
12309   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12311 (define_expand "sle"
12312   [(set (match_operand:QI 0 "register_operand" "")
12313         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12314   ""
12315   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12317 (define_expand "sleu"
12318   [(set (match_operand:QI 0 "register_operand" "")
12319         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12320   ""
12321   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12323 (define_expand "sunordered"
12324   [(set (match_operand:QI 0 "register_operand" "")
12325         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12326   "TARGET_80387 || TARGET_SSE"
12327   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12329 (define_expand "sordered"
12330   [(set (match_operand:QI 0 "register_operand" "")
12331         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12332   "TARGET_80387"
12333   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12335 (define_expand "suneq"
12336   [(set (match_operand:QI 0 "register_operand" "")
12337         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12338   "TARGET_80387 || TARGET_SSE"
12339   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12341 (define_expand "sunge"
12342   [(set (match_operand:QI 0 "register_operand" "")
12343         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12344   "TARGET_80387 || TARGET_SSE"
12345   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12347 (define_expand "sungt"
12348   [(set (match_operand:QI 0 "register_operand" "")
12349         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12350   "TARGET_80387 || TARGET_SSE"
12351   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12353 (define_expand "sunle"
12354   [(set (match_operand:QI 0 "register_operand" "")
12355         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12356   "TARGET_80387 || TARGET_SSE"
12357   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12359 (define_expand "sunlt"
12360   [(set (match_operand:QI 0 "register_operand" "")
12361         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12362   "TARGET_80387 || TARGET_SSE"
12363   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12365 (define_expand "sltgt"
12366   [(set (match_operand:QI 0 "register_operand" "")
12367         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12368   "TARGET_80387 || TARGET_SSE"
12369   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12371 (define_insn "*setcc_1"
12372   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12373         (match_operator:QI 1 "ix86_comparison_operator"
12374           [(reg FLAGS_REG) (const_int 0)]))]
12375   ""
12376   "set%C1\t%0"
12377   [(set_attr "type" "setcc")
12378    (set_attr "mode" "QI")])
12380 (define_insn "*setcc_2"
12381   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12382         (match_operator:QI 1 "ix86_comparison_operator"
12383           [(reg FLAGS_REG) (const_int 0)]))]
12384   ""
12385   "set%C1\t%0"
12386   [(set_attr "type" "setcc")
12387    (set_attr "mode" "QI")])
12389 ;; In general it is not safe to assume too much about CCmode registers,
12390 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12391 ;; conditions this is safe on x86, so help combine not create
12393 ;;      seta    %al
12394 ;;      testb   %al, %al
12395 ;;      sete    %al
12397 (define_split 
12398   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12399         (ne:QI (match_operator 1 "ix86_comparison_operator"
12400                  [(reg FLAGS_REG) (const_int 0)])
12401             (const_int 0)))]
12402   ""
12403   [(set (match_dup 0) (match_dup 1))]
12405   PUT_MODE (operands[1], QImode);
12408 (define_split 
12409   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12410         (ne:QI (match_operator 1 "ix86_comparison_operator"
12411                  [(reg FLAGS_REG) (const_int 0)])
12412             (const_int 0)))]
12413   ""
12414   [(set (match_dup 0) (match_dup 1))]
12416   PUT_MODE (operands[1], QImode);
12419 (define_split 
12420   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12421         (eq:QI (match_operator 1 "ix86_comparison_operator"
12422                  [(reg FLAGS_REG) (const_int 0)])
12423             (const_int 0)))]
12424   ""
12425   [(set (match_dup 0) (match_dup 1))]
12427   rtx new_op1 = copy_rtx (operands[1]);
12428   operands[1] = new_op1;
12429   PUT_MODE (new_op1, QImode);
12430   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12431                                              GET_MODE (XEXP (new_op1, 0))));
12433   /* Make sure that (a) the CCmode we have for the flags is strong
12434      enough for the reversed compare or (b) we have a valid FP compare.  */
12435   if (! ix86_comparison_operator (new_op1, VOIDmode))
12436     FAIL;
12439 (define_split 
12440   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12441         (eq:QI (match_operator 1 "ix86_comparison_operator"
12442                  [(reg FLAGS_REG) (const_int 0)])
12443             (const_int 0)))]
12444   ""
12445   [(set (match_dup 0) (match_dup 1))]
12447   rtx new_op1 = copy_rtx (operands[1]);
12448   operands[1] = new_op1;
12449   PUT_MODE (new_op1, QImode);
12450   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12451                                              GET_MODE (XEXP (new_op1, 0))));
12453   /* Make sure that (a) the CCmode we have for the flags is strong
12454      enough for the reversed compare or (b) we have a valid FP compare.  */
12455   if (! ix86_comparison_operator (new_op1, VOIDmode))
12456     FAIL;
12459 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12460 ;; subsequent logical operations are used to imitate conditional moves.
12461 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12462 ;; it directly.  Further holding this value in pseudo register might bring
12463 ;; problem in implicit normalization in spill code.
12464 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12465 ;; instructions after reload by splitting the conditional move patterns.
12467 (define_insn "*sse_setccsf"
12468   [(set (match_operand:SF 0 "register_operand" "=x")
12469         (match_operator:SF 1 "sse_comparison_operator"
12470           [(match_operand:SF 2 "register_operand" "0")
12471            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12472   "TARGET_SSE && reload_completed"
12473   "cmp%D1ss\t{%3, %0|%0, %3}"
12474   [(set_attr "type" "ssecmp")
12475    (set_attr "mode" "SF")])
12477 (define_insn "*sse_setccdf"
12478   [(set (match_operand:DF 0 "register_operand" "=Y")
12479         (match_operator:DF 1 "sse_comparison_operator"
12480           [(match_operand:DF 2 "register_operand" "0")
12481            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12482   "TARGET_SSE2 && reload_completed"
12483   "cmp%D1sd\t{%3, %0|%0, %3}"
12484   [(set_attr "type" "ssecmp")
12485    (set_attr "mode" "DF")])
12487 ;; Basic conditional jump instructions.
12488 ;; We ignore the overflow flag for signed branch instructions.
12490 ;; For all bCOND expanders, also expand the compare or test insn that
12491 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12493 (define_expand "beq"
12494   [(set (pc)
12495         (if_then_else (match_dup 1)
12496                       (label_ref (match_operand 0 "" ""))
12497                       (pc)))]
12498   ""
12499   "ix86_expand_branch (EQ, operands[0]); DONE;")
12501 (define_expand "bne"
12502   [(set (pc)
12503         (if_then_else (match_dup 1)
12504                       (label_ref (match_operand 0 "" ""))
12505                       (pc)))]
12506   ""
12507   "ix86_expand_branch (NE, operands[0]); DONE;")
12509 (define_expand "bgt"
12510   [(set (pc)
12511         (if_then_else (match_dup 1)
12512                       (label_ref (match_operand 0 "" ""))
12513                       (pc)))]
12514   ""
12515   "ix86_expand_branch (GT, operands[0]); DONE;")
12517 (define_expand "bgtu"
12518   [(set (pc)
12519         (if_then_else (match_dup 1)
12520                       (label_ref (match_operand 0 "" ""))
12521                       (pc)))]
12522   ""
12523   "ix86_expand_branch (GTU, operands[0]); DONE;")
12525 (define_expand "blt"
12526   [(set (pc)
12527         (if_then_else (match_dup 1)
12528                       (label_ref (match_operand 0 "" ""))
12529                       (pc)))]
12530   ""
12531   "ix86_expand_branch (LT, operands[0]); DONE;")
12533 (define_expand "bltu"
12534   [(set (pc)
12535         (if_then_else (match_dup 1)
12536                       (label_ref (match_operand 0 "" ""))
12537                       (pc)))]
12538   ""
12539   "ix86_expand_branch (LTU, operands[0]); DONE;")
12541 (define_expand "bge"
12542   [(set (pc)
12543         (if_then_else (match_dup 1)
12544                       (label_ref (match_operand 0 "" ""))
12545                       (pc)))]
12546   ""
12547   "ix86_expand_branch (GE, operands[0]); DONE;")
12549 (define_expand "bgeu"
12550   [(set (pc)
12551         (if_then_else (match_dup 1)
12552                       (label_ref (match_operand 0 "" ""))
12553                       (pc)))]
12554   ""
12555   "ix86_expand_branch (GEU, operands[0]); DONE;")
12557 (define_expand "ble"
12558   [(set (pc)
12559         (if_then_else (match_dup 1)
12560                       (label_ref (match_operand 0 "" ""))
12561                       (pc)))]
12562   ""
12563   "ix86_expand_branch (LE, operands[0]); DONE;")
12565 (define_expand "bleu"
12566   [(set (pc)
12567         (if_then_else (match_dup 1)
12568                       (label_ref (match_operand 0 "" ""))
12569                       (pc)))]
12570   ""
12571   "ix86_expand_branch (LEU, operands[0]); DONE;")
12573 (define_expand "bunordered"
12574   [(set (pc)
12575         (if_then_else (match_dup 1)
12576                       (label_ref (match_operand 0 "" ""))
12577                       (pc)))]
12578   "TARGET_80387 || TARGET_SSE_MATH"
12579   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12581 (define_expand "bordered"
12582   [(set (pc)
12583         (if_then_else (match_dup 1)
12584                       (label_ref (match_operand 0 "" ""))
12585                       (pc)))]
12586   "TARGET_80387 || TARGET_SSE_MATH"
12587   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12589 (define_expand "buneq"
12590   [(set (pc)
12591         (if_then_else (match_dup 1)
12592                       (label_ref (match_operand 0 "" ""))
12593                       (pc)))]
12594   "TARGET_80387 || TARGET_SSE_MATH"
12595   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12597 (define_expand "bunge"
12598   [(set (pc)
12599         (if_then_else (match_dup 1)
12600                       (label_ref (match_operand 0 "" ""))
12601                       (pc)))]
12602   "TARGET_80387 || TARGET_SSE_MATH"
12603   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12605 (define_expand "bungt"
12606   [(set (pc)
12607         (if_then_else (match_dup 1)
12608                       (label_ref (match_operand 0 "" ""))
12609                       (pc)))]
12610   "TARGET_80387 || TARGET_SSE_MATH"
12611   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12613 (define_expand "bunle"
12614   [(set (pc)
12615         (if_then_else (match_dup 1)
12616                       (label_ref (match_operand 0 "" ""))
12617                       (pc)))]
12618   "TARGET_80387 || TARGET_SSE_MATH"
12619   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12621 (define_expand "bunlt"
12622   [(set (pc)
12623         (if_then_else (match_dup 1)
12624                       (label_ref (match_operand 0 "" ""))
12625                       (pc)))]
12626   "TARGET_80387 || TARGET_SSE_MATH"
12627   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12629 (define_expand "bltgt"
12630   [(set (pc)
12631         (if_then_else (match_dup 1)
12632                       (label_ref (match_operand 0 "" ""))
12633                       (pc)))]
12634   "TARGET_80387 || TARGET_SSE_MATH"
12635   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12637 (define_insn "*jcc_1"
12638   [(set (pc)
12639         (if_then_else (match_operator 1 "ix86_comparison_operator"
12640                                       [(reg FLAGS_REG) (const_int 0)])
12641                       (label_ref (match_operand 0 "" ""))
12642                       (pc)))]
12643   ""
12644   "%+j%C1\t%l0"
12645   [(set_attr "type" "ibr")
12646    (set_attr "modrm" "0")
12647    (set (attr "length")
12648            (if_then_else (and (ge (minus (match_dup 0) (pc))
12649                                   (const_int -126))
12650                               (lt (minus (match_dup 0) (pc))
12651                                   (const_int 128)))
12652              (const_int 2)
12653              (const_int 6)))])
12655 (define_insn "*jcc_2"
12656   [(set (pc)
12657         (if_then_else (match_operator 1 "ix86_comparison_operator"
12658                                       [(reg FLAGS_REG) (const_int 0)])
12659                       (pc)
12660                       (label_ref (match_operand 0 "" ""))))]
12661   ""
12662   "%+j%c1\t%l0"
12663   [(set_attr "type" "ibr")
12664    (set_attr "modrm" "0")
12665    (set (attr "length")
12666            (if_then_else (and (ge (minus (match_dup 0) (pc))
12667                                   (const_int -126))
12668                               (lt (minus (match_dup 0) (pc))
12669                                   (const_int 128)))
12670              (const_int 2)
12671              (const_int 6)))])
12673 ;; In general it is not safe to assume too much about CCmode registers,
12674 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12675 ;; conditions this is safe on x86, so help combine not create
12677 ;;      seta    %al
12678 ;;      testb   %al, %al
12679 ;;      je      Lfoo
12681 (define_split 
12682   [(set (pc)
12683         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12684                                       [(reg FLAGS_REG) (const_int 0)])
12685                           (const_int 0))
12686                       (label_ref (match_operand 1 "" ""))
12687                       (pc)))]
12688   ""
12689   [(set (pc)
12690         (if_then_else (match_dup 0)
12691                       (label_ref (match_dup 1))
12692                       (pc)))]
12694   PUT_MODE (operands[0], VOIDmode);
12696   
12697 (define_split 
12698   [(set (pc)
12699         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12700                                       [(reg FLAGS_REG) (const_int 0)])
12701                           (const_int 0))
12702                       (label_ref (match_operand 1 "" ""))
12703                       (pc)))]
12704   ""
12705   [(set (pc)
12706         (if_then_else (match_dup 0)
12707                       (label_ref (match_dup 1))
12708                       (pc)))]
12710   rtx new_op0 = copy_rtx (operands[0]);
12711   operands[0] = new_op0;
12712   PUT_MODE (new_op0, VOIDmode);
12713   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12714                                              GET_MODE (XEXP (new_op0, 0))));
12716   /* Make sure that (a) the CCmode we have for the flags is strong
12717      enough for the reversed compare or (b) we have a valid FP compare.  */
12718   if (! ix86_comparison_operator (new_op0, VOIDmode))
12719     FAIL;
12722 ;; Define combination compare-and-branch fp compare instructions to use
12723 ;; during early optimization.  Splitting the operation apart early makes
12724 ;; for bad code when we want to reverse the operation.
12726 (define_insn "*fp_jcc_1_mixed"
12727   [(set (pc)
12728         (if_then_else (match_operator 0 "comparison_operator"
12729                         [(match_operand 1 "register_operand" "f#x,x#f")
12730                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12731           (label_ref (match_operand 3 "" ""))
12732           (pc)))
12733    (clobber (reg:CCFP FPSR_REG))
12734    (clobber (reg:CCFP FLAGS_REG))]
12735   "TARGET_MIX_SSE_I387
12736    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12737    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12738    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12739   "#")
12741 (define_insn "*fp_jcc_1_sse"
12742   [(set (pc)
12743         (if_then_else (match_operator 0 "comparison_operator"
12744                         [(match_operand 1 "register_operand" "x")
12745                          (match_operand 2 "nonimmediate_operand" "xm")])
12746           (label_ref (match_operand 3 "" ""))
12747           (pc)))
12748    (clobber (reg:CCFP FPSR_REG))
12749    (clobber (reg:CCFP FLAGS_REG))]
12750   "TARGET_SSE_MATH
12751    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12752    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12753    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12754   "#")
12756 (define_insn "*fp_jcc_1_387"
12757   [(set (pc)
12758         (if_then_else (match_operator 0 "comparison_operator"
12759                         [(match_operand 1 "register_operand" "f")
12760                          (match_operand 2 "register_operand" "f")])
12761           (label_ref (match_operand 3 "" ""))
12762           (pc)))
12763    (clobber (reg:CCFP FPSR_REG))
12764    (clobber (reg:CCFP FLAGS_REG))]
12765   "TARGET_CMOVE && TARGET_80387
12766    && FLOAT_MODE_P (GET_MODE (operands[1]))
12767    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12768    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12769   "#")
12771 (define_insn "*fp_jcc_2_mixed"
12772   [(set (pc)
12773         (if_then_else (match_operator 0 "comparison_operator"
12774                         [(match_operand 1 "register_operand" "f#x,x#f")
12775                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12776           (pc)
12777           (label_ref (match_operand 3 "" ""))))
12778    (clobber (reg:CCFP FPSR_REG))
12779    (clobber (reg:CCFP FLAGS_REG))]
12780   "TARGET_MIX_SSE_I387
12781    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12782    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12783    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12784   "#")
12786 (define_insn "*fp_jcc_2_sse"
12787   [(set (pc)
12788         (if_then_else (match_operator 0 "comparison_operator"
12789                         [(match_operand 1 "register_operand" "x")
12790                          (match_operand 2 "nonimmediate_operand" "xm")])
12791           (pc)
12792           (label_ref (match_operand 3 "" ""))))
12793    (clobber (reg:CCFP FPSR_REG))
12794    (clobber (reg:CCFP FLAGS_REG))]
12795   "TARGET_SSE_MATH
12796    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12797    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12798    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12799   "#")
12801 (define_insn "*fp_jcc_2_387"
12802   [(set (pc)
12803         (if_then_else (match_operator 0 "comparison_operator"
12804                         [(match_operand 1 "register_operand" "f")
12805                          (match_operand 2 "register_operand" "f")])
12806           (pc)
12807           (label_ref (match_operand 3 "" ""))))
12808    (clobber (reg:CCFP FPSR_REG))
12809    (clobber (reg:CCFP FLAGS_REG))]
12810   "TARGET_CMOVE && TARGET_80387
12811    && FLOAT_MODE_P (GET_MODE (operands[1]))
12812    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12813    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12814   "#")
12816 (define_insn "*fp_jcc_3_387"
12817   [(set (pc)
12818         (if_then_else (match_operator 0 "comparison_operator"
12819                         [(match_operand 1 "register_operand" "f")
12820                          (match_operand 2 "nonimmediate_operand" "fm")])
12821           (label_ref (match_operand 3 "" ""))
12822           (pc)))
12823    (clobber (reg:CCFP FPSR_REG))
12824    (clobber (reg:CCFP FLAGS_REG))
12825    (clobber (match_scratch:HI 4 "=a"))]
12826   "TARGET_80387
12827    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12828    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12829    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12830    && SELECT_CC_MODE (GET_CODE (operands[0]),
12831                       operands[1], operands[2]) == CCFPmode
12832    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12833   "#")
12835 (define_insn "*fp_jcc_4_387"
12836   [(set (pc)
12837         (if_then_else (match_operator 0 "comparison_operator"
12838                         [(match_operand 1 "register_operand" "f")
12839                          (match_operand 2 "nonimmediate_operand" "fm")])
12840           (pc)
12841           (label_ref (match_operand 3 "" ""))))
12842    (clobber (reg:CCFP FPSR_REG))
12843    (clobber (reg:CCFP FLAGS_REG))
12844    (clobber (match_scratch:HI 4 "=a"))]
12845   "TARGET_80387
12846    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12847    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12848    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12849    && SELECT_CC_MODE (GET_CODE (operands[0]),
12850                       operands[1], operands[2]) == CCFPmode
12851    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12852   "#")
12854 (define_insn "*fp_jcc_5_387"
12855   [(set (pc)
12856         (if_then_else (match_operator 0 "comparison_operator"
12857                         [(match_operand 1 "register_operand" "f")
12858                          (match_operand 2 "register_operand" "f")])
12859           (label_ref (match_operand 3 "" ""))
12860           (pc)))
12861    (clobber (reg:CCFP FPSR_REG))
12862    (clobber (reg:CCFP FLAGS_REG))
12863    (clobber (match_scratch:HI 4 "=a"))]
12864   "TARGET_80387
12865    && FLOAT_MODE_P (GET_MODE (operands[1]))
12866    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12867    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12868   "#")
12870 (define_insn "*fp_jcc_6_387"
12871   [(set (pc)
12872         (if_then_else (match_operator 0 "comparison_operator"
12873                         [(match_operand 1 "register_operand" "f")
12874                          (match_operand 2 "register_operand" "f")])
12875           (pc)
12876           (label_ref (match_operand 3 "" ""))))
12877    (clobber (reg:CCFP FPSR_REG))
12878    (clobber (reg:CCFP FLAGS_REG))
12879    (clobber (match_scratch:HI 4 "=a"))]
12880   "TARGET_80387
12881    && FLOAT_MODE_P (GET_MODE (operands[1]))
12882    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12883    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12884   "#")
12886 (define_insn "*fp_jcc_7_387"
12887   [(set (pc)
12888         (if_then_else (match_operator 0 "comparison_operator"
12889                         [(match_operand 1 "register_operand" "f")
12890                          (match_operand 2 "const_double_operand" "C")])
12891           (label_ref (match_operand 3 "" ""))
12892           (pc)))
12893    (clobber (reg:CCFP FPSR_REG))
12894    (clobber (reg:CCFP FLAGS_REG))
12895    (clobber (match_scratch:HI 4 "=a"))]
12896   "TARGET_80387
12897    && FLOAT_MODE_P (GET_MODE (operands[1]))
12898    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
12899    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12900    && SELECT_CC_MODE (GET_CODE (operands[0]),
12901                       operands[1], operands[2]) == CCFPmode
12902    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12903   "#")
12905 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12906 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12907 ;; with a precedence over other operators and is always put in the first
12908 ;; place. Swap condition and operands to match ficom instruction.
12910 (define_insn "*fp_jcc_8<mode>_387"
12911   [(set (pc)
12912         (if_then_else (match_operator 0 "comparison_operator"
12913                         [(match_operator 1 "float_operator"
12914                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12915                            (match_operand 3 "register_operand" "f,f")])
12916           (label_ref (match_operand 4 "" ""))
12917           (pc)))
12918    (clobber (reg:CCFP FPSR_REG))
12919    (clobber (reg:CCFP FLAGS_REG))
12920    (clobber (match_scratch:HI 5 "=a,a"))]
12921   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
12922    && FLOAT_MODE_P (GET_MODE (operands[3]))
12923    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12924    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12925    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12926    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12927   "#")
12929 (define_split
12930   [(set (pc)
12931         (if_then_else (match_operator 0 "comparison_operator"
12932                         [(match_operand 1 "register_operand" "")
12933                          (match_operand 2 "nonimmediate_operand" "")])
12934           (match_operand 3 "" "")
12935           (match_operand 4 "" "")))
12936    (clobber (reg:CCFP FPSR_REG))
12937    (clobber (reg:CCFP FLAGS_REG))]
12938   "reload_completed"
12939   [(const_int 0)]
12941   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12942                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12943   DONE;
12946 (define_split
12947   [(set (pc)
12948         (if_then_else (match_operator 0 "comparison_operator"
12949                         [(match_operand 1 "register_operand" "")
12950                          (match_operand 2 "general_operand" "")])
12951           (match_operand 3 "" "")
12952           (match_operand 4 "" "")))
12953    (clobber (reg:CCFP FPSR_REG))
12954    (clobber (reg:CCFP FLAGS_REG))
12955    (clobber (match_scratch:HI 5 "=a"))]
12956   "reload_completed"
12957   [(const_int 0)]
12959   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12960                         operands[3], operands[4], operands[5], NULL_RTX);
12961   DONE;
12964 (define_split
12965   [(set (pc)
12966         (if_then_else (match_operator 0 "comparison_operator"
12967                         [(match_operator 1 "float_operator"
12968                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
12969                            (match_operand 3 "register_operand" "")])
12970           (match_operand 4 "" "")
12971           (match_operand 5 "" "")))
12972    (clobber (reg:CCFP FPSR_REG))
12973    (clobber (reg:CCFP FLAGS_REG))
12974    (clobber (match_scratch:HI 6 "=a"))]
12975   "reload_completed"
12976   [(const_int 0)]
12978   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12979   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12980                         operands[3], operands[7],
12981                         operands[4], operands[5], operands[6], NULL_RTX);
12982   DONE;
12985 ;; %%% Kill this when reload knows how to do it.
12986 (define_split
12987   [(set (pc)
12988         (if_then_else (match_operator 0 "comparison_operator"
12989                         [(match_operator 1 "float_operator"
12990                            [(match_operand:X87MODEI12 2 "register_operand" "")])
12991                            (match_operand 3 "register_operand" "")])
12992           (match_operand 4 "" "")
12993           (match_operand 5 "" "")))
12994    (clobber (reg:CCFP FPSR_REG))
12995    (clobber (reg:CCFP FLAGS_REG))
12996    (clobber (match_scratch:HI 6 "=a"))]
12997   "reload_completed"
12998   [(const_int 0)]
13000   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13001   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13002   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13003                         operands[3], operands[7],
13004                         operands[4], operands[5], operands[6], operands[2]);
13005   DONE;
13008 ;; Unconditional and other jump instructions
13010 (define_insn "jump"
13011   [(set (pc)
13012         (label_ref (match_operand 0 "" "")))]
13013   ""
13014   "jmp\t%l0"
13015   [(set_attr "type" "ibr")
13016    (set (attr "length")
13017            (if_then_else (and (ge (minus (match_dup 0) (pc))
13018                                   (const_int -126))
13019                               (lt (minus (match_dup 0) (pc))
13020                                   (const_int 128)))
13021              (const_int 2)
13022              (const_int 5)))
13023    (set_attr "modrm" "0")])
13025 (define_expand "indirect_jump"
13026   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13027   ""
13028   "")
13030 (define_insn "*indirect_jump"
13031   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13032   "!TARGET_64BIT"
13033   "jmp\t%A0"
13034   [(set_attr "type" "ibr")
13035    (set_attr "length_immediate" "0")])
13037 (define_insn "*indirect_jump_rtx64"
13038   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13039   "TARGET_64BIT"
13040   "jmp\t%A0"
13041   [(set_attr "type" "ibr")
13042    (set_attr "length_immediate" "0")])
13044 (define_expand "tablejump"
13045   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13046               (use (label_ref (match_operand 1 "" "")))])]
13047   ""
13049   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13050      relative.  Convert the relative address to an absolute address.  */
13051   if (flag_pic)
13052     {
13053       rtx op0, op1;
13054       enum rtx_code code;
13056       if (TARGET_64BIT)
13057         {
13058           code = PLUS;
13059           op0 = operands[0];
13060           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13061         }
13062       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13063         {
13064           code = PLUS;
13065           op0 = operands[0];
13066           op1 = pic_offset_table_rtx;
13067         }
13068       else
13069         {
13070           code = MINUS;
13071           op0 = pic_offset_table_rtx;
13072           op1 = operands[0];
13073         }
13075       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13076                                          OPTAB_DIRECT);
13077     }
13080 (define_insn "*tablejump_1"
13081   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13082    (use (label_ref (match_operand 1 "" "")))]
13083   "!TARGET_64BIT"
13084   "jmp\t%A0"
13085   [(set_attr "type" "ibr")
13086    (set_attr "length_immediate" "0")])
13088 (define_insn "*tablejump_1_rtx64"
13089   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13090    (use (label_ref (match_operand 1 "" "")))]
13091   "TARGET_64BIT"
13092   "jmp\t%A0"
13093   [(set_attr "type" "ibr")
13094    (set_attr "length_immediate" "0")])
13096 ;; Loop instruction
13098 ;; This is all complicated by the fact that since this is a jump insn
13099 ;; we must handle our own reloads.
13101 (define_expand "doloop_end"
13102   [(use (match_operand 0 "" ""))        ; loop pseudo
13103    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13104    (use (match_operand 2 "" ""))        ; max iterations
13105    (use (match_operand 3 "" ""))        ; loop level 
13106    (use (match_operand 4 "" ""))]       ; label
13107   "!TARGET_64BIT && TARGET_USE_LOOP"
13108   "                                 
13110   /* Only use cloop on innermost loops.  */
13111   if (INTVAL (operands[3]) > 1)
13112     FAIL;
13113   if (GET_MODE (operands[0]) != SImode)
13114     FAIL;
13115   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13116                                            operands[0]));
13117   DONE;
13120 (define_insn "doloop_end_internal"
13121   [(set (pc)
13122         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13123                           (const_int 1))
13124                       (label_ref (match_operand 0 "" ""))
13125                       (pc)))
13126    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13127         (plus:SI (match_dup 1)
13128                  (const_int -1)))
13129    (clobber (match_scratch:SI 3 "=X,X,r"))
13130    (clobber (reg:CC FLAGS_REG))]
13131   "!TARGET_64BIT && TARGET_USE_LOOP
13132    && (reload_in_progress || reload_completed
13133        || register_operand (operands[2], VOIDmode))"
13135   if (which_alternative != 0)
13136     return "#";
13137   if (get_attr_length (insn) == 2)
13138     return "%+loop\t%l0";
13139   else
13140     return "dec{l}\t%1\;%+jne\t%l0";
13142   [(set (attr "length")
13143         (if_then_else (and (eq_attr "alternative" "0")
13144                            (and (ge (minus (match_dup 0) (pc))
13145                                     (const_int -126))
13146                                 (lt (minus (match_dup 0) (pc))
13147                                     (const_int 128))))
13148                       (const_int 2)
13149                       (const_int 16)))
13150    ;; We don't know the type before shorten branches.  Optimistically expect
13151    ;; the loop instruction to match.
13152    (set (attr "type") (const_string "ibr"))])
13154 (define_split
13155   [(set (pc)
13156         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13157                           (const_int 1))
13158                       (match_operand 0 "" "")
13159                       (pc)))
13160    (set (match_dup 1)
13161         (plus:SI (match_dup 1)
13162                  (const_int -1)))
13163    (clobber (match_scratch:SI 2 ""))
13164    (clobber (reg:CC FLAGS_REG))]
13165   "!TARGET_64BIT && TARGET_USE_LOOP
13166    && reload_completed
13167    && REGNO (operands[1]) != 2"
13168   [(parallel [(set (reg:CCZ FLAGS_REG)
13169                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13170                                  (const_int 0)))
13171               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13172    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13173                            (match_dup 0)
13174                            (pc)))]
13175   "")
13176   
13177 (define_split
13178   [(set (pc)
13179         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13180                           (const_int 1))
13181                       (match_operand 0 "" "")
13182                       (pc)))
13183    (set (match_operand:SI 2 "nonimmediate_operand" "")
13184         (plus:SI (match_dup 1)
13185                  (const_int -1)))
13186    (clobber (match_scratch:SI 3 ""))
13187    (clobber (reg:CC FLAGS_REG))]
13188   "!TARGET_64BIT && TARGET_USE_LOOP
13189    && reload_completed
13190    && (! REG_P (operands[2])
13191        || ! rtx_equal_p (operands[1], operands[2]))"
13192   [(set (match_dup 3) (match_dup 1))
13193    (parallel [(set (reg:CCZ FLAGS_REG)
13194                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13195                                 (const_int 0)))
13196               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13197    (set (match_dup 2) (match_dup 3))
13198    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13199                            (match_dup 0)
13200                            (pc)))]
13201   "")
13203 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13205 (define_peephole2
13206   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13207    (set (match_operand:QI 1 "register_operand" "")
13208         (match_operator:QI 2 "ix86_comparison_operator"
13209           [(reg FLAGS_REG) (const_int 0)]))
13210    (set (match_operand 3 "q_regs_operand" "")
13211         (zero_extend (match_dup 1)))]
13212   "(peep2_reg_dead_p (3, operands[1])
13213     || operands_match_p (operands[1], operands[3]))
13214    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13215   [(set (match_dup 4) (match_dup 0))
13216    (set (strict_low_part (match_dup 5))
13217         (match_dup 2))]
13219   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13220   operands[5] = gen_lowpart (QImode, operands[3]);
13221   ix86_expand_clear (operands[3]);
13224 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13226 (define_peephole2
13227   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13228    (set (match_operand:QI 1 "register_operand" "")
13229         (match_operator:QI 2 "ix86_comparison_operator"
13230           [(reg FLAGS_REG) (const_int 0)]))
13231    (parallel [(set (match_operand 3 "q_regs_operand" "")
13232                    (zero_extend (match_dup 1)))
13233               (clobber (reg:CC FLAGS_REG))])]
13234   "(peep2_reg_dead_p (3, operands[1])
13235     || operands_match_p (operands[1], operands[3]))
13236    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13237   [(set (match_dup 4) (match_dup 0))
13238    (set (strict_low_part (match_dup 5))
13239         (match_dup 2))]
13241   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13242   operands[5] = gen_lowpart (QImode, operands[3]);
13243   ix86_expand_clear (operands[3]);
13246 ;; Call instructions.
13248 ;; The predicates normally associated with named expanders are not properly
13249 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13250 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13252 ;; Call subroutine returning no value.
13254 (define_expand "call_pop"
13255   [(parallel [(call (match_operand:QI 0 "" "")
13256                     (match_operand:SI 1 "" ""))
13257               (set (reg:SI SP_REG)
13258                    (plus:SI (reg:SI SP_REG)
13259                             (match_operand:SI 3 "" "")))])]
13260   "!TARGET_64BIT"
13262   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13263   DONE;
13266 (define_insn "*call_pop_0"
13267   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13268          (match_operand:SI 1 "" ""))
13269    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13270                             (match_operand:SI 2 "immediate_operand" "")))]
13271   "!TARGET_64BIT"
13273   if (SIBLING_CALL_P (insn))
13274     return "jmp\t%P0";
13275   else
13276     return "call\t%P0";
13278   [(set_attr "type" "call")])
13279   
13280 (define_insn "*call_pop_1"
13281   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13282          (match_operand:SI 1 "" ""))
13283    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13284                             (match_operand:SI 2 "immediate_operand" "i")))]
13285   "!TARGET_64BIT"
13287   if (constant_call_address_operand (operands[0], Pmode))
13288     {
13289       if (SIBLING_CALL_P (insn))
13290         return "jmp\t%P0";
13291       else
13292         return "call\t%P0";
13293     }
13294   if (SIBLING_CALL_P (insn))
13295     return "jmp\t%A0";
13296   else
13297     return "call\t%A0";
13299   [(set_attr "type" "call")])
13301 (define_expand "call"
13302   [(call (match_operand:QI 0 "" "")
13303          (match_operand 1 "" ""))
13304    (use (match_operand 2 "" ""))]
13305   ""
13307   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13308   DONE;
13311 (define_expand "sibcall"
13312   [(call (match_operand:QI 0 "" "")
13313          (match_operand 1 "" ""))
13314    (use (match_operand 2 "" ""))]
13315   ""
13317   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13318   DONE;
13321 (define_insn "*call_0"
13322   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13323          (match_operand 1 "" ""))]
13324   ""
13326   if (SIBLING_CALL_P (insn))
13327     return "jmp\t%P0";
13328   else
13329     return "call\t%P0";
13331   [(set_attr "type" "call")])
13333 (define_insn "*call_1"
13334   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13335          (match_operand 1 "" ""))]
13336   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13338   if (constant_call_address_operand (operands[0], Pmode))
13339     return "call\t%P0";
13340   return "call\t%A0";
13342   [(set_attr "type" "call")])
13344 (define_insn "*sibcall_1"
13345   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13346          (match_operand 1 "" ""))]
13347   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13349   if (constant_call_address_operand (operands[0], Pmode))
13350     return "jmp\t%P0";
13351   return "jmp\t%A0";
13353   [(set_attr "type" "call")])
13355 (define_insn "*call_1_rex64"
13356   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13357          (match_operand 1 "" ""))]
13358   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13360   if (constant_call_address_operand (operands[0], Pmode))
13361     return "call\t%P0";
13362   return "call\t%A0";
13364   [(set_attr "type" "call")])
13366 (define_insn "*sibcall_1_rex64"
13367   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13368          (match_operand 1 "" ""))]
13369   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13370   "jmp\t%P0"
13371   [(set_attr "type" "call")])
13373 (define_insn "*sibcall_1_rex64_v"
13374   [(call (mem:QI (reg:DI 40))
13375          (match_operand 0 "" ""))]
13376   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13377   "jmp\t*%%r11"
13378   [(set_attr "type" "call")])
13381 ;; Call subroutine, returning value in operand 0
13383 (define_expand "call_value_pop"
13384   [(parallel [(set (match_operand 0 "" "")
13385                    (call (match_operand:QI 1 "" "")
13386                          (match_operand:SI 2 "" "")))
13387               (set (reg:SI SP_REG)
13388                    (plus:SI (reg:SI SP_REG)
13389                             (match_operand:SI 4 "" "")))])]
13390   "!TARGET_64BIT"
13392   ix86_expand_call (operands[0], operands[1], operands[2],
13393                     operands[3], operands[4], 0);
13394   DONE;
13397 (define_expand "call_value"
13398   [(set (match_operand 0 "" "")
13399         (call (match_operand:QI 1 "" "")
13400               (match_operand:SI 2 "" "")))
13401    (use (match_operand:SI 3 "" ""))]
13402   ;; Operand 2 not used on the i386.
13403   ""
13405   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13406   DONE;
13409 (define_expand "sibcall_value"
13410   [(set (match_operand 0 "" "")
13411         (call (match_operand:QI 1 "" "")
13412               (match_operand:SI 2 "" "")))
13413    (use (match_operand:SI 3 "" ""))]
13414   ;; Operand 2 not used on the i386.
13415   ""
13417   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13418   DONE;
13421 ;; Call subroutine returning any type.
13423 (define_expand "untyped_call"
13424   [(parallel [(call (match_operand 0 "" "")
13425                     (const_int 0))
13426               (match_operand 1 "" "")
13427               (match_operand 2 "" "")])]
13428   ""
13430   int i;
13432   /* In order to give reg-stack an easier job in validating two
13433      coprocessor registers as containing a possible return value,
13434      simply pretend the untyped call returns a complex long double
13435      value.  */
13437   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13438                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13439                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13440                     NULL, 0);
13442   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13443     {
13444       rtx set = XVECEXP (operands[2], 0, i);
13445       emit_move_insn (SET_DEST (set), SET_SRC (set));
13446     }
13448   /* The optimizer does not know that the call sets the function value
13449      registers we stored in the result block.  We avoid problems by
13450      claiming that all hard registers are used and clobbered at this
13451      point.  */
13452   emit_insn (gen_blockage (const0_rtx));
13454   DONE;
13457 ;; Prologue and epilogue instructions
13459 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13460 ;; all of memory.  This blocks insns from being moved across this point.
13462 (define_insn "blockage"
13463   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13464   ""
13465   ""
13466   [(set_attr "length" "0")])
13468 ;; Insn emitted into the body of a function to return from a function.
13469 ;; This is only done if the function's epilogue is known to be simple.
13470 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13472 (define_expand "return"
13473   [(return)]
13474   "ix86_can_use_return_insn_p ()"
13476   if (current_function_pops_args)
13477     {
13478       rtx popc = GEN_INT (current_function_pops_args);
13479       emit_jump_insn (gen_return_pop_internal (popc));
13480       DONE;
13481     }
13484 (define_insn "return_internal"
13485   [(return)]
13486   "reload_completed"
13487   "ret"
13488   [(set_attr "length" "1")
13489    (set_attr "length_immediate" "0")
13490    (set_attr "modrm" "0")])
13492 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13493 ;; instruction Athlon and K8 have.
13495 (define_insn "return_internal_long"
13496   [(return)
13497    (unspec [(const_int 0)] UNSPEC_REP)]
13498   "reload_completed"
13499   "rep {;} ret"
13500   [(set_attr "length" "1")
13501    (set_attr "length_immediate" "0")
13502    (set_attr "prefix_rep" "1")
13503    (set_attr "modrm" "0")])
13505 (define_insn "return_pop_internal"
13506   [(return)
13507    (use (match_operand:SI 0 "const_int_operand" ""))]
13508   "reload_completed"
13509   "ret\t%0"
13510   [(set_attr "length" "3")
13511    (set_attr "length_immediate" "2")
13512    (set_attr "modrm" "0")])
13514 (define_insn "return_indirect_internal"
13515   [(return)
13516    (use (match_operand:SI 0 "register_operand" "r"))]
13517   "reload_completed"
13518   "jmp\t%A0"
13519   [(set_attr "type" "ibr")
13520    (set_attr "length_immediate" "0")])
13522 (define_insn "nop"
13523   [(const_int 0)]
13524   ""
13525   "nop"
13526   [(set_attr "length" "1")
13527    (set_attr "length_immediate" "0")
13528    (set_attr "modrm" "0")])
13530 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13531 ;; branch prediction penalty for the third jump in a 16-byte
13532 ;; block on K8.
13534 (define_insn "align"
13535   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13536   ""
13538 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13539   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13540 #else
13541   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13542      The align insn is used to avoid 3 jump instructions in the row to improve
13543      branch prediction and the benefits hardly outweight the cost of extra 8
13544      nops on the average inserted by full alignment pseudo operation.  */
13545 #endif
13546   return "";
13548   [(set_attr "length" "16")])
13550 (define_expand "prologue"
13551   [(const_int 1)]
13552   ""
13553   "ix86_expand_prologue (); DONE;")
13555 (define_insn "set_got"
13556   [(set (match_operand:SI 0 "register_operand" "=r")
13557         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13558    (clobber (reg:CC FLAGS_REG))]
13559   "!TARGET_64BIT"
13560   { return output_set_got (operands[0]); }
13561   [(set_attr "type" "multi")
13562    (set_attr "length" "12")])
13564 (define_expand "epilogue"
13565   [(const_int 1)]
13566   ""
13567   "ix86_expand_epilogue (1); DONE;")
13569 (define_expand "sibcall_epilogue"
13570   [(const_int 1)]
13571   ""
13572   "ix86_expand_epilogue (0); DONE;")
13574 (define_expand "eh_return"
13575   [(use (match_operand 0 "register_operand" ""))]
13576   ""
13578   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13580   /* Tricky bit: we write the address of the handler to which we will
13581      be returning into someone else's stack frame, one word below the
13582      stack address we wish to restore.  */
13583   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13584   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13585   tmp = gen_rtx_MEM (Pmode, tmp);
13586   emit_move_insn (tmp, ra);
13588   if (Pmode == SImode)
13589     emit_jump_insn (gen_eh_return_si (sa));
13590   else
13591     emit_jump_insn (gen_eh_return_di (sa));
13592   emit_barrier ();
13593   DONE;
13596 (define_insn_and_split "eh_return_si"
13597   [(set (pc) 
13598         (unspec [(match_operand:SI 0 "register_operand" "c")]
13599                  UNSPEC_EH_RETURN))]
13600   "!TARGET_64BIT"
13601   "#"
13602   "reload_completed"
13603   [(const_int 1)]
13604   "ix86_expand_epilogue (2); DONE;")
13606 (define_insn_and_split "eh_return_di"
13607   [(set (pc) 
13608         (unspec [(match_operand:DI 0 "register_operand" "c")]
13609                  UNSPEC_EH_RETURN))]
13610   "TARGET_64BIT"
13611   "#"
13612   "reload_completed"
13613   [(const_int 1)]
13614   "ix86_expand_epilogue (2); DONE;")
13616 (define_insn "leave"
13617   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13618    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13619    (clobber (mem:BLK (scratch)))]
13620   "!TARGET_64BIT"
13621   "leave"
13622   [(set_attr "type" "leave")])
13624 (define_insn "leave_rex64"
13625   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13626    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13627    (clobber (mem:BLK (scratch)))]
13628   "TARGET_64BIT"
13629   "leave"
13630   [(set_attr "type" "leave")])
13632 (define_expand "ffssi2"
13633   [(parallel
13634      [(set (match_operand:SI 0 "register_operand" "") 
13635            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13636       (clobber (match_scratch:SI 2 ""))
13637       (clobber (reg:CC FLAGS_REG))])]
13638   ""
13639   "")
13641 (define_insn_and_split "*ffs_cmove"
13642   [(set (match_operand:SI 0 "register_operand" "=r") 
13643         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13644    (clobber (match_scratch:SI 2 "=&r"))
13645    (clobber (reg:CC FLAGS_REG))]
13646   "TARGET_CMOVE"
13647   "#"
13648   "&& reload_completed"
13649   [(set (match_dup 2) (const_int -1))
13650    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13651               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13652    (set (match_dup 0) (if_then_else:SI
13653                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13654                         (match_dup 2)
13655                         (match_dup 0)))
13656    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13657               (clobber (reg:CC FLAGS_REG))])]
13658   "")
13660 (define_insn_and_split "*ffs_no_cmove"
13661   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13662         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13663    (clobber (match_scratch:SI 2 "=&q"))
13664    (clobber (reg:CC FLAGS_REG))]
13665   ""
13666   "#"
13667   "reload_completed"
13668   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13669               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13670    (set (strict_low_part (match_dup 3))
13671         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13672    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13673               (clobber (reg:CC FLAGS_REG))])
13674    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13675               (clobber (reg:CC FLAGS_REG))])
13676    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13677               (clobber (reg:CC FLAGS_REG))])]
13679   operands[3] = gen_lowpart (QImode, operands[2]);
13680   ix86_expand_clear (operands[2]);
13683 (define_insn "*ffssi_1"
13684   [(set (reg:CCZ FLAGS_REG)
13685         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13686                      (const_int 0)))
13687    (set (match_operand:SI 0 "register_operand" "=r")
13688         (ctz:SI (match_dup 1)))]
13689   ""
13690   "bsf{l}\t{%1, %0|%0, %1}"
13691   [(set_attr "prefix_0f" "1")])
13693 (define_expand "ffsdi2"
13694   [(parallel
13695      [(set (match_operand:DI 0 "register_operand" "") 
13696            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13697       (clobber (match_scratch:DI 2 ""))
13698       (clobber (reg:CC FLAGS_REG))])]
13699   "TARGET_64BIT && TARGET_CMOVE"
13700   "")
13702 (define_insn_and_split "*ffs_rex64"
13703   [(set (match_operand:DI 0 "register_operand" "=r") 
13704         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13705    (clobber (match_scratch:DI 2 "=&r"))
13706    (clobber (reg:CC FLAGS_REG))]
13707   "TARGET_64BIT && TARGET_CMOVE"
13708   "#"
13709   "&& reload_completed"
13710   [(set (match_dup 2) (const_int -1))
13711    (parallel [(set (reg:CCZ FLAGS_REG)
13712                    (compare:CCZ (match_dup 1) (const_int 0)))
13713               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13714    (set (match_dup 0) (if_then_else:DI
13715                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13716                         (match_dup 2)
13717                         (match_dup 0)))
13718    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13719               (clobber (reg:CC FLAGS_REG))])]
13720   "")
13722 (define_insn "*ffsdi_1"
13723   [(set (reg:CCZ FLAGS_REG)
13724         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13725                      (const_int 0)))
13726    (set (match_operand:DI 0 "register_operand" "=r")
13727         (ctz:DI (match_dup 1)))]
13728   "TARGET_64BIT"
13729   "bsf{q}\t{%1, %0|%0, %1}"
13730   [(set_attr "prefix_0f" "1")])
13732 (define_insn "ctzsi2"
13733   [(set (match_operand:SI 0 "register_operand" "=r")
13734         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13735    (clobber (reg:CC FLAGS_REG))]
13736   ""
13737   "bsf{l}\t{%1, %0|%0, %1}"
13738   [(set_attr "prefix_0f" "1")])
13740 (define_insn "ctzdi2"
13741   [(set (match_operand:DI 0 "register_operand" "=r")
13742         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13743    (clobber (reg:CC FLAGS_REG))]
13744   "TARGET_64BIT"
13745   "bsf{q}\t{%1, %0|%0, %1}"
13746   [(set_attr "prefix_0f" "1")])
13748 (define_expand "clzsi2"
13749   [(parallel
13750      [(set (match_operand:SI 0 "register_operand" "")
13751            (minus:SI (const_int 31)
13752                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13753       (clobber (reg:CC FLAGS_REG))])
13754    (parallel
13755      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13756       (clobber (reg:CC FLAGS_REG))])]
13757   ""
13758   "")
13760 (define_insn "*bsr"
13761   [(set (match_operand:SI 0 "register_operand" "=r")
13762         (minus:SI (const_int 31)
13763                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13764    (clobber (reg:CC FLAGS_REG))]
13765   ""
13766   "bsr{l}\t{%1, %0|%0, %1}"
13767   [(set_attr "prefix_0f" "1")])
13769 (define_expand "clzdi2"
13770   [(parallel
13771      [(set (match_operand:DI 0 "register_operand" "")
13772            (minus:DI (const_int 63)
13773                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13774       (clobber (reg:CC FLAGS_REG))])
13775    (parallel
13776      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13777       (clobber (reg:CC FLAGS_REG))])]
13778   "TARGET_64BIT"
13779   "")
13781 (define_insn "*bsr_rex64"
13782   [(set (match_operand:DI 0 "register_operand" "=r")
13783         (minus:DI (const_int 63)
13784                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13785    (clobber (reg:CC FLAGS_REG))]
13786   "TARGET_64BIT"
13787   "bsr{q}\t{%1, %0|%0, %1}"
13788   [(set_attr "prefix_0f" "1")])
13790 ;; Thread-local storage patterns for ELF.
13792 ;; Note that these code sequences must appear exactly as shown
13793 ;; in order to allow linker relaxation.
13795 (define_insn "*tls_global_dynamic_32_gnu"
13796   [(set (match_operand:SI 0 "register_operand" "=a")
13797         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13798                     (match_operand:SI 2 "tls_symbolic_operand" "")
13799                     (match_operand:SI 3 "call_insn_operand" "")]
13800                     UNSPEC_TLS_GD))
13801    (clobber (match_scratch:SI 4 "=d"))
13802    (clobber (match_scratch:SI 5 "=c"))
13803    (clobber (reg:CC FLAGS_REG))]
13804   "!TARGET_64BIT && TARGET_GNU_TLS"
13805   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13806   [(set_attr "type" "multi")
13807    (set_attr "length" "12")])
13809 (define_insn "*tls_global_dynamic_32_sun"
13810   [(set (match_operand:SI 0 "register_operand" "=a")
13811         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13812                     (match_operand:SI 2 "tls_symbolic_operand" "")
13813                     (match_operand:SI 3 "call_insn_operand" "")]
13814                     UNSPEC_TLS_GD))
13815    (clobber (match_scratch:SI 4 "=d"))
13816    (clobber (match_scratch:SI 5 "=c"))
13817    (clobber (reg:CC FLAGS_REG))]
13818   "!TARGET_64BIT && TARGET_SUN_TLS"
13819   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13820         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13821   [(set_attr "type" "multi")
13822    (set_attr "length" "14")])
13824 (define_expand "tls_global_dynamic_32"
13825   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13826                    (unspec:SI
13827                     [(match_dup 2)
13828                      (match_operand:SI 1 "tls_symbolic_operand" "")
13829                      (match_dup 3)]
13830                     UNSPEC_TLS_GD))
13831               (clobber (match_scratch:SI 4 ""))
13832               (clobber (match_scratch:SI 5 ""))
13833               (clobber (reg:CC FLAGS_REG))])]
13834   ""
13836   if (flag_pic)
13837     operands[2] = pic_offset_table_rtx;
13838   else
13839     {
13840       operands[2] = gen_reg_rtx (Pmode);
13841       emit_insn (gen_set_got (operands[2]));
13842     }
13843   operands[3] = ix86_tls_get_addr ();
13846 (define_insn "*tls_global_dynamic_64"
13847   [(set (match_operand:DI 0 "register_operand" "=a")
13848         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13849                       (match_operand:DI 3 "" "")))
13850    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13851               UNSPEC_TLS_GD)]
13852   "TARGET_64BIT"
13853   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13854   [(set_attr "type" "multi")
13855    (set_attr "length" "16")])
13857 (define_expand "tls_global_dynamic_64"
13858   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13859                    (call (mem:QI (match_dup 2)) (const_int 0)))
13860               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13861                          UNSPEC_TLS_GD)])]
13862   ""
13864   operands[2] = ix86_tls_get_addr ();
13867 (define_insn "*tls_local_dynamic_base_32_gnu"
13868   [(set (match_operand:SI 0 "register_operand" "=a")
13869         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13870                     (match_operand:SI 2 "call_insn_operand" "")]
13871                    UNSPEC_TLS_LD_BASE))
13872    (clobber (match_scratch:SI 3 "=d"))
13873    (clobber (match_scratch:SI 4 "=c"))
13874    (clobber (reg:CC FLAGS_REG))]
13875   "!TARGET_64BIT && TARGET_GNU_TLS"
13876   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13877   [(set_attr "type" "multi")
13878    (set_attr "length" "11")])
13880 (define_insn "*tls_local_dynamic_base_32_sun"
13881   [(set (match_operand:SI 0 "register_operand" "=a")
13882         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13883                     (match_operand:SI 2 "call_insn_operand" "")]
13884                    UNSPEC_TLS_LD_BASE))
13885    (clobber (match_scratch:SI 3 "=d"))
13886    (clobber (match_scratch:SI 4 "=c"))
13887    (clobber (reg:CC FLAGS_REG))]
13888   "!TARGET_64BIT && TARGET_SUN_TLS"
13889   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13890         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13891   [(set_attr "type" "multi")
13892    (set_attr "length" "13")])
13894 (define_expand "tls_local_dynamic_base_32"
13895   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13896                    (unspec:SI [(match_dup 1) (match_dup 2)]
13897                               UNSPEC_TLS_LD_BASE))
13898               (clobber (match_scratch:SI 3 ""))
13899               (clobber (match_scratch:SI 4 ""))
13900               (clobber (reg:CC FLAGS_REG))])]
13901   ""
13903   if (flag_pic)
13904     operands[1] = pic_offset_table_rtx;
13905   else
13906     {
13907       operands[1] = gen_reg_rtx (Pmode);
13908       emit_insn (gen_set_got (operands[1]));
13909     }
13910   operands[2] = ix86_tls_get_addr ();
13913 (define_insn "*tls_local_dynamic_base_64"
13914   [(set (match_operand:DI 0 "register_operand" "=a")
13915         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13916                       (match_operand:DI 2 "" "")))
13917    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13918   "TARGET_64BIT"
13919   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13920   [(set_attr "type" "multi")
13921    (set_attr "length" "12")])
13923 (define_expand "tls_local_dynamic_base_64"
13924   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13925                    (call (mem:QI (match_dup 1)) (const_int 0)))
13926               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13927   ""
13929   operands[1] = ix86_tls_get_addr ();
13932 ;; Local dynamic of a single variable is a lose.  Show combine how
13933 ;; to convert that back to global dynamic.
13935 (define_insn_and_split "*tls_local_dynamic_32_once"
13936   [(set (match_operand:SI 0 "register_operand" "=a")
13937         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13938                              (match_operand:SI 2 "call_insn_operand" "")]
13939                             UNSPEC_TLS_LD_BASE)
13940                  (const:SI (unspec:SI
13941                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13942                             UNSPEC_DTPOFF))))
13943    (clobber (match_scratch:SI 4 "=d"))
13944    (clobber (match_scratch:SI 5 "=c"))
13945    (clobber (reg:CC FLAGS_REG))]
13946   ""
13947   "#"
13948   ""
13949   [(parallel [(set (match_dup 0)
13950                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13951                               UNSPEC_TLS_GD))
13952               (clobber (match_dup 4))
13953               (clobber (match_dup 5))
13954               (clobber (reg:CC FLAGS_REG))])]
13955   "")
13957 ;; Load and add the thread base pointer from %gs:0.
13959 (define_insn "*load_tp_si"
13960   [(set (match_operand:SI 0 "register_operand" "=r")
13961         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13962   "!TARGET_64BIT"
13963   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13964   [(set_attr "type" "imov")
13965    (set_attr "modrm" "0")
13966    (set_attr "length" "7")
13967    (set_attr "memory" "load")
13968    (set_attr "imm_disp" "false")])
13970 (define_insn "*add_tp_si"
13971   [(set (match_operand:SI 0 "register_operand" "=r")
13972         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13973                  (match_operand:SI 1 "register_operand" "0")))
13974    (clobber (reg:CC FLAGS_REG))]
13975   "!TARGET_64BIT"
13976   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13977   [(set_attr "type" "alu")
13978    (set_attr "modrm" "0")
13979    (set_attr "length" "7")
13980    (set_attr "memory" "load")
13981    (set_attr "imm_disp" "false")])
13983 (define_insn "*load_tp_di"
13984   [(set (match_operand:DI 0 "register_operand" "=r")
13985         (unspec:DI [(const_int 0)] UNSPEC_TP))]
13986   "TARGET_64BIT"
13987   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13988   [(set_attr "type" "imov")
13989    (set_attr "modrm" "0")
13990    (set_attr "length" "7")
13991    (set_attr "memory" "load")
13992    (set_attr "imm_disp" "false")])
13994 (define_insn "*add_tp_di"
13995   [(set (match_operand:DI 0 "register_operand" "=r")
13996         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
13997                  (match_operand:DI 1 "register_operand" "0")))
13998    (clobber (reg:CC FLAGS_REG))]
13999   "TARGET_64BIT"
14000   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14001   [(set_attr "type" "alu")
14002    (set_attr "modrm" "0")
14003    (set_attr "length" "7")
14004    (set_attr "memory" "load")
14005    (set_attr "imm_disp" "false")])
14007 ;; These patterns match the binary 387 instructions for addM3, subM3,
14008 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14009 ;; SFmode.  The first is the normal insn, the second the same insn but
14010 ;; with one operand a conversion, and the third the same insn but with
14011 ;; the other operand a conversion.  The conversion may be SFmode or
14012 ;; SImode if the target mode DFmode, but only SImode if the target mode
14013 ;; is SFmode.
14015 ;; Gcc is slightly more smart about handling normal two address instructions
14016 ;; so use special patterns for add and mull.
14018 (define_insn "*fop_sf_comm_mixed"
14019   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14020         (match_operator:SF 3 "binary_fp_operator"
14021                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14022                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14023   "TARGET_MIX_SSE_I387
14024    && COMMUTATIVE_ARITH_P (operands[3])
14025    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14026   "* return output_387_binary_op (insn, operands);"
14027   [(set (attr "type") 
14028         (if_then_else (eq_attr "alternative" "1")
14029            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14030               (const_string "ssemul")
14031               (const_string "sseadd"))
14032            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14033               (const_string "fmul")
14034               (const_string "fop"))))
14035    (set_attr "mode" "SF")])
14037 (define_insn "*fop_sf_comm_sse"
14038   [(set (match_operand:SF 0 "register_operand" "=x")
14039         (match_operator:SF 3 "binary_fp_operator"
14040                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14041                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14042   "TARGET_SSE_MATH
14043    && COMMUTATIVE_ARITH_P (operands[3])
14044    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14045   "* return output_387_binary_op (insn, operands);"
14046   [(set (attr "type") 
14047         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14048            (const_string "ssemul")
14049            (const_string "sseadd")))
14050    (set_attr "mode" "SF")])
14052 (define_insn "*fop_sf_comm_i387"
14053   [(set (match_operand:SF 0 "register_operand" "=f")
14054         (match_operator:SF 3 "binary_fp_operator"
14055                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14056                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14057   "TARGET_80387
14058    && COMMUTATIVE_ARITH_P (operands[3])
14059    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14060   "* return output_387_binary_op (insn, operands);"
14061   [(set (attr "type") 
14062         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14063            (const_string "fmul")
14064            (const_string "fop")))
14065    (set_attr "mode" "SF")])
14067 (define_insn "*fop_sf_1_mixed"
14068   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14069         (match_operator:SF 3 "binary_fp_operator"
14070                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14071                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14072   "TARGET_MIX_SSE_I387
14073    && !COMMUTATIVE_ARITH_P (operands[3])
14074    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14075   "* return output_387_binary_op (insn, operands);"
14076   [(set (attr "type") 
14077         (cond [(and (eq_attr "alternative" "2")
14078                     (match_operand:SF 3 "mult_operator" ""))
14079                  (const_string "ssemul")
14080                (and (eq_attr "alternative" "2")
14081                     (match_operand:SF 3 "div_operator" ""))
14082                  (const_string "ssediv")
14083                (eq_attr "alternative" "2")
14084                  (const_string "sseadd")
14085                (match_operand:SF 3 "mult_operator" "") 
14086                  (const_string "fmul")
14087                (match_operand:SF 3 "div_operator" "") 
14088                  (const_string "fdiv")
14089               ]
14090               (const_string "fop")))
14091    (set_attr "mode" "SF")])
14093 (define_insn "*fop_sf_1_sse"
14094   [(set (match_operand:SF 0 "register_operand" "=x")
14095         (match_operator:SF 3 "binary_fp_operator"
14096                         [(match_operand:SF 1 "register_operand" "0")
14097                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14098   "TARGET_SSE_MATH
14099    && !COMMUTATIVE_ARITH_P (operands[3])"
14100   "* return output_387_binary_op (insn, operands);"
14101   [(set (attr "type") 
14102         (cond [(match_operand:SF 3 "mult_operator" "")
14103                  (const_string "ssemul")
14104                (match_operand:SF 3 "div_operator" "")
14105                  (const_string "ssediv")
14106               ]
14107               (const_string "sseadd")))
14108    (set_attr "mode" "SF")])
14110 ;; This pattern is not fully shadowed by the pattern above.
14111 (define_insn "*fop_sf_1_i387"
14112   [(set (match_operand:SF 0 "register_operand" "=f,f")
14113         (match_operator:SF 3 "binary_fp_operator"
14114                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14115                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14116   "TARGET_80387 && !TARGET_SSE_MATH
14117    && !COMMUTATIVE_ARITH_P (operands[3])
14118    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14119   "* return output_387_binary_op (insn, operands);"
14120   [(set (attr "type") 
14121         (cond [(match_operand:SF 3 "mult_operator" "") 
14122                  (const_string "fmul")
14123                (match_operand:SF 3 "div_operator" "") 
14124                  (const_string "fdiv")
14125               ]
14126               (const_string "fop")))
14127    (set_attr "mode" "SF")])
14129 ;; ??? Add SSE splitters for these!
14130 (define_insn "*fop_sf_2<mode>_i387"
14131   [(set (match_operand:SF 0 "register_operand" "=f,f")
14132         (match_operator:SF 3 "binary_fp_operator"
14133           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14134            (match_operand:SF 2 "register_operand" "0,0")]))]
14135   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14136   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14137   [(set (attr "type") 
14138         (cond [(match_operand:SF 3 "mult_operator" "") 
14139                  (const_string "fmul")
14140                (match_operand:SF 3 "div_operator" "") 
14141                  (const_string "fdiv")
14142               ]
14143               (const_string "fop")))
14144    (set_attr "fp_int_src" "true")
14145    (set_attr "mode" "<MODE>")])
14147 (define_insn "*fop_sf_3<mode>_i387"
14148   [(set (match_operand:SF 0 "register_operand" "=f,f")
14149         (match_operator:SF 3 "binary_fp_operator"
14150           [(match_operand:SF 1 "register_operand" "0,0")
14151            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14152   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14153   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14154   [(set (attr "type") 
14155         (cond [(match_operand:SF 3 "mult_operator" "") 
14156                  (const_string "fmul")
14157                (match_operand:SF 3 "div_operator" "") 
14158                  (const_string "fdiv")
14159               ]
14160               (const_string "fop")))
14161    (set_attr "fp_int_src" "true")
14162    (set_attr "mode" "<MODE>")])
14164 (define_insn "*fop_df_comm_mixed"
14165   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14166         (match_operator:DF 3 "binary_fp_operator"
14167                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14168                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14169   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14170    && COMMUTATIVE_ARITH_P (operands[3])
14171    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14172   "* return output_387_binary_op (insn, operands);"
14173   [(set (attr "type") 
14174         (if_then_else (eq_attr "alternative" "1")
14175            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14176               (const_string "ssemul")
14177               (const_string "sseadd"))
14178            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14179               (const_string "fmul")
14180               (const_string "fop"))))
14181    (set_attr "mode" "DF")])
14183 (define_insn "*fop_df_comm_sse"
14184   [(set (match_operand:DF 0 "register_operand" "=Y")
14185         (match_operator:DF 3 "binary_fp_operator"
14186                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14187                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14188   "TARGET_SSE2 && TARGET_SSE_MATH
14189    && COMMUTATIVE_ARITH_P (operands[3])
14190    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14191   "* return output_387_binary_op (insn, operands);"
14192   [(set (attr "type") 
14193         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14194            (const_string "ssemul")
14195            (const_string "sseadd")))
14196    (set_attr "mode" "DF")])
14198 (define_insn "*fop_df_comm_i387"
14199   [(set (match_operand:DF 0 "register_operand" "=f")
14200         (match_operator:DF 3 "binary_fp_operator"
14201                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14202                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14203   "TARGET_80387
14204    && COMMUTATIVE_ARITH_P (operands[3])
14205    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14206   "* return output_387_binary_op (insn, operands);"
14207   [(set (attr "type") 
14208         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14209            (const_string "fmul")
14210            (const_string "fop")))
14211    (set_attr "mode" "DF")])
14213 (define_insn "*fop_df_1_mixed"
14214   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14215         (match_operator:DF 3 "binary_fp_operator"
14216                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14217                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14218   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14219    && !COMMUTATIVE_ARITH_P (operands[3])
14220    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14221   "* return output_387_binary_op (insn, operands);"
14222   [(set (attr "type") 
14223         (cond [(and (eq_attr "alternative" "2")
14224                     (match_operand:SF 3 "mult_operator" ""))
14225                  (const_string "ssemul")
14226                (and (eq_attr "alternative" "2")
14227                     (match_operand:SF 3 "div_operator" ""))
14228                  (const_string "ssediv")
14229                (eq_attr "alternative" "2")
14230                  (const_string "sseadd")
14231                (match_operand:DF 3 "mult_operator" "") 
14232                  (const_string "fmul")
14233                (match_operand:DF 3 "div_operator" "") 
14234                  (const_string "fdiv")
14235               ]
14236               (const_string "fop")))
14237    (set_attr "mode" "DF")])
14239 (define_insn "*fop_df_1_sse"
14240   [(set (match_operand:DF 0 "register_operand" "=Y")
14241         (match_operator:DF 3 "binary_fp_operator"
14242                         [(match_operand:DF 1 "register_operand" "0")
14243                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14244   "TARGET_SSE2 && TARGET_SSE_MATH
14245    && !COMMUTATIVE_ARITH_P (operands[3])"
14246   "* return output_387_binary_op (insn, operands);"
14247   [(set_attr "mode" "DF")
14248    (set (attr "type") 
14249         (cond [(match_operand:SF 3 "mult_operator" "")
14250                  (const_string "ssemul")
14251                (match_operand:SF 3 "div_operator" "")
14252                  (const_string "ssediv")
14253               ]
14254               (const_string "sseadd")))])
14256 ;; This pattern is not fully shadowed by the pattern above.
14257 (define_insn "*fop_df_1_i387"
14258   [(set (match_operand:DF 0 "register_operand" "=f,f")
14259         (match_operator:DF 3 "binary_fp_operator"
14260                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14261                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14262   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14263    && !COMMUTATIVE_ARITH_P (operands[3])
14264    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14265   "* return output_387_binary_op (insn, operands);"
14266   [(set (attr "type") 
14267         (cond [(match_operand:DF 3 "mult_operator" "") 
14268                  (const_string "fmul")
14269                (match_operand:DF 3 "div_operator" "")
14270                  (const_string "fdiv")
14271               ]
14272               (const_string "fop")))
14273    (set_attr "mode" "DF")])
14275 ;; ??? Add SSE splitters for these!
14276 (define_insn "*fop_df_2<mode>_i387"
14277   [(set (match_operand:DF 0 "register_operand" "=f,f")
14278         (match_operator:DF 3 "binary_fp_operator"
14279            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14280             (match_operand:DF 2 "register_operand" "0,0")]))]
14281   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14282    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14283   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14284   [(set (attr "type") 
14285         (cond [(match_operand:DF 3 "mult_operator" "") 
14286                  (const_string "fmul")
14287                (match_operand:DF 3 "div_operator" "") 
14288                  (const_string "fdiv")
14289               ]
14290               (const_string "fop")))
14291    (set_attr "fp_int_src" "true")
14292    (set_attr "mode" "<MODE>")])
14294 (define_insn "*fop_df_3<mode>_i387"
14295   [(set (match_operand:DF 0 "register_operand" "=f,f")
14296         (match_operator:DF 3 "binary_fp_operator"
14297            [(match_operand:DF 1 "register_operand" "0,0")
14298             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14299   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14300    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14301   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14302   [(set (attr "type") 
14303         (cond [(match_operand:DF 3 "mult_operator" "") 
14304                  (const_string "fmul")
14305                (match_operand:DF 3 "div_operator" "") 
14306                  (const_string "fdiv")
14307               ]
14308               (const_string "fop")))
14309    (set_attr "fp_int_src" "true")
14310    (set_attr "mode" "<MODE>")])
14312 (define_insn "*fop_df_4_i387"
14313   [(set (match_operand:DF 0 "register_operand" "=f,f")
14314         (match_operator:DF 3 "binary_fp_operator"
14315            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14316             (match_operand:DF 2 "register_operand" "0,f")]))]
14317   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14318    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14319   "* return output_387_binary_op (insn, operands);"
14320   [(set (attr "type") 
14321         (cond [(match_operand:DF 3 "mult_operator" "") 
14322                  (const_string "fmul")
14323                (match_operand:DF 3 "div_operator" "") 
14324                  (const_string "fdiv")
14325               ]
14326               (const_string "fop")))
14327    (set_attr "mode" "SF")])
14329 (define_insn "*fop_df_5_i387"
14330   [(set (match_operand:DF 0 "register_operand" "=f,f")
14331         (match_operator:DF 3 "binary_fp_operator"
14332           [(match_operand:DF 1 "register_operand" "0,f")
14333            (float_extend:DF
14334             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14335   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14336   "* return output_387_binary_op (insn, operands);"
14337   [(set (attr "type") 
14338         (cond [(match_operand:DF 3 "mult_operator" "") 
14339                  (const_string "fmul")
14340                (match_operand:DF 3 "div_operator" "") 
14341                  (const_string "fdiv")
14342               ]
14343               (const_string "fop")))
14344    (set_attr "mode" "SF")])
14346 (define_insn "*fop_df_6_i387"
14347   [(set (match_operand:DF 0 "register_operand" "=f,f")
14348         (match_operator:DF 3 "binary_fp_operator"
14349           [(float_extend:DF
14350             (match_operand:SF 1 "register_operand" "0,f"))
14351            (float_extend:DF
14352             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14353   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14354   "* return output_387_binary_op (insn, operands);"
14355   [(set (attr "type") 
14356         (cond [(match_operand:DF 3 "mult_operator" "") 
14357                  (const_string "fmul")
14358                (match_operand:DF 3 "div_operator" "") 
14359                  (const_string "fdiv")
14360               ]
14361               (const_string "fop")))
14362    (set_attr "mode" "SF")])
14364 (define_insn "*fop_xf_comm_i387"
14365   [(set (match_operand:XF 0 "register_operand" "=f")
14366         (match_operator:XF 3 "binary_fp_operator"
14367                         [(match_operand:XF 1 "register_operand" "%0")
14368                          (match_operand:XF 2 "register_operand" "f")]))]
14369   "TARGET_80387
14370    && COMMUTATIVE_ARITH_P (operands[3])"
14371   "* return output_387_binary_op (insn, operands);"
14372   [(set (attr "type") 
14373         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14374            (const_string "fmul")
14375            (const_string "fop")))
14376    (set_attr "mode" "XF")])
14378 (define_insn "*fop_xf_1_i387"
14379   [(set (match_operand:XF 0 "register_operand" "=f,f")
14380         (match_operator:XF 3 "binary_fp_operator"
14381                         [(match_operand:XF 1 "register_operand" "0,f")
14382                          (match_operand:XF 2 "register_operand" "f,0")]))]
14383   "TARGET_80387
14384    && !COMMUTATIVE_ARITH_P (operands[3])"
14385   "* return output_387_binary_op (insn, operands);"
14386   [(set (attr "type") 
14387         (cond [(match_operand:XF 3 "mult_operator" "") 
14388                  (const_string "fmul")
14389                (match_operand:XF 3 "div_operator" "") 
14390                  (const_string "fdiv")
14391               ]
14392               (const_string "fop")))
14393    (set_attr "mode" "XF")])
14395 (define_insn "*fop_xf_2<mode>_i387"
14396   [(set (match_operand:XF 0 "register_operand" "=f,f")
14397         (match_operator:XF 3 "binary_fp_operator"
14398            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14399             (match_operand:XF 2 "register_operand" "0,0")]))]
14400   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14401   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14402   [(set (attr "type") 
14403         (cond [(match_operand:XF 3 "mult_operator" "") 
14404                  (const_string "fmul")
14405                (match_operand:XF 3 "div_operator" "") 
14406                  (const_string "fdiv")
14407               ]
14408               (const_string "fop")))
14409    (set_attr "fp_int_src" "true")
14410    (set_attr "mode" "<MODE>")])
14412 (define_insn "*fop_xf_3<mode>_i387"
14413   [(set (match_operand:XF 0 "register_operand" "=f,f")
14414         (match_operator:XF 3 "binary_fp_operator"
14415           [(match_operand:XF 1 "register_operand" "0,0")
14416            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14417   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14418   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14419   [(set (attr "type") 
14420         (cond [(match_operand:XF 3 "mult_operator" "") 
14421                  (const_string "fmul")
14422                (match_operand:XF 3 "div_operator" "") 
14423                  (const_string "fdiv")
14424               ]
14425               (const_string "fop")))
14426    (set_attr "fp_int_src" "true")
14427    (set_attr "mode" "<MODE>")])
14429 (define_insn "*fop_xf_4_i387"
14430   [(set (match_operand:XF 0 "register_operand" "=f,f")
14431         (match_operator:XF 3 "binary_fp_operator"
14432            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14433             (match_operand:XF 2 "register_operand" "0,f")]))]
14434   "TARGET_80387"
14435   "* return output_387_binary_op (insn, operands);"
14436   [(set (attr "type") 
14437         (cond [(match_operand:XF 3 "mult_operator" "") 
14438                  (const_string "fmul")
14439                (match_operand:XF 3 "div_operator" "") 
14440                  (const_string "fdiv")
14441               ]
14442               (const_string "fop")))
14443    (set_attr "mode" "SF")])
14445 (define_insn "*fop_xf_5_i387"
14446   [(set (match_operand:XF 0 "register_operand" "=f,f")
14447         (match_operator:XF 3 "binary_fp_operator"
14448           [(match_operand:XF 1 "register_operand" "0,f")
14449            (float_extend:XF
14450             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14451   "TARGET_80387"
14452   "* return output_387_binary_op (insn, operands);"
14453   [(set (attr "type") 
14454         (cond [(match_operand:XF 3 "mult_operator" "") 
14455                  (const_string "fmul")
14456                (match_operand:XF 3 "div_operator" "") 
14457                  (const_string "fdiv")
14458               ]
14459               (const_string "fop")))
14460    (set_attr "mode" "SF")])
14462 (define_insn "*fop_xf_6_i387"
14463   [(set (match_operand:XF 0 "register_operand" "=f,f")
14464         (match_operator:XF 3 "binary_fp_operator"
14465           [(float_extend:XF
14466             (match_operand 1 "register_operand" "0,f"))
14467            (float_extend:XF
14468             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14469   "TARGET_80387"
14470   "* return output_387_binary_op (insn, operands);"
14471   [(set (attr "type") 
14472         (cond [(match_operand:XF 3 "mult_operator" "") 
14473                  (const_string "fmul")
14474                (match_operand:XF 3 "div_operator" "") 
14475                  (const_string "fdiv")
14476               ]
14477               (const_string "fop")))
14478    (set_attr "mode" "SF")])
14480 (define_split
14481   [(set (match_operand 0 "register_operand" "")
14482         (match_operator 3 "binary_fp_operator"
14483            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14484             (match_operand 2 "register_operand" "")]))]
14485   "TARGET_80387 && reload_completed
14486    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14487   [(const_int 0)]
14489   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14490   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14491   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14492                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14493                                           GET_MODE (operands[3]),
14494                                           operands[4],
14495                                           operands[2])));
14496   ix86_free_from_memory (GET_MODE (operands[1]));
14497   DONE;
14500 (define_split
14501   [(set (match_operand 0 "register_operand" "")
14502         (match_operator 3 "binary_fp_operator"
14503            [(match_operand 1 "register_operand" "")
14504             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14505   "TARGET_80387 && reload_completed
14506    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14507   [(const_int 0)]
14509   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14510   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14511   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14512                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14513                                           GET_MODE (operands[3]),
14514                                           operands[1],
14515                                           operands[4])));
14516   ix86_free_from_memory (GET_MODE (operands[2]));
14517   DONE;
14520 ;; FPU special functions.
14522 (define_expand "sqrtsf2"
14523   [(set (match_operand:SF 0 "register_operand" "")
14524         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14525   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14527   if (!TARGET_SSE_MATH)
14528     operands[1] = force_reg (SFmode, operands[1]);
14531 (define_insn "*sqrtsf2_mixed"
14532   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14533         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14534   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14535   "@
14536    fsqrt
14537    sqrtss\t{%1, %0|%0, %1}"
14538   [(set_attr "type" "fpspc,sse")
14539    (set_attr "mode" "SF,SF")
14540    (set_attr "athlon_decode" "direct,*")])
14542 (define_insn "*sqrtsf2_sse"
14543   [(set (match_operand:SF 0 "register_operand" "=x")
14544         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14545   "TARGET_SSE_MATH"
14546   "sqrtss\t{%1, %0|%0, %1}"
14547   [(set_attr "type" "sse")
14548    (set_attr "mode" "SF")
14549    (set_attr "athlon_decode" "*")])
14551 (define_insn "*sqrtsf2_i387"
14552   [(set (match_operand:SF 0 "register_operand" "=f")
14553         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14554   "TARGET_USE_FANCY_MATH_387"
14555   "fsqrt"
14556   [(set_attr "type" "fpspc")
14557    (set_attr "mode" "SF")
14558    (set_attr "athlon_decode" "direct")])
14560 (define_expand "sqrtdf2"
14561   [(set (match_operand:DF 0 "register_operand" "")
14562         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14563   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14565   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14566     operands[1] = force_reg (DFmode, operands[1]);
14569 (define_insn "*sqrtdf2_mixed"
14570   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14571         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14572   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14573   "@
14574    fsqrt
14575    sqrtsd\t{%1, %0|%0, %1}"
14576   [(set_attr "type" "fpspc,sse")
14577    (set_attr "mode" "DF,DF")
14578    (set_attr "athlon_decode" "direct,*")])
14580 (define_insn "*sqrtdf2_sse"
14581   [(set (match_operand:DF 0 "register_operand" "=Y")
14582         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14583   "TARGET_SSE2 && TARGET_SSE_MATH"
14584   "sqrtsd\t{%1, %0|%0, %1}"
14585   [(set_attr "type" "sse")
14586    (set_attr "mode" "DF")
14587    (set_attr "athlon_decode" "*")])
14589 (define_insn "*sqrtdf2_i387"
14590   [(set (match_operand:DF 0 "register_operand" "=f")
14591         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14592   "TARGET_USE_FANCY_MATH_387"
14593   "fsqrt"
14594   [(set_attr "type" "fpspc")
14595    (set_attr "mode" "DF")
14596    (set_attr "athlon_decode" "direct")])
14598 (define_insn "*sqrtextendsfdf2_i387"
14599   [(set (match_operand:DF 0 "register_operand" "=f")
14600         (sqrt:DF (float_extend:DF
14601                   (match_operand:SF 1 "register_operand" "0"))))]
14602   "TARGET_USE_FANCY_MATH_387
14603    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14604   "fsqrt"
14605   [(set_attr "type" "fpspc")
14606    (set_attr "mode" "DF")
14607    (set_attr "athlon_decode" "direct")])
14609 (define_insn "sqrtxf2"
14610   [(set (match_operand:XF 0 "register_operand" "=f")
14611         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14612   "TARGET_USE_FANCY_MATH_387 
14613    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14614   "fsqrt"
14615   [(set_attr "type" "fpspc")
14616    (set_attr "mode" "XF")
14617    (set_attr "athlon_decode" "direct")])
14619 (define_insn "*sqrtextendsfxf2_i387"
14620   [(set (match_operand:XF 0 "register_operand" "=f")
14621         (sqrt:XF (float_extend:XF
14622                   (match_operand:SF 1 "register_operand" "0"))))]
14623   "TARGET_USE_FANCY_MATH_387"
14624   "fsqrt"
14625   [(set_attr "type" "fpspc")
14626    (set_attr "mode" "XF")
14627    (set_attr "athlon_decode" "direct")])
14629 (define_insn "*sqrtextenddfxf2_i387"
14630   [(set (match_operand:XF 0 "register_operand" "=f")
14631         (sqrt:XF (float_extend:XF
14632                   (match_operand:DF 1 "register_operand" "0"))))]
14633   "TARGET_USE_FANCY_MATH_387"
14634   "fsqrt"
14635   [(set_attr "type" "fpspc")
14636    (set_attr "mode" "XF")
14637    (set_attr "athlon_decode" "direct")])
14639 (define_insn "fpremxf4"
14640   [(set (match_operand:XF 0 "register_operand" "=f")
14641         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14642                     (match_operand:XF 3 "register_operand" "1")]
14643                    UNSPEC_FPREM_F))
14644    (set (match_operand:XF 1 "register_operand" "=u")
14645         (unspec:XF [(match_dup 2) (match_dup 3)]
14646                    UNSPEC_FPREM_U))
14647    (set (reg:CCFP FPSR_REG)
14648         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14649   "TARGET_USE_FANCY_MATH_387
14650    && flag_unsafe_math_optimizations"
14651   "fprem"
14652   [(set_attr "type" "fpspc")
14653    (set_attr "mode" "XF")])
14655 (define_expand "fmodsf3"
14656   [(use (match_operand:SF 0 "register_operand" ""))
14657    (use (match_operand:SF 1 "register_operand" ""))
14658    (use (match_operand:SF 2 "register_operand" ""))]
14659   "TARGET_USE_FANCY_MATH_387
14660    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14661    && flag_unsafe_math_optimizations"
14663   rtx label = gen_label_rtx ();
14665   rtx op1 = gen_reg_rtx (XFmode);
14666   rtx op2 = gen_reg_rtx (XFmode);
14668   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14669   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14671   emit_label (label);
14673   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14674   ix86_emit_fp_unordered_jump (label);
14676   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14677   DONE;
14680 (define_expand "fmoddf3"
14681   [(use (match_operand:DF 0 "register_operand" ""))
14682    (use (match_operand:DF 1 "register_operand" ""))
14683    (use (match_operand:DF 2 "register_operand" ""))]
14684   "TARGET_USE_FANCY_MATH_387
14685    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14686    && flag_unsafe_math_optimizations"
14688   rtx label = gen_label_rtx ();
14690   rtx op1 = gen_reg_rtx (XFmode);
14691   rtx op2 = gen_reg_rtx (XFmode);
14693   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14694   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14696   emit_label (label);
14698   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14699   ix86_emit_fp_unordered_jump (label);
14701   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14702   DONE;
14705 (define_expand "fmodxf3"
14706   [(use (match_operand:XF 0 "register_operand" ""))
14707    (use (match_operand:XF 1 "register_operand" ""))
14708    (use (match_operand:XF 2 "register_operand" ""))]
14709   "TARGET_USE_FANCY_MATH_387
14710    && flag_unsafe_math_optimizations"
14712   rtx label = gen_label_rtx ();
14714   emit_label (label);
14716   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14717                            operands[1], operands[2]));
14718   ix86_emit_fp_unordered_jump (label);
14720   emit_move_insn (operands[0], operands[1]);
14721   DONE;
14724 (define_insn "fprem1xf4"
14725   [(set (match_operand:XF 0 "register_operand" "=f")
14726         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14727                     (match_operand:XF 3 "register_operand" "1")]
14728                    UNSPEC_FPREM1_F))
14729    (set (match_operand:XF 1 "register_operand" "=u")
14730         (unspec:XF [(match_dup 2) (match_dup 3)]
14731                    UNSPEC_FPREM1_U))
14732    (set (reg:CCFP FPSR_REG)
14733         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14734   "TARGET_USE_FANCY_MATH_387
14735    && flag_unsafe_math_optimizations"
14736   "fprem1"
14737   [(set_attr "type" "fpspc")
14738    (set_attr "mode" "XF")])
14740 (define_expand "dremsf3"
14741   [(use (match_operand:SF 0 "register_operand" ""))
14742    (use (match_operand:SF 1 "register_operand" ""))
14743    (use (match_operand:SF 2 "register_operand" ""))]
14744   "TARGET_USE_FANCY_MATH_387
14745    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14746    && flag_unsafe_math_optimizations"
14748   rtx label = gen_label_rtx ();
14750   rtx op1 = gen_reg_rtx (XFmode);
14751   rtx op2 = gen_reg_rtx (XFmode);
14753   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14754   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14756   emit_label (label);
14758   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14759   ix86_emit_fp_unordered_jump (label);
14761   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14762   DONE;
14765 (define_expand "dremdf3"
14766   [(use (match_operand:DF 0 "register_operand" ""))
14767    (use (match_operand:DF 1 "register_operand" ""))
14768    (use (match_operand:DF 2 "register_operand" ""))]
14769   "TARGET_USE_FANCY_MATH_387
14770    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14771    && flag_unsafe_math_optimizations"
14773   rtx label = gen_label_rtx ();
14775   rtx op1 = gen_reg_rtx (XFmode);
14776   rtx op2 = gen_reg_rtx (XFmode);
14778   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14779   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14781   emit_label (label);
14783   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14784   ix86_emit_fp_unordered_jump (label);
14786   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14787   DONE;
14790 (define_expand "dremxf3"
14791   [(use (match_operand:XF 0 "register_operand" ""))
14792    (use (match_operand:XF 1 "register_operand" ""))
14793    (use (match_operand:XF 2 "register_operand" ""))]
14794   "TARGET_USE_FANCY_MATH_387
14795    && flag_unsafe_math_optimizations"
14797   rtx label = gen_label_rtx ();
14799   emit_label (label);
14801   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14802                             operands[1], operands[2]));
14803   ix86_emit_fp_unordered_jump (label);
14805   emit_move_insn (operands[0], operands[1]);
14806   DONE;
14809 (define_insn "*sindf2"
14810   [(set (match_operand:DF 0 "register_operand" "=f")
14811         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14812   "TARGET_USE_FANCY_MATH_387
14813    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14814    && flag_unsafe_math_optimizations"
14815   "fsin"
14816   [(set_attr "type" "fpspc")
14817    (set_attr "mode" "DF")])
14819 (define_insn "*sinsf2"
14820   [(set (match_operand:SF 0 "register_operand" "=f")
14821         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14822   "TARGET_USE_FANCY_MATH_387
14823    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14824    && flag_unsafe_math_optimizations"
14825   "fsin"
14826   [(set_attr "type" "fpspc")
14827    (set_attr "mode" "SF")])
14829 (define_insn "*sinextendsfdf2"
14830   [(set (match_operand:DF 0 "register_operand" "=f")
14831         (unspec:DF [(float_extend:DF
14832                      (match_operand:SF 1 "register_operand" "0"))]
14833                    UNSPEC_SIN))]
14834   "TARGET_USE_FANCY_MATH_387
14835    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14836    && flag_unsafe_math_optimizations"
14837   "fsin"
14838   [(set_attr "type" "fpspc")
14839    (set_attr "mode" "DF")])
14841 (define_insn "*sinxf2"
14842   [(set (match_operand:XF 0 "register_operand" "=f")
14843         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14844   "TARGET_USE_FANCY_MATH_387
14845    && flag_unsafe_math_optimizations"
14846   "fsin"
14847   [(set_attr "type" "fpspc")
14848    (set_attr "mode" "XF")])
14850 (define_insn "*cosdf2"
14851   [(set (match_operand:DF 0 "register_operand" "=f")
14852         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14853   "TARGET_USE_FANCY_MATH_387
14854    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14855    && flag_unsafe_math_optimizations"
14856   "fcos"
14857   [(set_attr "type" "fpspc")
14858    (set_attr "mode" "DF")])
14860 (define_insn "*cossf2"
14861   [(set (match_operand:SF 0 "register_operand" "=f")
14862         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14863   "TARGET_USE_FANCY_MATH_387
14864    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14865    && flag_unsafe_math_optimizations"
14866   "fcos"
14867   [(set_attr "type" "fpspc")
14868    (set_attr "mode" "SF")])
14870 (define_insn "*cosextendsfdf2"
14871   [(set (match_operand:DF 0 "register_operand" "=f")
14872         (unspec:DF [(float_extend:DF
14873                      (match_operand:SF 1 "register_operand" "0"))]
14874                    UNSPEC_COS))]
14875   "TARGET_USE_FANCY_MATH_387
14876    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14877    && flag_unsafe_math_optimizations"
14878   "fcos"
14879   [(set_attr "type" "fpspc")
14880    (set_attr "mode" "DF")])
14882 (define_insn "*cosxf2"
14883   [(set (match_operand:XF 0 "register_operand" "=f")
14884         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14885   "TARGET_USE_FANCY_MATH_387
14886    && flag_unsafe_math_optimizations"
14887   "fcos"
14888   [(set_attr "type" "fpspc")
14889    (set_attr "mode" "XF")])
14891 ;; With sincos pattern defined, sin and cos builtin function will be
14892 ;; expanded to sincos pattern with one of its outputs left unused. 
14893 ;; Cse pass  will detected, if two sincos patterns can be combined,
14894 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14895 ;; depending on the unused output.
14897 (define_insn "sincosdf3"
14898   [(set (match_operand:DF 0 "register_operand" "=f")
14899         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14900                    UNSPEC_SINCOS_COS))
14901    (set (match_operand:DF 1 "register_operand" "=u")
14902         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14903   "TARGET_USE_FANCY_MATH_387
14904    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14905    && flag_unsafe_math_optimizations"
14906   "fsincos"
14907   [(set_attr "type" "fpspc")
14908    (set_attr "mode" "DF")])
14910 (define_split
14911   [(set (match_operand:DF 0 "register_operand" "")
14912         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14913                    UNSPEC_SINCOS_COS))
14914    (set (match_operand:DF 1 "register_operand" "")
14915         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14916   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14917    && !reload_completed && !reload_in_progress"
14918   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14919   "")
14921 (define_split
14922   [(set (match_operand:DF 0 "register_operand" "")
14923         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14924                    UNSPEC_SINCOS_COS))
14925    (set (match_operand:DF 1 "register_operand" "")
14926         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14927   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14928    && !reload_completed && !reload_in_progress"
14929   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14930   "")
14932 (define_insn "sincossf3"
14933   [(set (match_operand:SF 0 "register_operand" "=f")
14934         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14935                    UNSPEC_SINCOS_COS))
14936    (set (match_operand:SF 1 "register_operand" "=u")
14937         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14938   "TARGET_USE_FANCY_MATH_387
14939    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14940    && flag_unsafe_math_optimizations"
14941   "fsincos"
14942   [(set_attr "type" "fpspc")
14943    (set_attr "mode" "SF")])
14945 (define_split
14946   [(set (match_operand:SF 0 "register_operand" "")
14947         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14948                    UNSPEC_SINCOS_COS))
14949    (set (match_operand:SF 1 "register_operand" "")
14950         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14951   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14952    && !reload_completed && !reload_in_progress"
14953   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14954   "")
14956 (define_split
14957   [(set (match_operand:SF 0 "register_operand" "")
14958         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14959                    UNSPEC_SINCOS_COS))
14960    (set (match_operand:SF 1 "register_operand" "")
14961         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14962   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14963    && !reload_completed && !reload_in_progress"
14964   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14965   "")
14967 (define_insn "*sincosextendsfdf3"
14968   [(set (match_operand:DF 0 "register_operand" "=f")
14969         (unspec:DF [(float_extend:DF
14970                      (match_operand:SF 2 "register_operand" "0"))]
14971                    UNSPEC_SINCOS_COS))
14972    (set (match_operand:DF 1 "register_operand" "=u")
14973         (unspec:DF [(float_extend:DF
14974                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14975   "TARGET_USE_FANCY_MATH_387
14976    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14977    && flag_unsafe_math_optimizations"
14978   "fsincos"
14979   [(set_attr "type" "fpspc")
14980    (set_attr "mode" "DF")])
14982 (define_split
14983   [(set (match_operand:DF 0 "register_operand" "")
14984         (unspec:DF [(float_extend:DF
14985                      (match_operand:SF 2 "register_operand" ""))]
14986                    UNSPEC_SINCOS_COS))
14987    (set (match_operand:DF 1 "register_operand" "")
14988         (unspec:DF [(float_extend:DF
14989                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14990   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14991    && !reload_completed && !reload_in_progress"
14992   [(set (match_dup 1) (unspec:DF [(float_extend:DF
14993                                    (match_dup 2))] UNSPEC_SIN))]
14994   "")
14996 (define_split
14997   [(set (match_operand:DF 0 "register_operand" "")
14998         (unspec:DF [(float_extend:DF
14999                      (match_operand:SF 2 "register_operand" ""))]
15000                    UNSPEC_SINCOS_COS))
15001    (set (match_operand:DF 1 "register_operand" "")
15002         (unspec:DF [(float_extend:DF
15003                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15004   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15005    && !reload_completed && !reload_in_progress"
15006   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15007                                    (match_dup 2))] UNSPEC_COS))]
15008   "")
15010 (define_insn "sincosxf3"
15011   [(set (match_operand:XF 0 "register_operand" "=f")
15012         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15013                    UNSPEC_SINCOS_COS))
15014    (set (match_operand:XF 1 "register_operand" "=u")
15015         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15016   "TARGET_USE_FANCY_MATH_387
15017    && flag_unsafe_math_optimizations"
15018   "fsincos"
15019   [(set_attr "type" "fpspc")
15020    (set_attr "mode" "XF")])
15022 (define_split
15023   [(set (match_operand:XF 0 "register_operand" "")
15024         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15025                    UNSPEC_SINCOS_COS))
15026    (set (match_operand:XF 1 "register_operand" "")
15027         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15028   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15029    && !reload_completed && !reload_in_progress"
15030   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15031   "")
15033 (define_split
15034   [(set (match_operand:XF 0 "register_operand" "")
15035         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15036                    UNSPEC_SINCOS_COS))
15037    (set (match_operand:XF 1 "register_operand" "")
15038         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15039   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15040    && !reload_completed && !reload_in_progress"
15041   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15042   "")
15044 (define_insn "*tandf3_1"
15045   [(set (match_operand:DF 0 "register_operand" "=f")
15046         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15047                    UNSPEC_TAN_ONE))
15048    (set (match_operand:DF 1 "register_operand" "=u")
15049         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15050   "TARGET_USE_FANCY_MATH_387
15051    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15052    && flag_unsafe_math_optimizations"
15053   "fptan"
15054   [(set_attr "type" "fpspc")
15055    (set_attr "mode" "DF")])
15057 ;; optimize sequence: fptan
15058 ;;                    fstp    %st(0)
15059 ;;                    fld1
15060 ;; into fptan insn.
15062 (define_peephole2
15063   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15064                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15065                              UNSPEC_TAN_ONE))
15066              (set (match_operand:DF 1 "register_operand" "")
15067                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15068    (set (match_dup 0)
15069         (match_operand:DF 3 "immediate_operand" ""))]
15070   "standard_80387_constant_p (operands[3]) == 2"
15071   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15072              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15073   "")
15075 (define_expand "tandf2"
15076   [(parallel [(set (match_dup 2)
15077                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15078                               UNSPEC_TAN_ONE))
15079               (set (match_operand:DF 0 "register_operand" "")
15080                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15081   "TARGET_USE_FANCY_MATH_387
15082    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15083    && flag_unsafe_math_optimizations"
15085   operands[2] = gen_reg_rtx (DFmode);
15088 (define_insn "*tansf3_1"
15089   [(set (match_operand:SF 0 "register_operand" "=f")
15090         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15091                    UNSPEC_TAN_ONE))
15092    (set (match_operand:SF 1 "register_operand" "=u")
15093         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15094   "TARGET_USE_FANCY_MATH_387
15095    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15096    && flag_unsafe_math_optimizations"
15097   "fptan"
15098   [(set_attr "type" "fpspc")
15099    (set_attr "mode" "SF")])
15101 ;; optimize sequence: fptan
15102 ;;                    fstp    %st(0)
15103 ;;                    fld1
15104 ;; into fptan insn.
15106 (define_peephole2
15107   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15108                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15109                              UNSPEC_TAN_ONE))
15110              (set (match_operand:SF 1 "register_operand" "")
15111                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15112    (set (match_dup 0)
15113         (match_operand:SF 3 "immediate_operand" ""))]
15114   "standard_80387_constant_p (operands[3]) == 2"
15115   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15116              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15117   "")
15119 (define_expand "tansf2"
15120   [(parallel [(set (match_dup 2)
15121                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15122                               UNSPEC_TAN_ONE))
15123               (set (match_operand:SF 0 "register_operand" "")
15124                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15125   "TARGET_USE_FANCY_MATH_387
15126    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15127    && flag_unsafe_math_optimizations"
15129   operands[2] = gen_reg_rtx (SFmode);
15132 (define_insn "*tanxf3_1"
15133   [(set (match_operand:XF 0 "register_operand" "=f")
15134         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15135                    UNSPEC_TAN_ONE))
15136    (set (match_operand:XF 1 "register_operand" "=u")
15137         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15138   "TARGET_USE_FANCY_MATH_387
15139    && flag_unsafe_math_optimizations"
15140   "fptan"
15141   [(set_attr "type" "fpspc")
15142    (set_attr "mode" "XF")])
15144 ;; optimize sequence: fptan
15145 ;;                    fstp    %st(0)
15146 ;;                    fld1
15147 ;; into fptan insn.
15149 (define_peephole2
15150   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15151                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15152                              UNSPEC_TAN_ONE))
15153              (set (match_operand:XF 1 "register_operand" "")
15154                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15155    (set (match_dup 0)
15156         (match_operand:XF 3 "immediate_operand" ""))]
15157   "standard_80387_constant_p (operands[3]) == 2"
15158   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15159              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15160   "")
15162 (define_expand "tanxf2"
15163   [(parallel [(set (match_dup 2)
15164                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15165                               UNSPEC_TAN_ONE))
15166               (set (match_operand:XF 0 "register_operand" "")
15167                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15168   "TARGET_USE_FANCY_MATH_387
15169    && flag_unsafe_math_optimizations"
15171   operands[2] = gen_reg_rtx (XFmode);
15174 (define_insn "atan2df3_1"
15175   [(set (match_operand:DF 0 "register_operand" "=f")
15176         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15177                     (match_operand:DF 1 "register_operand" "u")]
15178                    UNSPEC_FPATAN))
15179    (clobber (match_scratch:DF 3 "=1"))]
15180   "TARGET_USE_FANCY_MATH_387
15181    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15182    && flag_unsafe_math_optimizations"
15183   "fpatan"
15184   [(set_attr "type" "fpspc")
15185    (set_attr "mode" "DF")])
15187 (define_expand "atan2df3"
15188   [(use (match_operand:DF 0 "register_operand" ""))
15189    (use (match_operand:DF 2 "register_operand" ""))
15190    (use (match_operand:DF 1 "register_operand" ""))]
15191   "TARGET_USE_FANCY_MATH_387
15192    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15193    && flag_unsafe_math_optimizations"
15195   rtx copy = gen_reg_rtx (DFmode);
15196   emit_move_insn (copy, operands[1]);
15197   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15198   DONE;
15201 (define_expand "atandf2"
15202   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15203                    (unspec:DF [(match_dup 2)
15204                                (match_operand:DF 1 "register_operand" "")]
15205                     UNSPEC_FPATAN))
15206               (clobber (match_scratch:DF 3 ""))])]
15207   "TARGET_USE_FANCY_MATH_387
15208    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15209    && flag_unsafe_math_optimizations"
15211   operands[2] = gen_reg_rtx (DFmode);
15212   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15215 (define_insn "atan2sf3_1"
15216   [(set (match_operand:SF 0 "register_operand" "=f")
15217         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15218                     (match_operand:SF 1 "register_operand" "u")]
15219                    UNSPEC_FPATAN))
15220    (clobber (match_scratch:SF 3 "=1"))]
15221   "TARGET_USE_FANCY_MATH_387
15222    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15223    && flag_unsafe_math_optimizations"
15224   "fpatan"
15225   [(set_attr "type" "fpspc")
15226    (set_attr "mode" "SF")])
15228 (define_expand "atan2sf3"
15229   [(use (match_operand:SF 0 "register_operand" ""))
15230    (use (match_operand:SF 2 "register_operand" ""))
15231    (use (match_operand:SF 1 "register_operand" ""))]
15232   "TARGET_USE_FANCY_MATH_387
15233    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15234    && flag_unsafe_math_optimizations"
15236   rtx copy = gen_reg_rtx (SFmode);
15237   emit_move_insn (copy, operands[1]);
15238   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15239   DONE;
15242 (define_expand "atansf2"
15243   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15244                    (unspec:SF [(match_dup 2)
15245                                (match_operand:SF 1 "register_operand" "")]
15246                     UNSPEC_FPATAN))
15247               (clobber (match_scratch:SF 3 ""))])]
15248   "TARGET_USE_FANCY_MATH_387
15249    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15250    && flag_unsafe_math_optimizations"
15252   operands[2] = gen_reg_rtx (SFmode);
15253   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15256 (define_insn "atan2xf3_1"
15257   [(set (match_operand:XF 0 "register_operand" "=f")
15258         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15259                     (match_operand:XF 1 "register_operand" "u")]
15260                    UNSPEC_FPATAN))
15261    (clobber (match_scratch:XF 3 "=1"))]
15262   "TARGET_USE_FANCY_MATH_387
15263    && flag_unsafe_math_optimizations"
15264   "fpatan"
15265   [(set_attr "type" "fpspc")
15266    (set_attr "mode" "XF")])
15268 (define_expand "atan2xf3"
15269   [(use (match_operand:XF 0 "register_operand" ""))
15270    (use (match_operand:XF 2 "register_operand" ""))
15271    (use (match_operand:XF 1 "register_operand" ""))]
15272   "TARGET_USE_FANCY_MATH_387
15273    && flag_unsafe_math_optimizations"
15275   rtx copy = gen_reg_rtx (XFmode);
15276   emit_move_insn (copy, operands[1]);
15277   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15278   DONE;
15281 (define_expand "atanxf2"
15282   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15283                    (unspec:XF [(match_dup 2)
15284                                (match_operand:XF 1 "register_operand" "")]
15285                     UNSPEC_FPATAN))
15286               (clobber (match_scratch:XF 3 ""))])]
15287   "TARGET_USE_FANCY_MATH_387
15288    && flag_unsafe_math_optimizations"
15290   operands[2] = gen_reg_rtx (XFmode);
15291   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15294 (define_expand "asindf2"
15295   [(set (match_dup 2)
15296         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15297    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15298    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15299    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15300    (parallel [(set (match_dup 7)
15301                    (unspec:XF [(match_dup 6) (match_dup 2)]
15302                               UNSPEC_FPATAN))
15303               (clobber (match_scratch:XF 8 ""))])
15304    (set (match_operand:DF 0 "register_operand" "")
15305         (float_truncate:DF (match_dup 7)))]
15306   "TARGET_USE_FANCY_MATH_387
15307    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15308    && flag_unsafe_math_optimizations"
15310   int i;
15312   for (i=2; i<8; i++)
15313     operands[i] = gen_reg_rtx (XFmode);
15315   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15318 (define_expand "asinsf2"
15319   [(set (match_dup 2)
15320         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15321    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15322    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15323    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15324    (parallel [(set (match_dup 7)
15325                    (unspec:XF [(match_dup 6) (match_dup 2)]
15326                               UNSPEC_FPATAN))
15327               (clobber (match_scratch:XF 8 ""))])
15328    (set (match_operand:SF 0 "register_operand" "")
15329         (float_truncate:SF (match_dup 7)))]
15330   "TARGET_USE_FANCY_MATH_387
15331    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15332    && flag_unsafe_math_optimizations"
15334   int i;
15336   for (i=2; i<8; i++)
15337     operands[i] = gen_reg_rtx (XFmode);
15339   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15342 (define_expand "asinxf2"
15343   [(set (match_dup 2)
15344         (mult:XF (match_operand:XF 1 "register_operand" "")
15345                  (match_dup 1)))
15346    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15347    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15348    (parallel [(set (match_operand:XF 0 "register_operand" "")
15349                    (unspec:XF [(match_dup 5) (match_dup 1)]
15350                               UNSPEC_FPATAN))
15351               (clobber (match_scratch:XF 6 ""))])]
15352   "TARGET_USE_FANCY_MATH_387
15353    && flag_unsafe_math_optimizations"
15355   int i;
15357   for (i=2; i<6; i++)
15358     operands[i] = gen_reg_rtx (XFmode);
15360   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15363 (define_expand "acosdf2"
15364   [(set (match_dup 2)
15365         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15366    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15367    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15368    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15369    (parallel [(set (match_dup 7)
15370                    (unspec:XF [(match_dup 2) (match_dup 6)]
15371                               UNSPEC_FPATAN))
15372               (clobber (match_scratch:XF 8 ""))])
15373    (set (match_operand:DF 0 "register_operand" "")
15374         (float_truncate:DF (match_dup 7)))]
15375   "TARGET_USE_FANCY_MATH_387
15376    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15377    && flag_unsafe_math_optimizations"
15379   int i;
15381   for (i=2; i<8; i++)
15382     operands[i] = gen_reg_rtx (XFmode);
15384   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15387 (define_expand "acossf2"
15388   [(set (match_dup 2)
15389         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15390    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15391    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15392    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15393    (parallel [(set (match_dup 7)
15394                    (unspec:XF [(match_dup 2) (match_dup 6)]
15395                               UNSPEC_FPATAN))
15396               (clobber (match_scratch:XF 8 ""))])
15397    (set (match_operand:SF 0 "register_operand" "")
15398         (float_truncate:SF (match_dup 7)))]
15399   "TARGET_USE_FANCY_MATH_387
15400    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15401    && flag_unsafe_math_optimizations"
15403   int i;
15405   for (i=2; i<8; i++)
15406     operands[i] = gen_reg_rtx (XFmode);
15408   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15411 (define_expand "acosxf2"
15412   [(set (match_dup 2)
15413         (mult:XF (match_operand:XF 1 "register_operand" "")
15414                  (match_dup 1)))
15415    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15416    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15417    (parallel [(set (match_operand:XF 0 "register_operand" "")
15418                    (unspec:XF [(match_dup 1) (match_dup 5)]
15419                               UNSPEC_FPATAN))
15420               (clobber (match_scratch:XF 6 ""))])]
15421   "TARGET_USE_FANCY_MATH_387
15422    && flag_unsafe_math_optimizations"
15424   int i;
15426   for (i=2; i<6; i++)
15427     operands[i] = gen_reg_rtx (XFmode);
15429   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15432 (define_insn "fyl2x_xf3"
15433   [(set (match_operand:XF 0 "register_operand" "=f")
15434         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15435                     (match_operand:XF 1 "register_operand" "u")]
15436                    UNSPEC_FYL2X))
15437    (clobber (match_scratch:XF 3 "=1"))]
15438   "TARGET_USE_FANCY_MATH_387
15439    && flag_unsafe_math_optimizations"
15440   "fyl2x"
15441   [(set_attr "type" "fpspc")
15442    (set_attr "mode" "XF")])
15444 (define_expand "logsf2"
15445   [(set (match_dup 2)
15446         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15447    (parallel [(set (match_dup 4)
15448                    (unspec:XF [(match_dup 2)
15449                                (match_dup 3)] UNSPEC_FYL2X))
15450               (clobber (match_scratch:XF 5 ""))])
15451    (set (match_operand:SF 0 "register_operand" "")
15452         (float_truncate:SF (match_dup 4)))]
15453   "TARGET_USE_FANCY_MATH_387
15454    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15455    && flag_unsafe_math_optimizations"
15457   rtx temp;
15459   operands[2] = gen_reg_rtx (XFmode);
15460   operands[3] = gen_reg_rtx (XFmode);
15461   operands[4] = gen_reg_rtx (XFmode);
15463   temp = standard_80387_constant_rtx (4); /* fldln2 */
15464   emit_move_insn (operands[3], temp);
15467 (define_expand "logdf2"
15468   [(set (match_dup 2)
15469         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15470    (parallel [(set (match_dup 4)
15471                    (unspec:XF [(match_dup 2)
15472                                (match_dup 3)] UNSPEC_FYL2X))
15473               (clobber (match_scratch:XF 5 ""))])
15474    (set (match_operand:DF 0 "register_operand" "")
15475         (float_truncate:DF (match_dup 4)))]
15476   "TARGET_USE_FANCY_MATH_387
15477    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15478    && flag_unsafe_math_optimizations"
15480   rtx temp;
15482   operands[2] = gen_reg_rtx (XFmode);
15483   operands[3] = gen_reg_rtx (XFmode);
15484   operands[4] = gen_reg_rtx (XFmode);
15486   temp = standard_80387_constant_rtx (4); /* fldln2 */
15487   emit_move_insn (operands[3], temp);
15490 (define_expand "logxf2"
15491   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15492                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15493                                (match_dup 2)] UNSPEC_FYL2X))
15494               (clobber (match_scratch:XF 3 ""))])]
15495   "TARGET_USE_FANCY_MATH_387
15496    && flag_unsafe_math_optimizations"
15498   rtx temp;
15500   operands[2] = gen_reg_rtx (XFmode);
15501   temp = standard_80387_constant_rtx (4); /* fldln2 */
15502   emit_move_insn (operands[2], temp);
15505 (define_expand "log10sf2"
15506   [(set (match_dup 2)
15507         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15508    (parallel [(set (match_dup 4)
15509                    (unspec:XF [(match_dup 2)
15510                                (match_dup 3)] UNSPEC_FYL2X))
15511               (clobber (match_scratch:XF 5 ""))])
15512    (set (match_operand:SF 0 "register_operand" "")
15513         (float_truncate:SF (match_dup 4)))]
15514   "TARGET_USE_FANCY_MATH_387
15515    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15516    && flag_unsafe_math_optimizations"
15518   rtx temp;
15520   operands[2] = gen_reg_rtx (XFmode);
15521   operands[3] = gen_reg_rtx (XFmode);
15522   operands[4] = gen_reg_rtx (XFmode);
15524   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15525   emit_move_insn (operands[3], temp);
15528 (define_expand "log10df2"
15529   [(set (match_dup 2)
15530         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15531    (parallel [(set (match_dup 4)
15532                    (unspec:XF [(match_dup 2)
15533                                (match_dup 3)] UNSPEC_FYL2X))
15534               (clobber (match_scratch:XF 5 ""))])
15535    (set (match_operand:DF 0 "register_operand" "")
15536         (float_truncate:DF (match_dup 4)))]
15537   "TARGET_USE_FANCY_MATH_387
15538    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15539    && flag_unsafe_math_optimizations"
15541   rtx temp;
15543   operands[2] = gen_reg_rtx (XFmode);
15544   operands[3] = gen_reg_rtx (XFmode);
15545   operands[4] = gen_reg_rtx (XFmode);
15547   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15548   emit_move_insn (operands[3], temp);
15551 (define_expand "log10xf2"
15552   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15553                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15554                                (match_dup 2)] UNSPEC_FYL2X))
15555               (clobber (match_scratch:XF 3 ""))])]
15556   "TARGET_USE_FANCY_MATH_387
15557    && flag_unsafe_math_optimizations"
15559   rtx temp;
15561   operands[2] = gen_reg_rtx (XFmode);
15562   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15563   emit_move_insn (operands[2], temp);
15566 (define_expand "log2sf2"
15567   [(set (match_dup 2)
15568         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15569    (parallel [(set (match_dup 4)
15570                    (unspec:XF [(match_dup 2)
15571                                (match_dup 3)] UNSPEC_FYL2X))
15572               (clobber (match_scratch:XF 5 ""))])
15573    (set (match_operand:SF 0 "register_operand" "")
15574         (float_truncate:SF (match_dup 4)))]
15575   "TARGET_USE_FANCY_MATH_387
15576    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15577    && flag_unsafe_math_optimizations"
15579   operands[2] = gen_reg_rtx (XFmode);
15580   operands[3] = gen_reg_rtx (XFmode);
15581   operands[4] = gen_reg_rtx (XFmode);
15583   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15586 (define_expand "log2df2"
15587   [(set (match_dup 2)
15588         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15589    (parallel [(set (match_dup 4)
15590                    (unspec:XF [(match_dup 2)
15591                                (match_dup 3)] UNSPEC_FYL2X))
15592               (clobber (match_scratch:XF 5 ""))])
15593    (set (match_operand:DF 0 "register_operand" "")
15594         (float_truncate:DF (match_dup 4)))]
15595   "TARGET_USE_FANCY_MATH_387
15596    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15597    && flag_unsafe_math_optimizations"
15599   operands[2] = gen_reg_rtx (XFmode);
15600   operands[3] = gen_reg_rtx (XFmode);
15601   operands[4] = gen_reg_rtx (XFmode);
15603   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15606 (define_expand "log2xf2"
15607   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15608                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15609                                (match_dup 2)] UNSPEC_FYL2X))
15610               (clobber (match_scratch:XF 3 ""))])]
15611   "TARGET_USE_FANCY_MATH_387
15612    && flag_unsafe_math_optimizations"
15614   operands[2] = gen_reg_rtx (XFmode);
15615   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15618 (define_insn "fyl2xp1_xf3"
15619   [(set (match_operand:XF 0 "register_operand" "=f")
15620         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15621                     (match_operand:XF 1 "register_operand" "u")]
15622                    UNSPEC_FYL2XP1))
15623    (clobber (match_scratch:XF 3 "=1"))]
15624   "TARGET_USE_FANCY_MATH_387
15625    && flag_unsafe_math_optimizations"
15626   "fyl2xp1"
15627   [(set_attr "type" "fpspc")
15628    (set_attr "mode" "XF")])
15630 (define_expand "log1psf2"
15631   [(use (match_operand:SF 0 "register_operand" ""))
15632    (use (match_operand:SF 1 "register_operand" ""))]
15633   "TARGET_USE_FANCY_MATH_387
15634    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15635    && flag_unsafe_math_optimizations"
15637   rtx op0 = gen_reg_rtx (XFmode);
15638   rtx op1 = gen_reg_rtx (XFmode);
15640   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15641   ix86_emit_i387_log1p (op0, op1);
15642   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15643   DONE;
15646 (define_expand "log1pdf2"
15647   [(use (match_operand:DF 0 "register_operand" ""))
15648    (use (match_operand:DF 1 "register_operand" ""))]
15649   "TARGET_USE_FANCY_MATH_387
15650    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15651    && flag_unsafe_math_optimizations"
15653   rtx op0 = gen_reg_rtx (XFmode);
15654   rtx op1 = gen_reg_rtx (XFmode);
15656   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15657   ix86_emit_i387_log1p (op0, op1);
15658   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15659   DONE;
15662 (define_expand "log1pxf2"
15663   [(use (match_operand:XF 0 "register_operand" ""))
15664    (use (match_operand:XF 1 "register_operand" ""))]
15665   "TARGET_USE_FANCY_MATH_387
15666    && flag_unsafe_math_optimizations"
15668   ix86_emit_i387_log1p (operands[0], operands[1]);
15669   DONE;
15672 (define_insn "*fxtractxf3"
15673   [(set (match_operand:XF 0 "register_operand" "=f")
15674         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15675                    UNSPEC_XTRACT_FRACT))
15676    (set (match_operand:XF 1 "register_operand" "=u")
15677         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15678   "TARGET_USE_FANCY_MATH_387
15679    && flag_unsafe_math_optimizations"
15680   "fxtract"
15681   [(set_attr "type" "fpspc")
15682    (set_attr "mode" "XF")])
15684 (define_expand "logbsf2"
15685   [(set (match_dup 2)
15686         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15687    (parallel [(set (match_dup 3)
15688                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15689               (set (match_dup 4)
15690                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15691    (set (match_operand:SF 0 "register_operand" "")
15692         (float_truncate:SF (match_dup 4)))]
15693   "TARGET_USE_FANCY_MATH_387
15694    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15695    && flag_unsafe_math_optimizations"
15697   operands[2] = gen_reg_rtx (XFmode);
15698   operands[3] = gen_reg_rtx (XFmode);
15699   operands[4] = gen_reg_rtx (XFmode);
15702 (define_expand "logbdf2"
15703   [(set (match_dup 2)
15704         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15705    (parallel [(set (match_dup 3)
15706                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15707               (set (match_dup 4)
15708                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15709    (set (match_operand:DF 0 "register_operand" "")
15710         (float_truncate:DF (match_dup 4)))]
15711   "TARGET_USE_FANCY_MATH_387
15712    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15713    && flag_unsafe_math_optimizations"
15715   operands[2] = gen_reg_rtx (XFmode);
15716   operands[3] = gen_reg_rtx (XFmode);
15717   operands[4] = gen_reg_rtx (XFmode);
15720 (define_expand "logbxf2"
15721   [(parallel [(set (match_dup 2)
15722                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15723                               UNSPEC_XTRACT_FRACT))
15724               (set (match_operand:XF 0 "register_operand" "")
15725                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15726   "TARGET_USE_FANCY_MATH_387
15727    && flag_unsafe_math_optimizations"
15729   operands[2] = gen_reg_rtx (XFmode);
15732 (define_expand "ilogbsi2"
15733   [(parallel [(set (match_dup 2)
15734                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15735                               UNSPEC_XTRACT_FRACT))
15736               (set (match_operand:XF 3 "register_operand" "")
15737                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15738    (parallel [(set (match_operand:SI 0 "register_operand" "")
15739                    (fix:SI (match_dup 3)))
15740               (clobber (reg:CC FLAGS_REG))])]
15741   "TARGET_USE_FANCY_MATH_387
15742    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15743    && flag_unsafe_math_optimizations"
15745   operands[2] = gen_reg_rtx (XFmode);
15746   operands[3] = gen_reg_rtx (XFmode);
15749 (define_insn "*f2xm1xf2"
15750   [(set (match_operand:XF 0 "register_operand" "=f")
15751         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15752          UNSPEC_F2XM1))]
15753   "TARGET_USE_FANCY_MATH_387
15754    && flag_unsafe_math_optimizations"
15755   "f2xm1"
15756   [(set_attr "type" "fpspc")
15757    (set_attr "mode" "XF")])
15759 (define_insn "*fscalexf4"
15760   [(set (match_operand:XF 0 "register_operand" "=f")
15761         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15762                     (match_operand:XF 3 "register_operand" "1")]
15763                    UNSPEC_FSCALE_FRACT))
15764    (set (match_operand:XF 1 "register_operand" "=u")
15765         (unspec:XF [(match_dup 2) (match_dup 3)]
15766                    UNSPEC_FSCALE_EXP))]
15767   "TARGET_USE_FANCY_MATH_387
15768    && flag_unsafe_math_optimizations"
15769   "fscale"
15770   [(set_attr "type" "fpspc")
15771    (set_attr "mode" "XF")])
15773 (define_expand "expsf2"
15774   [(set (match_dup 2)
15775         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15776    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15777    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15778    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15779    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15780    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15781    (parallel [(set (match_dup 10)
15782                    (unspec:XF [(match_dup 9) (match_dup 5)]
15783                               UNSPEC_FSCALE_FRACT))
15784               (set (match_dup 11)
15785                    (unspec:XF [(match_dup 9) (match_dup 5)]
15786                               UNSPEC_FSCALE_EXP))])
15787    (set (match_operand:SF 0 "register_operand" "")
15788         (float_truncate:SF (match_dup 10)))]
15789   "TARGET_USE_FANCY_MATH_387
15790    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15791    && flag_unsafe_math_optimizations"
15793   rtx temp;
15794   int i;
15796   for (i=2; i<12; i++)
15797     operands[i] = gen_reg_rtx (XFmode);
15798   temp = standard_80387_constant_rtx (5); /* fldl2e */
15799   emit_move_insn (operands[3], temp);
15800   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15803 (define_expand "expdf2"
15804   [(set (match_dup 2)
15805         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15806    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15807    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15808    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15809    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15810    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15811    (parallel [(set (match_dup 10)
15812                    (unspec:XF [(match_dup 9) (match_dup 5)]
15813                               UNSPEC_FSCALE_FRACT))
15814               (set (match_dup 11)
15815                    (unspec:XF [(match_dup 9) (match_dup 5)]
15816                               UNSPEC_FSCALE_EXP))])
15817    (set (match_operand:DF 0 "register_operand" "")
15818         (float_truncate:DF (match_dup 10)))]
15819   "TARGET_USE_FANCY_MATH_387
15820    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15821    && flag_unsafe_math_optimizations"
15823   rtx temp;
15824   int i;
15826   for (i=2; i<12; i++)
15827     operands[i] = gen_reg_rtx (XFmode);
15828   temp = standard_80387_constant_rtx (5); /* fldl2e */
15829   emit_move_insn (operands[3], temp);
15830   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15833 (define_expand "expxf2"
15834   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15835                                (match_dup 2)))
15836    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15837    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15838    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15839    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15840    (parallel [(set (match_operand:XF 0 "register_operand" "")
15841                    (unspec:XF [(match_dup 8) (match_dup 4)]
15842                               UNSPEC_FSCALE_FRACT))
15843               (set (match_dup 9)
15844                    (unspec:XF [(match_dup 8) (match_dup 4)]
15845                               UNSPEC_FSCALE_EXP))])]
15846   "TARGET_USE_FANCY_MATH_387
15847    && flag_unsafe_math_optimizations"
15849   rtx temp;
15850   int i;
15852   for (i=2; i<10; i++)
15853     operands[i] = gen_reg_rtx (XFmode);
15854   temp = standard_80387_constant_rtx (5); /* fldl2e */
15855   emit_move_insn (operands[2], temp);
15856   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15859 (define_expand "exp10sf2"
15860   [(set (match_dup 2)
15861         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15862    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15863    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15864    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15865    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15866    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15867    (parallel [(set (match_dup 10)
15868                    (unspec:XF [(match_dup 9) (match_dup 5)]
15869                               UNSPEC_FSCALE_FRACT))
15870               (set (match_dup 11)
15871                    (unspec:XF [(match_dup 9) (match_dup 5)]
15872                               UNSPEC_FSCALE_EXP))])
15873    (set (match_operand:SF 0 "register_operand" "")
15874         (float_truncate:SF (match_dup 10)))]
15875   "TARGET_USE_FANCY_MATH_387
15876    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15877    && flag_unsafe_math_optimizations"
15879   rtx temp;
15880   int i;
15882   for (i=2; i<12; i++)
15883     operands[i] = gen_reg_rtx (XFmode);
15884   temp = standard_80387_constant_rtx (6); /* fldl2t */
15885   emit_move_insn (operands[3], temp);
15886   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15889 (define_expand "exp10df2"
15890   [(set (match_dup 2)
15891         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15892    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15893    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15894    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15895    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15896    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15897    (parallel [(set (match_dup 10)
15898                    (unspec:XF [(match_dup 9) (match_dup 5)]
15899                               UNSPEC_FSCALE_FRACT))
15900               (set (match_dup 11)
15901                    (unspec:XF [(match_dup 9) (match_dup 5)]
15902                               UNSPEC_FSCALE_EXP))])
15903    (set (match_operand:DF 0 "register_operand" "")
15904         (float_truncate:DF (match_dup 10)))]
15905   "TARGET_USE_FANCY_MATH_387
15906    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15907    && flag_unsafe_math_optimizations"
15909   rtx temp;
15910   int i;
15912   for (i=2; i<12; i++)
15913     operands[i] = gen_reg_rtx (XFmode);
15914   temp = standard_80387_constant_rtx (6); /* fldl2t */
15915   emit_move_insn (operands[3], temp);
15916   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15919 (define_expand "exp10xf2"
15920   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15921                                (match_dup 2)))
15922    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15923    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15924    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15925    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15926    (parallel [(set (match_operand:XF 0 "register_operand" "")
15927                    (unspec:XF [(match_dup 8) (match_dup 4)]
15928                               UNSPEC_FSCALE_FRACT))
15929               (set (match_dup 9)
15930                    (unspec:XF [(match_dup 8) (match_dup 4)]
15931                               UNSPEC_FSCALE_EXP))])]
15932   "TARGET_USE_FANCY_MATH_387
15933    && flag_unsafe_math_optimizations"
15935   rtx temp;
15936   int i;
15938   for (i=2; i<10; i++)
15939     operands[i] = gen_reg_rtx (XFmode);
15940   temp = standard_80387_constant_rtx (6); /* fldl2t */
15941   emit_move_insn (operands[2], temp);
15942   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15945 (define_expand "exp2sf2"
15946   [(set (match_dup 2)
15947         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15948    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15949    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15950    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15951    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15952    (parallel [(set (match_dup 8)
15953                    (unspec:XF [(match_dup 7) (match_dup 3)]
15954                               UNSPEC_FSCALE_FRACT))
15955               (set (match_dup 9)
15956                    (unspec:XF [(match_dup 7) (match_dup 3)]
15957                               UNSPEC_FSCALE_EXP))])
15958    (set (match_operand:SF 0 "register_operand" "")
15959         (float_truncate:SF (match_dup 8)))]
15960   "TARGET_USE_FANCY_MATH_387
15961    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15962    && flag_unsafe_math_optimizations"
15964   int i;
15966   for (i=2; i<10; i++)
15967     operands[i] = gen_reg_rtx (XFmode);
15968   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15971 (define_expand "exp2df2"
15972   [(set (match_dup 2)
15973         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15974    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15975    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15976    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15977    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15978    (parallel [(set (match_dup 8)
15979                    (unspec:XF [(match_dup 7) (match_dup 3)]
15980                               UNSPEC_FSCALE_FRACT))
15981               (set (match_dup 9)
15982                    (unspec:XF [(match_dup 7) (match_dup 3)]
15983                               UNSPEC_FSCALE_EXP))])
15984    (set (match_operand:DF 0 "register_operand" "")
15985         (float_truncate:DF (match_dup 8)))]
15986   "TARGET_USE_FANCY_MATH_387
15987    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15988    && flag_unsafe_math_optimizations"
15990   int i;
15992   for (i=2; i<10; i++)
15993     operands[i] = gen_reg_rtx (XFmode);
15994   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15997 (define_expand "exp2xf2"
15998   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15999    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16000    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16001    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16002    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16003    (parallel [(set (match_operand:XF 0 "register_operand" "")
16004                    (unspec:XF [(match_dup 7) (match_dup 3)]
16005                               UNSPEC_FSCALE_FRACT))
16006               (set (match_dup 8)
16007                    (unspec:XF [(match_dup 7) (match_dup 3)]
16008                               UNSPEC_FSCALE_EXP))])]
16009   "TARGET_USE_FANCY_MATH_387
16010    && flag_unsafe_math_optimizations"
16012   int i;
16014   for (i=2; i<9; i++)
16015     operands[i] = gen_reg_rtx (XFmode);
16016   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16019 (define_expand "expm1df2"
16020   [(set (match_dup 2)
16021         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16022    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16023    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16024    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16025    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16026    (parallel [(set (match_dup 8)
16027                    (unspec:XF [(match_dup 7) (match_dup 5)]
16028                               UNSPEC_FSCALE_FRACT))
16029                    (set (match_dup 9)
16030                    (unspec:XF [(match_dup 7) (match_dup 5)]
16031                               UNSPEC_FSCALE_EXP))])
16032    (parallel [(set (match_dup 11)
16033                    (unspec:XF [(match_dup 10) (match_dup 9)]
16034                               UNSPEC_FSCALE_FRACT))
16035               (set (match_dup 12)
16036                    (unspec:XF [(match_dup 10) (match_dup 9)]
16037                               UNSPEC_FSCALE_EXP))])
16038    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16039    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16040    (set (match_operand:DF 0 "register_operand" "")
16041         (float_truncate:DF (match_dup 14)))]
16042   "TARGET_USE_FANCY_MATH_387
16043    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16044    && flag_unsafe_math_optimizations"
16046   rtx temp;
16047   int i;
16049   for (i=2; i<15; i++)
16050     operands[i] = gen_reg_rtx (XFmode);
16051   temp = standard_80387_constant_rtx (5); /* fldl2e */
16052   emit_move_insn (operands[3], temp);
16053   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16056 (define_expand "expm1sf2"
16057   [(set (match_dup 2)
16058         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16059    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16060    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16061    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16062    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16063    (parallel [(set (match_dup 8)
16064                    (unspec:XF [(match_dup 7) (match_dup 5)]
16065                               UNSPEC_FSCALE_FRACT))
16066                    (set (match_dup 9)
16067                    (unspec:XF [(match_dup 7) (match_dup 5)]
16068                               UNSPEC_FSCALE_EXP))])
16069    (parallel [(set (match_dup 11)
16070                    (unspec:XF [(match_dup 10) (match_dup 9)]
16071                               UNSPEC_FSCALE_FRACT))
16072               (set (match_dup 12)
16073                    (unspec:XF [(match_dup 10) (match_dup 9)]
16074                               UNSPEC_FSCALE_EXP))])
16075    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16076    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16077    (set (match_operand:SF 0 "register_operand" "")
16078         (float_truncate:SF (match_dup 14)))]
16079   "TARGET_USE_FANCY_MATH_387
16080    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16081    && flag_unsafe_math_optimizations"
16083   rtx temp;
16084   int i;
16086   for (i=2; i<15; i++)
16087     operands[i] = gen_reg_rtx (XFmode);
16088   temp = standard_80387_constant_rtx (5); /* fldl2e */
16089   emit_move_insn (operands[3], temp);
16090   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16093 (define_expand "expm1xf2"
16094   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16095                                (match_dup 2)))
16096    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16097    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16098    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16099    (parallel [(set (match_dup 7)
16100                    (unspec:XF [(match_dup 6) (match_dup 4)]
16101                               UNSPEC_FSCALE_FRACT))
16102                    (set (match_dup 8)
16103                    (unspec:XF [(match_dup 6) (match_dup 4)]
16104                               UNSPEC_FSCALE_EXP))])
16105    (parallel [(set (match_dup 10)
16106                    (unspec:XF [(match_dup 9) (match_dup 8)]
16107                               UNSPEC_FSCALE_FRACT))
16108               (set (match_dup 11)
16109                    (unspec:XF [(match_dup 9) (match_dup 8)]
16110                               UNSPEC_FSCALE_EXP))])
16111    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16112    (set (match_operand:XF 0 "register_operand" "")
16113         (plus:XF (match_dup 12) (match_dup 7)))]
16114   "TARGET_USE_FANCY_MATH_387
16115    && flag_unsafe_math_optimizations"
16117   rtx temp;
16118   int i;
16120   for (i=2; i<13; i++)
16121     operands[i] = gen_reg_rtx (XFmode);
16122   temp = standard_80387_constant_rtx (5); /* fldl2e */
16123   emit_move_insn (operands[2], temp);
16124   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16127 (define_expand "ldexpdf3"
16128   [(set (match_dup 3)
16129         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16130    (set (match_dup 4)
16131         (float:XF (match_operand:SI 2 "register_operand" "")))
16132    (parallel [(set (match_dup 5)
16133                    (unspec:XF [(match_dup 3) (match_dup 4)]
16134                               UNSPEC_FSCALE_FRACT))
16135               (set (match_dup 6)
16136                    (unspec:XF [(match_dup 3) (match_dup 4)]
16137                               UNSPEC_FSCALE_EXP))])
16138    (set (match_operand:DF 0 "register_operand" "")
16139         (float_truncate:DF (match_dup 5)))]
16140   "TARGET_USE_FANCY_MATH_387
16141    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16142    && flag_unsafe_math_optimizations"
16144   int i;
16146   for (i=3; i<7; i++)
16147     operands[i] = gen_reg_rtx (XFmode);
16150 (define_expand "ldexpsf3"
16151   [(set (match_dup 3)
16152         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16153    (set (match_dup 4)
16154         (float:XF (match_operand:SI 2 "register_operand" "")))
16155    (parallel [(set (match_dup 5)
16156                    (unspec:XF [(match_dup 3) (match_dup 4)]
16157                               UNSPEC_FSCALE_FRACT))
16158               (set (match_dup 6)
16159                    (unspec:XF [(match_dup 3) (match_dup 4)]
16160                               UNSPEC_FSCALE_EXP))])
16161    (set (match_operand:SF 0 "register_operand" "")
16162         (float_truncate:SF (match_dup 5)))]
16163   "TARGET_USE_FANCY_MATH_387
16164    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16165    && flag_unsafe_math_optimizations"
16167   int i;
16169   for (i=3; i<7; i++)
16170     operands[i] = gen_reg_rtx (XFmode);
16173 (define_expand "ldexpxf3"
16174   [(set (match_dup 3)
16175         (float:XF (match_operand:SI 2 "register_operand" "")))
16176    (parallel [(set (match_operand:XF 0 " register_operand" "")
16177                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16178                                (match_dup 3)]
16179                               UNSPEC_FSCALE_FRACT))
16180               (set (match_dup 4)
16181                    (unspec:XF [(match_dup 1) (match_dup 3)]
16182                               UNSPEC_FSCALE_EXP))])]
16183   "TARGET_USE_FANCY_MATH_387
16184    && flag_unsafe_math_optimizations"
16186   int i;
16188   for (i=3; i<5; i++)
16189     operands[i] = gen_reg_rtx (XFmode);
16193 (define_insn "frndintxf2"
16194   [(set (match_operand:XF 0 "register_operand" "=f")
16195         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16196          UNSPEC_FRNDINT))]
16197   "TARGET_USE_FANCY_MATH_387
16198    && flag_unsafe_math_optimizations"
16199   "frndint"
16200   [(set_attr "type" "fpspc")
16201    (set_attr "mode" "XF")])
16203 (define_expand "rintdf2"
16204   [(use (match_operand:DF 0 "register_operand" ""))
16205    (use (match_operand:DF 1 "register_operand" ""))]
16206   "TARGET_USE_FANCY_MATH_387
16207    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16208    && flag_unsafe_math_optimizations"
16210   rtx op0 = gen_reg_rtx (XFmode);
16211   rtx op1 = gen_reg_rtx (XFmode);
16213   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16214   emit_insn (gen_frndintxf2 (op0, op1));
16216   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16217   DONE;
16220 (define_expand "rintsf2"
16221   [(use (match_operand:SF 0 "register_operand" ""))
16222    (use (match_operand:SF 1 "register_operand" ""))]
16223   "TARGET_USE_FANCY_MATH_387
16224    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16225    && flag_unsafe_math_optimizations"
16227   rtx op0 = gen_reg_rtx (XFmode);
16228   rtx op1 = gen_reg_rtx (XFmode);
16230   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16231   emit_insn (gen_frndintxf2 (op0, op1));
16233   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16234   DONE;
16237 (define_expand "rintxf2"
16238   [(use (match_operand:XF 0 "register_operand" ""))
16239    (use (match_operand:XF 1 "register_operand" ""))]
16240   "TARGET_USE_FANCY_MATH_387
16241    && flag_unsafe_math_optimizations"
16243   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16244   DONE;
16247 (define_insn "frndintxf2_floor"
16248   [(set (match_operand:XF 0 "register_operand" "=f")
16249         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16250          UNSPEC_FRNDINT_FLOOR))
16251    (use (match_operand:HI 2 "memory_operand" "m"))
16252    (use (match_operand:HI 3 "memory_operand" "m"))]
16253   "TARGET_USE_FANCY_MATH_387
16254    && flag_unsafe_math_optimizations"
16255   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16256   [(set_attr "type" "frndint")
16257    (set_attr "i387_cw" "floor")
16258    (set_attr "mode" "XF")])
16260 (define_expand "floordf2"
16261   [(use (match_operand:DF 0 "register_operand" ""))
16262    (use (match_operand:DF 1 "register_operand" ""))]
16263   "TARGET_USE_FANCY_MATH_387
16264    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16265    && flag_unsafe_math_optimizations"
16267   rtx op0 = gen_reg_rtx (XFmode);
16268   rtx op1 = gen_reg_rtx (XFmode);
16269   rtx op2 = assign_386_stack_local (HImode, 1);
16270   rtx op3 = assign_386_stack_local (HImode, 2);
16271         
16272   ix86_optimize_mode_switching = 1;
16274   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16275   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16277   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16278   DONE;
16281 (define_expand "floorsf2"
16282   [(use (match_operand:SF 0 "register_operand" ""))
16283    (use (match_operand:SF 1 "register_operand" ""))]
16284   "TARGET_USE_FANCY_MATH_387
16285    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16286    && flag_unsafe_math_optimizations"
16288   rtx op0 = gen_reg_rtx (XFmode);
16289   rtx op1 = gen_reg_rtx (XFmode);
16290   rtx op2 = assign_386_stack_local (HImode, 1);
16291   rtx op3 = assign_386_stack_local (HImode, 2);
16292         
16293   ix86_optimize_mode_switching = 1;
16295   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16296   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16298   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16299   DONE;
16302 (define_expand "floorxf2"
16303   [(use (match_operand:XF 0 "register_operand" ""))
16304    (use (match_operand:XF 1 "register_operand" ""))]
16305   "TARGET_USE_FANCY_MATH_387
16306    && flag_unsafe_math_optimizations"
16308   rtx op2 = assign_386_stack_local (HImode, 1);
16309   rtx op3 = assign_386_stack_local (HImode, 2);
16310         
16311   ix86_optimize_mode_switching = 1;
16313   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16314   DONE;
16317 (define_insn "frndintxf2_ceil"
16318   [(set (match_operand:XF 0 "register_operand" "=f")
16319         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16320          UNSPEC_FRNDINT_CEIL))
16321    (use (match_operand:HI 2 "memory_operand" "m"))
16322    (use (match_operand:HI 3 "memory_operand" "m"))]
16323   "TARGET_USE_FANCY_MATH_387
16324    && flag_unsafe_math_optimizations"
16325   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16326   [(set_attr "type" "frndint")
16327    (set_attr "i387_cw" "ceil")
16328    (set_attr "mode" "XF")])
16330 (define_expand "ceildf2"
16331   [(use (match_operand:DF 0 "register_operand" ""))
16332    (use (match_operand:DF 1 "register_operand" ""))]
16333   "TARGET_USE_FANCY_MATH_387
16334    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16335    && flag_unsafe_math_optimizations"
16337   rtx op0 = gen_reg_rtx (XFmode);
16338   rtx op1 = gen_reg_rtx (XFmode);
16339   rtx op2 = assign_386_stack_local (HImode, 1);
16340   rtx op3 = assign_386_stack_local (HImode, 2);
16341         
16342   ix86_optimize_mode_switching = 1;
16344   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16345   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16347   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16348   DONE;
16351 (define_expand "ceilsf2"
16352   [(use (match_operand:SF 0 "register_operand" ""))
16353    (use (match_operand:SF 1 "register_operand" ""))]
16354   "TARGET_USE_FANCY_MATH_387
16355    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16356    && flag_unsafe_math_optimizations"
16358   rtx op0 = gen_reg_rtx (XFmode);
16359   rtx op1 = gen_reg_rtx (XFmode);
16360   rtx op2 = assign_386_stack_local (HImode, 1);
16361   rtx op3 = assign_386_stack_local (HImode, 2);
16362         
16363   ix86_optimize_mode_switching = 1;
16365   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16366   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16368   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16369   DONE;
16372 (define_expand "ceilxf2"
16373   [(use (match_operand:XF 0 "register_operand" ""))
16374    (use (match_operand:XF 1 "register_operand" ""))]
16375   "TARGET_USE_FANCY_MATH_387
16376    && flag_unsafe_math_optimizations"
16378   rtx op2 = assign_386_stack_local (HImode, 1);
16379   rtx op3 = assign_386_stack_local (HImode, 2);
16380         
16381   ix86_optimize_mode_switching = 1;
16383   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16384   DONE;
16387 (define_insn "frndintxf2_trunc"
16388   [(set (match_operand:XF 0 "register_operand" "=f")
16389         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16390          UNSPEC_FRNDINT_TRUNC))
16391    (use (match_operand:HI 2 "memory_operand" "m"))
16392    (use (match_operand:HI 3 "memory_operand" "m"))]
16393   "TARGET_USE_FANCY_MATH_387
16394    && flag_unsafe_math_optimizations"
16395   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16396   [(set_attr "type" "frndint")
16397    (set_attr "i387_cw" "trunc")
16398    (set_attr "mode" "XF")])
16400 (define_expand "btruncdf2"
16401   [(use (match_operand:DF 0 "register_operand" ""))
16402    (use (match_operand:DF 1 "register_operand" ""))]
16403   "TARGET_USE_FANCY_MATH_387
16404    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16405    && flag_unsafe_math_optimizations"
16407   rtx op0 = gen_reg_rtx (XFmode);
16408   rtx op1 = gen_reg_rtx (XFmode);
16409   rtx op2 = assign_386_stack_local (HImode, 1);
16410   rtx op3 = assign_386_stack_local (HImode, 2);
16411         
16412   ix86_optimize_mode_switching = 1;
16414   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16415   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16417   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16418   DONE;
16421 (define_expand "btruncsf2"
16422   [(use (match_operand:SF 0 "register_operand" ""))
16423    (use (match_operand:SF 1 "register_operand" ""))]
16424   "TARGET_USE_FANCY_MATH_387
16425    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16426    && flag_unsafe_math_optimizations"
16428   rtx op0 = gen_reg_rtx (XFmode);
16429   rtx op1 = gen_reg_rtx (XFmode);
16430   rtx op2 = assign_386_stack_local (HImode, 1);
16431   rtx op3 = assign_386_stack_local (HImode, 2);
16432         
16433   ix86_optimize_mode_switching = 1;
16435   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16436   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16438   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16439   DONE;
16442 (define_expand "btruncxf2"
16443   [(use (match_operand:XF 0 "register_operand" ""))
16444    (use (match_operand:XF 1 "register_operand" ""))]
16445   "TARGET_USE_FANCY_MATH_387
16446    && flag_unsafe_math_optimizations"
16448   rtx op2 = assign_386_stack_local (HImode, 1);
16449   rtx op3 = assign_386_stack_local (HImode, 2);
16450         
16451   ix86_optimize_mode_switching = 1;
16453   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16454   DONE;
16457 (define_insn "frndintxf2_mask_pm"
16458   [(set (match_operand:XF 0 "register_operand" "=f")
16459         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16460          UNSPEC_FRNDINT_MASK_PM))
16461    (use (match_operand:HI 2 "memory_operand" "m"))
16462    (use (match_operand:HI 3 "memory_operand" "m"))]
16463   "TARGET_USE_FANCY_MATH_387
16464    && flag_unsafe_math_optimizations"
16465   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16466   [(set_attr "type" "frndint")
16467    (set_attr "i387_cw" "mask_pm")
16468    (set_attr "mode" "XF")])
16470 (define_expand "nearbyintdf2"
16471   [(use (match_operand:DF 0 "register_operand" ""))
16472    (use (match_operand:DF 1 "register_operand" ""))]
16473   "TARGET_USE_FANCY_MATH_387
16474    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16475    && flag_unsafe_math_optimizations"
16477   rtx op0 = gen_reg_rtx (XFmode);
16478   rtx op1 = gen_reg_rtx (XFmode);
16479   rtx op2 = assign_386_stack_local (HImode, 1);
16480   rtx op3 = assign_386_stack_local (HImode, 2);
16481         
16482   ix86_optimize_mode_switching = 1;
16484   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16485   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16487   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16488   DONE;
16491 (define_expand "nearbyintsf2"
16492   [(use (match_operand:SF 0 "register_operand" ""))
16493    (use (match_operand:SF 1 "register_operand" ""))]
16494   "TARGET_USE_FANCY_MATH_387
16495    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16496    && flag_unsafe_math_optimizations"
16498   rtx op0 = gen_reg_rtx (XFmode);
16499   rtx op1 = gen_reg_rtx (XFmode);
16500   rtx op2 = assign_386_stack_local (HImode, 1);
16501   rtx op3 = assign_386_stack_local (HImode, 2);
16502         
16503   ix86_optimize_mode_switching = 1;
16505   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16506   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16508   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16509   DONE;
16512 (define_expand "nearbyintxf2"
16513   [(use (match_operand:XF 0 "register_operand" ""))
16514    (use (match_operand:XF 1 "register_operand" ""))]
16515   "TARGET_USE_FANCY_MATH_387
16516    && flag_unsafe_math_optimizations"
16518   rtx op2 = assign_386_stack_local (HImode, 1);
16519   rtx op3 = assign_386_stack_local (HImode, 2);
16520         
16521   ix86_optimize_mode_switching = 1;
16523   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16524                                      op2, op3));
16525   DONE;
16529 ;; Block operation instructions
16531 (define_insn "cld"
16532  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16533  ""
16534  "cld"
16535   [(set_attr "type" "cld")])
16537 (define_expand "movmemsi"
16538   [(use (match_operand:BLK 0 "memory_operand" ""))
16539    (use (match_operand:BLK 1 "memory_operand" ""))
16540    (use (match_operand:SI 2 "nonmemory_operand" ""))
16541    (use (match_operand:SI 3 "const_int_operand" ""))]
16542   "! optimize_size"
16544  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16545    DONE;
16546  else
16547    FAIL;
16550 (define_expand "movmemdi"
16551   [(use (match_operand:BLK 0 "memory_operand" ""))
16552    (use (match_operand:BLK 1 "memory_operand" ""))
16553    (use (match_operand:DI 2 "nonmemory_operand" ""))
16554    (use (match_operand:DI 3 "const_int_operand" ""))]
16555   "TARGET_64BIT"
16557  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16558    DONE;
16559  else
16560    FAIL;
16563 ;; Most CPUs don't like single string operations
16564 ;; Handle this case here to simplify previous expander.
16566 (define_expand "strmov"
16567   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16568    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16569    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16570               (clobber (reg:CC FLAGS_REG))])
16571    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16572               (clobber (reg:CC FLAGS_REG))])]
16573   ""
16575   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16577   /* If .md ever supports :P for Pmode, these can be directly
16578      in the pattern above.  */
16579   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16580   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16582   if (TARGET_SINGLE_STRINGOP || optimize_size)
16583     {
16584       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16585                                       operands[2], operands[3],
16586                                       operands[5], operands[6]));
16587       DONE;
16588     }
16590   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16593 (define_expand "strmov_singleop"
16594   [(parallel [(set (match_operand 1 "memory_operand" "")
16595                    (match_operand 3 "memory_operand" ""))
16596               (set (match_operand 0 "register_operand" "")
16597                    (match_operand 4 "" ""))
16598               (set (match_operand 2 "register_operand" "")
16599                    (match_operand 5 "" ""))
16600               (use (reg:SI DIRFLAG_REG))])]
16601   "TARGET_SINGLE_STRINGOP || optimize_size"
16602   "")
16604 (define_insn "*strmovdi_rex_1"
16605   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16606         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16607    (set (match_operand:DI 0 "register_operand" "=D")
16608         (plus:DI (match_dup 2)
16609                  (const_int 8)))
16610    (set (match_operand:DI 1 "register_operand" "=S")
16611         (plus:DI (match_dup 3)
16612                  (const_int 8)))
16613    (use (reg:SI DIRFLAG_REG))]
16614   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16615   "movsq"
16616   [(set_attr "type" "str")
16617    (set_attr "mode" "DI")
16618    (set_attr "memory" "both")])
16620 (define_insn "*strmovsi_1"
16621   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16622         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16623    (set (match_operand:SI 0 "register_operand" "=D")
16624         (plus:SI (match_dup 2)
16625                  (const_int 4)))
16626    (set (match_operand:SI 1 "register_operand" "=S")
16627         (plus:SI (match_dup 3)
16628                  (const_int 4)))
16629    (use (reg:SI DIRFLAG_REG))]
16630   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16631   "{movsl|movsd}"
16632   [(set_attr "type" "str")
16633    (set_attr "mode" "SI")
16634    (set_attr "memory" "both")])
16636 (define_insn "*strmovsi_rex_1"
16637   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16638         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16639    (set (match_operand:DI 0 "register_operand" "=D")
16640         (plus:DI (match_dup 2)
16641                  (const_int 4)))
16642    (set (match_operand:DI 1 "register_operand" "=S")
16643         (plus:DI (match_dup 3)
16644                  (const_int 4)))
16645    (use (reg:SI DIRFLAG_REG))]
16646   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16647   "{movsl|movsd}"
16648   [(set_attr "type" "str")
16649    (set_attr "mode" "SI")
16650    (set_attr "memory" "both")])
16652 (define_insn "*strmovhi_1"
16653   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16654         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16655    (set (match_operand:SI 0 "register_operand" "=D")
16656         (plus:SI (match_dup 2)
16657                  (const_int 2)))
16658    (set (match_operand:SI 1 "register_operand" "=S")
16659         (plus:SI (match_dup 3)
16660                  (const_int 2)))
16661    (use (reg:SI DIRFLAG_REG))]
16662   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16663   "movsw"
16664   [(set_attr "type" "str")
16665    (set_attr "memory" "both")
16666    (set_attr "mode" "HI")])
16668 (define_insn "*strmovhi_rex_1"
16669   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16670         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16671    (set (match_operand:DI 0 "register_operand" "=D")
16672         (plus:DI (match_dup 2)
16673                  (const_int 2)))
16674    (set (match_operand:DI 1 "register_operand" "=S")
16675         (plus:DI (match_dup 3)
16676                  (const_int 2)))
16677    (use (reg:SI DIRFLAG_REG))]
16678   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16679   "movsw"
16680   [(set_attr "type" "str")
16681    (set_attr "memory" "both")
16682    (set_attr "mode" "HI")])
16684 (define_insn "*strmovqi_1"
16685   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16686         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16687    (set (match_operand:SI 0 "register_operand" "=D")
16688         (plus:SI (match_dup 2)
16689                  (const_int 1)))
16690    (set (match_operand:SI 1 "register_operand" "=S")
16691         (plus:SI (match_dup 3)
16692                  (const_int 1)))
16693    (use (reg:SI DIRFLAG_REG))]
16694   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16695   "movsb"
16696   [(set_attr "type" "str")
16697    (set_attr "memory" "both")
16698    (set_attr "mode" "QI")])
16700 (define_insn "*strmovqi_rex_1"
16701   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16702         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16703    (set (match_operand:DI 0 "register_operand" "=D")
16704         (plus:DI (match_dup 2)
16705                  (const_int 1)))
16706    (set (match_operand:DI 1 "register_operand" "=S")
16707         (plus:DI (match_dup 3)
16708                  (const_int 1)))
16709    (use (reg:SI DIRFLAG_REG))]
16710   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16711   "movsb"
16712   [(set_attr "type" "str")
16713    (set_attr "memory" "both")
16714    (set_attr "mode" "QI")])
16716 (define_expand "rep_mov"
16717   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16718               (set (match_operand 0 "register_operand" "")
16719                    (match_operand 5 "" ""))
16720               (set (match_operand 2 "register_operand" "")
16721                    (match_operand 6 "" ""))
16722               (set (match_operand 1 "memory_operand" "")
16723                    (match_operand 3 "memory_operand" ""))
16724               (use (match_dup 4))
16725               (use (reg:SI DIRFLAG_REG))])]
16726   ""
16727   "")
16729 (define_insn "*rep_movdi_rex64"
16730   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16731    (set (match_operand:DI 0 "register_operand" "=D") 
16732         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16733                             (const_int 3))
16734                  (match_operand:DI 3 "register_operand" "0")))
16735    (set (match_operand:DI 1 "register_operand" "=S") 
16736         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16737                  (match_operand:DI 4 "register_operand" "1")))
16738    (set (mem:BLK (match_dup 3))
16739         (mem:BLK (match_dup 4)))
16740    (use (match_dup 5))
16741    (use (reg:SI DIRFLAG_REG))]
16742   "TARGET_64BIT"
16743   "{rep\;movsq|rep movsq}"
16744   [(set_attr "type" "str")
16745    (set_attr "prefix_rep" "1")
16746    (set_attr "memory" "both")
16747    (set_attr "mode" "DI")])
16749 (define_insn "*rep_movsi"
16750   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16751    (set (match_operand:SI 0 "register_operand" "=D") 
16752         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16753                             (const_int 2))
16754                  (match_operand:SI 3 "register_operand" "0")))
16755    (set (match_operand:SI 1 "register_operand" "=S") 
16756         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16757                  (match_operand:SI 4 "register_operand" "1")))
16758    (set (mem:BLK (match_dup 3))
16759         (mem:BLK (match_dup 4)))
16760    (use (match_dup 5))
16761    (use (reg:SI DIRFLAG_REG))]
16762   "!TARGET_64BIT"
16763   "{rep\;movsl|rep movsd}"
16764   [(set_attr "type" "str")
16765    (set_attr "prefix_rep" "1")
16766    (set_attr "memory" "both")
16767    (set_attr "mode" "SI")])
16769 (define_insn "*rep_movsi_rex64"
16770   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16771    (set (match_operand:DI 0 "register_operand" "=D") 
16772         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16773                             (const_int 2))
16774                  (match_operand:DI 3 "register_operand" "0")))
16775    (set (match_operand:DI 1 "register_operand" "=S") 
16776         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16777                  (match_operand:DI 4 "register_operand" "1")))
16778    (set (mem:BLK (match_dup 3))
16779         (mem:BLK (match_dup 4)))
16780    (use (match_dup 5))
16781    (use (reg:SI DIRFLAG_REG))]
16782   "TARGET_64BIT"
16783   "{rep\;movsl|rep movsd}"
16784   [(set_attr "type" "str")
16785    (set_attr "prefix_rep" "1")
16786    (set_attr "memory" "both")
16787    (set_attr "mode" "SI")])
16789 (define_insn "*rep_movqi"
16790   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16791    (set (match_operand:SI 0 "register_operand" "=D") 
16792         (plus:SI (match_operand:SI 3 "register_operand" "0")
16793                  (match_operand:SI 5 "register_operand" "2")))
16794    (set (match_operand:SI 1 "register_operand" "=S") 
16795         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16796    (set (mem:BLK (match_dup 3))
16797         (mem:BLK (match_dup 4)))
16798    (use (match_dup 5))
16799    (use (reg:SI DIRFLAG_REG))]
16800   "!TARGET_64BIT"
16801   "{rep\;movsb|rep movsb}"
16802   [(set_attr "type" "str")
16803    (set_attr "prefix_rep" "1")
16804    (set_attr "memory" "both")
16805    (set_attr "mode" "SI")])
16807 (define_insn "*rep_movqi_rex64"
16808   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16809    (set (match_operand:DI 0 "register_operand" "=D") 
16810         (plus:DI (match_operand:DI 3 "register_operand" "0")
16811                  (match_operand:DI 5 "register_operand" "2")))
16812    (set (match_operand:DI 1 "register_operand" "=S") 
16813         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16814    (set (mem:BLK (match_dup 3))
16815         (mem:BLK (match_dup 4)))
16816    (use (match_dup 5))
16817    (use (reg:SI DIRFLAG_REG))]
16818   "TARGET_64BIT"
16819   "{rep\;movsb|rep movsb}"
16820   [(set_attr "type" "str")
16821    (set_attr "prefix_rep" "1")
16822    (set_attr "memory" "both")
16823    (set_attr "mode" "SI")])
16825 (define_expand "clrmemsi"
16826    [(use (match_operand:BLK 0 "memory_operand" ""))
16827     (use (match_operand:SI 1 "nonmemory_operand" ""))
16828     (use (match_operand 2 "const_int_operand" ""))]
16829   ""
16831  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16832    DONE;
16833  else
16834    FAIL;
16837 (define_expand "clrmemdi"
16838    [(use (match_operand:BLK 0 "memory_operand" ""))
16839     (use (match_operand:DI 1 "nonmemory_operand" ""))
16840     (use (match_operand 2 "const_int_operand" ""))]
16841   "TARGET_64BIT"
16843  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16844    DONE;
16845  else
16846    FAIL;
16849 ;; Most CPUs don't like single string operations
16850 ;; Handle this case here to simplify previous expander.
16852 (define_expand "strset"
16853   [(set (match_operand 1 "memory_operand" "")
16854         (match_operand 2 "register_operand" ""))
16855    (parallel [(set (match_operand 0 "register_operand" "")
16856                    (match_dup 3))
16857               (clobber (reg:CC FLAGS_REG))])]
16858   ""
16860   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16861     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16863   /* If .md ever supports :P for Pmode, this can be directly
16864      in the pattern above.  */
16865   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16866                               GEN_INT (GET_MODE_SIZE (GET_MODE
16867                                                       (operands[2]))));
16868   if (TARGET_SINGLE_STRINGOP || optimize_size)
16869     {
16870       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16871                                       operands[3]));
16872       DONE;
16873     }
16876 (define_expand "strset_singleop"
16877   [(parallel [(set (match_operand 1 "memory_operand" "")
16878                    (match_operand 2 "register_operand" ""))
16879               (set (match_operand 0 "register_operand" "")
16880                    (match_operand 3 "" ""))
16881               (use (reg:SI DIRFLAG_REG))])]
16882   "TARGET_SINGLE_STRINGOP || optimize_size"
16883   "")
16885 (define_insn "*strsetdi_rex_1"
16886   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16887         (match_operand:DI 2 "register_operand" "a"))
16888    (set (match_operand:DI 0 "register_operand" "=D")
16889         (plus:DI (match_dup 1)
16890                  (const_int 8)))
16891    (use (reg:SI DIRFLAG_REG))]
16892   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16893   "stosq"
16894   [(set_attr "type" "str")
16895    (set_attr "memory" "store")
16896    (set_attr "mode" "DI")])
16898 (define_insn "*strsetsi_1"
16899   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16900         (match_operand:SI 2 "register_operand" "a"))
16901    (set (match_operand:SI 0 "register_operand" "=D")
16902         (plus:SI (match_dup 1)
16903                  (const_int 4)))
16904    (use (reg:SI DIRFLAG_REG))]
16905   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16906   "{stosl|stosd}"
16907   [(set_attr "type" "str")
16908    (set_attr "memory" "store")
16909    (set_attr "mode" "SI")])
16911 (define_insn "*strsetsi_rex_1"
16912   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16913         (match_operand:SI 2 "register_operand" "a"))
16914    (set (match_operand:DI 0 "register_operand" "=D")
16915         (plus:DI (match_dup 1)
16916                  (const_int 4)))
16917    (use (reg:SI DIRFLAG_REG))]
16918   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16919   "{stosl|stosd}"
16920   [(set_attr "type" "str")
16921    (set_attr "memory" "store")
16922    (set_attr "mode" "SI")])
16924 (define_insn "*strsethi_1"
16925   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16926         (match_operand:HI 2 "register_operand" "a"))
16927    (set (match_operand:SI 0 "register_operand" "=D")
16928         (plus:SI (match_dup 1)
16929                  (const_int 2)))
16930    (use (reg:SI DIRFLAG_REG))]
16931   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16932   "stosw"
16933   [(set_attr "type" "str")
16934    (set_attr "memory" "store")
16935    (set_attr "mode" "HI")])
16937 (define_insn "*strsethi_rex_1"
16938   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16939         (match_operand:HI 2 "register_operand" "a"))
16940    (set (match_operand:DI 0 "register_operand" "=D")
16941         (plus:DI (match_dup 1)
16942                  (const_int 2)))
16943    (use (reg:SI DIRFLAG_REG))]
16944   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16945   "stosw"
16946   [(set_attr "type" "str")
16947    (set_attr "memory" "store")
16948    (set_attr "mode" "HI")])
16950 (define_insn "*strsetqi_1"
16951   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16952         (match_operand:QI 2 "register_operand" "a"))
16953    (set (match_operand:SI 0 "register_operand" "=D")
16954         (plus:SI (match_dup 1)
16955                  (const_int 1)))
16956    (use (reg:SI DIRFLAG_REG))]
16957   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16958   "stosb"
16959   [(set_attr "type" "str")
16960    (set_attr "memory" "store")
16961    (set_attr "mode" "QI")])
16963 (define_insn "*strsetqi_rex_1"
16964   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16965         (match_operand:QI 2 "register_operand" "a"))
16966    (set (match_operand:DI 0 "register_operand" "=D")
16967         (plus:DI (match_dup 1)
16968                  (const_int 1)))
16969    (use (reg:SI DIRFLAG_REG))]
16970   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16971   "stosb"
16972   [(set_attr "type" "str")
16973    (set_attr "memory" "store")
16974    (set_attr "mode" "QI")])
16976 (define_expand "rep_stos"
16977   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16978               (set (match_operand 0 "register_operand" "")
16979                    (match_operand 4 "" ""))
16980               (set (match_operand 2 "memory_operand" "") (const_int 0))
16981               (use (match_operand 3 "register_operand" ""))
16982               (use (match_dup 1))
16983               (use (reg:SI DIRFLAG_REG))])]
16984   ""
16985   "")
16987 (define_insn "*rep_stosdi_rex64"
16988   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16989    (set (match_operand:DI 0 "register_operand" "=D") 
16990         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16991                             (const_int 3))
16992                  (match_operand:DI 3 "register_operand" "0")))
16993    (set (mem:BLK (match_dup 3))
16994         (const_int 0))
16995    (use (match_operand:DI 2 "register_operand" "a"))
16996    (use (match_dup 4))
16997    (use (reg:SI DIRFLAG_REG))]
16998   "TARGET_64BIT"
16999   "{rep\;stosq|rep stosq}"
17000   [(set_attr "type" "str")
17001    (set_attr "prefix_rep" "1")
17002    (set_attr "memory" "store")
17003    (set_attr "mode" "DI")])
17005 (define_insn "*rep_stossi"
17006   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17007    (set (match_operand:SI 0 "register_operand" "=D") 
17008         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17009                             (const_int 2))
17010                  (match_operand:SI 3 "register_operand" "0")))
17011    (set (mem:BLK (match_dup 3))
17012         (const_int 0))
17013    (use (match_operand:SI 2 "register_operand" "a"))
17014    (use (match_dup 4))
17015    (use (reg:SI DIRFLAG_REG))]
17016   "!TARGET_64BIT"
17017   "{rep\;stosl|rep stosd}"
17018   [(set_attr "type" "str")
17019    (set_attr "prefix_rep" "1")
17020    (set_attr "memory" "store")
17021    (set_attr "mode" "SI")])
17023 (define_insn "*rep_stossi_rex64"
17024   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17025    (set (match_operand:DI 0 "register_operand" "=D") 
17026         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17027                             (const_int 2))
17028                  (match_operand:DI 3 "register_operand" "0")))
17029    (set (mem:BLK (match_dup 3))
17030         (const_int 0))
17031    (use (match_operand:SI 2 "register_operand" "a"))
17032    (use (match_dup 4))
17033    (use (reg:SI DIRFLAG_REG))]
17034   "TARGET_64BIT"
17035   "{rep\;stosl|rep stosd}"
17036   [(set_attr "type" "str")
17037    (set_attr "prefix_rep" "1")
17038    (set_attr "memory" "store")
17039    (set_attr "mode" "SI")])
17041 (define_insn "*rep_stosqi"
17042   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17043    (set (match_operand:SI 0 "register_operand" "=D") 
17044         (plus:SI (match_operand:SI 3 "register_operand" "0")
17045                  (match_operand:SI 4 "register_operand" "1")))
17046    (set (mem:BLK (match_dup 3))
17047         (const_int 0))
17048    (use (match_operand:QI 2 "register_operand" "a"))
17049    (use (match_dup 4))
17050    (use (reg:SI DIRFLAG_REG))]
17051   "!TARGET_64BIT"
17052   "{rep\;stosb|rep stosb}"
17053   [(set_attr "type" "str")
17054    (set_attr "prefix_rep" "1")
17055    (set_attr "memory" "store")
17056    (set_attr "mode" "QI")])
17058 (define_insn "*rep_stosqi_rex64"
17059   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17060    (set (match_operand:DI 0 "register_operand" "=D") 
17061         (plus:DI (match_operand:DI 3 "register_operand" "0")
17062                  (match_operand:DI 4 "register_operand" "1")))
17063    (set (mem:BLK (match_dup 3))
17064         (const_int 0))
17065    (use (match_operand:QI 2 "register_operand" "a"))
17066    (use (match_dup 4))
17067    (use (reg:SI DIRFLAG_REG))]
17068   "TARGET_64BIT"
17069   "{rep\;stosb|rep stosb}"
17070   [(set_attr "type" "str")
17071    (set_attr "prefix_rep" "1")
17072    (set_attr "memory" "store")
17073    (set_attr "mode" "QI")])
17075 (define_expand "cmpstrsi"
17076   [(set (match_operand:SI 0 "register_operand" "")
17077         (compare:SI (match_operand:BLK 1 "general_operand" "")
17078                     (match_operand:BLK 2 "general_operand" "")))
17079    (use (match_operand 3 "general_operand" ""))
17080    (use (match_operand 4 "immediate_operand" ""))]
17081   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17083   rtx addr1, addr2, out, outlow, count, countreg, align;
17085   /* Can't use this if the user has appropriated esi or edi.  */
17086   if (global_regs[4] || global_regs[5])
17087     FAIL;
17089   out = operands[0];
17090   if (GET_CODE (out) != REG)
17091     out = gen_reg_rtx (SImode);
17093   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17094   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17095   if (addr1 != XEXP (operands[1], 0))
17096     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17097   if (addr2 != XEXP (operands[2], 0))
17098     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17100   count = operands[3];
17101   countreg = ix86_zero_extend_to_Pmode (count);
17103   /* %%% Iff we are testing strict equality, we can use known alignment
17104      to good advantage.  This may be possible with combine, particularly
17105      once cc0 is dead.  */
17106   align = operands[4];
17108   emit_insn (gen_cld ());
17109   if (GET_CODE (count) == CONST_INT)
17110     {
17111       if (INTVAL (count) == 0)
17112         {
17113           emit_move_insn (operands[0], const0_rtx);
17114           DONE;
17115         }
17116       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17117                                     operands[1], operands[2]));
17118     }
17119   else
17120     {
17121       if (TARGET_64BIT)
17122         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17123       else
17124         emit_insn (gen_cmpsi_1 (countreg, countreg));
17125       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17126                                  operands[1], operands[2]));
17127     }
17129   outlow = gen_lowpart (QImode, out);
17130   emit_insn (gen_cmpintqi (outlow));
17131   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17133   if (operands[0] != out)
17134     emit_move_insn (operands[0], out);
17136   DONE;
17139 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17141 (define_expand "cmpintqi"
17142   [(set (match_dup 1)
17143         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17144    (set (match_dup 2)
17145         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17146    (parallel [(set (match_operand:QI 0 "register_operand" "")
17147                    (minus:QI (match_dup 1)
17148                              (match_dup 2)))
17149               (clobber (reg:CC FLAGS_REG))])]
17150   ""
17151   "operands[1] = gen_reg_rtx (QImode);
17152    operands[2] = gen_reg_rtx (QImode);")
17154 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17155 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17157 (define_expand "cmpstrqi_nz_1"
17158   [(parallel [(set (reg:CC FLAGS_REG)
17159                    (compare:CC (match_operand 4 "memory_operand" "")
17160                                (match_operand 5 "memory_operand" "")))
17161               (use (match_operand 2 "register_operand" ""))
17162               (use (match_operand:SI 3 "immediate_operand" ""))
17163               (use (reg:SI DIRFLAG_REG))
17164               (clobber (match_operand 0 "register_operand" ""))
17165               (clobber (match_operand 1 "register_operand" ""))
17166               (clobber (match_dup 2))])]
17167   ""
17168   "")
17170 (define_insn "*cmpstrqi_nz_1"
17171   [(set (reg:CC FLAGS_REG)
17172         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17173                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17174    (use (match_operand:SI 6 "register_operand" "2"))
17175    (use (match_operand:SI 3 "immediate_operand" "i"))
17176    (use (reg:SI DIRFLAG_REG))
17177    (clobber (match_operand:SI 0 "register_operand" "=S"))
17178    (clobber (match_operand:SI 1 "register_operand" "=D"))
17179    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17180   "!TARGET_64BIT"
17181   "repz{\;| }cmpsb"
17182   [(set_attr "type" "str")
17183    (set_attr "mode" "QI")
17184    (set_attr "prefix_rep" "1")])
17186 (define_insn "*cmpstrqi_nz_rex_1"
17187   [(set (reg:CC FLAGS_REG)
17188         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17189                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17190    (use (match_operand:DI 6 "register_operand" "2"))
17191    (use (match_operand:SI 3 "immediate_operand" "i"))
17192    (use (reg:SI DIRFLAG_REG))
17193    (clobber (match_operand:DI 0 "register_operand" "=S"))
17194    (clobber (match_operand:DI 1 "register_operand" "=D"))
17195    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17196   "TARGET_64BIT"
17197   "repz{\;| }cmpsb"
17198   [(set_attr "type" "str")
17199    (set_attr "mode" "QI")
17200    (set_attr "prefix_rep" "1")])
17202 ;; The same, but the count is not known to not be zero.
17204 (define_expand "cmpstrqi_1"
17205   [(parallel [(set (reg:CC FLAGS_REG)
17206                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17207                                      (const_int 0))
17208                   (compare:CC (match_operand 4 "memory_operand" "")
17209                               (match_operand 5 "memory_operand" ""))
17210                   (const_int 0)))
17211               (use (match_operand:SI 3 "immediate_operand" ""))
17212               (use (reg:CC FLAGS_REG))
17213               (use (reg:SI DIRFLAG_REG))
17214               (clobber (match_operand 0 "register_operand" ""))
17215               (clobber (match_operand 1 "register_operand" ""))
17216               (clobber (match_dup 2))])]
17217   ""
17218   "")
17220 (define_insn "*cmpstrqi_1"
17221   [(set (reg:CC FLAGS_REG)
17222         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17223                              (const_int 0))
17224           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17225                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17226           (const_int 0)))
17227    (use (match_operand:SI 3 "immediate_operand" "i"))
17228    (use (reg:CC FLAGS_REG))
17229    (use (reg:SI DIRFLAG_REG))
17230    (clobber (match_operand:SI 0 "register_operand" "=S"))
17231    (clobber (match_operand:SI 1 "register_operand" "=D"))
17232    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17233   "!TARGET_64BIT"
17234   "repz{\;| }cmpsb"
17235   [(set_attr "type" "str")
17236    (set_attr "mode" "QI")
17237    (set_attr "prefix_rep" "1")])
17239 (define_insn "*cmpstrqi_rex_1"
17240   [(set (reg:CC FLAGS_REG)
17241         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17242                              (const_int 0))
17243           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17244                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17245           (const_int 0)))
17246    (use (match_operand:SI 3 "immediate_operand" "i"))
17247    (use (reg:CC FLAGS_REG))
17248    (use (reg:SI DIRFLAG_REG))
17249    (clobber (match_operand:DI 0 "register_operand" "=S"))
17250    (clobber (match_operand:DI 1 "register_operand" "=D"))
17251    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17252   "TARGET_64BIT"
17253   "repz{\;| }cmpsb"
17254   [(set_attr "type" "str")
17255    (set_attr "mode" "QI")
17256    (set_attr "prefix_rep" "1")])
17258 (define_expand "strlensi"
17259   [(set (match_operand:SI 0 "register_operand" "")
17260         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17261                     (match_operand:QI 2 "immediate_operand" "")
17262                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17263   ""
17265  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17266    DONE;
17267  else
17268    FAIL;
17271 (define_expand "strlendi"
17272   [(set (match_operand:DI 0 "register_operand" "")
17273         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17274                     (match_operand:QI 2 "immediate_operand" "")
17275                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17276   ""
17278  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17279    DONE;
17280  else
17281    FAIL;
17284 (define_expand "strlenqi_1"
17285   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17286               (use (reg:SI DIRFLAG_REG))
17287               (clobber (match_operand 1 "register_operand" ""))
17288               (clobber (reg:CC FLAGS_REG))])]
17289   ""
17290   "")
17292 (define_insn "*strlenqi_1"
17293   [(set (match_operand:SI 0 "register_operand" "=&c")
17294         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17295                     (match_operand:QI 2 "register_operand" "a")
17296                     (match_operand:SI 3 "immediate_operand" "i")
17297                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17298    (use (reg:SI DIRFLAG_REG))
17299    (clobber (match_operand:SI 1 "register_operand" "=D"))
17300    (clobber (reg:CC FLAGS_REG))]
17301   "!TARGET_64BIT"
17302   "repnz{\;| }scasb"
17303   [(set_attr "type" "str")
17304    (set_attr "mode" "QI")
17305    (set_attr "prefix_rep" "1")])
17307 (define_insn "*strlenqi_rex_1"
17308   [(set (match_operand:DI 0 "register_operand" "=&c")
17309         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17310                     (match_operand:QI 2 "register_operand" "a")
17311                     (match_operand:DI 3 "immediate_operand" "i")
17312                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17313    (use (reg:SI DIRFLAG_REG))
17314    (clobber (match_operand:DI 1 "register_operand" "=D"))
17315    (clobber (reg:CC FLAGS_REG))]
17316   "TARGET_64BIT"
17317   "repnz{\;| }scasb"
17318   [(set_attr "type" "str")
17319    (set_attr "mode" "QI")
17320    (set_attr "prefix_rep" "1")])
17322 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17323 ;; handled in combine, but it is not currently up to the task.
17324 ;; When used for their truth value, the cmpstr* expanders generate
17325 ;; code like this:
17327 ;;   repz cmpsb
17328 ;;   seta       %al
17329 ;;   setb       %dl
17330 ;;   cmpb       %al, %dl
17331 ;;   jcc        label
17333 ;; The intermediate three instructions are unnecessary.
17335 ;; This one handles cmpstr*_nz_1...
17336 (define_peephole2
17337   [(parallel[
17338      (set (reg:CC FLAGS_REG)
17339           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17340                       (mem:BLK (match_operand 5 "register_operand" ""))))
17341      (use (match_operand 6 "register_operand" ""))
17342      (use (match_operand:SI 3 "immediate_operand" ""))
17343      (use (reg:SI DIRFLAG_REG))
17344      (clobber (match_operand 0 "register_operand" ""))
17345      (clobber (match_operand 1 "register_operand" ""))
17346      (clobber (match_operand 2 "register_operand" ""))])
17347    (set (match_operand:QI 7 "register_operand" "")
17348         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17349    (set (match_operand:QI 8 "register_operand" "")
17350         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17351    (set (reg FLAGS_REG)
17352         (compare (match_dup 7) (match_dup 8)))
17353   ]
17354   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17355   [(parallel[
17356      (set (reg:CC FLAGS_REG)
17357           (compare:CC (mem:BLK (match_dup 4))
17358                       (mem:BLK (match_dup 5))))
17359      (use (match_dup 6))
17360      (use (match_dup 3))
17361      (use (reg:SI DIRFLAG_REG))
17362      (clobber (match_dup 0))
17363      (clobber (match_dup 1))
17364      (clobber (match_dup 2))])]
17365   "")
17367 ;; ...and this one handles cmpstr*_1.
17368 (define_peephole2
17369   [(parallel[
17370      (set (reg:CC FLAGS_REG)
17371           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17372                                (const_int 0))
17373             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17374                         (mem:BLK (match_operand 5 "register_operand" "")))
17375             (const_int 0)))
17376      (use (match_operand:SI 3 "immediate_operand" ""))
17377      (use (reg:CC FLAGS_REG))
17378      (use (reg:SI DIRFLAG_REG))
17379      (clobber (match_operand 0 "register_operand" ""))
17380      (clobber (match_operand 1 "register_operand" ""))
17381      (clobber (match_operand 2 "register_operand" ""))])
17382    (set (match_operand:QI 7 "register_operand" "")
17383         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17384    (set (match_operand:QI 8 "register_operand" "")
17385         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17386    (set (reg FLAGS_REG)
17387         (compare (match_dup 7) (match_dup 8)))
17388   ]
17389   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17390   [(parallel[
17391      (set (reg:CC FLAGS_REG)
17392           (if_then_else:CC (ne (match_dup 6)
17393                                (const_int 0))
17394             (compare:CC (mem:BLK (match_dup 4))
17395                         (mem:BLK (match_dup 5)))
17396             (const_int 0)))
17397      (use (match_dup 3))
17398      (use (reg:CC FLAGS_REG))
17399      (use (reg:SI DIRFLAG_REG))
17400      (clobber (match_dup 0))
17401      (clobber (match_dup 1))
17402      (clobber (match_dup 2))])]
17403   "")
17407 ;; Conditional move instructions.
17409 (define_expand "movdicc"
17410   [(set (match_operand:DI 0 "register_operand" "")
17411         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17412                          (match_operand:DI 2 "general_operand" "")
17413                          (match_operand:DI 3 "general_operand" "")))]
17414   "TARGET_64BIT"
17415   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17417 (define_insn "x86_movdicc_0_m1_rex64"
17418   [(set (match_operand:DI 0 "register_operand" "=r")
17419         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17420           (const_int -1)
17421           (const_int 0)))
17422    (clobber (reg:CC FLAGS_REG))]
17423   "TARGET_64BIT"
17424   "sbb{q}\t%0, %0"
17425   ; Since we don't have the proper number of operands for an alu insn,
17426   ; fill in all the blanks.
17427   [(set_attr "type" "alu")
17428    (set_attr "pent_pair" "pu")
17429    (set_attr "memory" "none")
17430    (set_attr "imm_disp" "false")
17431    (set_attr "mode" "DI")
17432    (set_attr "length_immediate" "0")])
17434 (define_insn "*movdicc_c_rex64"
17435   [(set (match_operand:DI 0 "register_operand" "=r,r")
17436         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17437                                 [(reg FLAGS_REG) (const_int 0)])
17438                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17439                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17440   "TARGET_64BIT && TARGET_CMOVE
17441    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17442   "@
17443    cmov%O2%C1\t{%2, %0|%0, %2}
17444    cmov%O2%c1\t{%3, %0|%0, %3}"
17445   [(set_attr "type" "icmov")
17446    (set_attr "mode" "DI")])
17448 (define_expand "movsicc"
17449   [(set (match_operand:SI 0 "register_operand" "")
17450         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17451                          (match_operand:SI 2 "general_operand" "")
17452                          (match_operand:SI 3 "general_operand" "")))]
17453   ""
17454   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17456 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17457 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17458 ;; So just document what we're doing explicitly.
17460 (define_insn "x86_movsicc_0_m1"
17461   [(set (match_operand:SI 0 "register_operand" "=r")
17462         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17463           (const_int -1)
17464           (const_int 0)))
17465    (clobber (reg:CC FLAGS_REG))]
17466   ""
17467   "sbb{l}\t%0, %0"
17468   ; Since we don't have the proper number of operands for an alu insn,
17469   ; fill in all the blanks.
17470   [(set_attr "type" "alu")
17471    (set_attr "pent_pair" "pu")
17472    (set_attr "memory" "none")
17473    (set_attr "imm_disp" "false")
17474    (set_attr "mode" "SI")
17475    (set_attr "length_immediate" "0")])
17477 (define_insn "*movsicc_noc"
17478   [(set (match_operand:SI 0 "register_operand" "=r,r")
17479         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17480                                 [(reg FLAGS_REG) (const_int 0)])
17481                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17482                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17483   "TARGET_CMOVE
17484    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17485   "@
17486    cmov%O2%C1\t{%2, %0|%0, %2}
17487    cmov%O2%c1\t{%3, %0|%0, %3}"
17488   [(set_attr "type" "icmov")
17489    (set_attr "mode" "SI")])
17491 (define_expand "movhicc"
17492   [(set (match_operand:HI 0 "register_operand" "")
17493         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17494                          (match_operand:HI 2 "general_operand" "")
17495                          (match_operand:HI 3 "general_operand" "")))]
17496   "TARGET_HIMODE_MATH"
17497   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17499 (define_insn "*movhicc_noc"
17500   [(set (match_operand:HI 0 "register_operand" "=r,r")
17501         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17502                                 [(reg FLAGS_REG) (const_int 0)])
17503                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17504                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17505   "TARGET_CMOVE
17506    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17507   "@
17508    cmov%O2%C1\t{%2, %0|%0, %2}
17509    cmov%O2%c1\t{%3, %0|%0, %3}"
17510   [(set_attr "type" "icmov")
17511    (set_attr "mode" "HI")])
17513 (define_expand "movqicc"
17514   [(set (match_operand:QI 0 "register_operand" "")
17515         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17516                          (match_operand:QI 2 "general_operand" "")
17517                          (match_operand:QI 3 "general_operand" "")))]
17518   "TARGET_QIMODE_MATH"
17519   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17521 (define_insn_and_split "*movqicc_noc"
17522   [(set (match_operand:QI 0 "register_operand" "=r,r")
17523         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17524                                 [(match_operand 4 "flags_reg_operand" "")
17525                                  (const_int 0)])
17526                       (match_operand:QI 2 "register_operand" "r,0")
17527                       (match_operand:QI 3 "register_operand" "0,r")))]
17528   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17529   "#"
17530   "&& reload_completed"
17531   [(set (match_dup 0)
17532         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17533                       (match_dup 2)
17534                       (match_dup 3)))]
17535   "operands[0] = gen_lowpart (SImode, operands[0]);
17536    operands[2] = gen_lowpart (SImode, operands[2]);
17537    operands[3] = gen_lowpart (SImode, operands[3]);"
17538   [(set_attr "type" "icmov")
17539    (set_attr "mode" "SI")])
17541 (define_expand "movsfcc"
17542   [(set (match_operand:SF 0 "register_operand" "")
17543         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17544                          (match_operand:SF 2 "register_operand" "")
17545                          (match_operand:SF 3 "register_operand" "")))]
17546   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17547   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17549 ;; These versions of min/max are aware of the instruction's behavior
17550 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17551 ;; should have used the smin/smax expanders in the first place.
17552 (define_insn "*movsfcc_1_sse_min"
17553   [(set (match_operand:SF 0 "register_operand" "=x")
17554         (if_then_else:SF
17555           (lt:SF (match_operand:SF 1 "register_operand" "0")
17556                  (match_operand:SF 2 "nonimmediate_operand" "xm"))
17557           (match_dup 1)
17558           (match_dup 2)))]
17559   "TARGET_SSE_MATH"
17560   "minss\t{%2, %0|%0, %2}"
17561   [(set_attr "type" "sseadd")
17562    (set_attr "mode" "SF")])
17564 (define_insn "*movsfcc_1_sse_max"
17565   [(set (match_operand:SF 0 "register_operand" "=x")
17566         (if_then_else:SF
17567           (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
17568                  (match_operand:SF 1 "nonimmediate_operand" "0"))
17569           (match_dup 1)
17570           (match_dup 2)))]
17571   "TARGET_SSE_MATH"
17572   "maxss\t{%2, %0|%0, %2}"
17573   [(set_attr "type" "sseadd")
17574    (set_attr "mode" "SF")])
17576 (define_insn_and_split "*movsfcc_1_sse"
17577   [(set (match_operand:SF 0 "register_operand" "=x,x,x")
17578         (if_then_else:SF
17579           (match_operator:SF 4 "sse_comparison_operator"
17580             [(match_operand:SF 5 "register_operand" "0,0,0")
17581              (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
17582           (match_operand:SF 2 "reg_or_0_operand" "C,x,x")
17583           (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
17584    (clobber (match_scratch:V4SF 1 "=&x,&x,&x"))]
17585   "TARGET_SSE_MATH"
17586   "#"
17587   "&& reload_completed"
17588   [(const_int 0)]
17590   ix86_split_sse_movcc (operands);
17591   DONE;
17594 (define_insn "*movsfcc_1_387"
17595   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17596         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17597                                 [(reg FLAGS_REG) (const_int 0)])
17598                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17599                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17600   "TARGET_80387 && TARGET_CMOVE
17601    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17602   "@
17603    fcmov%F1\t{%2, %0|%0, %2}
17604    fcmov%f1\t{%3, %0|%0, %3}
17605    cmov%O2%C1\t{%2, %0|%0, %2}
17606    cmov%O2%c1\t{%3, %0|%0, %3}"
17607   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17608    (set_attr "mode" "SF,SF,SI,SI")])
17610 (define_expand "movdfcc"
17611   [(set (match_operand:DF 0 "register_operand" "")
17612         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17613                          (match_operand:DF 2 "register_operand" "")
17614                          (match_operand:DF 3 "register_operand" "")))]
17615   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17616   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17618 ;; These versions of min/max are aware of the instruction's behavior
17619 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17620 ;; should have used the smin/smax expanders in the first place.
17621 (define_insn "*movdfcc_1_sse_min"
17622   [(set (match_operand:DF 0 "register_operand" "=x")
17623         (if_then_else:DF
17624           (lt:DF (match_operand:DF 1 "register_operand" "0")
17625                  (match_operand:DF 2 "nonimmediate_operand" "xm"))
17626           (match_dup 1)
17627           (match_dup 2)))]
17628   "TARGET_SSE2 && TARGET_SSE_MATH"
17629   "minsd\t{%2, %0|%0, %2}"
17630   [(set_attr "type" "sseadd")
17631    (set_attr "mode" "DF")])
17633 (define_insn "*movdfcc_1_sse_max"
17634   [(set (match_operand:DF 0 "register_operand" "=x")
17635         (if_then_else:DF
17636           (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
17637                  (match_operand:DF 1 "nonimmediate_operand" "0"))
17638           (match_dup 1)
17639           (match_dup 2)))]
17640   "TARGET_SSE2 && TARGET_SSE_MATH"
17641   "maxsd\t{%2, %0|%0, %2}"
17642   [(set_attr "type" "sseadd")
17643    (set_attr "mode" "DF")])
17645 (define_insn_and_split "*movdfcc_1_sse"
17646   [(set (match_operand:DF 0 "register_operand" "=x,x,x")
17647         (if_then_else:DF
17648           (match_operator:DF 4 "sse_comparison_operator"
17649             [(match_operand:DF 5 "register_operand" "0,0,0")
17650              (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
17651           (match_operand:DF 2 "reg_or_0_operand" "C,x,x")
17652           (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
17653    (clobber (match_scratch:V2DF 1 "=&x,&x,&x"))]
17654   "TARGET_SSE2 && TARGET_SSE_MATH"
17655   "#"
17656   "&& reload_completed"
17657   [(const_int 0)]
17659   ix86_split_sse_movcc (operands);
17660   DONE;
17663 (define_insn "*movdfcc_1"
17664   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17665         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17666                                 [(reg FLAGS_REG) (const_int 0)])
17667                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17668                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17669   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17670    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17671   "@
17672    fcmov%F1\t{%2, %0|%0, %2}
17673    fcmov%f1\t{%3, %0|%0, %3}
17674    #
17675    #"
17676   [(set_attr "type" "fcmov,fcmov,multi,multi")
17677    (set_attr "mode" "DF")])
17679 (define_insn "*movdfcc_1_rex64"
17680   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17681         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17682                                 [(reg FLAGS_REG) (const_int 0)])
17683                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17684                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17685   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17686    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17687   "@
17688    fcmov%F1\t{%2, %0|%0, %2}
17689    fcmov%f1\t{%3, %0|%0, %3}
17690    cmov%O2%C1\t{%2, %0|%0, %2}
17691    cmov%O2%c1\t{%3, %0|%0, %3}"
17692   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17693    (set_attr "mode" "DF")])
17695 (define_split
17696   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17697         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17698                                 [(match_operand 4 "flags_reg_operand" "")
17699                                  (const_int 0)])
17700                       (match_operand:DF 2 "nonimmediate_operand" "")
17701                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17702   "!TARGET_64BIT && reload_completed"
17703   [(set (match_dup 2)
17704         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17705                       (match_dup 5)
17706                       (match_dup 7)))
17707    (set (match_dup 3)
17708         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17709                       (match_dup 6)
17710                       (match_dup 8)))]
17711   "split_di (operands+2, 1, operands+5, operands+6);
17712    split_di (operands+3, 1, operands+7, operands+8);
17713    split_di (operands, 1, operands+2, operands+3);")
17715 (define_expand "movxfcc"
17716   [(set (match_operand:XF 0 "register_operand" "")
17717         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17718                          (match_operand:XF 2 "register_operand" "")
17719                          (match_operand:XF 3 "register_operand" "")))]
17720   "TARGET_80387 && TARGET_CMOVE"
17721   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17723 (define_insn "*movxfcc_1"
17724   [(set (match_operand:XF 0 "register_operand" "=f,f")
17725         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17726                                 [(reg FLAGS_REG) (const_int 0)])
17727                       (match_operand:XF 2 "register_operand" "f,0")
17728                       (match_operand:XF 3 "register_operand" "0,f")))]
17729   "TARGET_80387 && TARGET_CMOVE"
17730   "@
17731    fcmov%F1\t{%2, %0|%0, %2}
17732    fcmov%f1\t{%3, %0|%0, %3}"
17733   [(set_attr "type" "fcmov")
17734    (set_attr "mode" "XF")])
17736 ;; These versions of the min/max patterns are intentionally ignorant of
17737 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17738 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17739 ;; are undefined in this condition, we're certain this is correct.
17741 (define_insn "sminsf3"
17742   [(set (match_operand:SF 0 "register_operand" "=x")
17743         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17744                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17745   "TARGET_SSE_MATH"
17746   "minss\t{%2, %0|%0, %2}"
17747   [(set_attr "type" "sseadd")
17748    (set_attr "mode" "SF")])
17750 (define_insn "smaxsf3"
17751   [(set (match_operand:SF 0 "register_operand" "=x")
17752         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17753                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17754   "TARGET_SSE_MATH"
17755   "maxss\t{%2, %0|%0, %2}"
17756   [(set_attr "type" "sseadd")
17757    (set_attr "mode" "SF")])
17759 (define_insn "smindf3"
17760   [(set (match_operand:DF 0 "register_operand" "=x")
17761         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17762                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17763   "TARGET_SSE2 && TARGET_SSE_MATH"
17764   "minsd\t{%2, %0|%0, %2}"
17765   [(set_attr "type" "sseadd")
17766    (set_attr "mode" "DF")])
17768 (define_insn "smaxdf3"
17769   [(set (match_operand:DF 0 "register_operand" "=x")
17770         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17771                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17772   "TARGET_SSE2 && TARGET_SSE_MATH"
17773   "maxsd\t{%2, %0|%0, %2}"
17774   [(set_attr "type" "sseadd")
17775    (set_attr "mode" "DF")])
17777 ;; Conditional addition patterns
17778 (define_expand "addqicc"
17779   [(match_operand:QI 0 "register_operand" "")
17780    (match_operand 1 "comparison_operator" "")
17781    (match_operand:QI 2 "register_operand" "")
17782    (match_operand:QI 3 "const_int_operand" "")]
17783   ""
17784   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17786 (define_expand "addhicc"
17787   [(match_operand:HI 0 "register_operand" "")
17788    (match_operand 1 "comparison_operator" "")
17789    (match_operand:HI 2 "register_operand" "")
17790    (match_operand:HI 3 "const_int_operand" "")]
17791   ""
17792   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17794 (define_expand "addsicc"
17795   [(match_operand:SI 0 "register_operand" "")
17796    (match_operand 1 "comparison_operator" "")
17797    (match_operand:SI 2 "register_operand" "")
17798    (match_operand:SI 3 "const_int_operand" "")]
17799   ""
17800   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17802 (define_expand "adddicc"
17803   [(match_operand:DI 0 "register_operand" "")
17804    (match_operand 1 "comparison_operator" "")
17805    (match_operand:DI 2 "register_operand" "")
17806    (match_operand:DI 3 "const_int_operand" "")]
17807   "TARGET_64BIT"
17808   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17811 ;; Misc patterns (?)
17813 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17814 ;; Otherwise there will be nothing to keep
17815 ;; 
17816 ;; [(set (reg ebp) (reg esp))]
17817 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17818 ;;  (clobber (eflags)]
17819 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17821 ;; in proper program order.
17822 (define_insn "pro_epilogue_adjust_stack_1"
17823   [(set (match_operand:SI 0 "register_operand" "=r,r")
17824         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17825                  (match_operand:SI 2 "immediate_operand" "i,i")))
17826    (clobber (reg:CC FLAGS_REG))
17827    (clobber (mem:BLK (scratch)))]
17828   "!TARGET_64BIT"
17830   switch (get_attr_type (insn))
17831     {
17832     case TYPE_IMOV:
17833       return "mov{l}\t{%1, %0|%0, %1}";
17835     case TYPE_ALU:
17836       if (GET_CODE (operands[2]) == CONST_INT
17837           && (INTVAL (operands[2]) == 128
17838               || (INTVAL (operands[2]) < 0
17839                   && INTVAL (operands[2]) != -128)))
17840         {
17841           operands[2] = GEN_INT (-INTVAL (operands[2]));
17842           return "sub{l}\t{%2, %0|%0, %2}";
17843         }
17844       return "add{l}\t{%2, %0|%0, %2}";
17846     case TYPE_LEA:
17847       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17848       return "lea{l}\t{%a2, %0|%0, %a2}";
17850     default:
17851       abort ();
17852     }
17854   [(set (attr "type")
17855         (cond [(eq_attr "alternative" "0")
17856                  (const_string "alu")
17857                (match_operand:SI 2 "const0_operand" "")
17858                  (const_string "imov")
17859               ]
17860               (const_string "lea")))
17861    (set_attr "mode" "SI")])
17863 (define_insn "pro_epilogue_adjust_stack_rex64"
17864   [(set (match_operand:DI 0 "register_operand" "=r,r")
17865         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17866                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17867    (clobber (reg:CC FLAGS_REG))
17868    (clobber (mem:BLK (scratch)))]
17869   "TARGET_64BIT"
17871   switch (get_attr_type (insn))
17872     {
17873     case TYPE_IMOV:
17874       return "mov{q}\t{%1, %0|%0, %1}";
17876     case TYPE_ALU:
17877       if (GET_CODE (operands[2]) == CONST_INT
17878           /* Avoid overflows.  */
17879           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17880           && (INTVAL (operands[2]) == 128
17881               || (INTVAL (operands[2]) < 0
17882                   && INTVAL (operands[2]) != -128)))
17883         {
17884           operands[2] = GEN_INT (-INTVAL (operands[2]));
17885           return "sub{q}\t{%2, %0|%0, %2}";
17886         }
17887       return "add{q}\t{%2, %0|%0, %2}";
17889     case TYPE_LEA:
17890       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17891       return "lea{q}\t{%a2, %0|%0, %a2}";
17893     default:
17894       abort ();
17895     }
17897   [(set (attr "type")
17898         (cond [(eq_attr "alternative" "0")
17899                  (const_string "alu")
17900                (match_operand:DI 2 "const0_operand" "")
17901                  (const_string "imov")
17902               ]
17903               (const_string "lea")))
17904    (set_attr "mode" "DI")])
17906 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17907   [(set (match_operand:DI 0 "register_operand" "=r,r")
17908         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17909                  (match_operand:DI 3 "immediate_operand" "i,i")))
17910    (use (match_operand:DI 2 "register_operand" "r,r"))
17911    (clobber (reg:CC FLAGS_REG))
17912    (clobber (mem:BLK (scratch)))]
17913   "TARGET_64BIT"
17915   switch (get_attr_type (insn))
17916     {
17917     case TYPE_ALU:
17918       return "add{q}\t{%2, %0|%0, %2}";
17920     case TYPE_LEA:
17921       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17922       return "lea{q}\t{%a2, %0|%0, %a2}";
17924     default:
17925       abort ();
17926     }
17928   [(set_attr "type" "alu,lea")
17929    (set_attr "mode" "DI")])
17931 (define_expand "allocate_stack_worker"
17932   [(match_operand:SI 0 "register_operand" "")]
17933   "TARGET_STACK_PROBE"
17935   if (reload_completed)
17936     {
17937       if (TARGET_64BIT)
17938         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17939       else
17940         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17941     }
17942   else
17943     {
17944       if (TARGET_64BIT)
17945         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17946       else
17947         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17948     }
17949   DONE;
17952 (define_insn "allocate_stack_worker_1"
17953   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17954     UNSPECV_STACK_PROBE)
17955    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
17956    (clobber (match_scratch:SI 1 "=0"))
17957    (clobber (reg:CC FLAGS_REG))]
17958   "!TARGET_64BIT && TARGET_STACK_PROBE"
17959   "call\t__alloca"
17960   [(set_attr "type" "multi")
17961    (set_attr "length" "5")])
17963 (define_expand "allocate_stack_worker_postreload"
17964   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17965                                     UNSPECV_STACK_PROBE)
17966               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
17967               (clobber (match_dup 0))
17968               (clobber (reg:CC FLAGS_REG))])]
17969   ""
17970   "")
17972 (define_insn "allocate_stack_worker_rex64"
17973   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17974     UNSPECV_STACK_PROBE)
17975    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
17976    (clobber (match_scratch:DI 1 "=0"))
17977    (clobber (reg:CC FLAGS_REG))]
17978   "TARGET_64BIT && TARGET_STACK_PROBE"
17979   "call\t__alloca"
17980   [(set_attr "type" "multi")
17981    (set_attr "length" "5")])
17983 (define_expand "allocate_stack_worker_rex64_postreload"
17984   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17985                                     UNSPECV_STACK_PROBE)
17986               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
17987               (clobber (match_dup 0))
17988               (clobber (reg:CC FLAGS_REG))])]
17989   ""
17990   "")
17992 (define_expand "allocate_stack"
17993   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17994                    (minus:SI (reg:SI SP_REG)
17995                              (match_operand:SI 1 "general_operand" "")))
17996               (clobber (reg:CC FLAGS_REG))])
17997    (parallel [(set (reg:SI SP_REG)
17998                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
17999               (clobber (reg:CC FLAGS_REG))])]
18000   "TARGET_STACK_PROBE"
18002 #ifdef CHECK_STACK_LIMIT
18003   if (GET_CODE (operands[1]) == CONST_INT
18004       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18005     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18006                            operands[1]));
18007   else 
18008 #endif
18009     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18010                                                             operands[1])));
18012   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18013   DONE;
18016 (define_expand "builtin_setjmp_receiver"
18017   [(label_ref (match_operand 0 "" ""))]
18018   "!TARGET_64BIT && flag_pic"
18020   emit_insn (gen_set_got (pic_offset_table_rtx));
18021   DONE;
18024 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18026 (define_split
18027   [(set (match_operand 0 "register_operand" "")
18028         (match_operator 3 "promotable_binary_operator"
18029            [(match_operand 1 "register_operand" "")
18030             (match_operand 2 "aligned_operand" "")]))
18031    (clobber (reg:CC FLAGS_REG))]
18032   "! TARGET_PARTIAL_REG_STALL && reload_completed
18033    && ((GET_MODE (operands[0]) == HImode 
18034         && ((!optimize_size && !TARGET_FAST_PREFIX)
18035             || GET_CODE (operands[2]) != CONST_INT
18036             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18037        || (GET_MODE (operands[0]) == QImode 
18038            && (TARGET_PROMOTE_QImode || optimize_size)))"
18039   [(parallel [(set (match_dup 0)
18040                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18041               (clobber (reg:CC FLAGS_REG))])]
18042   "operands[0] = gen_lowpart (SImode, operands[0]);
18043    operands[1] = gen_lowpart (SImode, operands[1]);
18044    if (GET_CODE (operands[3]) != ASHIFT)
18045      operands[2] = gen_lowpart (SImode, operands[2]);
18046    PUT_MODE (operands[3], SImode);")
18048 ; Promote the QImode tests, as i386 has encoding of the AND
18049 ; instruction with 32-bit sign-extended immediate and thus the
18050 ; instruction size is unchanged, except in the %eax case for
18051 ; which it is increased by one byte, hence the ! optimize_size.
18052 (define_split
18053   [(set (match_operand 0 "flags_reg_operand" "")
18054         (match_operator 2 "compare_operator"
18055           [(and (match_operand 3 "aligned_operand" "")
18056                 (match_operand 4 "const_int_operand" ""))
18057            (const_int 0)]))
18058    (set (match_operand 1 "register_operand" "")
18059         (and (match_dup 3) (match_dup 4)))]
18060   "! TARGET_PARTIAL_REG_STALL && reload_completed
18061    /* Ensure that the operand will remain sign-extended immediate.  */
18062    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18063    && ! optimize_size
18064    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18065        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18066   [(parallel [(set (match_dup 0)
18067                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18068                                     (const_int 0)]))
18069               (set (match_dup 1)
18070                    (and:SI (match_dup 3) (match_dup 4)))])]
18072   operands[4]
18073     = gen_int_mode (INTVAL (operands[4])
18074                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18075   operands[1] = gen_lowpart (SImode, operands[1]);
18076   operands[3] = gen_lowpart (SImode, operands[3]);
18079 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18080 ; the TEST instruction with 32-bit sign-extended immediate and thus
18081 ; the instruction size would at least double, which is not what we
18082 ; want even with ! optimize_size.
18083 (define_split
18084   [(set (match_operand 0 "flags_reg_operand" "")
18085         (match_operator 1 "compare_operator"
18086           [(and (match_operand:HI 2 "aligned_operand" "")
18087                 (match_operand:HI 3 "const_int_operand" ""))
18088            (const_int 0)]))]
18089   "! TARGET_PARTIAL_REG_STALL && reload_completed
18090    /* Ensure that the operand will remain sign-extended immediate.  */
18091    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18092    && ! TARGET_FAST_PREFIX
18093    && ! optimize_size"
18094   [(set (match_dup 0)
18095         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18096                          (const_int 0)]))]
18098   operands[3]
18099     = gen_int_mode (INTVAL (operands[3])
18100                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18101   operands[2] = gen_lowpart (SImode, operands[2]);
18104 (define_split
18105   [(set (match_operand 0 "register_operand" "")
18106         (neg (match_operand 1 "register_operand" "")))
18107    (clobber (reg:CC FLAGS_REG))]
18108   "! TARGET_PARTIAL_REG_STALL && reload_completed
18109    && (GET_MODE (operands[0]) == HImode
18110        || (GET_MODE (operands[0]) == QImode 
18111            && (TARGET_PROMOTE_QImode || optimize_size)))"
18112   [(parallel [(set (match_dup 0)
18113                    (neg:SI (match_dup 1)))
18114               (clobber (reg:CC FLAGS_REG))])]
18115   "operands[0] = gen_lowpart (SImode, operands[0]);
18116    operands[1] = gen_lowpart (SImode, operands[1]);")
18118 (define_split
18119   [(set (match_operand 0 "register_operand" "")
18120         (not (match_operand 1 "register_operand" "")))]
18121   "! TARGET_PARTIAL_REG_STALL && reload_completed
18122    && (GET_MODE (operands[0]) == HImode
18123        || (GET_MODE (operands[0]) == QImode 
18124            && (TARGET_PROMOTE_QImode || optimize_size)))"
18125   [(set (match_dup 0)
18126         (not:SI (match_dup 1)))]
18127   "operands[0] = gen_lowpart (SImode, operands[0]);
18128    operands[1] = gen_lowpart (SImode, operands[1]);")
18130 (define_split 
18131   [(set (match_operand 0 "register_operand" "")
18132         (if_then_else (match_operator 1 "comparison_operator" 
18133                                 [(reg FLAGS_REG) (const_int 0)])
18134                       (match_operand 2 "register_operand" "")
18135                       (match_operand 3 "register_operand" "")))]
18136   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18137    && (GET_MODE (operands[0]) == HImode
18138        || (GET_MODE (operands[0]) == QImode 
18139            && (TARGET_PROMOTE_QImode || optimize_size)))"
18140   [(set (match_dup 0)
18141         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18142   "operands[0] = gen_lowpart (SImode, operands[0]);
18143    operands[2] = gen_lowpart (SImode, operands[2]);
18144    operands[3] = gen_lowpart (SImode, operands[3]);")
18145                         
18147 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18148 ;; transform a complex memory operation into two memory to register operations.
18150 ;; Don't push memory operands
18151 (define_peephole2
18152   [(set (match_operand:SI 0 "push_operand" "")
18153         (match_operand:SI 1 "memory_operand" ""))
18154    (match_scratch:SI 2 "r")]
18155   "! optimize_size && ! TARGET_PUSH_MEMORY"
18156   [(set (match_dup 2) (match_dup 1))
18157    (set (match_dup 0) (match_dup 2))]
18158   "")
18160 (define_peephole2
18161   [(set (match_operand:DI 0 "push_operand" "")
18162         (match_operand:DI 1 "memory_operand" ""))
18163    (match_scratch:DI 2 "r")]
18164   "! optimize_size && ! TARGET_PUSH_MEMORY"
18165   [(set (match_dup 2) (match_dup 1))
18166    (set (match_dup 0) (match_dup 2))]
18167   "")
18169 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18170 ;; SImode pushes.
18171 (define_peephole2
18172   [(set (match_operand:SF 0 "push_operand" "")
18173         (match_operand:SF 1 "memory_operand" ""))
18174    (match_scratch:SF 2 "r")]
18175   "! optimize_size && ! TARGET_PUSH_MEMORY"
18176   [(set (match_dup 2) (match_dup 1))
18177    (set (match_dup 0) (match_dup 2))]
18178   "")
18180 (define_peephole2
18181   [(set (match_operand:HI 0 "push_operand" "")
18182         (match_operand:HI 1 "memory_operand" ""))
18183    (match_scratch:HI 2 "r")]
18184   "! optimize_size && ! TARGET_PUSH_MEMORY"
18185   [(set (match_dup 2) (match_dup 1))
18186    (set (match_dup 0) (match_dup 2))]
18187   "")
18189 (define_peephole2
18190   [(set (match_operand:QI 0 "push_operand" "")
18191         (match_operand:QI 1 "memory_operand" ""))
18192    (match_scratch:QI 2 "q")]
18193   "! optimize_size && ! TARGET_PUSH_MEMORY"
18194   [(set (match_dup 2) (match_dup 1))
18195    (set (match_dup 0) (match_dup 2))]
18196   "")
18198 ;; Don't move an immediate directly to memory when the instruction
18199 ;; gets too big.
18200 (define_peephole2
18201   [(match_scratch:SI 1 "r")
18202    (set (match_operand:SI 0 "memory_operand" "")
18203         (const_int 0))]
18204   "! optimize_size
18205    && ! TARGET_USE_MOV0
18206    && TARGET_SPLIT_LONG_MOVES
18207    && get_attr_length (insn) >= ix86_cost->large_insn
18208    && peep2_regno_dead_p (0, FLAGS_REG)"
18209   [(parallel [(set (match_dup 1) (const_int 0))
18210               (clobber (reg:CC FLAGS_REG))])
18211    (set (match_dup 0) (match_dup 1))]
18212   "")
18214 (define_peephole2
18215   [(match_scratch:HI 1 "r")
18216    (set (match_operand:HI 0 "memory_operand" "")
18217         (const_int 0))]
18218   "! optimize_size
18219    && ! TARGET_USE_MOV0
18220    && TARGET_SPLIT_LONG_MOVES
18221    && get_attr_length (insn) >= ix86_cost->large_insn
18222    && peep2_regno_dead_p (0, FLAGS_REG)"
18223   [(parallel [(set (match_dup 2) (const_int 0))
18224               (clobber (reg:CC FLAGS_REG))])
18225    (set (match_dup 0) (match_dup 1))]
18226   "operands[2] = gen_lowpart (SImode, operands[1]);")
18228 (define_peephole2
18229   [(match_scratch:QI 1 "q")
18230    (set (match_operand:QI 0 "memory_operand" "")
18231         (const_int 0))]
18232   "! optimize_size
18233    && ! TARGET_USE_MOV0
18234    && TARGET_SPLIT_LONG_MOVES
18235    && get_attr_length (insn) >= ix86_cost->large_insn
18236    && peep2_regno_dead_p (0, FLAGS_REG)"
18237   [(parallel [(set (match_dup 2) (const_int 0))
18238               (clobber (reg:CC FLAGS_REG))])
18239    (set (match_dup 0) (match_dup 1))]
18240   "operands[2] = gen_lowpart (SImode, operands[1]);")
18242 (define_peephole2
18243   [(match_scratch:SI 2 "r")
18244    (set (match_operand:SI 0 "memory_operand" "")
18245         (match_operand:SI 1 "immediate_operand" ""))]
18246   "! optimize_size
18247    && get_attr_length (insn) >= ix86_cost->large_insn
18248    && TARGET_SPLIT_LONG_MOVES"
18249   [(set (match_dup 2) (match_dup 1))
18250    (set (match_dup 0) (match_dup 2))]
18251   "")
18253 (define_peephole2
18254   [(match_scratch:HI 2 "r")
18255    (set (match_operand:HI 0 "memory_operand" "")
18256         (match_operand:HI 1 "immediate_operand" ""))]
18257   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18258   && TARGET_SPLIT_LONG_MOVES"
18259   [(set (match_dup 2) (match_dup 1))
18260    (set (match_dup 0) (match_dup 2))]
18261   "")
18263 (define_peephole2
18264   [(match_scratch:QI 2 "q")
18265    (set (match_operand:QI 0 "memory_operand" "")
18266         (match_operand:QI 1 "immediate_operand" ""))]
18267   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18268   && TARGET_SPLIT_LONG_MOVES"
18269   [(set (match_dup 2) (match_dup 1))
18270    (set (match_dup 0) (match_dup 2))]
18271   "")
18273 ;; Don't compare memory with zero, load and use a test instead.
18274 (define_peephole2
18275   [(set (match_operand 0 "flags_reg_operand" "")
18276         (match_operator 1 "compare_operator"
18277           [(match_operand:SI 2 "memory_operand" "")
18278            (const_int 0)]))
18279    (match_scratch:SI 3 "r")]
18280   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18281   [(set (match_dup 3) (match_dup 2))
18282    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18283   "")
18285 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18286 ;; Don't split NOTs with a displacement operand, because resulting XOR
18287 ;; will not be pairable anyway.
18289 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18290 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18291 ;; so this split helps here as well.
18293 ;; Note: Can't do this as a regular split because we can't get proper
18294 ;; lifetime information then.
18296 (define_peephole2
18297   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18298         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18299   "!optimize_size
18300    && peep2_regno_dead_p (0, FLAGS_REG)
18301    && ((TARGET_PENTIUM 
18302         && (GET_CODE (operands[0]) != MEM
18303             || !memory_displacement_operand (operands[0], SImode)))
18304        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18305   [(parallel [(set (match_dup 0)
18306                    (xor:SI (match_dup 1) (const_int -1)))
18307               (clobber (reg:CC FLAGS_REG))])]
18308   "")
18310 (define_peephole2
18311   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18312         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18313   "!optimize_size
18314    && peep2_regno_dead_p (0, FLAGS_REG)
18315    && ((TARGET_PENTIUM 
18316         && (GET_CODE (operands[0]) != MEM
18317             || !memory_displacement_operand (operands[0], HImode)))
18318        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18319   [(parallel [(set (match_dup 0)
18320                    (xor:HI (match_dup 1) (const_int -1)))
18321               (clobber (reg:CC FLAGS_REG))])]
18322   "")
18324 (define_peephole2
18325   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18326         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18327   "!optimize_size
18328    && peep2_regno_dead_p (0, FLAGS_REG)
18329    && ((TARGET_PENTIUM 
18330         && (GET_CODE (operands[0]) != MEM
18331             || !memory_displacement_operand (operands[0], QImode)))
18332        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18333   [(parallel [(set (match_dup 0)
18334                    (xor:QI (match_dup 1) (const_int -1)))
18335               (clobber (reg:CC FLAGS_REG))])]
18336   "")
18338 ;; Non pairable "test imm, reg" instructions can be translated to
18339 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18340 ;; byte opcode instead of two, have a short form for byte operands),
18341 ;; so do it for other CPUs as well.  Given that the value was dead,
18342 ;; this should not create any new dependencies.  Pass on the sub-word
18343 ;; versions if we're concerned about partial register stalls.
18345 (define_peephole2
18346   [(set (match_operand 0 "flags_reg_operand" "")
18347         (match_operator 1 "compare_operator"
18348           [(and:SI (match_operand:SI 2 "register_operand" "")
18349                    (match_operand:SI 3 "immediate_operand" ""))
18350            (const_int 0)]))]
18351   "ix86_match_ccmode (insn, CCNOmode)
18352    && (true_regnum (operands[2]) != 0
18353        || (GET_CODE (operands[3]) == CONST_INT
18354            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18355    && peep2_reg_dead_p (1, operands[2])"
18356   [(parallel
18357      [(set (match_dup 0)
18358            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18359                             (const_int 0)]))
18360       (set (match_dup 2)
18361            (and:SI (match_dup 2) (match_dup 3)))])]
18362   "")
18364 ;; We don't need to handle HImode case, because it will be promoted to SImode
18365 ;; on ! TARGET_PARTIAL_REG_STALL
18367 (define_peephole2
18368   [(set (match_operand 0 "flags_reg_operand" "")
18369         (match_operator 1 "compare_operator"
18370           [(and:QI (match_operand:QI 2 "register_operand" "")
18371                    (match_operand:QI 3 "immediate_operand" ""))
18372            (const_int 0)]))]
18373   "! TARGET_PARTIAL_REG_STALL
18374    && ix86_match_ccmode (insn, CCNOmode)
18375    && true_regnum (operands[2]) != 0
18376    && peep2_reg_dead_p (1, operands[2])"
18377   [(parallel
18378      [(set (match_dup 0)
18379            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18380                             (const_int 0)]))
18381       (set (match_dup 2)
18382            (and:QI (match_dup 2) (match_dup 3)))])]
18383   "")
18385 (define_peephole2
18386   [(set (match_operand 0 "flags_reg_operand" "")
18387         (match_operator 1 "compare_operator"
18388           [(and:SI
18389              (zero_extract:SI
18390                (match_operand 2 "ext_register_operand" "")
18391                (const_int 8)
18392                (const_int 8))
18393              (match_operand 3 "const_int_operand" ""))
18394            (const_int 0)]))]
18395   "! TARGET_PARTIAL_REG_STALL
18396    && ix86_match_ccmode (insn, CCNOmode)
18397    && true_regnum (operands[2]) != 0
18398    && peep2_reg_dead_p (1, operands[2])"
18399   [(parallel [(set (match_dup 0)
18400                    (match_op_dup 1
18401                      [(and:SI
18402                         (zero_extract:SI
18403                           (match_dup 2)
18404                           (const_int 8)
18405                           (const_int 8))
18406                         (match_dup 3))
18407                       (const_int 0)]))
18408               (set (zero_extract:SI (match_dup 2)
18409                                     (const_int 8)
18410                                     (const_int 8))
18411                    (and:SI 
18412                      (zero_extract:SI
18413                        (match_dup 2)
18414                        (const_int 8)
18415                        (const_int 8))
18416                      (match_dup 3)))])]
18417   "")
18419 ;; Don't do logical operations with memory inputs.
18420 (define_peephole2
18421   [(match_scratch:SI 2 "r")
18422    (parallel [(set (match_operand:SI 0 "register_operand" "")
18423                    (match_operator:SI 3 "arith_or_logical_operator"
18424                      [(match_dup 0)
18425                       (match_operand:SI 1 "memory_operand" "")]))
18426               (clobber (reg:CC FLAGS_REG))])]
18427   "! optimize_size && ! TARGET_READ_MODIFY"
18428   [(set (match_dup 2) (match_dup 1))
18429    (parallel [(set (match_dup 0)
18430                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18431               (clobber (reg:CC FLAGS_REG))])]
18432   "")
18434 (define_peephole2
18435   [(match_scratch:SI 2 "r")
18436    (parallel [(set (match_operand:SI 0 "register_operand" "")
18437                    (match_operator:SI 3 "arith_or_logical_operator"
18438                      [(match_operand:SI 1 "memory_operand" "")
18439                       (match_dup 0)]))
18440               (clobber (reg:CC FLAGS_REG))])]
18441   "! optimize_size && ! TARGET_READ_MODIFY"
18442   [(set (match_dup 2) (match_dup 1))
18443    (parallel [(set (match_dup 0)
18444                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18445               (clobber (reg:CC FLAGS_REG))])]
18446   "")
18448 ; Don't do logical operations with memory outputs
18450 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18451 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18452 ; the same decoder scheduling characteristics as the original.
18454 (define_peephole2
18455   [(match_scratch:SI 2 "r")
18456    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18457                    (match_operator:SI 3 "arith_or_logical_operator"
18458                      [(match_dup 0)
18459                       (match_operand:SI 1 "nonmemory_operand" "")]))
18460               (clobber (reg:CC FLAGS_REG))])]
18461   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18462   [(set (match_dup 2) (match_dup 0))
18463    (parallel [(set (match_dup 2)
18464                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18465               (clobber (reg:CC FLAGS_REG))])
18466    (set (match_dup 0) (match_dup 2))]
18467   "")
18469 (define_peephole2
18470   [(match_scratch:SI 2 "r")
18471    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18472                    (match_operator:SI 3 "arith_or_logical_operator"
18473                      [(match_operand:SI 1 "nonmemory_operand" "")
18474                       (match_dup 0)]))
18475               (clobber (reg:CC FLAGS_REG))])]
18476   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18477   [(set (match_dup 2) (match_dup 0))
18478    (parallel [(set (match_dup 2)
18479                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18480               (clobber (reg:CC FLAGS_REG))])
18481    (set (match_dup 0) (match_dup 2))]
18482   "")
18484 ;; Attempt to always use XOR for zeroing registers.
18485 (define_peephole2
18486   [(set (match_operand 0 "register_operand" "")
18487         (const_int 0))]
18488   "(GET_MODE (operands[0]) == QImode
18489     || GET_MODE (operands[0]) == HImode
18490     || GET_MODE (operands[0]) == SImode
18491     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18492    && (! TARGET_USE_MOV0 || optimize_size)
18493    && GENERAL_REG_P (operands[0])
18494    && peep2_regno_dead_p (0, FLAGS_REG)"
18495   [(parallel [(set (match_dup 0) (const_int 0))
18496               (clobber (reg:CC FLAGS_REG))])]
18497   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18498                               operands[0]);")
18500 (define_peephole2
18501   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18502         (const_int 0))]
18503   "(GET_MODE (operands[0]) == QImode
18504     || GET_MODE (operands[0]) == HImode)
18505    && (! TARGET_USE_MOV0 || optimize_size)
18506    && peep2_regno_dead_p (0, FLAGS_REG)"
18507   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18508               (clobber (reg:CC FLAGS_REG))])])
18510 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18511 (define_peephole2
18512   [(set (match_operand 0 "register_operand" "")
18513         (const_int -1))]
18514   "(GET_MODE (operands[0]) == HImode
18515     || GET_MODE (operands[0]) == SImode 
18516     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18517    && (optimize_size || TARGET_PENTIUM)
18518    && peep2_regno_dead_p (0, FLAGS_REG)"
18519   [(parallel [(set (match_dup 0) (const_int -1))
18520               (clobber (reg:CC FLAGS_REG))])]
18521   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18522                               operands[0]);")
18524 ;; Attempt to convert simple leas to adds. These can be created by
18525 ;; move expanders.
18526 (define_peephole2
18527   [(set (match_operand:SI 0 "register_operand" "")
18528         (plus:SI (match_dup 0)
18529                  (match_operand:SI 1 "nonmemory_operand" "")))]
18530   "peep2_regno_dead_p (0, FLAGS_REG)"
18531   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18532               (clobber (reg:CC FLAGS_REG))])]
18533   "")
18535 (define_peephole2
18536   [(set (match_operand:SI 0 "register_operand" "")
18537         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18538                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18539   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18540   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18541               (clobber (reg:CC FLAGS_REG))])]
18542   "operands[2] = gen_lowpart (SImode, operands[2]);")
18544 (define_peephole2
18545   [(set (match_operand:DI 0 "register_operand" "")
18546         (plus:DI (match_dup 0)
18547                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18548   "peep2_regno_dead_p (0, FLAGS_REG)"
18549   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18550               (clobber (reg:CC FLAGS_REG))])]
18551   "")
18553 (define_peephole2
18554   [(set (match_operand:SI 0 "register_operand" "")
18555         (mult:SI (match_dup 0)
18556                  (match_operand:SI 1 "const_int_operand" "")))]
18557   "exact_log2 (INTVAL (operands[1])) >= 0
18558    && peep2_regno_dead_p (0, FLAGS_REG)"
18559   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18560               (clobber (reg:CC FLAGS_REG))])]
18561   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18563 (define_peephole2
18564   [(set (match_operand:DI 0 "register_operand" "")
18565         (mult:DI (match_dup 0)
18566                  (match_operand:DI 1 "const_int_operand" "")))]
18567   "exact_log2 (INTVAL (operands[1])) >= 0
18568    && peep2_regno_dead_p (0, FLAGS_REG)"
18569   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18570               (clobber (reg:CC FLAGS_REG))])]
18571   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18573 (define_peephole2
18574   [(set (match_operand:SI 0 "register_operand" "")
18575         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18576                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18577   "exact_log2 (INTVAL (operands[2])) >= 0
18578    && REGNO (operands[0]) == REGNO (operands[1])
18579    && peep2_regno_dead_p (0, FLAGS_REG)"
18580   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18581               (clobber (reg:CC FLAGS_REG))])]
18582   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18584 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18585 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18586 ;; many CPUs it is also faster, since special hardware to avoid esp
18587 ;; dependencies is present.
18589 ;; While some of these conversions may be done using splitters, we use peepholes
18590 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18592 ;; Convert prologue esp subtractions to push.
18593 ;; We need register to push.  In order to keep verify_flow_info happy we have
18594 ;; two choices
18595 ;; - use scratch and clobber it in order to avoid dependencies
18596 ;; - use already live register
18597 ;; We can't use the second way right now, since there is no reliable way how to
18598 ;; verify that given register is live.  First choice will also most likely in
18599 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18600 ;; call clobbered registers are dead.  We may want to use base pointer as an
18601 ;; alternative when no register is available later.
18603 (define_peephole2
18604   [(match_scratch:SI 0 "r")
18605    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18606               (clobber (reg:CC FLAGS_REG))
18607               (clobber (mem:BLK (scratch)))])]
18608   "optimize_size || !TARGET_SUB_ESP_4"
18609   [(clobber (match_dup 0))
18610    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18611               (clobber (mem:BLK (scratch)))])])
18613 (define_peephole2
18614   [(match_scratch:SI 0 "r")
18615    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18616               (clobber (reg:CC FLAGS_REG))
18617               (clobber (mem:BLK (scratch)))])]
18618   "optimize_size || !TARGET_SUB_ESP_8"
18619   [(clobber (match_dup 0))
18620    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18621    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18622               (clobber (mem:BLK (scratch)))])])
18624 ;; Convert esp subtractions to push.
18625 (define_peephole2
18626   [(match_scratch:SI 0 "r")
18627    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18628               (clobber (reg:CC FLAGS_REG))])]
18629   "optimize_size || !TARGET_SUB_ESP_4"
18630   [(clobber (match_dup 0))
18631    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18633 (define_peephole2
18634   [(match_scratch:SI 0 "r")
18635    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18636               (clobber (reg:CC FLAGS_REG))])]
18637   "optimize_size || !TARGET_SUB_ESP_8"
18638   [(clobber (match_dup 0))
18639    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18640    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18642 ;; Convert epilogue deallocator to pop.
18643 (define_peephole2
18644   [(match_scratch:SI 0 "r")
18645    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18646               (clobber (reg:CC FLAGS_REG))
18647               (clobber (mem:BLK (scratch)))])]
18648   "optimize_size || !TARGET_ADD_ESP_4"
18649   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18650               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18651               (clobber (mem:BLK (scratch)))])]
18652   "")
18654 ;; Two pops case is tricky, since pop causes dependency on destination register.
18655 ;; We use two registers if available.
18656 (define_peephole2
18657   [(match_scratch:SI 0 "r")
18658    (match_scratch:SI 1 "r")
18659    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18660               (clobber (reg:CC FLAGS_REG))
18661               (clobber (mem:BLK (scratch)))])]
18662   "optimize_size || !TARGET_ADD_ESP_8"
18663   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18664               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18665               (clobber (mem:BLK (scratch)))])
18666    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18667               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18668   "")
18670 (define_peephole2
18671   [(match_scratch:SI 0 "r")
18672    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18673               (clobber (reg:CC FLAGS_REG))
18674               (clobber (mem:BLK (scratch)))])]
18675   "optimize_size"
18676   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18677               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18678               (clobber (mem:BLK (scratch)))])
18679    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18680               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18681   "")
18683 ;; Convert esp additions to pop.
18684 (define_peephole2
18685   [(match_scratch:SI 0 "r")
18686    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18687               (clobber (reg:CC FLAGS_REG))])]
18688   ""
18689   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18690               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18691   "")
18693 ;; Two pops case is tricky, since pop causes dependency on destination register.
18694 ;; We use two registers if available.
18695 (define_peephole2
18696   [(match_scratch:SI 0 "r")
18697    (match_scratch:SI 1 "r")
18698    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18699               (clobber (reg:CC FLAGS_REG))])]
18700   ""
18701   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18702               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18703    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18704               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18705   "")
18707 (define_peephole2
18708   [(match_scratch:SI 0 "r")
18709    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18710               (clobber (reg:CC FLAGS_REG))])]
18711   "optimize_size"
18712   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18713               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18714    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18715               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18716   "")
18718 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18719 ;; required and register dies.  Similarly for 128 to plus -128.
18720 (define_peephole2
18721   [(set (match_operand 0 "flags_reg_operand" "")
18722         (match_operator 1 "compare_operator"
18723           [(match_operand 2 "register_operand" "")
18724            (match_operand 3 "const_int_operand" "")]))]
18725   "(INTVAL (operands[3]) == -1
18726     || INTVAL (operands[3]) == 1
18727     || INTVAL (operands[3]) == 128)
18728    && ix86_match_ccmode (insn, CCGCmode)
18729    && peep2_reg_dead_p (1, operands[2])"
18730   [(parallel [(set (match_dup 0)
18731                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18732               (clobber (match_dup 2))])]
18733   "")
18735 (define_peephole2
18736   [(match_scratch:DI 0 "r")
18737    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18738               (clobber (reg:CC FLAGS_REG))
18739               (clobber (mem:BLK (scratch)))])]
18740   "optimize_size || !TARGET_SUB_ESP_4"
18741   [(clobber (match_dup 0))
18742    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18743               (clobber (mem:BLK (scratch)))])])
18745 (define_peephole2
18746   [(match_scratch:DI 0 "r")
18747    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18748               (clobber (reg:CC FLAGS_REG))
18749               (clobber (mem:BLK (scratch)))])]
18750   "optimize_size || !TARGET_SUB_ESP_8"
18751   [(clobber (match_dup 0))
18752    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18753    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18754               (clobber (mem:BLK (scratch)))])])
18756 ;; Convert esp subtractions to push.
18757 (define_peephole2
18758   [(match_scratch:DI 0 "r")
18759    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18760               (clobber (reg:CC FLAGS_REG))])]
18761   "optimize_size || !TARGET_SUB_ESP_4"
18762   [(clobber (match_dup 0))
18763    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18765 (define_peephole2
18766   [(match_scratch:DI 0 "r")
18767    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18768               (clobber (reg:CC FLAGS_REG))])]
18769   "optimize_size || !TARGET_SUB_ESP_8"
18770   [(clobber (match_dup 0))
18771    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18772    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18774 ;; Convert epilogue deallocator to pop.
18775 (define_peephole2
18776   [(match_scratch:DI 0 "r")
18777    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18778               (clobber (reg:CC FLAGS_REG))
18779               (clobber (mem:BLK (scratch)))])]
18780   "optimize_size || !TARGET_ADD_ESP_4"
18781   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18782               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18783               (clobber (mem:BLK (scratch)))])]
18784   "")
18786 ;; Two pops case is tricky, since pop causes dependency on destination register.
18787 ;; We use two registers if available.
18788 (define_peephole2
18789   [(match_scratch:DI 0 "r")
18790    (match_scratch:DI 1 "r")
18791    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18792               (clobber (reg:CC FLAGS_REG))
18793               (clobber (mem:BLK (scratch)))])]
18794   "optimize_size || !TARGET_ADD_ESP_8"
18795   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18796               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18797               (clobber (mem:BLK (scratch)))])
18798    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18799               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18800   "")
18802 (define_peephole2
18803   [(match_scratch:DI 0 "r")
18804    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18805               (clobber (reg:CC FLAGS_REG))
18806               (clobber (mem:BLK (scratch)))])]
18807   "optimize_size"
18808   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18809               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18810               (clobber (mem:BLK (scratch)))])
18811    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18812               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18813   "")
18815 ;; Convert esp additions to pop.
18816 (define_peephole2
18817   [(match_scratch:DI 0 "r")
18818    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18819               (clobber (reg:CC FLAGS_REG))])]
18820   ""
18821   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18822               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18823   "")
18825 ;; Two pops case is tricky, since pop causes dependency on destination register.
18826 ;; We use two registers if available.
18827 (define_peephole2
18828   [(match_scratch:DI 0 "r")
18829    (match_scratch:DI 1 "r")
18830    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18831               (clobber (reg:CC FLAGS_REG))])]
18832   ""
18833   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18834               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18835    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18836               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18837   "")
18839 (define_peephole2
18840   [(match_scratch:DI 0 "r")
18841    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18842               (clobber (reg:CC FLAGS_REG))])]
18843   "optimize_size"
18844   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18845               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18846    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18847               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18848   "")
18850 ;; Convert imul by three, five and nine into lea
18851 (define_peephole2
18852   [(parallel
18853     [(set (match_operand:SI 0 "register_operand" "")
18854           (mult:SI (match_operand:SI 1 "register_operand" "")
18855                    (match_operand:SI 2 "const_int_operand" "")))
18856      (clobber (reg:CC FLAGS_REG))])]
18857   "INTVAL (operands[2]) == 3
18858    || INTVAL (operands[2]) == 5
18859    || INTVAL (operands[2]) == 9"
18860   [(set (match_dup 0)
18861         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18862                  (match_dup 1)))]
18863   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18865 (define_peephole2
18866   [(parallel
18867     [(set (match_operand:SI 0 "register_operand" "")
18868           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18869                    (match_operand:SI 2 "const_int_operand" "")))
18870      (clobber (reg:CC FLAGS_REG))])]
18871   "!optimize_size 
18872    && (INTVAL (operands[2]) == 3
18873        || INTVAL (operands[2]) == 5
18874        || INTVAL (operands[2]) == 9)"
18875   [(set (match_dup 0) (match_dup 1))
18876    (set (match_dup 0)
18877         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18878                  (match_dup 0)))]
18879   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18881 (define_peephole2
18882   [(parallel
18883     [(set (match_operand:DI 0 "register_operand" "")
18884           (mult:DI (match_operand:DI 1 "register_operand" "")
18885                    (match_operand:DI 2 "const_int_operand" "")))
18886      (clobber (reg:CC FLAGS_REG))])]
18887   "TARGET_64BIT
18888    && (INTVAL (operands[2]) == 3
18889        || INTVAL (operands[2]) == 5
18890        || INTVAL (operands[2]) == 9)"
18891   [(set (match_dup 0)
18892         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18893                  (match_dup 1)))]
18894   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18896 (define_peephole2
18897   [(parallel
18898     [(set (match_operand:DI 0 "register_operand" "")
18899           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18900                    (match_operand:DI 2 "const_int_operand" "")))
18901      (clobber (reg:CC FLAGS_REG))])]
18902   "TARGET_64BIT
18903    && !optimize_size 
18904    && (INTVAL (operands[2]) == 3
18905        || INTVAL (operands[2]) == 5
18906        || INTVAL (operands[2]) == 9)"
18907   [(set (match_dup 0) (match_dup 1))
18908    (set (match_dup 0)
18909         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18910                  (match_dup 0)))]
18911   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18913 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18914 ;; imul $32bit_imm, reg, reg is direct decoded.
18915 (define_peephole2
18916   [(match_scratch:DI 3 "r")
18917    (parallel [(set (match_operand:DI 0 "register_operand" "")
18918                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18919                             (match_operand:DI 2 "immediate_operand" "")))
18920               (clobber (reg:CC FLAGS_REG))])]
18921   "TARGET_K8 && !optimize_size
18922    && (GET_CODE (operands[2]) != CONST_INT
18923        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18924   [(set (match_dup 3) (match_dup 1))
18925    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18926               (clobber (reg:CC FLAGS_REG))])]
18929 (define_peephole2
18930   [(match_scratch:SI 3 "r")
18931    (parallel [(set (match_operand:SI 0 "register_operand" "")
18932                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18933                             (match_operand:SI 2 "immediate_operand" "")))
18934               (clobber (reg:CC FLAGS_REG))])]
18935   "TARGET_K8 && !optimize_size
18936    && (GET_CODE (operands[2]) != CONST_INT
18937        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18938   [(set (match_dup 3) (match_dup 1))
18939    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18940               (clobber (reg:CC FLAGS_REG))])]
18943 (define_peephole2
18944   [(match_scratch:SI 3 "r")
18945    (parallel [(set (match_operand:DI 0 "register_operand" "")
18946                    (zero_extend:DI
18947                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18948                               (match_operand:SI 2 "immediate_operand" ""))))
18949               (clobber (reg:CC FLAGS_REG))])]
18950   "TARGET_K8 && !optimize_size
18951    && (GET_CODE (operands[2]) != CONST_INT
18952        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18953   [(set (match_dup 3) (match_dup 1))
18954    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18955               (clobber (reg:CC FLAGS_REG))])]
18958 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18959 ;; Convert it into imul reg, reg
18960 ;; It would be better to force assembler to encode instruction using long
18961 ;; immediate, but there is apparently no way to do so.
18962 (define_peephole2
18963   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18964                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18965                             (match_operand:DI 2 "const_int_operand" "")))
18966               (clobber (reg:CC FLAGS_REG))])
18967    (match_scratch:DI 3 "r")]
18968   "TARGET_K8 && !optimize_size
18969    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18970   [(set (match_dup 3) (match_dup 2))
18971    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18972               (clobber (reg:CC FLAGS_REG))])]
18974   if (!rtx_equal_p (operands[0], operands[1]))
18975     emit_move_insn (operands[0], operands[1]);
18978 (define_peephole2
18979   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18980                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18981                             (match_operand:SI 2 "const_int_operand" "")))
18982               (clobber (reg:CC FLAGS_REG))])
18983    (match_scratch:SI 3 "r")]
18984   "TARGET_K8 && !optimize_size
18985    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18986   [(set (match_dup 3) (match_dup 2))
18987    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18988               (clobber (reg:CC FLAGS_REG))])]
18990   if (!rtx_equal_p (operands[0], operands[1]))
18991     emit_move_insn (operands[0], operands[1]);
18994 (define_peephole2
18995   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18996                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18997                             (match_operand:HI 2 "immediate_operand" "")))
18998               (clobber (reg:CC FLAGS_REG))])
18999    (match_scratch:HI 3 "r")]
19000   "TARGET_K8 && !optimize_size"
19001   [(set (match_dup 3) (match_dup 2))
19002    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19003               (clobber (reg:CC FLAGS_REG))])]
19005   if (!rtx_equal_p (operands[0], operands[1]))
19006     emit_move_insn (operands[0], operands[1]);
19009 ;; Call-value patterns last so that the wildcard operand does not
19010 ;; disrupt insn-recog's switch tables.
19012 (define_insn "*call_value_pop_0"
19013   [(set (match_operand 0 "" "")
19014         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19015               (match_operand:SI 2 "" "")))
19016    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19017                             (match_operand:SI 3 "immediate_operand" "")))]
19018   "!TARGET_64BIT"
19020   if (SIBLING_CALL_P (insn))
19021     return "jmp\t%P1";
19022   else
19023     return "call\t%P1";
19025   [(set_attr "type" "callv")])
19027 (define_insn "*call_value_pop_1"
19028   [(set (match_operand 0 "" "")
19029         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19030               (match_operand:SI 2 "" "")))
19031    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19032                             (match_operand:SI 3 "immediate_operand" "i")))]
19033   "!TARGET_64BIT"
19035   if (constant_call_address_operand (operands[1], Pmode))
19036     {
19037       if (SIBLING_CALL_P (insn))
19038         return "jmp\t%P1";
19039       else
19040         return "call\t%P1";
19041     }
19042   if (SIBLING_CALL_P (insn))
19043     return "jmp\t%A1";
19044   else
19045     return "call\t%A1";
19047   [(set_attr "type" "callv")])
19049 (define_insn "*call_value_0"
19050   [(set (match_operand 0 "" "")
19051         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19052               (match_operand:SI 2 "" "")))]
19053   "!TARGET_64BIT"
19055   if (SIBLING_CALL_P (insn))
19056     return "jmp\t%P1";
19057   else
19058     return "call\t%P1";
19060   [(set_attr "type" "callv")])
19062 (define_insn "*call_value_0_rex64"
19063   [(set (match_operand 0 "" "")
19064         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19065               (match_operand:DI 2 "const_int_operand" "")))]
19066   "TARGET_64BIT"
19068   if (SIBLING_CALL_P (insn))
19069     return "jmp\t%P1";
19070   else
19071     return "call\t%P1";
19073   [(set_attr "type" "callv")])
19075 (define_insn "*call_value_1"
19076   [(set (match_operand 0 "" "")
19077         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19078               (match_operand:SI 2 "" "")))]
19079   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19081   if (constant_call_address_operand (operands[1], Pmode))
19082     return "call\t%P1";
19083   return "call\t%A1";
19085   [(set_attr "type" "callv")])
19087 (define_insn "*sibcall_value_1"
19088   [(set (match_operand 0 "" "")
19089         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19090               (match_operand:SI 2 "" "")))]
19091   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19093   if (constant_call_address_operand (operands[1], Pmode))
19094     return "jmp\t%P1";
19095   return "jmp\t%A1";
19097   [(set_attr "type" "callv")])
19099 (define_insn "*call_value_1_rex64"
19100   [(set (match_operand 0 "" "")
19101         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19102               (match_operand:DI 2 "" "")))]
19103   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19105   if (constant_call_address_operand (operands[1], Pmode))
19106     return "call\t%P1";
19107   return "call\t%A1";
19109   [(set_attr "type" "callv")])
19111 (define_insn "*sibcall_value_1_rex64"
19112   [(set (match_operand 0 "" "")
19113         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19114               (match_operand:DI 2 "" "")))]
19115   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19116   "jmp\t%P1"
19117   [(set_attr "type" "callv")])
19119 (define_insn "*sibcall_value_1_rex64_v"
19120   [(set (match_operand 0 "" "")
19121         (call (mem:QI (reg:DI 40))
19122               (match_operand:DI 1 "" "")))]
19123   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19124   "jmp\t*%%r11"
19125   [(set_attr "type" "callv")])
19127 (define_insn "trap"
19128   [(trap_if (const_int 1) (const_int 5))]
19129   ""
19130   "int\t$5")
19132 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19133 ;;; for the sake of bounds checking.  By emitting bounds checks as
19134 ;;; conditional traps rather than as conditional jumps around
19135 ;;; unconditional traps we avoid introducing spurious basic-block
19136 ;;; boundaries and facilitate elimination of redundant checks.  In
19137 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19138 ;;; interrupt 5.
19139 ;;; 
19140 ;;; FIXME: Static branch prediction rules for ix86 are such that
19141 ;;; forward conditional branches predict as untaken.  As implemented
19142 ;;; below, pseudo conditional traps violate that rule.  We should use
19143 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19144 ;;; section loaded at the end of the text segment and branch forward
19145 ;;; there on bounds-failure, and then jump back immediately (in case
19146 ;;; the system chooses to ignore bounds violations, or to report
19147 ;;; violations and continue execution).
19149 (define_expand "conditional_trap"
19150   [(trap_if (match_operator 0 "comparison_operator"
19151              [(match_dup 2) (const_int 0)])
19152             (match_operand 1 "const_int_operand" ""))]
19153   ""
19155   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19156                               ix86_expand_compare (GET_CODE (operands[0]),
19157                                                    NULL, NULL),
19158                               operands[1]));
19159   DONE;
19162 (define_insn "*conditional_trap_1"
19163   [(trap_if (match_operator 0 "comparison_operator"
19164              [(reg FLAGS_REG) (const_int 0)])
19165             (match_operand 1 "const_int_operand" ""))]
19166   ""
19168   operands[2] = gen_label_rtx ();
19169   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19170   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19171                              CODE_LABEL_NUMBER (operands[2]));
19172   RET;
19175 (define_expand "sse_prologue_save"
19176   [(parallel [(set (match_operand:BLK 0 "" "")
19177                    (unspec:BLK [(reg:DI 21)
19178                                 (reg:DI 22)
19179                                 (reg:DI 23)
19180                                 (reg:DI 24)
19181                                 (reg:DI 25)
19182                                 (reg:DI 26)
19183                                 (reg:DI 27)
19184                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19185               (use (match_operand:DI 1 "register_operand" ""))
19186               (use (match_operand:DI 2 "immediate_operand" ""))
19187               (use (label_ref:DI (match_operand 3 "" "")))])]
19188   "TARGET_64BIT"
19189   "")
19191 (define_insn "*sse_prologue_save_insn"
19192   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19193                           (match_operand:DI 4 "const_int_operand" "n")))
19194         (unspec:BLK [(reg:DI 21)
19195                      (reg:DI 22)
19196                      (reg:DI 23)
19197                      (reg:DI 24)
19198                      (reg:DI 25)
19199                      (reg:DI 26)
19200                      (reg:DI 27)
19201                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19202    (use (match_operand:DI 1 "register_operand" "r"))
19203    (use (match_operand:DI 2 "const_int_operand" "i"))
19204    (use (label_ref:DI (match_operand 3 "" "X")))]
19205   "TARGET_64BIT
19206    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19207    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19208   "*
19210   int i;
19211   operands[0] = gen_rtx_MEM (Pmode,
19212                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19213   output_asm_insn (\"jmp\\t%A1\", operands);
19214   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19215     {
19216       operands[4] = adjust_address (operands[0], DImode, i*16);
19217       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19218       PUT_MODE (operands[4], TImode);
19219       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19220         output_asm_insn (\"rex\", operands);
19221       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19222     }
19223   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19224                              CODE_LABEL_NUMBER (operands[3]));
19225   RET;
19227   "
19228   [(set_attr "type" "other")
19229    (set_attr "length_immediate" "0")
19230    (set_attr "length_address" "0")
19231    (set_attr "length" "135")
19232    (set_attr "memory" "store")
19233    (set_attr "modrm" "0")
19234    (set_attr "mode" "DI")])
19236 (define_expand "prefetch"
19237   [(prefetch (match_operand 0 "address_operand" "")
19238              (match_operand:SI 1 "const_int_operand" "")
19239              (match_operand:SI 2 "const_int_operand" ""))]
19240   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19242   int rw = INTVAL (operands[1]);
19243   int locality = INTVAL (operands[2]);
19245   if (rw != 0 && rw != 1)
19246     abort ();
19247   if (locality < 0 || locality > 3)
19248     abort ();
19249   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19250     abort ();
19252   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19253      suported by SSE counterpart or the SSE prefetch is not available
19254      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19255      of locality.  */
19256   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19257     operands[2] = GEN_INT (3);
19258   else
19259     operands[1] = const0_rtx;
19262 (define_insn "*prefetch_sse"
19263   [(prefetch (match_operand:SI 0 "address_operand" "p")
19264              (const_int 0)
19265              (match_operand:SI 1 "const_int_operand" ""))]
19266   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19268   static const char * const patterns[4] = {
19269    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19270   };
19272   int locality = INTVAL (operands[1]);
19273   if (locality < 0 || locality > 3)
19274     abort ();
19276   return patterns[locality];  
19278   [(set_attr "type" "sse")
19279    (set_attr "memory" "none")])
19281 (define_insn "*prefetch_sse_rex"
19282   [(prefetch (match_operand:DI 0 "address_operand" "p")
19283              (const_int 0)
19284              (match_operand:SI 1 "const_int_operand" ""))]
19285   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19287   static const char * const patterns[4] = {
19288    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19289   };
19291   int locality = INTVAL (operands[1]);
19292   if (locality < 0 || locality > 3)
19293     abort ();
19295   return patterns[locality];  
19297   [(set_attr "type" "sse")
19298    (set_attr "memory" "none")])
19300 (define_insn "*prefetch_3dnow"
19301   [(prefetch (match_operand:SI 0 "address_operand" "p")
19302              (match_operand:SI 1 "const_int_operand" "n")
19303              (const_int 3))]
19304   "TARGET_3DNOW && !TARGET_64BIT"
19306   if (INTVAL (operands[1]) == 0)
19307     return "prefetch\t%a0";
19308   else
19309     return "prefetchw\t%a0";
19311   [(set_attr "type" "mmx")
19312    (set_attr "memory" "none")])
19314 (define_insn "*prefetch_3dnow_rex"
19315   [(prefetch (match_operand:DI 0 "address_operand" "p")
19316              (match_operand:SI 1 "const_int_operand" "n")
19317              (const_int 3))]
19318   "TARGET_3DNOW && TARGET_64BIT"
19320   if (INTVAL (operands[1]) == 0)
19321     return "prefetch\t%a0";
19322   else
19323     return "prefetchw\t%a0";
19325   [(set_attr "type" "mmx")
19326    (set_attr "memory" "none")])
19328 (include "sse.md")
19329 (include "mmx.md")