Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / config / i386 / i386.md
blobd9a4ce599ed6ca8a83d685e7a39f7a2a3e223f70
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,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,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 ;; Scheduling descriptions
447 (include "pentium.md")
448 (include "ppro.md")
449 (include "k6.md")
450 (include "athlon.md")
453 ;; Operand and operator predicates
455 (include "predicates.md")
458 ;; Compare instructions.
460 ;; All compare insns have expanders that save the operands away without
461 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
462 ;; after the cmp) will actually emit the cmpM.
464 (define_expand "cmpdi"
465   [(set (reg:CC FLAGS_REG)
466         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
467                     (match_operand:DI 1 "x86_64_general_operand" "")))]
468   ""
470   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
471     operands[0] = force_reg (DImode, operands[0]);
472   ix86_compare_op0 = operands[0];
473   ix86_compare_op1 = operands[1];
474   DONE;
477 (define_expand "cmpsi"
478   [(set (reg:CC FLAGS_REG)
479         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
480                     (match_operand:SI 1 "general_operand" "")))]
481   ""
483   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
484     operands[0] = force_reg (SImode, operands[0]);
485   ix86_compare_op0 = operands[0];
486   ix86_compare_op1 = operands[1];
487   DONE;
490 (define_expand "cmphi"
491   [(set (reg:CC FLAGS_REG)
492         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
493                     (match_operand:HI 1 "general_operand" "")))]
494   ""
496   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
497     operands[0] = force_reg (HImode, operands[0]);
498   ix86_compare_op0 = operands[0];
499   ix86_compare_op1 = operands[1];
500   DONE;
503 (define_expand "cmpqi"
504   [(set (reg:CC FLAGS_REG)
505         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
506                     (match_operand:QI 1 "general_operand" "")))]
507   "TARGET_QIMODE_MATH"
509   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
510     operands[0] = force_reg (QImode, operands[0]);
511   ix86_compare_op0 = operands[0];
512   ix86_compare_op1 = operands[1];
513   DONE;
516 (define_insn "cmpdi_ccno_1_rex64"
517   [(set (reg FLAGS_REG)
518         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
519                  (match_operand:DI 1 "const0_operand" "n,n")))]
520   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
521   "@
522    test{q}\t{%0, %0|%0, %0}
523    cmp{q}\t{%1, %0|%0, %1}"
524   [(set_attr "type" "test,icmp")
525    (set_attr "length_immediate" "0,1")
526    (set_attr "mode" "DI")])
528 (define_insn "*cmpdi_minus_1_rex64"
529   [(set (reg FLAGS_REG)
530         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
531                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
532                  (const_int 0)))]
533   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
534   "cmp{q}\t{%1, %0|%0, %1}"
535   [(set_attr "type" "icmp")
536    (set_attr "mode" "DI")])
538 (define_expand "cmpdi_1_rex64"
539   [(set (reg:CC FLAGS_REG)
540         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
541                     (match_operand:DI 1 "general_operand" "")))]
542   "TARGET_64BIT"
543   "")
545 (define_insn "cmpdi_1_insn_rex64"
546   [(set (reg FLAGS_REG)
547         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
548                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
549   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
550   "cmp{q}\t{%1, %0|%0, %1}"
551   [(set_attr "type" "icmp")
552    (set_attr "mode" "DI")])
555 (define_insn "*cmpsi_ccno_1"
556   [(set (reg FLAGS_REG)
557         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
558                  (match_operand:SI 1 "const0_operand" "n,n")))]
559   "ix86_match_ccmode (insn, CCNOmode)"
560   "@
561    test{l}\t{%0, %0|%0, %0}
562    cmp{l}\t{%1, %0|%0, %1}"
563   [(set_attr "type" "test,icmp")
564    (set_attr "length_immediate" "0,1")
565    (set_attr "mode" "SI")])
567 (define_insn "*cmpsi_minus_1"
568   [(set (reg FLAGS_REG)
569         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
570                            (match_operand:SI 1 "general_operand" "ri,mr"))
571                  (const_int 0)))]
572   "ix86_match_ccmode (insn, CCGOCmode)"
573   "cmp{l}\t{%1, %0|%0, %1}"
574   [(set_attr "type" "icmp")
575    (set_attr "mode" "SI")])
577 (define_expand "cmpsi_1"
578   [(set (reg:CC FLAGS_REG)
579         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
580                     (match_operand:SI 1 "general_operand" "ri,mr")))]
581   ""
582   "")
584 (define_insn "*cmpsi_1_insn"
585   [(set (reg FLAGS_REG)
586         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
587                  (match_operand:SI 1 "general_operand" "ri,mr")))]
588   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
589     && ix86_match_ccmode (insn, CCmode)"
590   "cmp{l}\t{%1, %0|%0, %1}"
591   [(set_attr "type" "icmp")
592    (set_attr "mode" "SI")])
594 (define_insn "*cmphi_ccno_1"
595   [(set (reg FLAGS_REG)
596         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
597                  (match_operand:HI 1 "const0_operand" "n,n")))]
598   "ix86_match_ccmode (insn, CCNOmode)"
599   "@
600    test{w}\t{%0, %0|%0, %0}
601    cmp{w}\t{%1, %0|%0, %1}"
602   [(set_attr "type" "test,icmp")
603    (set_attr "length_immediate" "0,1")
604    (set_attr "mode" "HI")])
606 (define_insn "*cmphi_minus_1"
607   [(set (reg FLAGS_REG)
608         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
609                            (match_operand:HI 1 "general_operand" "ri,mr"))
610                  (const_int 0)))]
611   "ix86_match_ccmode (insn, CCGOCmode)"
612   "cmp{w}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "HI")])
616 (define_insn "*cmphi_1"
617   [(set (reg FLAGS_REG)
618         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
619                  (match_operand:HI 1 "general_operand" "ri,mr")))]
620   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
621    && ix86_match_ccmode (insn, CCmode)"
622   "cmp{w}\t{%1, %0|%0, %1}"
623   [(set_attr "type" "icmp")
624    (set_attr "mode" "HI")])
626 (define_insn "*cmpqi_ccno_1"
627   [(set (reg FLAGS_REG)
628         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
629                  (match_operand:QI 1 "const0_operand" "n,n")))]
630   "ix86_match_ccmode (insn, CCNOmode)"
631   "@
632    test{b}\t{%0, %0|%0, %0}
633    cmp{b}\t{$0, %0|%0, 0}"
634   [(set_attr "type" "test,icmp")
635    (set_attr "length_immediate" "0,1")
636    (set_attr "mode" "QI")])
638 (define_insn "*cmpqi_1"
639   [(set (reg FLAGS_REG)
640         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
641                  (match_operand:QI 1 "general_operand" "qi,mq")))]
642   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
643     && ix86_match_ccmode (insn, CCmode)"
644   "cmp{b}\t{%1, %0|%0, %1}"
645   [(set_attr "type" "icmp")
646    (set_attr "mode" "QI")])
648 (define_insn "*cmpqi_minus_1"
649   [(set (reg FLAGS_REG)
650         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
651                            (match_operand:QI 1 "general_operand" "qi,mq"))
652                  (const_int 0)))]
653   "ix86_match_ccmode (insn, CCGOCmode)"
654   "cmp{b}\t{%1, %0|%0, %1}"
655   [(set_attr "type" "icmp")
656    (set_attr "mode" "QI")])
658 (define_insn "*cmpqi_ext_1"
659   [(set (reg FLAGS_REG)
660         (compare
661           (match_operand:QI 0 "general_operand" "Qm")
662           (subreg:QI
663             (zero_extract:SI
664               (match_operand 1 "ext_register_operand" "Q")
665               (const_int 8)
666               (const_int 8)) 0)))]
667   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
668   "cmp{b}\t{%h1, %0|%0, %h1}"
669   [(set_attr "type" "icmp")
670    (set_attr "mode" "QI")])
672 (define_insn "*cmpqi_ext_1_rex64"
673   [(set (reg FLAGS_REG)
674         (compare
675           (match_operand:QI 0 "register_operand" "Q")
676           (subreg:QI
677             (zero_extract:SI
678               (match_operand 1 "ext_register_operand" "Q")
679               (const_int 8)
680               (const_int 8)) 0)))]
681   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
682   "cmp{b}\t{%h1, %0|%0, %h1}"
683   [(set_attr "type" "icmp")
684    (set_attr "mode" "QI")])
686 (define_insn "*cmpqi_ext_2"
687   [(set (reg FLAGS_REG)
688         (compare
689           (subreg:QI
690             (zero_extract:SI
691               (match_operand 0 "ext_register_operand" "Q")
692               (const_int 8)
693               (const_int 8)) 0)
694           (match_operand:QI 1 "const0_operand" "n")))]
695   "ix86_match_ccmode (insn, CCNOmode)"
696   "test{b}\t%h0, %h0"
697   [(set_attr "type" "test")
698    (set_attr "length_immediate" "0")
699    (set_attr "mode" "QI")])
701 (define_expand "cmpqi_ext_3"
702   [(set (reg:CC FLAGS_REG)
703         (compare:CC
704           (subreg:QI
705             (zero_extract:SI
706               (match_operand 0 "ext_register_operand" "")
707               (const_int 8)
708               (const_int 8)) 0)
709           (match_operand:QI 1 "general_operand" "")))]
710   ""
711   "")
713 (define_insn "cmpqi_ext_3_insn"
714   [(set (reg FLAGS_REG)
715         (compare
716           (subreg:QI
717             (zero_extract:SI
718               (match_operand 0 "ext_register_operand" "Q")
719               (const_int 8)
720               (const_int 8)) 0)
721           (match_operand:QI 1 "general_operand" "Qmn")))]
722   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
723   "cmp{b}\t{%1, %h0|%h0, %1}"
724   [(set_attr "type" "icmp")
725    (set_attr "mode" "QI")])
727 (define_insn "cmpqi_ext_3_insn_rex64"
728   [(set (reg FLAGS_REG)
729         (compare
730           (subreg:QI
731             (zero_extract:SI
732               (match_operand 0 "ext_register_operand" "Q")
733               (const_int 8)
734               (const_int 8)) 0)
735           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
736   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
737   "cmp{b}\t{%1, %h0|%h0, %1}"
738   [(set_attr "type" "icmp")
739    (set_attr "mode" "QI")])
741 (define_insn "*cmpqi_ext_4"
742   [(set (reg FLAGS_REG)
743         (compare
744           (subreg:QI
745             (zero_extract:SI
746               (match_operand 0 "ext_register_operand" "Q")
747               (const_int 8)
748               (const_int 8)) 0)
749           (subreg:QI
750             (zero_extract:SI
751               (match_operand 1 "ext_register_operand" "Q")
752               (const_int 8)
753               (const_int 8)) 0)))]
754   "ix86_match_ccmode (insn, CCmode)"
755   "cmp{b}\t{%h1, %h0|%h0, %h1}"
756   [(set_attr "type" "icmp")
757    (set_attr "mode" "QI")])
759 ;; These implement float point compares.
760 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
761 ;; which would allow mix and match FP modes on the compares.  Which is what
762 ;; the old patterns did, but with many more of them.
764 (define_expand "cmpxf"
765   [(set (reg:CC FLAGS_REG)
766         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
767                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
768   "TARGET_80387"
770   ix86_compare_op0 = operands[0];
771   ix86_compare_op1 = operands[1];
772   DONE;
775 (define_expand "cmpdf"
776   [(set (reg:CC FLAGS_REG)
777         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
778                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
779   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
781   ix86_compare_op0 = operands[0];
782   ix86_compare_op1 = operands[1];
783   DONE;
786 (define_expand "cmpsf"
787   [(set (reg:CC FLAGS_REG)
788         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
789                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
790   "TARGET_80387 || TARGET_SSE_MATH"
792   ix86_compare_op0 = operands[0];
793   ix86_compare_op1 = operands[1];
794   DONE;
797 ;; FP compares, step 1:
798 ;; Set the FP condition codes.
800 ;; CCFPmode     compare with exceptions
801 ;; CCFPUmode    compare with no exceptions
803 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
804 ;; used to manage the reg stack popping would not be preserved.
806 (define_insn "*cmpfp_0_sf"
807   [(set (match_operand:HI 0 "register_operand" "=a")
808         (unspec:HI
809           [(compare:CCFP
810              (match_operand:SF 1 "register_operand" "f")
811              (match_operand:SF 2 "const0_operand" "X"))]
812         UNSPEC_FNSTSW))]
813   "TARGET_80387"
814   "* return output_fp_compare (insn, operands, 0, 0);"
815   [(set_attr "type" "multi")
816    (set_attr "mode" "SF")])
818 (define_insn "*cmpfp_0_df"
819   [(set (match_operand:HI 0 "register_operand" "=a")
820         (unspec:HI
821           [(compare:CCFP
822              (match_operand:DF 1 "register_operand" "f")
823              (match_operand:DF 2 "const0_operand" "X"))]
824         UNSPEC_FNSTSW))]
825   "TARGET_80387"
826   "* return output_fp_compare (insn, operands, 0, 0);"
827   [(set_attr "type" "multi")
828    (set_attr "mode" "DF")])
830 (define_insn "*cmpfp_0_xf"
831   [(set (match_operand:HI 0 "register_operand" "=a")
832         (unspec:HI
833           [(compare:CCFP
834              (match_operand:XF 1 "register_operand" "f")
835              (match_operand:XF 2 "const0_operand" "X"))]
836         UNSPEC_FNSTSW))]
837   "TARGET_80387"
838   "* return output_fp_compare (insn, operands, 0, 0);"
839   [(set_attr "type" "multi")
840    (set_attr "mode" "XF")])
842 (define_insn "*cmpfp_sf"
843   [(set (match_operand:HI 0 "register_operand" "=a")
844         (unspec:HI
845           [(compare:CCFP
846              (match_operand:SF 1 "register_operand" "f")
847              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
848           UNSPEC_FNSTSW))]
849   "TARGET_80387"
850   "* return output_fp_compare (insn, operands, 0, 0);"
851   [(set_attr "type" "multi")
852    (set_attr "mode" "SF")])
854 (define_insn "*cmpfp_df"
855   [(set (match_operand:HI 0 "register_operand" "=a")
856         (unspec:HI
857           [(compare:CCFP
858              (match_operand:DF 1 "register_operand" "f")
859              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
860           UNSPEC_FNSTSW))]
861   "TARGET_80387"
862   "* return output_fp_compare (insn, operands, 0, 0);"
863   [(set_attr "type" "multi")
864    (set_attr "mode" "DF")])
866 (define_insn "*cmpfp_xf"
867   [(set (match_operand:HI 0 "register_operand" "=a")
868         (unspec:HI
869           [(compare:CCFP
870              (match_operand:XF 1 "register_operand" "f")
871              (match_operand:XF 2 "register_operand" "f"))]
872           UNSPEC_FNSTSW))]
873   "TARGET_80387"
874   "* return output_fp_compare (insn, operands, 0, 0);"
875   [(set_attr "type" "multi")
876    (set_attr "mode" "XF")])
878 (define_insn "*cmpfp_u"
879   [(set (match_operand:HI 0 "register_operand" "=a")
880         (unspec:HI
881           [(compare:CCFPU
882              (match_operand 1 "register_operand" "f")
883              (match_operand 2 "register_operand" "f"))]
884           UNSPEC_FNSTSW))]
885   "TARGET_80387
886    && FLOAT_MODE_P (GET_MODE (operands[1]))
887    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
888   "* return output_fp_compare (insn, operands, 0, 1);"
889   [(set_attr "type" "multi")
890    (set (attr "mode")
891      (cond [(match_operand:SF 1 "" "")
892               (const_string "SF")
893             (match_operand:DF 1 "" "")
894               (const_string "DF")
895            ]
896            (const_string "XF")))])
898 (define_insn "*cmpfp_si"
899   [(set (match_operand:HI 0 "register_operand" "=a")
900         (unspec:HI
901           [(compare:CCFP
902              (match_operand 1 "register_operand" "f")
903              (match_operator 3 "float_operator"
904                [(match_operand:SI 2 "memory_operand" "m")]))]
905           UNSPEC_FNSTSW))]
906   "TARGET_80387 && TARGET_USE_FIOP
907    && FLOAT_MODE_P (GET_MODE (operands[1]))
908    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
909   "* return output_fp_compare (insn, operands, 0, 0);"
910   [(set_attr "type" "multi")
911    (set_attr "fp_int_src" "true")
912    (set_attr "mode" "SI")])
914 ;; FP compares, step 2
915 ;; Move the fpsw to ax.
917 (define_insn "x86_fnstsw_1"
918   [(set (match_operand:HI 0 "register_operand" "=a")
919         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
920   "TARGET_80387"
921   "fnstsw\t%0"
922   [(set_attr "length" "2")
923    (set_attr "mode" "SI")
924    (set_attr "unit" "i387")])
926 ;; FP compares, step 3
927 ;; Get ax into flags, general case.
929 (define_insn "x86_sahf_1"
930   [(set (reg:CC FLAGS_REG)
931         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
932   "!TARGET_64BIT"
933   "sahf"
934   [(set_attr "length" "1")
935    (set_attr "athlon_decode" "vector")
936    (set_attr "mode" "SI")])
938 ;; Pentium Pro can do steps 1 through 3 in one go.
940 (define_insn "*cmpfp_i_mixed"
941   [(set (reg:CCFP FLAGS_REG)
942         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
943                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
944   "TARGET_MIX_SSE_I387
945    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
946    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
947   "* return output_fp_compare (insn, operands, 1, 0);"
948   [(set_attr "type" "fcmp,ssecomi")
949    (set (attr "mode")
950      (if_then_else (match_operand:SF 1 "" "")
951         (const_string "SF")
952         (const_string "DF")))
953    (set_attr "athlon_decode" "vector")])
955 (define_insn "*cmpfp_i_sse"
956   [(set (reg:CCFP FLAGS_REG)
957         (compare:CCFP (match_operand 0 "register_operand" "x")
958                       (match_operand 1 "nonimmediate_operand" "xm")))]
959   "TARGET_SSE_MATH
960    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
961    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
962   "* return output_fp_compare (insn, operands, 1, 0);"
963   [(set_attr "type" "ssecomi")
964    (set (attr "mode")
965      (if_then_else (match_operand:SF 1 "" "")
966         (const_string "SF")
967         (const_string "DF")))
968    (set_attr "athlon_decode" "vector")])
970 (define_insn "*cmpfp_i_i387"
971   [(set (reg:CCFP FLAGS_REG)
972         (compare:CCFP (match_operand 0 "register_operand" "f")
973                       (match_operand 1 "register_operand" "f")))]
974   "TARGET_80387 && TARGET_CMOVE
975    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
976    && 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" "fcmp")
980    (set (attr "mode")
981      (cond [(match_operand:SF 1 "" "")
982               (const_string "SF")
983             (match_operand:DF 1 "" "")
984               (const_string "DF")
985            ]
986            (const_string "XF")))
987    (set_attr "athlon_decode" "vector")])
989 (define_insn "*cmpfp_iu_mixed"
990   [(set (reg:CCFPU FLAGS_REG)
991         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
992                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
993   "TARGET_MIX_SSE_I387
994    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
995    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
996   "* return output_fp_compare (insn, operands, 1, 1);"
997   [(set_attr "type" "fcmp,ssecomi")
998    (set (attr "mode")
999      (if_then_else (match_operand:SF 1 "" "")
1000         (const_string "SF")
1001         (const_string "DF")))
1002    (set_attr "athlon_decode" "vector")])
1004 (define_insn "*cmpfp_iu_sse"
1005   [(set (reg:CCFPU FLAGS_REG)
1006         (compare:CCFPU (match_operand 0 "register_operand" "x")
1007                        (match_operand 1 "nonimmediate_operand" "xm")))]
1008   "TARGET_SSE_MATH
1009    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011   "* return output_fp_compare (insn, operands, 1, 1);"
1012   [(set_attr "type" "ssecomi")
1013    (set (attr "mode")
1014      (if_then_else (match_operand:SF 1 "" "")
1015         (const_string "SF")
1016         (const_string "DF")))
1017    (set_attr "athlon_decode" "vector")])
1019 (define_insn "*cmpfp_iu_387"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "f")
1022                        (match_operand 1 "register_operand" "f")))]
1023   "TARGET_80387 && TARGET_CMOVE
1024    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1025    && 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" "fcmp")
1029    (set (attr "mode")
1030      (cond [(match_operand:SF 1 "" "")
1031               (const_string "SF")
1032             (match_operand:DF 1 "" "")
1033               (const_string "DF")
1034            ]
1035            (const_string "XF")))
1036    (set_attr "athlon_decode" "vector")])
1038 ;; Move instructions.
1040 ;; General case of fullword move.
1042 (define_expand "movsi"
1043   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1044         (match_operand:SI 1 "general_operand" ""))]
1045   ""
1046   "ix86_expand_move (SImode, operands); DONE;")
1048 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1049 ;; general_operand.
1051 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1052 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1053 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1054 ;; targets without our curiosities, and it is just as easy to represent
1055 ;; this differently.
1057 (define_insn "*pushsi2"
1058   [(set (match_operand:SI 0 "push_operand" "=<")
1059         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1060   "!TARGET_64BIT"
1061   "push{l}\t%1"
1062   [(set_attr "type" "push")
1063    (set_attr "mode" "SI")])
1065 ;; For 64BIT abi we always round up to 8 bytes.
1066 (define_insn "*pushsi2_rex64"
1067   [(set (match_operand:SI 0 "push_operand" "=X")
1068         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1069   "TARGET_64BIT"
1070   "push{q}\t%q1"
1071   [(set_attr "type" "push")
1072    (set_attr "mode" "SI")])
1074 (define_insn "*pushsi2_prologue"
1075   [(set (match_operand:SI 0 "push_operand" "=<")
1076         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1077    (clobber (mem:BLK (scratch)))]
1078   "!TARGET_64BIT"
1079   "push{l}\t%1"
1080   [(set_attr "type" "push")
1081    (set_attr "mode" "SI")])
1083 (define_insn "*popsi1_epilogue"
1084   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1085         (mem:SI (reg:SI SP_REG)))
1086    (set (reg:SI SP_REG)
1087         (plus:SI (reg:SI SP_REG) (const_int 4)))
1088    (clobber (mem:BLK (scratch)))]
1089   "!TARGET_64BIT"
1090   "pop{l}\t%0"
1091   [(set_attr "type" "pop")
1092    (set_attr "mode" "SI")])
1094 (define_insn "popsi1"
1095   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1096         (mem:SI (reg:SI SP_REG)))
1097    (set (reg:SI SP_REG)
1098         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1099   "!TARGET_64BIT"
1100   "pop{l}\t%0"
1101   [(set_attr "type" "pop")
1102    (set_attr "mode" "SI")])
1104 (define_insn "*movsi_xor"
1105   [(set (match_operand:SI 0 "register_operand" "=r")
1106         (match_operand:SI 1 "const0_operand" "i"))
1107    (clobber (reg:CC FLAGS_REG))]
1108   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1109   "xor{l}\t{%0, %0|%0, %0}"
1110   [(set_attr "type" "alu1")
1111    (set_attr "mode" "SI")
1112    (set_attr "length_immediate" "0")])
1114 (define_insn "*movsi_or"
1115   [(set (match_operand:SI 0 "register_operand" "=r")
1116         (match_operand:SI 1 "immediate_operand" "i"))
1117    (clobber (reg:CC FLAGS_REG))]
1118   "reload_completed
1119    && operands[1] == constm1_rtx
1120    && (TARGET_PENTIUM || optimize_size)"
1122   operands[1] = constm1_rtx;
1123   return "or{l}\t{%1, %0|%0, %1}";
1125   [(set_attr "type" "alu1")
1126    (set_attr "mode" "SI")
1127    (set_attr "length_immediate" "1")])
1129 (define_insn "*movsi_1"
1130   [(set (match_operand:SI 0 "nonimmediate_operand"
1131                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1132         (match_operand:SI 1 "general_operand"
1133                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1134   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1136   switch (get_attr_type (insn))
1137     {
1138     case TYPE_SSELOG1:
1139       if (get_attr_mode (insn) == MODE_TI)
1140         return "pxor\t%0, %0";
1141       return "xorps\t%0, %0";
1143     case TYPE_SSEMOV:
1144       switch (get_attr_mode (insn))
1145         {
1146         case MODE_TI:
1147           return "movdqa\t{%1, %0|%0, %1}";
1148         case MODE_V4SF:
1149           return "movaps\t{%1, %0|%0, %1}";
1150         case MODE_SI:
1151           return "movd\t{%1, %0|%0, %1}";
1152         case MODE_SF:
1153           return "movss\t{%1, %0|%0, %1}";
1154         default:
1155           gcc_unreachable ();
1156         }
1158     case TYPE_MMXADD:
1159       return "pxor\t%0, %0";
1161     case TYPE_MMXMOV:
1162       if (get_attr_mode (insn) == MODE_DI)
1163         return "movq\t{%1, %0|%0, %1}";
1164       return "movd\t{%1, %0|%0, %1}";
1166     case TYPE_LEA:
1167       return "lea{l}\t{%1, %0|%0, %1}";
1169     default:
1170       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1171         abort();
1172       return "mov{l}\t{%1, %0|%0, %1}";
1173     }
1175   [(set (attr "type")
1176      (cond [(eq_attr "alternative" "2")
1177               (const_string "mmx")
1178             (eq_attr "alternative" "3,4,5")
1179               (const_string "mmxmov")
1180             (eq_attr "alternative" "6")
1181               (const_string "sselog1")
1182             (eq_attr "alternative" "7,8,9,10,11")
1183               (const_string "ssemov")
1184             (and (ne (symbol_ref "flag_pic") (const_int 0))
1185                  (match_operand:SI 1 "symbolic_operand" ""))
1186               (const_string "lea")
1187            ]
1188            (const_string "imov")))
1189    (set (attr "mode")
1190      (cond [(eq_attr "alternative" "2,3")
1191               (const_string "DI")
1192             (eq_attr "alternative" "6,7")
1193               (if_then_else
1194                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1195                 (const_string "V4SF")
1196                 (const_string "TI"))
1197             (and (eq_attr "alternative" "8,9,10,11")
1198                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1199               (const_string "SF")
1200            ]
1201            (const_string "SI")))])
1203 ;; Stores and loads of ax to arbitrary constant address.
1204 ;; We fake an second form of instruction to force reload to load address
1205 ;; into register when rax is not available
1206 (define_insn "*movabssi_1_rex64"
1207   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1208         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1209   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1210   "@
1211    movabs{l}\t{%1, %P0|%P0, %1}
1212    mov{l}\t{%1, %a0|%a0, %1}"
1213   [(set_attr "type" "imov")
1214    (set_attr "modrm" "0,*")
1215    (set_attr "length_address" "8,0")
1216    (set_attr "length_immediate" "0,*")
1217    (set_attr "memory" "store")
1218    (set_attr "mode" "SI")])
1220 (define_insn "*movabssi_2_rex64"
1221   [(set (match_operand:SI 0 "register_operand" "=a,r")
1222         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1223   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1224   "@
1225    movabs{l}\t{%P1, %0|%0, %P1}
1226    mov{l}\t{%a1, %0|%0, %a1}"
1227   [(set_attr "type" "imov")
1228    (set_attr "modrm" "0,*")
1229    (set_attr "length_address" "8,0")
1230    (set_attr "length_immediate" "0")
1231    (set_attr "memory" "load")
1232    (set_attr "mode" "SI")])
1234 (define_insn "*swapsi"
1235   [(set (match_operand:SI 0 "register_operand" "+r")
1236         (match_operand:SI 1 "register_operand" "+r"))
1237    (set (match_dup 1)
1238         (match_dup 0))]
1239   ""
1240   "xchg{l}\t%1, %0"
1241   [(set_attr "type" "imov")
1242    (set_attr "mode" "SI")
1243    (set_attr "pent_pair" "np")
1244    (set_attr "athlon_decode" "vector")])
1246 (define_expand "movhi"
1247   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1248         (match_operand:HI 1 "general_operand" ""))]
1249   ""
1250   "ix86_expand_move (HImode, operands); DONE;")
1252 (define_insn "*pushhi2"
1253   [(set (match_operand:HI 0 "push_operand" "=<,<")
1254         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1255   "!TARGET_64BIT"
1256   "@
1257    push{w}\t{|WORD PTR }%1
1258    push{w}\t%1"
1259   [(set_attr "type" "push")
1260    (set_attr "mode" "HI")])
1262 ;; For 64BIT abi we always round up to 8 bytes.
1263 (define_insn "*pushhi2_rex64"
1264   [(set (match_operand:HI 0 "push_operand" "=X")
1265         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1266   "TARGET_64BIT"
1267   "push{q}\t%q1"
1268   [(set_attr "type" "push")
1269    (set_attr "mode" "QI")])
1271 (define_insn "*movhi_1"
1272   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1273         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1274   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1276   switch (get_attr_type (insn))
1277     {
1278     case TYPE_IMOVX:
1279       /* movzwl is faster than movw on p2 due to partial word stalls,
1280          though not as fast as an aligned movl.  */
1281       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1282     default:
1283       if (get_attr_mode (insn) == MODE_SI)
1284         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1285       else
1286         return "mov{w}\t{%1, %0|%0, %1}";
1287     }
1289   [(set (attr "type")
1290      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1291               (const_string "imov")
1292             (and (eq_attr "alternative" "0")
1293                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1294                           (const_int 0))
1295                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1296                           (const_int 0))))
1297               (const_string "imov")
1298             (and (eq_attr "alternative" "1,2")
1299                  (match_operand:HI 1 "aligned_operand" ""))
1300               (const_string "imov")
1301             (and (ne (symbol_ref "TARGET_MOVX")
1302                      (const_int 0))
1303                  (eq_attr "alternative" "0,2"))
1304               (const_string "imovx")
1305            ]
1306            (const_string "imov")))
1307     (set (attr "mode")
1308       (cond [(eq_attr "type" "imovx")
1309                (const_string "SI")
1310              (and (eq_attr "alternative" "1,2")
1311                   (match_operand:HI 1 "aligned_operand" ""))
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "0")
1314                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315                            (const_int 0))
1316                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1317                            (const_int 0))))
1318                (const_string "SI")
1319             ]
1320             (const_string "HI")))])
1322 ;; Stores and loads of ax to arbitrary constant address.
1323 ;; We fake an second form of instruction to force reload to load address
1324 ;; into register when rax is not available
1325 (define_insn "*movabshi_1_rex64"
1326   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1327         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1328   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1329   "@
1330    movabs{w}\t{%1, %P0|%P0, %1}
1331    mov{w}\t{%1, %a0|%a0, %1}"
1332   [(set_attr "type" "imov")
1333    (set_attr "modrm" "0,*")
1334    (set_attr "length_address" "8,0")
1335    (set_attr "length_immediate" "0,*")
1336    (set_attr "memory" "store")
1337    (set_attr "mode" "HI")])
1339 (define_insn "*movabshi_2_rex64"
1340   [(set (match_operand:HI 0 "register_operand" "=a,r")
1341         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1342   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1343   "@
1344    movabs{w}\t{%P1, %0|%0, %P1}
1345    mov{w}\t{%a1, %0|%0, %a1}"
1346   [(set_attr "type" "imov")
1347    (set_attr "modrm" "0,*")
1348    (set_attr "length_address" "8,0")
1349    (set_attr "length_immediate" "0")
1350    (set_attr "memory" "load")
1351    (set_attr "mode" "HI")])
1353 (define_insn "*swaphi_1"
1354   [(set (match_operand:HI 0 "register_operand" "+r")
1355         (match_operand:HI 1 "register_operand" "+r"))
1356    (set (match_dup 1)
1357         (match_dup 0))]
1358   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1359   "xchg{l}\t%k1, %k0"
1360   [(set_attr "type" "imov")
1361    (set_attr "mode" "SI")
1362    (set_attr "pent_pair" "np")
1363    (set_attr "athlon_decode" "vector")])
1365 (define_insn "*swaphi_2"
1366   [(set (match_operand:HI 0 "register_operand" "+r")
1367         (match_operand:HI 1 "register_operand" "+r"))
1368    (set (match_dup 1)
1369         (match_dup 0))]
1370   "TARGET_PARTIAL_REG_STALL"
1371   "xchg{w}\t%1, %0"
1372   [(set_attr "type" "imov")
1373    (set_attr "mode" "HI")
1374    (set_attr "pent_pair" "np")
1375    (set_attr "athlon_decode" "vector")])
1377 (define_expand "movstricthi"
1378   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1379         (match_operand:HI 1 "general_operand" ""))]
1380   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1382   /* Don't generate memory->memory moves, go through a register */
1383   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1384     operands[1] = force_reg (HImode, operands[1]);
1387 (define_insn "*movstricthi_1"
1388   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1389         (match_operand:HI 1 "general_operand" "rn,m"))]
1390   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1391    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1392   "mov{w}\t{%1, %0|%0, %1}"
1393   [(set_attr "type" "imov")
1394    (set_attr "mode" "HI")])
1396 (define_insn "*movstricthi_xor"
1397   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1398         (match_operand:HI 1 "const0_operand" "i"))
1399    (clobber (reg:CC FLAGS_REG))]
1400   "reload_completed
1401    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1402   "xor{w}\t{%0, %0|%0, %0}"
1403   [(set_attr "type" "alu1")
1404    (set_attr "mode" "HI")
1405    (set_attr "length_immediate" "0")])
1407 (define_expand "movqi"
1408   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1409         (match_operand:QI 1 "general_operand" ""))]
1410   ""
1411   "ix86_expand_move (QImode, operands); DONE;")
1413 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1414 ;; "push a byte".  But actually we use pushw, which has the effect
1415 ;; of rounding the amount pushed up to a halfword.
1417 (define_insn "*pushqi2"
1418   [(set (match_operand:QI 0 "push_operand" "=X,X")
1419         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1420   "!TARGET_64BIT"
1421   "@
1422    push{w}\t{|word ptr }%1
1423    push{w}\t%w1"
1424   [(set_attr "type" "push")
1425    (set_attr "mode" "HI")])
1427 ;; For 64BIT abi we always round up to 8 bytes.
1428 (define_insn "*pushqi2_rex64"
1429   [(set (match_operand:QI 0 "push_operand" "=X")
1430         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1431   "TARGET_64BIT"
1432   "push{q}\t%q1"
1433   [(set_attr "type" "push")
1434    (set_attr "mode" "QI")])
1436 ;; Situation is quite tricky about when to choose full sized (SImode) move
1437 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1438 ;; partial register dependency machines (such as AMD Athlon), where QImode
1439 ;; moves issue extra dependency and for partial register stalls machines
1440 ;; that don't use QImode patterns (and QImode move cause stall on the next
1441 ;; instruction).
1443 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1444 ;; register stall machines with, where we use QImode instructions, since
1445 ;; partial register stall can be caused there.  Then we use movzx.
1446 (define_insn "*movqi_1"
1447   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1448         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1449   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1451   switch (get_attr_type (insn))
1452     {
1453     case TYPE_IMOVX:
1454       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1455         abort ();
1456       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1457     default:
1458       if (get_attr_mode (insn) == MODE_SI)
1459         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1460       else
1461         return "mov{b}\t{%1, %0|%0, %1}";
1462     }
1464   [(set (attr "type")
1465      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1466               (const_string "imov")
1467             (and (eq_attr "alternative" "3")
1468                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1469                           (const_int 0))
1470                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1471                           (const_int 0))))
1472               (const_string "imov")
1473             (eq_attr "alternative" "3,5")
1474               (const_string "imovx")
1475             (and (ne (symbol_ref "TARGET_MOVX")
1476                      (const_int 0))
1477                  (eq_attr "alternative" "2"))
1478               (const_string "imovx")
1479            ]
1480            (const_string "imov")))
1481    (set (attr "mode")
1482       (cond [(eq_attr "alternative" "3,4,5")
1483                (const_string "SI")
1484              (eq_attr "alternative" "6")
1485                (const_string "QI")
1486              (eq_attr "type" "imovx")
1487                (const_string "SI")
1488              (and (eq_attr "type" "imov")
1489                   (and (eq_attr "alternative" "0,1")
1490                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1491                            (const_int 0))))
1492                (const_string "SI")
1493              ;; Avoid partial register stalls when not using QImode arithmetic
1494              (and (eq_attr "type" "imov")
1495                   (and (eq_attr "alternative" "0,1")
1496                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1497                                 (const_int 0))
1498                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1499                                 (const_int 0)))))
1500                (const_string "SI")
1501            ]
1502            (const_string "QI")))])
1504 (define_expand "reload_outqi"
1505   [(parallel [(match_operand:QI 0 "" "=m")
1506               (match_operand:QI 1 "register_operand" "r")
1507               (match_operand:QI 2 "register_operand" "=&q")])]
1508   ""
1510   rtx op0, op1, op2;
1511   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1513   if (reg_overlap_mentioned_p (op2, op0))
1514     abort ();
1515   if (! q_regs_operand (op1, QImode))
1516     {
1517       emit_insn (gen_movqi (op2, op1));
1518       op1 = op2;
1519     }
1520   emit_insn (gen_movqi (op0, op1));
1521   DONE;
1524 (define_insn "*swapqi_1"
1525   [(set (match_operand:QI 0 "register_operand" "+r")
1526         (match_operand:QI 1 "register_operand" "+r"))
1527    (set (match_dup 1)
1528         (match_dup 0))]
1529   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1530   "xchg{l}\t%k1, %k0"
1531   [(set_attr "type" "imov")
1532    (set_attr "mode" "SI")
1533    (set_attr "pent_pair" "np")
1534    (set_attr "athlon_decode" "vector")])
1536 (define_insn "*swapqi_2"
1537   [(set (match_operand:QI 0 "register_operand" "+q")
1538         (match_operand:QI 1 "register_operand" "+q"))
1539    (set (match_dup 1)
1540         (match_dup 0))]
1541   "TARGET_PARTIAL_REG_STALL"
1542   "xchg{b}\t%1, %0"
1543   [(set_attr "type" "imov")
1544    (set_attr "mode" "QI")
1545    (set_attr "pent_pair" "np")
1546    (set_attr "athlon_decode" "vector")])
1548 (define_expand "movstrictqi"
1549   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1550         (match_operand:QI 1 "general_operand" ""))]
1551   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1553   /* Don't generate memory->memory moves, go through a register.  */
1554   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1555     operands[1] = force_reg (QImode, operands[1]);
1558 (define_insn "*movstrictqi_1"
1559   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1560         (match_operand:QI 1 "general_operand" "*qn,m"))]
1561   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1562    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1563   "mov{b}\t{%1, %0|%0, %1}"
1564   [(set_attr "type" "imov")
1565    (set_attr "mode" "QI")])
1567 (define_insn "*movstrictqi_xor"
1568   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1569         (match_operand:QI 1 "const0_operand" "i"))
1570    (clobber (reg:CC FLAGS_REG))]
1571   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1572   "xor{b}\t{%0, %0|%0, %0}"
1573   [(set_attr "type" "alu1")
1574    (set_attr "mode" "QI")
1575    (set_attr "length_immediate" "0")])
1577 (define_insn "*movsi_extv_1"
1578   [(set (match_operand:SI 0 "register_operand" "=R")
1579         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1580                          (const_int 8)
1581                          (const_int 8)))]
1582   ""
1583   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1584   [(set_attr "type" "imovx")
1585    (set_attr "mode" "SI")])
1587 (define_insn "*movhi_extv_1"
1588   [(set (match_operand:HI 0 "register_operand" "=R")
1589         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1590                          (const_int 8)
1591                          (const_int 8)))]
1592   ""
1593   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1594   [(set_attr "type" "imovx")
1595    (set_attr "mode" "SI")])
1597 (define_insn "*movqi_extv_1"
1598   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1599         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1600                          (const_int 8)
1601                          (const_int 8)))]
1602   "!TARGET_64BIT"
1604   switch (get_attr_type (insn))
1605     {
1606     case TYPE_IMOVX:
1607       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1608     default:
1609       return "mov{b}\t{%h1, %0|%0, %h1}";
1610     }
1612   [(set (attr "type")
1613      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1614                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1615                              (ne (symbol_ref "TARGET_MOVX")
1616                                  (const_int 0))))
1617         (const_string "imovx")
1618         (const_string "imov")))
1619    (set (attr "mode")
1620      (if_then_else (eq_attr "type" "imovx")
1621         (const_string "SI")
1622         (const_string "QI")))])
1624 (define_insn "*movqi_extv_1_rex64"
1625   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1626         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1627                          (const_int 8)
1628                          (const_int 8)))]
1629   "TARGET_64BIT"
1631   switch (get_attr_type (insn))
1632     {
1633     case TYPE_IMOVX:
1634       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1635     default:
1636       return "mov{b}\t{%h1, %0|%0, %h1}";
1637     }
1639   [(set (attr "type")
1640      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1641                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1642                              (ne (symbol_ref "TARGET_MOVX")
1643                                  (const_int 0))))
1644         (const_string "imovx")
1645         (const_string "imov")))
1646    (set (attr "mode")
1647      (if_then_else (eq_attr "type" "imovx")
1648         (const_string "SI")
1649         (const_string "QI")))])
1651 ;; Stores and loads of ax to arbitrary constant address.
1652 ;; We fake an second form of instruction to force reload to load address
1653 ;; into register when rax is not available
1654 (define_insn "*movabsqi_1_rex64"
1655   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1656         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1657   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1658   "@
1659    movabs{b}\t{%1, %P0|%P0, %1}
1660    mov{b}\t{%1, %a0|%a0, %1}"
1661   [(set_attr "type" "imov")
1662    (set_attr "modrm" "0,*")
1663    (set_attr "length_address" "8,0")
1664    (set_attr "length_immediate" "0,*")
1665    (set_attr "memory" "store")
1666    (set_attr "mode" "QI")])
1668 (define_insn "*movabsqi_2_rex64"
1669   [(set (match_operand:QI 0 "register_operand" "=a,r")
1670         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1671   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1672   "@
1673    movabs{b}\t{%P1, %0|%0, %P1}
1674    mov{b}\t{%a1, %0|%0, %a1}"
1675   [(set_attr "type" "imov")
1676    (set_attr "modrm" "0,*")
1677    (set_attr "length_address" "8,0")
1678    (set_attr "length_immediate" "0")
1679    (set_attr "memory" "load")
1680    (set_attr "mode" "QI")])
1682 (define_insn "*movsi_extzv_1"
1683   [(set (match_operand:SI 0 "register_operand" "=R")
1684         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1685                          (const_int 8)
1686                          (const_int 8)))]
1687   ""
1688   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1689   [(set_attr "type" "imovx")
1690    (set_attr "mode" "SI")])
1692 (define_insn "*movqi_extzv_2"
1693   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1694         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1695                                     (const_int 8)
1696                                     (const_int 8)) 0))]
1697   "!TARGET_64BIT"
1699   switch (get_attr_type (insn))
1700     {
1701     case TYPE_IMOVX:
1702       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1703     default:
1704       return "mov{b}\t{%h1, %0|%0, %h1}";
1705     }
1707   [(set (attr "type")
1708      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1709                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1710                              (ne (symbol_ref "TARGET_MOVX")
1711                                  (const_int 0))))
1712         (const_string "imovx")
1713         (const_string "imov")))
1714    (set (attr "mode")
1715      (if_then_else (eq_attr "type" "imovx")
1716         (const_string "SI")
1717         (const_string "QI")))])
1719 (define_insn "*movqi_extzv_2_rex64"
1720   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1721         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1722                                     (const_int 8)
1723                                     (const_int 8)) 0))]
1724   "TARGET_64BIT"
1726   switch (get_attr_type (insn))
1727     {
1728     case TYPE_IMOVX:
1729       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1730     default:
1731       return "mov{b}\t{%h1, %0|%0, %h1}";
1732     }
1734   [(set (attr "type")
1735      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1736                         (ne (symbol_ref "TARGET_MOVX")
1737                             (const_int 0)))
1738         (const_string "imovx")
1739         (const_string "imov")))
1740    (set (attr "mode")
1741      (if_then_else (eq_attr "type" "imovx")
1742         (const_string "SI")
1743         (const_string "QI")))])
1745 (define_insn "movsi_insv_1"
1746   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1747                          (const_int 8)
1748                          (const_int 8))
1749         (match_operand:SI 1 "general_operand" "Qmn"))]
1750   "!TARGET_64BIT"
1751   "mov{b}\t{%b1, %h0|%h0, %b1}"
1752   [(set_attr "type" "imov")
1753    (set_attr "mode" "QI")])
1755 (define_insn "movdi_insv_1_rex64"
1756   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1757                          (const_int 8)
1758                          (const_int 8))
1759         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1760   "TARGET_64BIT"
1761   "mov{b}\t{%b1, %h0|%h0, %b1}"
1762   [(set_attr "type" "imov")
1763    (set_attr "mode" "QI")])
1765 (define_insn "*movqi_insv_2"
1766   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1767                          (const_int 8)
1768                          (const_int 8))
1769         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1770                      (const_int 8)))]
1771   ""
1772   "mov{b}\t{%h1, %h0|%h0, %h1}"
1773   [(set_attr "type" "imov")
1774    (set_attr "mode" "QI")])
1776 (define_expand "movdi"
1777   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1778         (match_operand:DI 1 "general_operand" ""))]
1779   ""
1780   "ix86_expand_move (DImode, operands); DONE;")
1782 (define_insn "*pushdi"
1783   [(set (match_operand:DI 0 "push_operand" "=<")
1784         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1785   "!TARGET_64BIT"
1786   "#")
1788 (define_insn "*pushdi2_rex64"
1789   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1790         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1791   "TARGET_64BIT"
1792   "@
1793    push{q}\t%1
1794    #"
1795   [(set_attr "type" "push,multi")
1796    (set_attr "mode" "DI")])
1798 ;; Convert impossible pushes of immediate to existing instructions.
1799 ;; First try to get scratch register and go through it.  In case this
1800 ;; fails, push sign extended lower part first and then overwrite
1801 ;; upper part by 32bit move.
1802 (define_peephole2
1803   [(match_scratch:DI 2 "r")
1804    (set (match_operand:DI 0 "push_operand" "")
1805         (match_operand:DI 1 "immediate_operand" ""))]
1806   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1807    && !x86_64_immediate_operand (operands[1], DImode)"
1808   [(set (match_dup 2) (match_dup 1))
1809    (set (match_dup 0) (match_dup 2))]
1810   "")
1812 ;; We need to define this as both peepholer and splitter for case
1813 ;; peephole2 pass is not run.
1814 ;; "&& 1" is needed to keep it from matching the previous pattern.
1815 (define_peephole2
1816   [(set (match_operand:DI 0 "push_operand" "")
1817         (match_operand:DI 1 "immediate_operand" ""))]
1818   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1819    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1820   [(set (match_dup 0) (match_dup 1))
1821    (set (match_dup 2) (match_dup 3))]
1822   "split_di (operands + 1, 1, operands + 2, operands + 3);
1823    operands[1] = gen_lowpart (DImode, operands[2]);
1824    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1825                                                     GEN_INT (4)));
1826   ")
1828 (define_split
1829   [(set (match_operand:DI 0 "push_operand" "")
1830         (match_operand:DI 1 "immediate_operand" ""))]
1831   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1832    && !symbolic_operand (operands[1], DImode)
1833    && !x86_64_immediate_operand (operands[1], DImode)"
1834   [(set (match_dup 0) (match_dup 1))
1835    (set (match_dup 2) (match_dup 3))]
1836   "split_di (operands + 1, 1, operands + 2, operands + 3);
1837    operands[1] = gen_lowpart (DImode, operands[2]);
1838    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1839                                                     GEN_INT (4)));
1840   ")
1842 (define_insn "*pushdi2_prologue_rex64"
1843   [(set (match_operand:DI 0 "push_operand" "=<")
1844         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1845    (clobber (mem:BLK (scratch)))]
1846   "TARGET_64BIT"
1847   "push{q}\t%1"
1848   [(set_attr "type" "push")
1849    (set_attr "mode" "DI")])
1851 (define_insn "*popdi1_epilogue_rex64"
1852   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1853         (mem:DI (reg:DI SP_REG)))
1854    (set (reg:DI SP_REG)
1855         (plus:DI (reg:DI SP_REG) (const_int 8)))
1856    (clobber (mem:BLK (scratch)))]
1857   "TARGET_64BIT"
1858   "pop{q}\t%0"
1859   [(set_attr "type" "pop")
1860    (set_attr "mode" "DI")])
1862 (define_insn "popdi1"
1863   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1864         (mem:DI (reg:DI SP_REG)))
1865    (set (reg:DI SP_REG)
1866         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1867   "TARGET_64BIT"
1868   "pop{q}\t%0"
1869   [(set_attr "type" "pop")
1870    (set_attr "mode" "DI")])
1872 (define_insn "*movdi_xor_rex64"
1873   [(set (match_operand:DI 0 "register_operand" "=r")
1874         (match_operand:DI 1 "const0_operand" "i"))
1875    (clobber (reg:CC FLAGS_REG))]
1876   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1877    && reload_completed"
1878   "xor{l}\t{%k0, %k0|%k0, %k0}"
1879   [(set_attr "type" "alu1")
1880    (set_attr "mode" "SI")
1881    (set_attr "length_immediate" "0")])
1883 (define_insn "*movdi_or_rex64"
1884   [(set (match_operand:DI 0 "register_operand" "=r")
1885         (match_operand:DI 1 "const_int_operand" "i"))
1886    (clobber (reg:CC FLAGS_REG))]
1887   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1888    && reload_completed
1889    && operands[1] == constm1_rtx"
1891   operands[1] = constm1_rtx;
1892   return "or{q}\t{%1, %0|%0, %1}";
1894   [(set_attr "type" "alu1")
1895    (set_attr "mode" "DI")
1896    (set_attr "length_immediate" "1")])
1898 (define_insn "*movdi_2"
1899   [(set (match_operand:DI 0 "nonimmediate_operand"
1900                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1901         (match_operand:DI 1 "general_operand"
1902                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1903   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1904   "@
1905    #
1906    #
1907    pxor\t%0, %0
1908    movq\t{%1, %0|%0, %1}
1909    movq\t{%1, %0|%0, %1}
1910    pxor\t%0, %0
1911    movq\t{%1, %0|%0, %1}
1912    movdqa\t{%1, %0|%0, %1}
1913    movq\t{%1, %0|%0, %1}
1914    xorps\t%0, %0
1915    movlps\t{%1, %0|%0, %1}
1916    movaps\t{%1, %0|%0, %1}
1917    movlps\t{%1, %0|%0, %1}"
1918   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1919    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1921 (define_split
1922   [(set (match_operand:DI 0 "push_operand" "")
1923         (match_operand:DI 1 "general_operand" ""))]
1924   "!TARGET_64BIT && reload_completed
1925    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1926   [(const_int 0)]
1927   "ix86_split_long_move (operands); DONE;")
1929 ;; %%% This multiword shite has got to go.
1930 (define_split
1931   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1932         (match_operand:DI 1 "general_operand" ""))]
1933   "!TARGET_64BIT && reload_completed
1934    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1935    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1936   [(const_int 0)]
1937   "ix86_split_long_move (operands); DONE;")
1939 (define_insn "*movdi_1_rex64"
1940   [(set (match_operand:DI 0 "nonimmediate_operand"
1941                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1942         (match_operand:DI 1 "general_operand"
1943                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1944   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1946   switch (get_attr_type (insn))
1947     {
1948     case TYPE_SSECVT:
1949       if (which_alternative == 13)
1950         return "movq2dq\t{%1, %0|%0, %1}";
1951       else
1952         return "movdq2q\t{%1, %0|%0, %1}";
1953     case TYPE_SSEMOV:
1954       if (get_attr_mode (insn) == MODE_TI)
1955           return "movdqa\t{%1, %0|%0, %1}";
1956       /* FALLTHRU */
1957     case TYPE_MMXMOV:
1958       /* Moves from and into integer register is done using movd opcode with
1959          REX prefix.  */
1960       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1961           return "movd\t{%1, %0|%0, %1}";
1962       return "movq\t{%1, %0|%0, %1}";
1963     case TYPE_SSELOG1:
1964     case TYPE_MMXADD:
1965       return "pxor\t%0, %0";
1966     case TYPE_MULTI:
1967       return "#";
1968     case TYPE_LEA:
1969       return "lea{q}\t{%a1, %0|%0, %a1}";
1970     default:
1971       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1972         abort ();
1973       if (get_attr_mode (insn) == MODE_SI)
1974         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1975       else if (which_alternative == 2)
1976         return "movabs{q}\t{%1, %0|%0, %1}";
1977       else
1978         return "mov{q}\t{%1, %0|%0, %1}";
1979     }
1981   [(set (attr "type")
1982      (cond [(eq_attr "alternative" "5")
1983               (const_string "mmx")
1984             (eq_attr "alternative" "6,7,8")
1985               (const_string "mmxmov")
1986             (eq_attr "alternative" "9")
1987               (const_string "sselog1")
1988             (eq_attr "alternative" "10,11,12")
1989               (const_string "ssemov")
1990             (eq_attr "alternative" "13,14")
1991               (const_string "ssecvt")
1992             (eq_attr "alternative" "4")
1993               (const_string "multi")
1994             (and (ne (symbol_ref "flag_pic") (const_int 0))
1995                  (match_operand:DI 1 "symbolic_operand" ""))
1996               (const_string "lea")
1997            ]
1998            (const_string "imov")))
1999    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2000    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2001    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2003 ;; Stores and loads of ax to arbitrary constant address.
2004 ;; We fake an second form of instruction to force reload to load address
2005 ;; into register when rax is not available
2006 (define_insn "*movabsdi_1_rex64"
2007   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2008         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2009   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2010   "@
2011    movabs{q}\t{%1, %P0|%P0, %1}
2012    mov{q}\t{%1, %a0|%a0, %1}"
2013   [(set_attr "type" "imov")
2014    (set_attr "modrm" "0,*")
2015    (set_attr "length_address" "8,0")
2016    (set_attr "length_immediate" "0,*")
2017    (set_attr "memory" "store")
2018    (set_attr "mode" "DI")])
2020 (define_insn "*movabsdi_2_rex64"
2021   [(set (match_operand:DI 0 "register_operand" "=a,r")
2022         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2023   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2024   "@
2025    movabs{q}\t{%P1, %0|%0, %P1}
2026    mov{q}\t{%a1, %0|%0, %a1}"
2027   [(set_attr "type" "imov")
2028    (set_attr "modrm" "0,*")
2029    (set_attr "length_address" "8,0")
2030    (set_attr "length_immediate" "0")
2031    (set_attr "memory" "load")
2032    (set_attr "mode" "DI")])
2034 ;; Convert impossible stores of immediate to existing instructions.
2035 ;; First try to get scratch register and go through it.  In case this
2036 ;; fails, move by 32bit parts.
2037 (define_peephole2
2038   [(match_scratch:DI 2 "r")
2039    (set (match_operand:DI 0 "memory_operand" "")
2040         (match_operand:DI 1 "immediate_operand" ""))]
2041   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2042    && !x86_64_immediate_operand (operands[1], DImode)"
2043   [(set (match_dup 2) (match_dup 1))
2044    (set (match_dup 0) (match_dup 2))]
2045   "")
2047 ;; We need to define this as both peepholer and splitter for case
2048 ;; peephole2 pass is not run.
2049 ;; "&& 1" is needed to keep it from matching the previous pattern.
2050 (define_peephole2
2051   [(set (match_operand:DI 0 "memory_operand" "")
2052         (match_operand:DI 1 "immediate_operand" ""))]
2053   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2054    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2055   [(set (match_dup 2) (match_dup 3))
2056    (set (match_dup 4) (match_dup 5))]
2057   "split_di (operands, 2, operands + 2, operands + 4);")
2059 (define_split
2060   [(set (match_operand:DI 0 "memory_operand" "")
2061         (match_operand:DI 1 "immediate_operand" ""))]
2062   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2063    && !symbolic_operand (operands[1], DImode)
2064    && !x86_64_immediate_operand (operands[1], DImode)"
2065   [(set (match_dup 2) (match_dup 3))
2066    (set (match_dup 4) (match_dup 5))]
2067   "split_di (operands, 2, operands + 2, operands + 4);")
2069 (define_insn "*swapdi_rex64"
2070   [(set (match_operand:DI 0 "register_operand" "+r")
2071         (match_operand:DI 1 "register_operand" "+r"))
2072    (set (match_dup 1)
2073         (match_dup 0))]
2074   "TARGET_64BIT"
2075   "xchg{q}\t%1, %0"
2076   [(set_attr "type" "imov")
2077    (set_attr "mode" "DI")
2078    (set_attr "pent_pair" "np")
2079    (set_attr "athlon_decode" "vector")])
2081 (define_expand "movti"
2082   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2083         (match_operand:TI 1 "nonimmediate_operand" ""))]
2084   "TARGET_SSE || TARGET_64BIT"
2086   if (TARGET_64BIT)
2087     ix86_expand_move (TImode, operands);
2088   else
2089     ix86_expand_vector_move (TImode, operands);
2090   DONE;
2093 (define_insn "*movti_internal"
2094   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2095         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2096   "TARGET_SSE && !TARGET_64BIT
2097    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2099   switch (which_alternative)
2100     {
2101     case 0:
2102       if (get_attr_mode (insn) == MODE_V4SF)
2103         return "xorps\t%0, %0";
2104       else
2105         return "pxor\t%0, %0";
2106     case 1:
2107     case 2:
2108       if (get_attr_mode (insn) == MODE_V4SF)
2109         return "movaps\t{%1, %0|%0, %1}";
2110       else
2111         return "movdqa\t{%1, %0|%0, %1}";
2112     default:
2113       abort ();
2114     }
2116   [(set_attr "type" "ssemov,ssemov,ssemov")
2117    (set (attr "mode")
2118         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2119                  (const_string "V4SF")
2121                (eq_attr "alternative" "0,1")
2122                  (if_then_else
2123                    (ne (symbol_ref "optimize_size")
2124                        (const_int 0))
2125                    (const_string "V4SF")
2126                    (const_string "TI"))
2127                (eq_attr "alternative" "2")
2128                  (if_then_else
2129                    (ne (symbol_ref "optimize_size")
2130                        (const_int 0))
2131                    (const_string "V4SF")
2132                    (const_string "TI"))]
2133                (const_string "TI")))])
2135 (define_insn "*movti_rex64"
2136   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2137         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2138   "TARGET_64BIT
2139    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2141   switch (which_alternative)
2142     {
2143     case 0:
2144     case 1:
2145       return "#";
2146     case 2:
2147       if (get_attr_mode (insn) == MODE_V4SF)
2148         return "xorps\t%0, %0";
2149       else
2150         return "pxor\t%0, %0";
2151     case 3:
2152     case 4:
2153       if (get_attr_mode (insn) == MODE_V4SF)
2154         return "movaps\t{%1, %0|%0, %1}";
2155       else
2156         return "movdqa\t{%1, %0|%0, %1}";
2157     default:
2158       abort ();
2159     }
2161   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2162    (set (attr "mode")
2163         (cond [(eq_attr "alternative" "2,3")
2164                  (if_then_else
2165                    (ne (symbol_ref "optimize_size")
2166                        (const_int 0))
2167                    (const_string "V4SF")
2168                    (const_string "TI"))
2169                (eq_attr "alternative" "4")
2170                  (if_then_else
2171                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2172                             (const_int 0))
2173                         (ne (symbol_ref "optimize_size")
2174                             (const_int 0)))
2175                    (const_string "V4SF")
2176                    (const_string "TI"))]
2177                (const_string "DI")))])
2179 (define_split
2180   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2181         (match_operand:TI 1 "general_operand" ""))]
2182   "reload_completed && !SSE_REG_P (operands[0])
2183    && !SSE_REG_P (operands[1])"
2184   [(const_int 0)]
2185   "ix86_split_long_move (operands); DONE;")
2187 (define_expand "movsf"
2188   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2189         (match_operand:SF 1 "general_operand" ""))]
2190   ""
2191   "ix86_expand_move (SFmode, operands); DONE;")
2193 (define_insn "*pushsf"
2194   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2195         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2196   "!TARGET_64BIT"
2198   switch (which_alternative)
2199     {
2200     case 1:
2201       return "push{l}\t%1";
2203     default:
2204       /* This insn should be already split before reg-stack.  */
2205       abort ();
2206     }
2208   [(set_attr "type" "multi,push,multi")
2209    (set_attr "mode" "SF,SI,SF")])
2211 (define_insn "*pushsf_rex64"
2212   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2213         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2214   "TARGET_64BIT"
2216   switch (which_alternative)
2217     {
2218     case 1:
2219       return "push{q}\t%q1";
2221     default:
2222       /* This insn should be already split before reg-stack.  */
2223       abort ();
2224     }
2226   [(set_attr "type" "multi,push,multi")
2227    (set_attr "mode" "SF,DI,SF")])
2229 (define_split
2230   [(set (match_operand:SF 0 "push_operand" "")
2231         (match_operand:SF 1 "memory_operand" ""))]
2232   "reload_completed
2233    && GET_CODE (operands[1]) == MEM
2234    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2235    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2236   [(set (match_dup 0)
2237         (match_dup 1))]
2238   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2241 ;; %%% Kill this when call knows how to work this out.
2242 (define_split
2243   [(set (match_operand:SF 0 "push_operand" "")
2244         (match_operand:SF 1 "any_fp_register_operand" ""))]
2245   "!TARGET_64BIT"
2246   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2247    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2249 (define_split
2250   [(set (match_operand:SF 0 "push_operand" "")
2251         (match_operand:SF 1 "any_fp_register_operand" ""))]
2252   "TARGET_64BIT"
2253   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2254    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2256 (define_insn "*movsf_1"
2257   [(set (match_operand:SF 0 "nonimmediate_operand"
2258           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2259         (match_operand:SF 1 "general_operand"
2260           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2261   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2262    && (reload_in_progress || reload_completed
2263        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2264        || GET_CODE (operands[1]) != CONST_DOUBLE
2265        || memory_operand (operands[0], SFmode))" 
2267   switch (which_alternative)
2268     {
2269     case 0:
2270       return output_387_reg_move (insn, operands);
2272     case 1:
2273       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2274         return "fstp%z0\t%y0";
2275       else
2276         return "fst%z0\t%y0";
2278     case 2:
2279       return standard_80387_constant_opcode (operands[1]);
2281     case 3:
2282     case 4:
2283       return "mov{l}\t{%1, %0|%0, %1}";
2284     case 5:
2285       if (get_attr_mode (insn) == MODE_TI)
2286         return "pxor\t%0, %0";
2287       else
2288         return "xorps\t%0, %0";
2289     case 6:
2290       if (get_attr_mode (insn) == MODE_V4SF)
2291         return "movaps\t{%1, %0|%0, %1}";
2292       else
2293         return "movss\t{%1, %0|%0, %1}";
2294     case 7:
2295     case 8:
2296       return "movss\t{%1, %0|%0, %1}";
2298     case 9:
2299     case 10:
2300       return "movd\t{%1, %0|%0, %1}";
2302     case 11:
2303       return "movq\t{%1, %0|%0, %1}";
2305     default:
2306       abort();
2307     }
2309   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2310    (set (attr "mode")
2311         (cond [(eq_attr "alternative" "3,4,9,10")
2312                  (const_string "SI")
2313                (eq_attr "alternative" "5")
2314                  (if_then_else
2315                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2316                                  (const_int 0))
2317                              (ne (symbol_ref "TARGET_SSE2")
2318                                  (const_int 0)))
2319                         (eq (symbol_ref "optimize_size")
2320                             (const_int 0)))
2321                    (const_string "TI")
2322                    (const_string "V4SF"))
2323                /* For architectures resolving dependencies on
2324                   whole SSE registers use APS move to break dependency
2325                   chains, otherwise use short move to avoid extra work. 
2327                   Do the same for architectures resolving dependencies on
2328                   the parts.  While in DF mode it is better to always handle
2329                   just register parts, the SF mode is different due to lack
2330                   of instructions to load just part of the register.  It is
2331                   better to maintain the whole registers in single format
2332                   to avoid problems on using packed logical operations.  */
2333                (eq_attr "alternative" "6")
2334                  (if_then_else
2335                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2336                             (const_int 0))
2337                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2338                             (const_int 0)))
2339                    (const_string "V4SF")
2340                    (const_string "SF"))
2341                (eq_attr "alternative" "11")
2342                  (const_string "DI")]
2343                (const_string "SF")))])
2345 (define_insn "*swapsf"
2346   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2347         (match_operand:SF 1 "fp_register_operand" "+f"))
2348    (set (match_dup 1)
2349         (match_dup 0))]
2350   "reload_completed || TARGET_80387"
2352   if (STACK_TOP_P (operands[0]))
2353     return "fxch\t%1";
2354   else
2355     return "fxch\t%0";
2357   [(set_attr "type" "fxch")
2358    (set_attr "mode" "SF")])
2360 (define_expand "movdf"
2361   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2362         (match_operand:DF 1 "general_operand" ""))]
2363   ""
2364   "ix86_expand_move (DFmode, operands); DONE;")
2366 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2367 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2368 ;; On the average, pushdf using integers can be still shorter.  Allow this
2369 ;; pattern for optimize_size too.
2371 (define_insn "*pushdf_nointeger"
2372   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2373         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2374   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2376   /* This insn should be already split before reg-stack.  */
2377   abort ();
2379   [(set_attr "type" "multi")
2380    (set_attr "mode" "DF,SI,SI,DF")])
2382 (define_insn "*pushdf_integer"
2383   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2384         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2385   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2387   /* This insn should be already split before reg-stack.  */
2388   abort ();
2390   [(set_attr "type" "multi")
2391    (set_attr "mode" "DF,SI,DF")])
2393 ;; %%% Kill this when call knows how to work this out.
2394 (define_split
2395   [(set (match_operand:DF 0 "push_operand" "")
2396         (match_operand:DF 1 "any_fp_register_operand" ""))]
2397   "!TARGET_64BIT && reload_completed"
2398   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2399    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2400   "")
2402 (define_split
2403   [(set (match_operand:DF 0 "push_operand" "")
2404         (match_operand:DF 1 "any_fp_register_operand" ""))]
2405   "TARGET_64BIT && reload_completed"
2406   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2407    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2408   "")
2410 (define_split
2411   [(set (match_operand:DF 0 "push_operand" "")
2412         (match_operand:DF 1 "general_operand" ""))]
2413   "reload_completed"
2414   [(const_int 0)]
2415   "ix86_split_long_move (operands); DONE;")
2417 ;; Moving is usually shorter when only FP registers are used. This separate
2418 ;; movdf pattern avoids the use of integer registers for FP operations
2419 ;; when optimizing for size.
2421 (define_insn "*movdf_nointeger"
2422   [(set (match_operand:DF 0 "nonimmediate_operand"
2423                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2424         (match_operand:DF 1 "general_operand"
2425                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2426   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2427    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2428    && (reload_in_progress || reload_completed
2429        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2430        || GET_CODE (operands[1]) != CONST_DOUBLE
2431        || memory_operand (operands[0], DFmode))" 
2433   switch (which_alternative)
2434     {
2435     case 0:
2436       return output_387_reg_move (insn, operands);
2438     case 1:
2439       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2440         return "fstp%z0\t%y0";
2441       else
2442         return "fst%z0\t%y0";
2444     case 2:
2445       return standard_80387_constant_opcode (operands[1]);
2447     case 3:
2448     case 4:
2449       return "#";
2450     case 5:
2451       switch (get_attr_mode (insn))
2452         {
2453         case MODE_V4SF:
2454           return "xorps\t%0, %0";
2455         case MODE_V2DF:
2456           return "xorpd\t%0, %0";
2457         case MODE_TI:
2458           return "pxor\t%0, %0";
2459         default:
2460           abort ();
2461         }
2462     case 6:
2463     case 7:
2464     case 8:
2465       switch (get_attr_mode (insn))
2466         {
2467         case MODE_V4SF:
2468           return "movaps\t{%1, %0|%0, %1}";
2469         case MODE_V2DF:
2470           return "movapd\t{%1, %0|%0, %1}";
2471         case MODE_TI:
2472           return "movdqa\t{%1, %0|%0, %1}";
2473         case MODE_DI:
2474           return "movq\t{%1, %0|%0, %1}";
2475         case MODE_DF:
2476           return "movsd\t{%1, %0|%0, %1}";
2477         case MODE_V1DF:
2478           return "movlpd\t{%1, %0|%0, %1}";
2479         case MODE_V2SF:
2480           return "movlps\t{%1, %0|%0, %1}";
2481         default:
2482           abort ();
2483         }
2485     default:
2486       abort();
2487     }
2489   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2490    (set (attr "mode")
2491         (cond [(eq_attr "alternative" "0,1,2")
2492                  (const_string "DF")
2493                (eq_attr "alternative" "3,4")
2494                  (const_string "SI")
2496                /* For SSE1, we have many fewer alternatives.  */
2497                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2498                  (cond [(eq_attr "alternative" "5,6")
2499                           (const_string "V4SF")
2500                        ]
2501                    (const_string "V2SF"))
2503                /* xorps is one byte shorter.  */
2504                (eq_attr "alternative" "5")
2505                  (cond [(ne (symbol_ref "optimize_size")
2506                             (const_int 0))
2507                           (const_string "V4SF")
2508                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2509                             (const_int 0))
2510                           (const_string "TI")
2511                        ]
2512                        (const_string "V2DF"))
2514                /* For architectures resolving dependencies on
2515                   whole SSE registers use APD move to break dependency
2516                   chains, otherwise use short move to avoid extra work.
2518                   movaps encodes one byte shorter.  */
2519                (eq_attr "alternative" "6")
2520                  (cond
2521                    [(ne (symbol_ref "optimize_size")
2522                         (const_int 0))
2523                       (const_string "V4SF")
2524                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2525                         (const_int 0))
2526                       (const_string "V2DF")
2527                    ]
2528                    (const_string "DF"))
2529                /* For architectures resolving dependencies on register
2530                   parts we may avoid extra work to zero out upper part
2531                   of register.  */
2532                (eq_attr "alternative" "7")
2533                  (if_then_else
2534                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2535                        (const_int 0))
2536                    (const_string "V1DF")
2537                    (const_string "DF"))
2538               ]
2539               (const_string "DF")))])
2541 (define_insn "*movdf_integer"
2542   [(set (match_operand:DF 0 "nonimmediate_operand"
2543                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2544         (match_operand:DF 1 "general_operand"
2545                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2546   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2547    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2548    && (reload_in_progress || reload_completed
2549        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2550        || GET_CODE (operands[1]) != CONST_DOUBLE
2551        || memory_operand (operands[0], DFmode))" 
2553   switch (which_alternative)
2554     {
2555     case 0:
2556       return output_387_reg_move (insn, operands);
2558     case 1:
2559       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2560         return "fstp%z0\t%y0";
2561       else
2562         return "fst%z0\t%y0";
2564     case 2:
2565       return standard_80387_constant_opcode (operands[1]);
2567     case 3:
2568     case 4:
2569       return "#";
2571     case 5:
2572       switch (get_attr_mode (insn))
2573         {
2574         case MODE_V4SF:
2575           return "xorps\t%0, %0";
2576         case MODE_V2DF:
2577           return "xorpd\t%0, %0";
2578         case MODE_TI:
2579           return "pxor\t%0, %0";
2580         default:
2581           abort ();
2582         }
2583     case 6:
2584     case 7:
2585     case 8:
2586       switch (get_attr_mode (insn))
2587         {
2588         case MODE_V4SF:
2589           return "movaps\t{%1, %0|%0, %1}";
2590         case MODE_V2DF:
2591           return "movapd\t{%1, %0|%0, %1}";
2592         case MODE_TI:
2593           return "movdqa\t{%1, %0|%0, %1}";
2594         case MODE_DI:
2595           return "movq\t{%1, %0|%0, %1}";
2596         case MODE_DF:
2597           return "movsd\t{%1, %0|%0, %1}";
2598         case MODE_V1DF:
2599           return "movlpd\t{%1, %0|%0, %1}";
2600         case MODE_V2SF:
2601           return "movlps\t{%1, %0|%0, %1}";
2602         default:
2603           abort ();
2604         }
2606     default:
2607       abort();
2608     }
2610   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2611    (set (attr "mode")
2612         (cond [(eq_attr "alternative" "0,1,2")
2613                  (const_string "DF")
2614                (eq_attr "alternative" "3,4")
2615                  (const_string "SI")
2617                /* For SSE1, we have many fewer alternatives.  */
2618                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2619                  (cond [(eq_attr "alternative" "5,6")
2620                           (const_string "V4SF")
2621                        ]
2622                    (const_string "V2SF"))
2624                /* xorps is one byte shorter.  */
2625                (eq_attr "alternative" "5")
2626                  (cond [(ne (symbol_ref "optimize_size")
2627                             (const_int 0))
2628                           (const_string "V4SF")
2629                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2630                             (const_int 0))
2631                           (const_string "TI")
2632                        ]
2633                        (const_string "V2DF"))
2635                /* For architectures resolving dependencies on
2636                   whole SSE registers use APD move to break dependency
2637                   chains, otherwise use short move to avoid extra work.
2639                   movaps encodes one byte shorter.  */
2640                (eq_attr "alternative" "6")
2641                  (cond
2642                    [(ne (symbol_ref "optimize_size")
2643                         (const_int 0))
2644                       (const_string "V4SF")
2645                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2646                         (const_int 0))
2647                       (const_string "V2DF")
2648                    ]
2649                    (const_string "DF"))
2650                /* For architectures resolving dependencies on register
2651                   parts we may avoid extra work to zero out upper part
2652                   of register.  */
2653                (eq_attr "alternative" "7")
2654                  (if_then_else
2655                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2656                        (const_int 0))
2657                    (const_string "V1DF")
2658                    (const_string "DF"))
2659               ]
2660               (const_string "DF")))])
2662 (define_split
2663   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2664         (match_operand:DF 1 "general_operand" ""))]
2665   "reload_completed
2666    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2667    && ! (ANY_FP_REG_P (operands[0]) || 
2668          (GET_CODE (operands[0]) == SUBREG
2669           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2670    && ! (ANY_FP_REG_P (operands[1]) || 
2671          (GET_CODE (operands[1]) == SUBREG
2672           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2673   [(const_int 0)]
2674   "ix86_split_long_move (operands); DONE;")
2676 (define_insn "*swapdf"
2677   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2678         (match_operand:DF 1 "fp_register_operand" "+f"))
2679    (set (match_dup 1)
2680         (match_dup 0))]
2681   "reload_completed || TARGET_80387"
2683   if (STACK_TOP_P (operands[0]))
2684     return "fxch\t%1";
2685   else
2686     return "fxch\t%0";
2688   [(set_attr "type" "fxch")
2689    (set_attr "mode" "DF")])
2691 (define_expand "movxf"
2692   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2693         (match_operand:XF 1 "general_operand" ""))]
2694   ""
2695   "ix86_expand_move (XFmode, operands); DONE;")
2697 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2698 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2699 ;; Pushing using integer instructions is longer except for constants
2700 ;; and direct memory references.
2701 ;; (assuming that any given constant is pushed only once, but this ought to be
2702 ;;  handled elsewhere).
2704 (define_insn "*pushxf_nointeger"
2705   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2706         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2707   "optimize_size"
2709   /* This insn should be already split before reg-stack.  */
2710   abort ();
2712   [(set_attr "type" "multi")
2713    (set_attr "mode" "XF,SI,SI")])
2715 (define_insn "*pushxf_integer"
2716   [(set (match_operand:XF 0 "push_operand" "=<,<")
2717         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2718   "!optimize_size"
2720   /* This insn should be already split before reg-stack.  */
2721   abort ();
2723   [(set_attr "type" "multi")
2724    (set_attr "mode" "XF,SI")])
2726 (define_split
2727   [(set (match_operand 0 "push_operand" "")
2728         (match_operand 1 "general_operand" ""))]
2729   "reload_completed
2730    && (GET_MODE (operands[0]) == XFmode
2731        || GET_MODE (operands[0]) == DFmode)
2732    && !ANY_FP_REG_P (operands[1])"
2733   [(const_int 0)]
2734   "ix86_split_long_move (operands); DONE;")
2736 (define_split
2737   [(set (match_operand:XF 0 "push_operand" "")
2738         (match_operand:XF 1 "any_fp_register_operand" ""))]
2739   "!TARGET_64BIT"
2740   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2741    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2742   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2744 (define_split
2745   [(set (match_operand:XF 0 "push_operand" "")
2746         (match_operand:XF 1 "any_fp_register_operand" ""))]
2747   "TARGET_64BIT"
2748   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2749    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2750   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2752 ;; Do not use integer registers when optimizing for size
2753 (define_insn "*movxf_nointeger"
2754   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2755         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2756   "optimize_size
2757    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2758    && (reload_in_progress || reload_completed
2759        || GET_CODE (operands[1]) != CONST_DOUBLE
2760        || memory_operand (operands[0], XFmode))" 
2762   switch (which_alternative)
2763     {
2764     case 0:
2765       return output_387_reg_move (insn, operands);
2767     case 1:
2768       /* There is no non-popping store to memory for XFmode.  So if
2769          we need one, follow the store with a load.  */
2770       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2771         return "fstp%z0\t%y0\;fld%z0\t%y0";
2772       else
2773         return "fstp%z0\t%y0";
2775     case 2:
2776       return standard_80387_constant_opcode (operands[1]);
2778     case 3: case 4:
2779       return "#";
2780     }
2781   abort();
2783   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2784    (set_attr "mode" "XF,XF,XF,SI,SI")])
2786 (define_insn "*movxf_integer"
2787   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2788         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2789   "!optimize_size
2790    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2791    && (reload_in_progress || reload_completed
2792        || GET_CODE (operands[1]) != CONST_DOUBLE
2793        || memory_operand (operands[0], XFmode))" 
2795   switch (which_alternative)
2796     {
2797     case 0:
2798       return output_387_reg_move (insn, operands);
2800     case 1:
2801       /* There is no non-popping store to memory for XFmode.  So if
2802          we need one, follow the store with a load.  */
2803       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2804         return "fstp%z0\t%y0\;fld%z0\t%y0";
2805       else
2806         return "fstp%z0\t%y0";
2808     case 2:
2809       return standard_80387_constant_opcode (operands[1]);
2811     case 3: case 4:
2812       return "#";
2813     }
2814   abort();
2816   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2817    (set_attr "mode" "XF,XF,XF,SI,SI")])
2819 (define_split
2820   [(set (match_operand 0 "nonimmediate_operand" "")
2821         (match_operand 1 "general_operand" ""))]
2822   "reload_completed
2823    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2824    && GET_MODE (operands[0]) == XFmode
2825    && ! (ANY_FP_REG_P (operands[0]) || 
2826          (GET_CODE (operands[0]) == SUBREG
2827           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2828    && ! (ANY_FP_REG_P (operands[1]) || 
2829          (GET_CODE (operands[1]) == SUBREG
2830           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2831   [(const_int 0)]
2832   "ix86_split_long_move (operands); DONE;")
2834 (define_split
2835   [(set (match_operand 0 "register_operand" "")
2836         (match_operand 1 "memory_operand" ""))]
2837   "reload_completed
2838    && GET_CODE (operands[1]) == MEM
2839    && (GET_MODE (operands[0]) == XFmode
2840        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2841    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2842    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2843   [(set (match_dup 0) (match_dup 1))]
2845   rtx c = get_pool_constant (XEXP (operands[1], 0));
2846   rtx r = operands[0];
2848   if (GET_CODE (r) == SUBREG)
2849     r = SUBREG_REG (r);
2851   if (SSE_REG_P (r))
2852     {
2853       if (!standard_sse_constant_p (c))
2854         FAIL;
2855     }
2856   else if (FP_REG_P (r))
2857     {
2858       if (!standard_80387_constant_p (c))
2859         FAIL;
2860     }
2861   else if (MMX_REG_P (r))
2862     FAIL;
2864   operands[1] = c;
2867 (define_insn "swapxf"
2868   [(set (match_operand:XF 0 "register_operand" "+f")
2869         (match_operand:XF 1 "register_operand" "+f"))
2870    (set (match_dup 1)
2871         (match_dup 0))]
2872   "TARGET_80387"
2874   if (STACK_TOP_P (operands[0]))
2875     return "fxch\t%1";
2876   else
2877     return "fxch\t%0";
2879   [(set_attr "type" "fxch")
2880    (set_attr "mode" "XF")])
2882 (define_expand "movtf"
2883   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2884         (match_operand:TF 1 "nonimmediate_operand" ""))]
2885   "TARGET_64BIT"
2887   ix86_expand_move (TFmode, operands);
2888   DONE;
2891 (define_insn "*movtf_internal"
2892   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2893         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2894   "TARGET_64BIT
2895    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2897   switch (which_alternative)
2898     {
2899     case 0:
2900     case 1:
2901       return "#";
2902     case 2:
2903       if (get_attr_mode (insn) == MODE_V4SF)
2904         return "xorps\t%0, %0";
2905       else
2906         return "pxor\t%0, %0";
2907     case 3:
2908     case 4:
2909       if (get_attr_mode (insn) == MODE_V4SF)
2910         return "movaps\t{%1, %0|%0, %1}";
2911       else
2912         return "movdqa\t{%1, %0|%0, %1}";
2913     default:
2914       abort ();
2915     }
2917   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2918    (set (attr "mode")
2919         (cond [(eq_attr "alternative" "2,3")
2920                  (if_then_else
2921                    (ne (symbol_ref "optimize_size")
2922                        (const_int 0))
2923                    (const_string "V4SF")
2924                    (const_string "TI"))
2925                (eq_attr "alternative" "4")
2926                  (if_then_else
2927                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2928                             (const_int 0))
2929                         (ne (symbol_ref "optimize_size")
2930                             (const_int 0)))
2931                    (const_string "V4SF")
2932                    (const_string "TI"))]
2933                (const_string "DI")))])
2935 (define_split
2936   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2937         (match_operand:TF 1 "general_operand" ""))]
2938   "reload_completed && !SSE_REG_P (operands[0])
2939    && !SSE_REG_P (operands[1])"
2940   [(const_int 0)]
2941   "ix86_split_long_move (operands); DONE;")
2943 ;; Zero extension instructions
2945 (define_expand "zero_extendhisi2"
2946   [(set (match_operand:SI 0 "register_operand" "")
2947      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2948   ""
2950   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2951     {
2952       operands[1] = force_reg (HImode, operands[1]);
2953       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2954       DONE;
2955     }
2958 (define_insn "zero_extendhisi2_and"
2959   [(set (match_operand:SI 0 "register_operand" "=r")
2960      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2961    (clobber (reg:CC FLAGS_REG))]
2962   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2963   "#"
2964   [(set_attr "type" "alu1")
2965    (set_attr "mode" "SI")])
2967 (define_split
2968   [(set (match_operand:SI 0 "register_operand" "")
2969         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2970    (clobber (reg:CC FLAGS_REG))]
2971   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2972   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2973               (clobber (reg:CC FLAGS_REG))])]
2974   "")
2976 (define_insn "*zero_extendhisi2_movzwl"
2977   [(set (match_operand:SI 0 "register_operand" "=r")
2978      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2979   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2980   "movz{wl|x}\t{%1, %0|%0, %1}"
2981   [(set_attr "type" "imovx")
2982    (set_attr "mode" "SI")])
2984 (define_expand "zero_extendqihi2"
2985   [(parallel
2986     [(set (match_operand:HI 0 "register_operand" "")
2987        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2988      (clobber (reg:CC FLAGS_REG))])]
2989   ""
2990   "")
2992 (define_insn "*zero_extendqihi2_and"
2993   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2994      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997   "#"
2998   [(set_attr "type" "alu1")
2999    (set_attr "mode" "HI")])
3001 (define_insn "*zero_extendqihi2_movzbw_and"
3002   [(set (match_operand:HI 0 "register_operand" "=r,r")
3003      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3004    (clobber (reg:CC FLAGS_REG))]
3005   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3006   "#"
3007   [(set_attr "type" "imovx,alu1")
3008    (set_attr "mode" "HI")])
3010 (define_insn "*zero_extendqihi2_movzbw"
3011   [(set (match_operand:HI 0 "register_operand" "=r")
3012      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3013   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3014   "movz{bw|x}\t{%1, %0|%0, %1}"
3015   [(set_attr "type" "imovx")
3016    (set_attr "mode" "HI")])
3018 ;; For the movzbw case strip only the clobber
3019 (define_split
3020   [(set (match_operand:HI 0 "register_operand" "")
3021         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "reload_completed 
3024    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3025    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3026   [(set (match_operand:HI 0 "register_operand" "")
3027         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3029 ;; When source and destination does not overlap, clear destination
3030 ;; first and then do the movb
3031 (define_split
3032   [(set (match_operand:HI 0 "register_operand" "")
3033         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3034    (clobber (reg:CC FLAGS_REG))]
3035   "reload_completed
3036    && ANY_QI_REG_P (operands[0])
3037    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3038    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3039   [(set (match_dup 0) (const_int 0))
3040    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3041   "operands[2] = gen_lowpart (QImode, operands[0]);")
3043 ;; Rest is handled by single and.
3044 (define_split
3045   [(set (match_operand:HI 0 "register_operand" "")
3046         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3047    (clobber (reg:CC FLAGS_REG))]
3048   "reload_completed
3049    && true_regnum (operands[0]) == true_regnum (operands[1])"
3050   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3051               (clobber (reg:CC FLAGS_REG))])]
3052   "")
3054 (define_expand "zero_extendqisi2"
3055   [(parallel
3056     [(set (match_operand:SI 0 "register_operand" "")
3057        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3058      (clobber (reg:CC FLAGS_REG))])]
3059   ""
3060   "")
3062 (define_insn "*zero_extendqisi2_and"
3063   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3064      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3065    (clobber (reg:CC FLAGS_REG))]
3066   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3067   "#"
3068   [(set_attr "type" "alu1")
3069    (set_attr "mode" "SI")])
3071 (define_insn "*zero_extendqisi2_movzbw_and"
3072   [(set (match_operand:SI 0 "register_operand" "=r,r")
3073      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3074    (clobber (reg:CC FLAGS_REG))]
3075   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3076   "#"
3077   [(set_attr "type" "imovx,alu1")
3078    (set_attr "mode" "SI")])
3080 (define_insn "*zero_extendqisi2_movzbw"
3081   [(set (match_operand:SI 0 "register_operand" "=r")
3082      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3083   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3084   "movz{bl|x}\t{%1, %0|%0, %1}"
3085   [(set_attr "type" "imovx")
3086    (set_attr "mode" "SI")])
3088 ;; For the movzbl case strip only the clobber
3089 (define_split
3090   [(set (match_operand:SI 0 "register_operand" "")
3091         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3092    (clobber (reg:CC FLAGS_REG))]
3093   "reload_completed 
3094    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3095    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3096   [(set (match_dup 0)
3097         (zero_extend:SI (match_dup 1)))])
3099 ;; When source and destination does not overlap, clear destination
3100 ;; first and then do the movb
3101 (define_split
3102   [(set (match_operand:SI 0 "register_operand" "")
3103         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3104    (clobber (reg:CC FLAGS_REG))]
3105   "reload_completed
3106    && ANY_QI_REG_P (operands[0])
3107    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3108    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3109    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3110   [(set (match_dup 0) (const_int 0))
3111    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3112   "operands[2] = gen_lowpart (QImode, operands[0]);")
3114 ;; Rest is handled by single and.
3115 (define_split
3116   [(set (match_operand:SI 0 "register_operand" "")
3117         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3118    (clobber (reg:CC FLAGS_REG))]
3119   "reload_completed
3120    && true_regnum (operands[0]) == true_regnum (operands[1])"
3121   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3122               (clobber (reg:CC FLAGS_REG))])]
3123   "")
3125 ;; %%% Kill me once multi-word ops are sane.
3126 (define_expand "zero_extendsidi2"
3127   [(set (match_operand:DI 0 "register_operand" "=r")
3128      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3129   ""
3130   "if (!TARGET_64BIT)
3131      {
3132        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3133        DONE;
3134      }
3135   ")
3137 (define_insn "zero_extendsidi2_32"
3138   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3139         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3140    (clobber (reg:CC FLAGS_REG))]
3141   "!TARGET_64BIT"
3142   "@
3143    #
3144    #
3145    #
3146    movd\t{%1, %0|%0, %1}
3147    movd\t{%1, %0|%0, %1}"
3148   [(set_attr "mode" "SI,SI,SI,DI,TI")
3149    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3151 (define_insn "zero_extendsidi2_rex64"
3152   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3153      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3154   "TARGET_64BIT"
3155   "@
3156    mov\t{%k1, %k0|%k0, %k1}
3157    #
3158    movd\t{%1, %0|%0, %1}
3159    movd\t{%1, %0|%0, %1}"
3160   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3161    (set_attr "mode" "SI,DI,SI,SI")])
3163 (define_split
3164   [(set (match_operand:DI 0 "memory_operand" "")
3165      (zero_extend:DI (match_dup 0)))]
3166   "TARGET_64BIT"
3167   [(set (match_dup 4) (const_int 0))]
3168   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3170 (define_split 
3171   [(set (match_operand:DI 0 "register_operand" "")
3172         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3173    (clobber (reg:CC FLAGS_REG))]
3174   "!TARGET_64BIT && reload_completed
3175    && true_regnum (operands[0]) == true_regnum (operands[1])"
3176   [(set (match_dup 4) (const_int 0))]
3177   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3179 (define_split 
3180   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3181         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3182    (clobber (reg:CC FLAGS_REG))]
3183   "!TARGET_64BIT && reload_completed
3184    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3185   [(set (match_dup 3) (match_dup 1))
3186    (set (match_dup 4) (const_int 0))]
3187   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3189 (define_insn "zero_extendhidi2"
3190   [(set (match_operand:DI 0 "register_operand" "=r,r")
3191      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3192   "TARGET_64BIT"
3193   "@
3194    movz{wl|x}\t{%1, %k0|%k0, %1}
3195    movz{wq|x}\t{%1, %0|%0, %1}"
3196   [(set_attr "type" "imovx")
3197    (set_attr "mode" "SI,DI")])
3199 (define_insn "zero_extendqidi2"
3200   [(set (match_operand:DI 0 "register_operand" "=r,r")
3201      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3202   "TARGET_64BIT"
3203   "@
3204    movz{bl|x}\t{%1, %k0|%k0, %1}
3205    movz{bq|x}\t{%1, %0|%0, %1}"
3206   [(set_attr "type" "imovx")
3207    (set_attr "mode" "SI,DI")])
3209 ;; Sign extension instructions
3211 (define_expand "extendsidi2"
3212   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3213                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3214               (clobber (reg:CC FLAGS_REG))
3215               (clobber (match_scratch:SI 2 ""))])]
3216   ""
3218   if (TARGET_64BIT)
3219     {
3220       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3221       DONE;
3222     }
3225 (define_insn "*extendsidi2_1"
3226   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3227         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3228    (clobber (reg:CC FLAGS_REG))
3229    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3230   "!TARGET_64BIT"
3231   "#")
3233 (define_insn "extendsidi2_rex64"
3234   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3235         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3236   "TARGET_64BIT"
3237   "@
3238    {cltq|cdqe}
3239    movs{lq|x}\t{%1,%0|%0, %1}"
3240   [(set_attr "type" "imovx")
3241    (set_attr "mode" "DI")
3242    (set_attr "prefix_0f" "0")
3243    (set_attr "modrm" "0,1")])
3245 (define_insn "extendhidi2"
3246   [(set (match_operand:DI 0 "register_operand" "=r")
3247         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3248   "TARGET_64BIT"
3249   "movs{wq|x}\t{%1,%0|%0, %1}"
3250   [(set_attr "type" "imovx")
3251    (set_attr "mode" "DI")])
3253 (define_insn "extendqidi2"
3254   [(set (match_operand:DI 0 "register_operand" "=r")
3255         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3256   "TARGET_64BIT"
3257   "movs{bq|x}\t{%1,%0|%0, %1}"
3258    [(set_attr "type" "imovx")
3259     (set_attr "mode" "DI")])
3261 ;; Extend to memory case when source register does die.
3262 (define_split 
3263   [(set (match_operand:DI 0 "memory_operand" "")
3264         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3265    (clobber (reg:CC FLAGS_REG))
3266    (clobber (match_operand:SI 2 "register_operand" ""))]
3267   "(reload_completed
3268     && dead_or_set_p (insn, operands[1])
3269     && !reg_mentioned_p (operands[1], operands[0]))"
3270   [(set (match_dup 3) (match_dup 1))
3271    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3272               (clobber (reg:CC FLAGS_REG))])
3273    (set (match_dup 4) (match_dup 1))]
3274   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3276 ;; Extend to memory case when source register does not die.
3277 (define_split 
3278   [(set (match_operand:DI 0 "memory_operand" "")
3279         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3280    (clobber (reg:CC FLAGS_REG))
3281    (clobber (match_operand:SI 2 "register_operand" ""))]
3282   "reload_completed"
3283   [(const_int 0)]
3285   split_di (&operands[0], 1, &operands[3], &operands[4]);
3287   emit_move_insn (operands[3], operands[1]);
3289   /* Generate a cltd if possible and doing so it profitable.  */
3290   if (true_regnum (operands[1]) == 0
3291       && true_regnum (operands[2]) == 1
3292       && (optimize_size || TARGET_USE_CLTD))
3293     {
3294       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3295     }
3296   else
3297     {
3298       emit_move_insn (operands[2], operands[1]);
3299       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3300     }
3301   emit_move_insn (operands[4], operands[2]);
3302   DONE;
3305 ;; Extend to register case.  Optimize case where source and destination
3306 ;; registers match and cases where we can use cltd.
3307 (define_split 
3308   [(set (match_operand:DI 0 "register_operand" "")
3309         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3310    (clobber (reg:CC FLAGS_REG))
3311    (clobber (match_scratch:SI 2 ""))]
3312   "reload_completed"
3313   [(const_int 0)]
3315   split_di (&operands[0], 1, &operands[3], &operands[4]);
3317   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3318     emit_move_insn (operands[3], operands[1]);
3320   /* Generate a cltd if possible and doing so it profitable.  */
3321   if (true_regnum (operands[3]) == 0
3322       && (optimize_size || TARGET_USE_CLTD))
3323     {
3324       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3325       DONE;
3326     }
3328   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3329     emit_move_insn (operands[4], operands[1]);
3331   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3332   DONE;
3335 (define_insn "extendhisi2"
3336   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3337         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3338   ""
3340   switch (get_attr_prefix_0f (insn))
3341     {
3342     case 0:
3343       return "{cwtl|cwde}";
3344     default:
3345       return "movs{wl|x}\t{%1,%0|%0, %1}";
3346     }
3348   [(set_attr "type" "imovx")
3349    (set_attr "mode" "SI")
3350    (set (attr "prefix_0f")
3351      ;; movsx is short decodable while cwtl is vector decoded.
3352      (if_then_else (and (eq_attr "cpu" "!k6")
3353                         (eq_attr "alternative" "0"))
3354         (const_string "0")
3355         (const_string "1")))
3356    (set (attr "modrm")
3357      (if_then_else (eq_attr "prefix_0f" "0")
3358         (const_string "0")
3359         (const_string "1")))])
3361 (define_insn "*extendhisi2_zext"
3362   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3363         (zero_extend:DI
3364           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3365   "TARGET_64BIT"
3367   switch (get_attr_prefix_0f (insn))
3368     {
3369     case 0:
3370       return "{cwtl|cwde}";
3371     default:
3372       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3373     }
3375   [(set_attr "type" "imovx")
3376    (set_attr "mode" "SI")
3377    (set (attr "prefix_0f")
3378      ;; movsx is short decodable while cwtl is vector decoded.
3379      (if_then_else (and (eq_attr "cpu" "!k6")
3380                         (eq_attr "alternative" "0"))
3381         (const_string "0")
3382         (const_string "1")))
3383    (set (attr "modrm")
3384      (if_then_else (eq_attr "prefix_0f" "0")
3385         (const_string "0")
3386         (const_string "1")))])
3388 (define_insn "extendqihi2"
3389   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3390         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3391   ""
3393   switch (get_attr_prefix_0f (insn))
3394     {
3395     case 0:
3396       return "{cbtw|cbw}";
3397     default:
3398       return "movs{bw|x}\t{%1,%0|%0, %1}";
3399     }
3401   [(set_attr "type" "imovx")
3402    (set_attr "mode" "HI")
3403    (set (attr "prefix_0f")
3404      ;; movsx is short decodable while cwtl is vector decoded.
3405      (if_then_else (and (eq_attr "cpu" "!k6")
3406                         (eq_attr "alternative" "0"))
3407         (const_string "0")
3408         (const_string "1")))
3409    (set (attr "modrm")
3410      (if_then_else (eq_attr "prefix_0f" "0")
3411         (const_string "0")
3412         (const_string "1")))])
3414 (define_insn "extendqisi2"
3415   [(set (match_operand:SI 0 "register_operand" "=r")
3416         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3417   ""
3418   "movs{bl|x}\t{%1,%0|%0, %1}"
3419    [(set_attr "type" "imovx")
3420     (set_attr "mode" "SI")])
3422 (define_insn "*extendqisi2_zext"
3423   [(set (match_operand:DI 0 "register_operand" "=r")
3424         (zero_extend:DI
3425           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3426   "TARGET_64BIT"
3427   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3428    [(set_attr "type" "imovx")
3429     (set_attr "mode" "SI")])
3431 ;; Conversions between float and double.
3433 ;; These are all no-ops in the model used for the 80387.  So just
3434 ;; emit moves.
3436 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3437 (define_insn "*dummy_extendsfdf2"
3438   [(set (match_operand:DF 0 "push_operand" "=<")
3439         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3440   "0"
3441   "#")
3443 (define_split
3444   [(set (match_operand:DF 0 "push_operand" "")
3445         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3446   "!TARGET_64BIT"
3447   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3448    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3450 (define_split
3451   [(set (match_operand:DF 0 "push_operand" "")
3452         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3453   "TARGET_64BIT"
3454   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3455    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3457 (define_insn "*dummy_extendsfxf2"
3458   [(set (match_operand:XF 0 "push_operand" "=<")
3459         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3460   "0"
3461   "#")
3463 (define_split
3464   [(set (match_operand:XF 0 "push_operand" "")
3465         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3466   ""
3467   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3468    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3469   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3471 (define_split
3472   [(set (match_operand:XF 0 "push_operand" "")
3473         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3474   "TARGET_64BIT"
3475   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3476    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3477   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3479 (define_split
3480   [(set (match_operand:XF 0 "push_operand" "")
3481         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3482   ""
3483   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3484    (set (mem:DF (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:DF 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:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3493   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3495 (define_expand "extendsfdf2"
3496   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3497         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3498   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3500   /* ??? Needed for compress_float_constant since all fp constants
3501      are LEGITIMATE_CONSTANT_P.  */
3502   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3503     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3504   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3505     operands[1] = force_reg (SFmode, operands[1]);
3508 (define_insn "*extendsfdf2_mixed"
3509   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3510         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3511   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3512    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3514   switch (which_alternative)
3515     {
3516     case 0:
3517       return output_387_reg_move (insn, operands);
3519     case 1:
3520       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3521         return "fstp%z0\t%y0";
3522       else
3523         return "fst%z0\t%y0";
3525     case 2:
3526       return "cvtss2sd\t{%1, %0|%0, %1}";
3528     default:
3529       abort ();
3530     }
3532   [(set_attr "type" "fmov,fmov,ssecvt")
3533    (set_attr "mode" "SF,XF,DF")])
3535 (define_insn "*extendsfdf2_sse"
3536   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3537         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3538   "TARGET_SSE2 && TARGET_SSE_MATH
3539    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3540   "cvtss2sd\t{%1, %0|%0, %1}"
3541   [(set_attr "type" "ssecvt")
3542    (set_attr "mode" "DF")])
3544 (define_insn "*extendsfdf2_i387"
3545   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3546         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3547   "TARGET_80387
3548    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3550   switch (which_alternative)
3551     {
3552     case 0:
3553       return output_387_reg_move (insn, operands);
3555     case 1:
3556       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3557         return "fstp%z0\t%y0";
3558       else
3559         return "fst%z0\t%y0";
3561     default:
3562       abort ();
3563     }
3565   [(set_attr "type" "fmov")
3566    (set_attr "mode" "SF,XF")])
3568 (define_expand "extendsfxf2"
3569   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3570         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3571   "TARGET_80387"
3573   /* ??? Needed for compress_float_constant since all fp constants
3574      are LEGITIMATE_CONSTANT_P.  */
3575   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3576     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3577   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3578     operands[1] = force_reg (SFmode, operands[1]);
3581 (define_insn "*extendsfxf2_i387"
3582   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3583         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3584   "TARGET_80387
3585    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3587   switch (which_alternative)
3588     {
3589     case 0:
3590       return output_387_reg_move (insn, operands);
3592     case 1:
3593       /* There is no non-popping store to memory for XFmode.  So if
3594          we need one, follow the store with a load.  */
3595       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3596         return "fstp%z0\t%y0";
3597       else
3598         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3600     default:
3601       abort ();
3602     }
3604   [(set_attr "type" "fmov")
3605    (set_attr "mode" "SF,XF")])
3607 (define_expand "extenddfxf2"
3608   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3609         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3610   "TARGET_80387"
3612   /* ??? Needed for compress_float_constant since all fp constants
3613      are LEGITIMATE_CONSTANT_P.  */
3614   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3615     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3616   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3617     operands[1] = force_reg (DFmode, operands[1]);
3620 (define_insn "*extenddfxf2_i387"
3621   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3622         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3623   "TARGET_80387
3624    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3626   switch (which_alternative)
3627     {
3628     case 0:
3629       return output_387_reg_move (insn, operands);
3631     case 1:
3632       /* There is no non-popping store to memory for XFmode.  So if
3633          we need one, follow the store with a load.  */
3634       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3635         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3636       else
3637         return "fstp%z0\t%y0";
3639     default:
3640       abort ();
3641     }
3643   [(set_attr "type" "fmov")
3644    (set_attr "mode" "DF,XF")])
3646 ;; %%% This seems bad bad news.
3647 ;; This cannot output into an f-reg because there is no way to be sure
3648 ;; of truncating in that case.  Otherwise this is just like a simple move
3649 ;; insn.  So we pretend we can output to a reg in order to get better
3650 ;; register preferencing, but we really use a stack slot.
3652 ;; Conversion from DFmode to SFmode.
3654 (define_expand "truncdfsf2"
3655   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3656         (float_truncate:SF
3657           (match_operand:DF 1 "nonimmediate_operand" "")))]
3658   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3660   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3661     operands[1] = force_reg (DFmode, operands[1]);
3663   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3664     ;
3665   else if (flag_unsafe_math_optimizations)
3666     ;
3667   else
3668     {
3669       rtx temp = assign_386_stack_local (SFmode, 0);
3670       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3671       DONE;
3672     }
3675 (define_expand "truncdfsf2_with_temp"
3676   [(parallel [(set (match_operand:SF 0 "" "")
3677                    (float_truncate:SF (match_operand:DF 1 "" "")))
3678               (clobber (match_operand:SF 2 "" ""))])]
3679   "")
3681 (define_insn "*truncdfsf_fast_mixed"
3682   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3683         (float_truncate:SF
3684           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3685   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3687   switch (which_alternative)
3688     {
3689     case 0:
3690       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3691         return "fstp%z0\t%y0";
3692       else
3693         return "fst%z0\t%y0";
3694     case 1:
3695       return output_387_reg_move (insn, operands);
3696     case 2:
3697       return "cvtsd2ss\t{%1, %0|%0, %1}";
3698     default:
3699       abort ();
3700     }
3702   [(set_attr "type" "fmov,fmov,ssecvt")
3703    (set_attr "mode" "SF")])
3705 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3706 ;; because nothing we do here is unsafe.
3707 (define_insn "*truncdfsf_fast_sse"
3708   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3709         (float_truncate:SF
3710           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3711   "TARGET_SSE2 && TARGET_SSE_MATH"
3712   "cvtsd2ss\t{%1, %0|%0, %1}"
3713   [(set_attr "type" "ssecvt")
3714    (set_attr "mode" "SF")])
3716 (define_insn "*truncdfsf_fast_i387"
3717   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3718         (float_truncate:SF
3719           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3720   "TARGET_80387 && flag_unsafe_math_optimizations"
3721   "* return output_387_reg_move (insn, operands);"
3722   [(set_attr "type" "fmov")
3723    (set_attr "mode" "SF")])
3725 (define_insn "*truncdfsf_mixed"
3726   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3727         (float_truncate:SF
3728           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3729    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3730   "TARGET_MIX_SSE_I387"
3732   switch (which_alternative)
3733     {
3734     case 0:
3735       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3736         return "fstp%z0\t%y0";
3737       else
3738         return "fst%z0\t%y0";
3739     case 1:
3740       return "#";
3741     case 2:
3742       return "cvtsd2ss\t{%1, %0|%0, %1}";
3743     default:
3744       abort ();
3745     }
3747   [(set_attr "type" "fmov,multi,ssecvt")
3748    (set_attr "mode" "SF")])
3750 (define_insn "*truncdfsf_i387"
3751   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3752         (float_truncate:SF
3753           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3754    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3755   "TARGET_80387"
3757   switch (which_alternative)
3758     {
3759     case 0:
3760       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3761         return "fstp%z0\t%y0";
3762       else
3763         return "fst%z0\t%y0";
3764     case 1:
3765       return "#";
3766     default:
3767       abort ();
3768     }
3770   [(set_attr "type" "fmov,multi")
3771    (set_attr "mode" "SF")])
3773 (define_split
3774   [(set (match_operand:SF 0 "register_operand" "")
3775         (float_truncate:SF
3776          (match_operand:DF 1 "fp_register_operand" "")))
3777    (clobber (match_operand 2 "" ""))]
3778   "reload_completed"
3779   [(set (match_dup 2) (match_dup 1))
3780    (set (match_dup 0) (match_dup 2))]
3782   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3785 ;; Conversion from XFmode to SFmode.
3787 (define_expand "truncxfsf2"
3788   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3789                    (float_truncate:SF
3790                     (match_operand:XF 1 "register_operand" "")))
3791               (clobber (match_dup 2))])]
3792   "TARGET_80387"
3794   if (flag_unsafe_math_optimizations)
3795     {
3796       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3797       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3798       if (reg != operands[0])
3799         emit_move_insn (operands[0], reg);
3800       DONE;
3801     }
3802   else
3803     operands[2] = assign_386_stack_local (SFmode, 0);
3806 (define_insn "*truncxfsf2_mixed"
3807   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3808         (float_truncate:SF
3809          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3810    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3811   "TARGET_MIX_SSE_I387"
3813   switch (which_alternative)
3814     {
3815     case 0:
3816       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3817         return "fstp%z0\t%y0";
3818       else
3819         return "fst%z0\t%y0";
3820     default:
3821       abort();
3822     }
3824   [(set_attr "type" "fmov,multi,multi,multi")
3825    (set_attr "mode" "SF")])
3827 (define_insn "truncxfsf2_i387_noop"
3828   [(set (match_operand:SF 0 "register_operand" "=f")
3829         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3830   "TARGET_80387 && flag_unsafe_math_optimizations"
3832   return output_387_reg_move (insn, operands);
3834   [(set_attr "type" "fmov")
3835    (set_attr "mode" "SF")])
3837 (define_insn "*truncxfsf2_i387"
3838   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3839         (float_truncate:SF
3840          (match_operand:XF 1 "register_operand" "f,f,f")))
3841    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3842   "TARGET_80387"
3844   switch (which_alternative)
3845     {
3846     case 0:
3847       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3848         return "fstp%z0\t%y0";
3849       else
3850         return "fst%z0\t%y0";
3851     default:
3852       abort ();
3853     }
3855   [(set_attr "type" "fmov,multi,multi")
3856    (set_attr "mode" "SF")])
3858 (define_insn "*truncxfsf2_i387_1"
3859   [(set (match_operand:SF 0 "memory_operand" "=m")
3860         (float_truncate:SF
3861          (match_operand:XF 1 "register_operand" "f")))]
3862   "TARGET_80387"
3864   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3865     return "fstp%z0\t%y0";
3866   else
3867     return "fst%z0\t%y0";
3869   [(set_attr "type" "fmov")
3870    (set_attr "mode" "SF")])
3872 (define_split
3873   [(set (match_operand:SF 0 "register_operand" "")
3874         (float_truncate:SF
3875          (match_operand:XF 1 "register_operand" "")))
3876    (clobber (match_operand:SF 2 "memory_operand" ""))]
3877   "TARGET_80387 && reload_completed"
3878   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3879    (set (match_dup 0) (match_dup 2))]
3880   "")
3882 (define_split
3883   [(set (match_operand:SF 0 "memory_operand" "")
3884         (float_truncate:SF
3885          (match_operand:XF 1 "register_operand" "")))
3886    (clobber (match_operand:SF 2 "memory_operand" ""))]
3887   "TARGET_80387"
3888   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3889   "")
3891 ;; Conversion from XFmode to DFmode.
3893 (define_expand "truncxfdf2"
3894   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3895                    (float_truncate:DF
3896                     (match_operand:XF 1 "register_operand" "")))
3897               (clobber (match_dup 2))])]
3898   "TARGET_80387"
3900   if (flag_unsafe_math_optimizations)
3901     {
3902       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3903       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3904       if (reg != operands[0])
3905         emit_move_insn (operands[0], reg);
3906       DONE;
3907     }
3908   else
3909     operands[2] = assign_386_stack_local (DFmode, 0);
3912 (define_insn "*truncxfdf2_mixed"
3913   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3914         (float_truncate:DF
3915          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3916    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3917   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3919   switch (which_alternative)
3920     {
3921     case 0:
3922       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3923         return "fstp%z0\t%y0";
3924       else
3925         return "fst%z0\t%y0";
3926     default:
3927       abort();
3928     }
3929   abort ();
3931   [(set_attr "type" "fmov,multi,multi,multi")
3932    (set_attr "mode" "DF")])
3934 (define_insn "truncxfdf2_i387_noop"
3935   [(set (match_operand:DF 0 "register_operand" "=f")
3936         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3937   "TARGET_80387 && flag_unsafe_math_optimizations"
3939   return output_387_reg_move (insn, operands);
3941   [(set_attr "type" "fmov")
3942    (set_attr "mode" "DF")])
3944 (define_insn "*truncxfdf2_i387"
3945   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3946         (float_truncate:DF
3947          (match_operand:XF 1 "register_operand" "f,f,f")))
3948    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3949   "TARGET_80387"
3951   switch (which_alternative)
3952     {
3953     case 0:
3954       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3955         return "fstp%z0\t%y0";
3956       else
3957         return "fst%z0\t%y0";
3958     default:
3959       abort ();
3960     }
3962   [(set_attr "type" "fmov,multi,multi")
3963    (set_attr "mode" "DF")])
3965 (define_insn "*truncxfdf2_i387_1"
3966   [(set (match_operand:DF 0 "memory_operand" "=m")
3967         (float_truncate:DF
3968           (match_operand:XF 1 "register_operand" "f")))]
3969   "TARGET_80387"
3971   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3972     return "fstp%z0\t%y0";
3973   else
3974     return "fst%z0\t%y0";
3976   [(set_attr "type" "fmov")
3977    (set_attr "mode" "DF")])
3979 (define_split
3980   [(set (match_operand:DF 0 "register_operand" "")
3981         (float_truncate:DF
3982          (match_operand:XF 1 "register_operand" "")))
3983    (clobber (match_operand:DF 2 "memory_operand" ""))]
3984   "TARGET_80387 && reload_completed"
3985   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3986    (set (match_dup 0) (match_dup 2))]
3987   "")
3989 (define_split
3990   [(set (match_operand:DF 0 "memory_operand" "")
3991         (float_truncate:DF
3992          (match_operand:XF 1 "register_operand" "")))
3993    (clobber (match_operand:DF 2 "memory_operand" ""))]
3994   "TARGET_80387"
3995   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3996   "")
3998 ;; %%% Break up all these bad boys.
4000 ;; Signed conversion to DImode.
4002 (define_expand "fix_truncxfdi2"
4003   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4004                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4005               (clobber (reg:CC FLAGS_REG))])]
4006   "TARGET_80387"
4007   "")
4009 (define_expand "fix_truncdfdi2"
4010   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4011                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4012               (clobber (reg:CC FLAGS_REG))])]
4013   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
4015   if (TARGET_64BIT && TARGET_SSE2)
4016    {
4017      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4018      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4019      if (out != operands[0])
4020         emit_move_insn (operands[0], out);
4021      DONE;
4022    }
4025 (define_expand "fix_truncsfdi2"
4026   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4027                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4028               (clobber (reg:CC FLAGS_REG))])] 
4029   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
4031   if (TARGET_64BIT && TARGET_SSE)
4032    {
4033      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4034      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4035      if (out != operands[0])
4036         emit_move_insn (operands[0], out);
4037      DONE;
4038    }
4041 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4042 ;; of the machinery.
4043 (define_insn_and_split "*fix_truncdi_i387"
4044   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4045         (fix:DI (match_operand 1 "register_operand" "f,f")))
4046    (clobber (reg:CC FLAGS_REG))]
4047   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4048    && !reload_completed && !reload_in_progress
4049    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4050   "#"
4051   "&& 1"
4052   [(const_int 0)]
4054   ix86_optimize_mode_switching = 1;
4055   operands[2] = assign_386_stack_local (HImode, 1);
4056   operands[3] = assign_386_stack_local (HImode, 2);
4057   if (memory_operand (operands[0], VOIDmode))
4058     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4059                                        operands[2], operands[3]));
4060   else
4061     {
4062       operands[4] = assign_386_stack_local (DImode, 0);
4063       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4064                                            operands[2], operands[3],
4065                                            operands[4]));
4066     }
4067   DONE;
4069   [(set_attr "type" "fistp")
4070    (set_attr "i387_cw" "trunc")
4071    (set_attr "mode" "DI")])
4073 (define_insn "fix_truncdi_nomemory"
4074   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4075         (fix:DI (match_operand 1 "register_operand" "f,f")))
4076    (use (match_operand:HI 2 "memory_operand" "m,m"))
4077    (use (match_operand:HI 3 "memory_operand" "m,m"))
4078    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4079    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4080   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4081    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4082   "#"
4083   [(set_attr "type" "fistp")
4084    (set_attr "i387_cw" "trunc")
4085    (set_attr "mode" "DI")])
4087 (define_insn "fix_truncdi_memory"
4088   [(set (match_operand:DI 0 "memory_operand" "=m")
4089         (fix:DI (match_operand 1 "register_operand" "f")))
4090    (use (match_operand:HI 2 "memory_operand" "m"))
4091    (use (match_operand:HI 3 "memory_operand" "m"))
4092    (clobber (match_scratch:DF 4 "=&1f"))]
4093   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4094    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4095   "* return output_fix_trunc (insn, operands);"
4096   [(set_attr "type" "fistp")
4097    (set_attr "i387_cw" "trunc")
4098    (set_attr "mode" "DI")])
4100 (define_split 
4101   [(set (match_operand:DI 0 "register_operand" "")
4102         (fix:DI (match_operand 1 "register_operand" "")))
4103    (use (match_operand:HI 2 "memory_operand" ""))
4104    (use (match_operand:HI 3 "memory_operand" ""))
4105    (clobber (match_operand:DI 4 "memory_operand" ""))
4106    (clobber (match_scratch 5 ""))]
4107   "reload_completed"
4108   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4109               (use (match_dup 2))
4110               (use (match_dup 3))
4111               (clobber (match_dup 5))])
4112    (set (match_dup 0) (match_dup 4))]
4113   "")
4115 (define_split 
4116   [(set (match_operand:DI 0 "memory_operand" "")
4117         (fix:DI (match_operand 1 "register_operand" "")))
4118    (use (match_operand:HI 2 "memory_operand" ""))
4119    (use (match_operand:HI 3 "memory_operand" ""))
4120    (clobber (match_operand:DI 4 "memory_operand" ""))
4121    (clobber (match_scratch 5 ""))]
4122   "reload_completed"
4123   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4124               (use (match_dup 2))
4125               (use (match_dup 3))
4126               (clobber (match_dup 5))])]
4127   "")
4129 ;; When SSE available, it is always faster to use it!
4130 (define_insn "fix_truncsfdi_sse"
4131   [(set (match_operand:DI 0 "register_operand" "=r,r")
4132         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4133   "TARGET_64BIT && TARGET_SSE"
4134   "cvttss2si{q}\t{%1, %0|%0, %1}"
4135   [(set_attr "type" "sseicvt")
4136    (set_attr "mode" "SF")
4137    (set_attr "athlon_decode" "double,vector")])
4139 ;; Avoid vector decoded form of the instruction.
4140 (define_peephole2
4141   [(match_scratch:SF 2 "x")
4142    (set (match_operand:DI 0 "register_operand" "")
4143         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4144   "TARGET_K8 && !optimize_size"
4145   [(set (match_dup 2) (match_dup 1))
4146    (set (match_dup 0) (fix:DI (match_dup 2)))]
4147   "")
4149 (define_insn "fix_truncdfdi_sse"
4150   [(set (match_operand:DI 0 "register_operand" "=r,r")
4151         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4152   "TARGET_64BIT && TARGET_SSE2"
4153   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4154   [(set_attr "type" "sseicvt,sseicvt")
4155    (set_attr "mode" "DF")
4156    (set_attr "athlon_decode" "double,vector")])
4158 ;; Avoid vector decoded form of the instruction.
4159 (define_peephole2
4160   [(match_scratch:DF 2 "Y")
4161    (set (match_operand:DI 0 "register_operand" "")
4162         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4163   "TARGET_K8 && !optimize_size"
4164   [(set (match_dup 2) (match_dup 1))
4165    (set (match_dup 0) (fix:DI (match_dup 2)))]
4166   "")
4168 ;; Signed conversion to SImode.
4170 (define_expand "fix_truncxfsi2"
4171   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4172                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4173               (clobber (reg:CC FLAGS_REG))])]
4174   "TARGET_80387"
4175   "")
4177 (define_expand "fix_truncdfsi2"
4178   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4179                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4180               (clobber (reg:CC FLAGS_REG))])]
4181   "TARGET_80387 || TARGET_SSE2"
4183   if (TARGET_SSE2)
4184    {
4185      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4186      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4187      if (out != operands[0])
4188         emit_move_insn (operands[0], out);
4189      DONE;
4190    }
4193 (define_expand "fix_truncsfsi2"
4194   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4195                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4196               (clobber (reg:CC FLAGS_REG))])] 
4197   "TARGET_80387 || TARGET_SSE"
4199   if (TARGET_SSE)
4200    {
4201      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4202      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4203      if (out != operands[0])
4204         emit_move_insn (operands[0], out);
4205      DONE;
4206    }
4209 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4210 ;; of the machinery.
4211 (define_insn_and_split "*fix_truncsi_i387"
4212   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4213         (fix:SI (match_operand 1 "register_operand" "f,f")))
4214    (clobber (reg:CC FLAGS_REG))]
4215   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4216    && !reload_completed && !reload_in_progress
4217    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4218   "#"
4219   "&& 1"
4220   [(const_int 0)]
4222   ix86_optimize_mode_switching = 1;
4223   operands[2] = assign_386_stack_local (HImode, 1);
4224   operands[3] = assign_386_stack_local (HImode, 2);
4225   if (memory_operand (operands[0], VOIDmode))
4226     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4227                                        operands[2], operands[3]));
4228   else
4229     {
4230       operands[4] = assign_386_stack_local (SImode, 0);
4231       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4232                                            operands[2], operands[3],
4233                                            operands[4]));
4234     }
4235   DONE;
4237   [(set_attr "type" "fistp")
4238    (set_attr "i387_cw" "trunc")
4239    (set_attr "mode" "SI")])
4241 (define_insn "fix_truncsi_nomemory"
4242   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4243         (fix:SI (match_operand 1 "register_operand" "f,f")))
4244    (use (match_operand:HI 2 "memory_operand" "m,m"))
4245    (use (match_operand:HI 3 "memory_operand" "m,m"))
4246    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4247   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4248    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4249   "#"
4250   [(set_attr "type" "fistp")
4251    (set_attr "i387_cw" "trunc")
4252    (set_attr "mode" "SI")])
4254 (define_insn "fix_truncsi_memory"
4255   [(set (match_operand:SI 0 "memory_operand" "=m")
4256         (fix:SI (match_operand 1 "register_operand" "f")))
4257    (use (match_operand:HI 2 "memory_operand" "m"))
4258    (use (match_operand:HI 3 "memory_operand" "m"))]
4259   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4260    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4261   "* return output_fix_trunc (insn, operands);"
4262   [(set_attr "type" "fistp")
4263    (set_attr "i387_cw" "trunc")
4264    (set_attr "mode" "SI")])
4266 ;; When SSE available, it is always faster to use it!
4267 (define_insn "fix_truncsfsi_sse"
4268   [(set (match_operand:SI 0 "register_operand" "=r,r")
4269         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4270   "TARGET_SSE"
4271   "cvttss2si\t{%1, %0|%0, %1}"
4272   [(set_attr "type" "sseicvt")
4273    (set_attr "mode" "DF")
4274    (set_attr "athlon_decode" "double,vector")])
4276 ;; Avoid vector decoded form of the instruction.
4277 (define_peephole2
4278   [(match_scratch:SF 2 "x")
4279    (set (match_operand:SI 0 "register_operand" "")
4280         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4281   "TARGET_K8 && !optimize_size"
4282   [(set (match_dup 2) (match_dup 1))
4283    (set (match_dup 0) (fix:SI (match_dup 2)))]
4284   "")
4286 (define_insn "fix_truncdfsi_sse"
4287   [(set (match_operand:SI 0 "register_operand" "=r,r")
4288         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4289   "TARGET_SSE2"
4290   "cvttsd2si\t{%1, %0|%0, %1}"
4291   [(set_attr "type" "sseicvt")
4292    (set_attr "mode" "DF")
4293    (set_attr "athlon_decode" "double,vector")])
4295 ;; Avoid vector decoded form of the instruction.
4296 (define_peephole2
4297   [(match_scratch:DF 2 "Y")
4298    (set (match_operand:SI 0 "register_operand" "")
4299         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4300   "TARGET_K8 && !optimize_size"
4301   [(set (match_dup 2) (match_dup 1))
4302    (set (match_dup 0) (fix:SI (match_dup 2)))]
4303   "")
4305 (define_split 
4306   [(set (match_operand:SI 0 "register_operand" "")
4307         (fix:SI (match_operand 1 "register_operand" "")))
4308    (use (match_operand:HI 2 "memory_operand" ""))
4309    (use (match_operand:HI 3 "memory_operand" ""))
4310    (clobber (match_operand:SI 4 "memory_operand" ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))])
4315    (set (match_dup 0) (match_dup 4))]
4316   "")
4318 (define_split 
4319   [(set (match_operand:SI 0 "memory_operand" "")
4320         (fix:SI (match_operand 1 "register_operand" "")))
4321    (use (match_operand:HI 2 "memory_operand" ""))
4322    (use (match_operand:HI 3 "memory_operand" ""))
4323    (clobber (match_operand:SI 4 "memory_operand" ""))]
4324   "reload_completed"
4325   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4326               (use (match_dup 2))
4327               (use (match_dup 3))])]
4328   "")
4330 ;; Signed conversion to HImode.
4332 (define_expand "fix_truncxfhi2"
4333   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4334                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4335               (clobber (reg:CC FLAGS_REG))])] 
4336   "TARGET_80387"
4337   "")
4339 (define_expand "fix_truncdfhi2"
4340   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4341                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4342               (clobber (reg:CC FLAGS_REG))])]
4343   "TARGET_80387 && !TARGET_SSE2"
4344   "")
4346 (define_expand "fix_truncsfhi2"
4347   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4348                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4349                (clobber (reg:CC FLAGS_REG))])]
4350   "TARGET_80387 && !TARGET_SSE"
4351   "")
4353 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4354 ;; of the machinery.
4355 (define_insn_and_split "*fix_trunchi_i387"
4356   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4357         (fix:HI (match_operand 1 "register_operand" "f,f")))
4358    (clobber (reg:CC FLAGS_REG))]
4359   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4360    && !reload_completed && !reload_in_progress
4361    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4362   "#"
4363   "&& 1"
4364   [(const_int 0)]
4366   ix86_optimize_mode_switching = 1;
4367   operands[2] = assign_386_stack_local (HImode, 1);
4368   operands[3] = assign_386_stack_local (HImode, 2);
4369   if (memory_operand (operands[0], VOIDmode))
4370     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4371                                        operands[2], operands[3]));
4372   else
4373     {
4374       operands[4] = assign_386_stack_local (HImode, 0);
4375       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4376                                            operands[2], operands[3],
4377                                            operands[4]));
4378     }
4379   DONE;
4381   [(set_attr "type" "fistp")
4382    (set_attr "i387_cw" "trunc")
4383    (set_attr "mode" "HI")])
4385 (define_insn "fix_trunchi_nomemory"
4386   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4387         (fix:HI (match_operand 1 "register_operand" "f,f")))
4388    (use (match_operand:HI 2 "memory_operand" "m,m"))
4389    (use (match_operand:HI 3 "memory_operand" "m,m"))
4390    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4391   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4392    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4393   "#"
4394   [(set_attr "type" "fistp")
4395    (set_attr "i387_cw" "trunc")
4396    (set_attr "mode" "HI")])
4398 (define_insn "fix_trunchi_memory"
4399   [(set (match_operand:HI 0 "memory_operand" "=m")
4400         (fix:HI (match_operand 1 "register_operand" "f")))
4401    (use (match_operand:HI 2 "memory_operand" "m"))
4402    (use (match_operand:HI 3 "memory_operand" "m"))]
4403   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4404    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4405   "* return output_fix_trunc (insn, operands);"
4406   [(set_attr "type" "fistp")
4407    (set_attr "i387_cw" "trunc")
4408    (set_attr "mode" "HI")])
4410 (define_split 
4411   [(set (match_operand:HI 0 "memory_operand" "")
4412         (fix:HI (match_operand 1 "register_operand" "")))
4413    (use (match_operand:HI 2 "memory_operand" ""))
4414    (use (match_operand:HI 3 "memory_operand" ""))
4415    (clobber (match_operand:HI 4 "memory_operand" ""))]
4416   "reload_completed"
4417   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4418               (use (match_dup 2))
4419               (use (match_dup 3))])]
4420   "")
4422 (define_split 
4423   [(set (match_operand:HI 0 "register_operand" "")
4424         (fix:HI (match_operand 1 "register_operand" "")))
4425    (use (match_operand:HI 2 "memory_operand" ""))
4426    (use (match_operand:HI 3 "memory_operand" ""))
4427    (clobber (match_operand:HI 4 "memory_operand" ""))]
4428   "reload_completed"
4429   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4430               (use (match_dup 2))
4431               (use (match_dup 3))
4432               (clobber (match_dup 4))])
4433    (set (match_dup 0) (match_dup 4))]
4434   "")
4436 (define_insn "x86_fnstcw_1"
4437   [(set (match_operand:HI 0 "memory_operand" "=m")
4438         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4439   "TARGET_80387"
4440   "fnstcw\t%0"
4441   [(set_attr "length" "2")
4442    (set_attr "mode" "HI")
4443    (set_attr "unit" "i387")])
4445 (define_insn "x86_fldcw_1"
4446   [(set (reg:HI FPSR_REG)
4447         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4448   "TARGET_80387"
4449   "fldcw\t%0"
4450   [(set_attr "length" "2")
4451    (set_attr "mode" "HI")
4452    (set_attr "unit" "i387")
4453    (set_attr "athlon_decode" "vector")])
4455 ;; Conversion between fixed point and floating point.
4457 ;; Even though we only accept memory inputs, the backend _really_
4458 ;; wants to be able to do this between registers.
4460 (define_expand "floathisf2"
4461   [(set (match_operand:SF 0 "register_operand" "")
4462         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4463   "TARGET_80387 || TARGET_SSE_MATH"
4465   if (TARGET_SSE_MATH)
4466     {
4467       emit_insn (gen_floatsisf2 (operands[0],
4468                                  convert_to_mode (SImode, operands[1], 0)));
4469       DONE;
4470     }
4473 (define_insn "*floathisf2_i387"
4474   [(set (match_operand:SF 0 "register_operand" "=f,f")
4475         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4476   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4477   "@
4478    fild%z1\t%1
4479    #"
4480   [(set_attr "type" "fmov,multi")
4481    (set_attr "mode" "SF")
4482    (set_attr "fp_int_src" "true")])
4484 (define_expand "floatsisf2"
4485   [(set (match_operand:SF 0 "register_operand" "")
4486         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4487   "TARGET_80387 || TARGET_SSE_MATH"
4488   "")
4490 (define_insn "*floatsisf2_mixed"
4491   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4492         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4493   "TARGET_MIX_SSE_I387"
4494   "@
4495    fild%z1\t%1
4496    #
4497    cvtsi2ss\t{%1, %0|%0, %1}
4498    cvtsi2ss\t{%1, %0|%0, %1}"
4499   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4500    (set_attr "mode" "SF")
4501    (set_attr "athlon_decode" "*,*,vector,double")
4502    (set_attr "fp_int_src" "true")])
4504 (define_insn "*floatsisf2_sse"
4505   [(set (match_operand:SF 0 "register_operand" "=x,x")
4506         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4507   "TARGET_SSE_MATH"
4508   "cvtsi2ss\t{%1, %0|%0, %1}"
4509   [(set_attr "type" "sseicvt")
4510    (set_attr "mode" "SF")
4511    (set_attr "athlon_decode" "vector,double")
4512    (set_attr "fp_int_src" "true")])
4514 (define_insn "*floatsisf2_i387"
4515   [(set (match_operand:SF 0 "register_operand" "=f,f")
4516         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4517   "TARGET_80387"
4518   "@
4519    fild%z1\t%1
4520    #"
4521   [(set_attr "type" "fmov,multi")
4522    (set_attr "mode" "SF")
4523    (set_attr "fp_int_src" "true")])
4525 (define_expand "floatdisf2"
4526   [(set (match_operand:SF 0 "register_operand" "")
4527         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4528   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4529   "")
4531 (define_insn "*floatdisf2_mixed"
4532   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4533         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4534   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4535   "@
4536    fild%z1\t%1
4537    #
4538    cvtsi2ss{q}\t{%1, %0|%0, %1}
4539    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4540   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4541    (set_attr "mode" "SF")
4542    (set_attr "athlon_decode" "*,*,vector,double")
4543    (set_attr "fp_int_src" "true")])
4545 (define_insn "*floatdisf2_sse"
4546   [(set (match_operand:SF 0 "register_operand" "=x,x")
4547         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4548   "TARGET_64BIT && TARGET_SSE_MATH"
4549   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4550   [(set_attr "type" "sseicvt")
4551    (set_attr "mode" "SF")
4552    (set_attr "athlon_decode" "vector,double")
4553    (set_attr "fp_int_src" "true")])
4555 (define_insn "*floatdisf2_i387"
4556   [(set (match_operand:SF 0 "register_operand" "=f,f")
4557         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4558   "TARGET_80387"
4559   "@
4560    fild%z1\t%1
4561    #"
4562   [(set_attr "type" "fmov,multi")
4563    (set_attr "mode" "SF")
4564    (set_attr "fp_int_src" "true")])
4566 (define_expand "floathidf2"
4567   [(set (match_operand:DF 0 "register_operand" "")
4568         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4569   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4571   if (TARGET_SSE2 && TARGET_SSE_MATH)
4572     {
4573       emit_insn (gen_floatsidf2 (operands[0],
4574                                  convert_to_mode (SImode, operands[1], 0)));
4575       DONE;
4576     }
4579 (define_insn "*floathidf2_i387"
4580   [(set (match_operand:DF 0 "register_operand" "=f,f")
4581         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4582   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4583   "@
4584    fild%z1\t%1
4585    #"
4586   [(set_attr "type" "fmov,multi")
4587    (set_attr "mode" "DF")
4588    (set_attr "fp_int_src" "true")])
4590 (define_expand "floatsidf2"
4591   [(set (match_operand:DF 0 "register_operand" "")
4592         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4593   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4594   "")
4596 (define_insn "*floatsidf2_mixed"
4597   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4598         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4599   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4600   "@
4601    fild%z1\t%1
4602    #
4603    cvtsi2sd\t{%1, %0|%0, %1}
4604    cvtsi2sd\t{%1, %0|%0, %1}"
4605   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4606    (set_attr "mode" "DF")
4607    (set_attr "athlon_decode" "*,*,double,direct")
4608    (set_attr "fp_int_src" "true")])
4610 (define_insn "*floatsidf2_sse"
4611   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4612         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4613   "TARGET_SSE2 && TARGET_SSE_MATH"
4614   "cvtsi2sd\t{%1, %0|%0, %1}"
4615   [(set_attr "type" "sseicvt")
4616    (set_attr "mode" "DF")
4617    (set_attr "athlon_decode" "double,direct")
4618    (set_attr "fp_int_src" "true")])
4620 (define_insn "*floatsidf2_i387"
4621   [(set (match_operand:DF 0 "register_operand" "=f,f")
4622         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4623   "TARGET_80387"
4624   "@
4625    fild%z1\t%1
4626    #"
4627   [(set_attr "type" "fmov,multi")
4628    (set_attr "mode" "DF")
4629    (set_attr "fp_int_src" "true")])
4631 (define_expand "floatdidf2"
4632   [(set (match_operand:DF 0 "register_operand" "")
4633         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4634   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4635   "")
4637 (define_insn "*floatdidf2_mixed"
4638   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4639         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4640   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4641   "@
4642    fild%z1\t%1
4643    #
4644    cvtsi2sd{q}\t{%1, %0|%0, %1}
4645    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4646   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4647    (set_attr "mode" "DF")
4648    (set_attr "athlon_decode" "*,*,double,direct")
4649    (set_attr "fp_int_src" "true")])
4651 (define_insn "*floatdidf2_sse"
4652   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4653         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4654   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4655   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4656   [(set_attr "type" "sseicvt")
4657    (set_attr "mode" "DF")
4658    (set_attr "athlon_decode" "double,direct")
4659    (set_attr "fp_int_src" "true")])
4661 (define_insn "*floatdidf2_i387"
4662   [(set (match_operand:DF 0 "register_operand" "=f,f")
4663         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4664   "TARGET_80387"
4665   "@
4666    fild%z1\t%1
4667    #"
4668   [(set_attr "type" "fmov,multi")
4669    (set_attr "mode" "DF")
4670    (set_attr "fp_int_src" "true")])
4672 (define_insn "floathixf2"
4673   [(set (match_operand:XF 0 "register_operand" "=f,f")
4674         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4675   "TARGET_80387"
4676   "@
4677    fild%z1\t%1
4678    #"
4679   [(set_attr "type" "fmov,multi")
4680    (set_attr "mode" "XF")
4681    (set_attr "fp_int_src" "true")])
4683 (define_insn "floatsixf2"
4684   [(set (match_operand:XF 0 "register_operand" "=f,f")
4685         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4686   "TARGET_80387"
4687   "@
4688    fild%z1\t%1
4689    #"
4690   [(set_attr "type" "fmov,multi")
4691    (set_attr "mode" "XF")
4692    (set_attr "fp_int_src" "true")])
4694 (define_insn "floatdixf2"
4695   [(set (match_operand:XF 0 "register_operand" "=f,f")
4696         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4697   "TARGET_80387"
4698   "@
4699    fild%z1\t%1
4700    #"
4701   [(set_attr "type" "fmov,multi")
4702    (set_attr "mode" "XF")
4703    (set_attr "fp_int_src" "true")])
4705 ;; %%% Kill these when reload knows how to do it.
4706 (define_split
4707   [(set (match_operand 0 "fp_register_operand" "")
4708         (float (match_operand 1 "register_operand" "")))]
4709   "reload_completed
4710    && TARGET_80387
4711    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4712   [(const_int 0)]
4714   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4715   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4716   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4717   ix86_free_from_memory (GET_MODE (operands[1]));
4718   DONE;
4721 (define_expand "floatunssisf2"
4722   [(use (match_operand:SF 0 "register_operand" ""))
4723    (use (match_operand:SI 1 "register_operand" ""))]
4724   "!TARGET_64BIT && TARGET_SSE_MATH"
4725   "x86_emit_floatuns (operands); DONE;")
4727 (define_expand "floatunsdisf2"
4728   [(use (match_operand:SF 0 "register_operand" ""))
4729    (use (match_operand:DI 1 "register_operand" ""))]
4730   "TARGET_64BIT && TARGET_SSE_MATH"
4731   "x86_emit_floatuns (operands); DONE;")
4733 (define_expand "floatunsdidf2"
4734   [(use (match_operand:DF 0 "register_operand" ""))
4735    (use (match_operand:DI 1 "register_operand" ""))]
4736   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4737   "x86_emit_floatuns (operands); DONE;")
4739 ;; SSE extract/set expanders
4742 ;; Add instructions
4744 ;; %%% splits for addsidi3
4745 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4746 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4747 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4749 (define_expand "adddi3"
4750   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4751         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4752                  (match_operand:DI 2 "x86_64_general_operand" "")))
4753    (clobber (reg:CC FLAGS_REG))]
4754   ""
4755   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4757 (define_insn "*adddi3_1"
4758   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4759         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4760                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4761    (clobber (reg:CC FLAGS_REG))]
4762   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4763   "#")
4765 (define_split
4766   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4767         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4768                  (match_operand:DI 2 "general_operand" "")))
4769    (clobber (reg:CC FLAGS_REG))]
4770   "!TARGET_64BIT && reload_completed"
4771   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4772                                           UNSPEC_ADD_CARRY))
4773               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4774    (parallel [(set (match_dup 3)
4775                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4776                                      (match_dup 4))
4777                             (match_dup 5)))
4778               (clobber (reg:CC FLAGS_REG))])]
4779   "split_di (operands+0, 1, operands+0, operands+3);
4780    split_di (operands+1, 1, operands+1, operands+4);
4781    split_di (operands+2, 1, operands+2, operands+5);")
4783 (define_insn "adddi3_carry_rex64"
4784   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4785           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4786                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4787                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4788    (clobber (reg:CC FLAGS_REG))]
4789   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4790   "adc{q}\t{%2, %0|%0, %2}"
4791   [(set_attr "type" "alu")
4792    (set_attr "pent_pair" "pu")
4793    (set_attr "mode" "DI")])
4795 (define_insn "*adddi3_cc_rex64"
4796   [(set (reg:CC FLAGS_REG)
4797         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4798                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4799                    UNSPEC_ADD_CARRY))
4800    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4801         (plus:DI (match_dup 1) (match_dup 2)))]
4802   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4803   "add{q}\t{%2, %0|%0, %2}"
4804   [(set_attr "type" "alu")
4805    (set_attr "mode" "DI")])
4807 (define_insn "addqi3_carry"
4808   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4809           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4810                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4811                    (match_operand:QI 2 "general_operand" "qi,qm")))
4812    (clobber (reg:CC FLAGS_REG))]
4813   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4814   "adc{b}\t{%2, %0|%0, %2}"
4815   [(set_attr "type" "alu")
4816    (set_attr "pent_pair" "pu")
4817    (set_attr "mode" "QI")])
4819 (define_insn "addhi3_carry"
4820   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4821           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4822                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4823                    (match_operand:HI 2 "general_operand" "ri,rm")))
4824    (clobber (reg:CC FLAGS_REG))]
4825   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4826   "adc{w}\t{%2, %0|%0, %2}"
4827   [(set_attr "type" "alu")
4828    (set_attr "pent_pair" "pu")
4829    (set_attr "mode" "HI")])
4831 (define_insn "addsi3_carry"
4832   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4833           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4834                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4835                    (match_operand:SI 2 "general_operand" "ri,rm")))
4836    (clobber (reg:CC FLAGS_REG))]
4837   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4838   "adc{l}\t{%2, %0|%0, %2}"
4839   [(set_attr "type" "alu")
4840    (set_attr "pent_pair" "pu")
4841    (set_attr "mode" "SI")])
4843 (define_insn "*addsi3_carry_zext"
4844   [(set (match_operand:DI 0 "register_operand" "=r")
4845           (zero_extend:DI 
4846             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4847                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4848                      (match_operand:SI 2 "general_operand" "rim"))))
4849    (clobber (reg:CC FLAGS_REG))]
4850   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4851   "adc{l}\t{%2, %k0|%k0, %2}"
4852   [(set_attr "type" "alu")
4853    (set_attr "pent_pair" "pu")
4854    (set_attr "mode" "SI")])
4856 (define_insn "*addsi3_cc"
4857   [(set (reg:CC FLAGS_REG)
4858         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4859                     (match_operand:SI 2 "general_operand" "ri,rm")]
4860                    UNSPEC_ADD_CARRY))
4861    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4862         (plus:SI (match_dup 1) (match_dup 2)))]
4863   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4864   "add{l}\t{%2, %0|%0, %2}"
4865   [(set_attr "type" "alu")
4866    (set_attr "mode" "SI")])
4868 (define_insn "addqi3_cc"
4869   [(set (reg:CC FLAGS_REG)
4870         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4871                     (match_operand:QI 2 "general_operand" "qi,qm")]
4872                    UNSPEC_ADD_CARRY))
4873    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4874         (plus:QI (match_dup 1) (match_dup 2)))]
4875   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4876   "add{b}\t{%2, %0|%0, %2}"
4877   [(set_attr "type" "alu")
4878    (set_attr "mode" "QI")])
4880 (define_expand "addsi3"
4881   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4882                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4883                             (match_operand:SI 2 "general_operand" "")))
4884               (clobber (reg:CC FLAGS_REG))])]
4885   ""
4886   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4888 (define_insn "*lea_1"
4889   [(set (match_operand:SI 0 "register_operand" "=r")
4890         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4891   "!TARGET_64BIT"
4892   "lea{l}\t{%a1, %0|%0, %a1}"
4893   [(set_attr "type" "lea")
4894    (set_attr "mode" "SI")])
4896 (define_insn "*lea_1_rex64"
4897   [(set (match_operand:SI 0 "register_operand" "=r")
4898         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4899   "TARGET_64BIT"
4900   "lea{l}\t{%a1, %0|%0, %a1}"
4901   [(set_attr "type" "lea")
4902    (set_attr "mode" "SI")])
4904 (define_insn "*lea_1_zext"
4905   [(set (match_operand:DI 0 "register_operand" "=r")
4906         (zero_extend:DI
4907          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4908   "TARGET_64BIT"
4909   "lea{l}\t{%a1, %k0|%k0, %a1}"
4910   [(set_attr "type" "lea")
4911    (set_attr "mode" "SI")])
4913 (define_insn "*lea_2_rex64"
4914   [(set (match_operand:DI 0 "register_operand" "=r")
4915         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4916   "TARGET_64BIT"
4917   "lea{q}\t{%a1, %0|%0, %a1}"
4918   [(set_attr "type" "lea")
4919    (set_attr "mode" "DI")])
4921 ;; The lea patterns for non-Pmodes needs to be matched by several
4922 ;; insns converted to real lea by splitters.
4924 (define_insn_and_split "*lea_general_1"
4925   [(set (match_operand 0 "register_operand" "=r")
4926         (plus (plus (match_operand 1 "index_register_operand" "l")
4927                     (match_operand 2 "register_operand" "r"))
4928               (match_operand 3 "immediate_operand" "i")))]
4929   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4930     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4931    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4932    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4933    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4934    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4935        || GET_MODE (operands[3]) == VOIDmode)"
4936   "#"
4937   "&& reload_completed"
4938   [(const_int 0)]
4940   rtx pat;
4941   operands[0] = gen_lowpart (SImode, operands[0]);
4942   operands[1] = gen_lowpart (Pmode, operands[1]);
4943   operands[2] = gen_lowpart (Pmode, operands[2]);
4944   operands[3] = gen_lowpart (Pmode, operands[3]);
4945   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4946                       operands[3]);
4947   if (Pmode != SImode)
4948     pat = gen_rtx_SUBREG (SImode, pat, 0);
4949   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4950   DONE;
4952   [(set_attr "type" "lea")
4953    (set_attr "mode" "SI")])
4955 (define_insn_and_split "*lea_general_1_zext"
4956   [(set (match_operand:DI 0 "register_operand" "=r")
4957         (zero_extend:DI
4958           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4959                             (match_operand:SI 2 "register_operand" "r"))
4960                    (match_operand:SI 3 "immediate_operand" "i"))))]
4961   "TARGET_64BIT"
4962   "#"
4963   "&& reload_completed"
4964   [(set (match_dup 0)
4965         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4966                                                      (match_dup 2))
4967                                             (match_dup 3)) 0)))]
4969   operands[1] = gen_lowpart (Pmode, operands[1]);
4970   operands[2] = gen_lowpart (Pmode, operands[2]);
4971   operands[3] = gen_lowpart (Pmode, operands[3]);
4973   [(set_attr "type" "lea")
4974    (set_attr "mode" "SI")])
4976 (define_insn_and_split "*lea_general_2"
4977   [(set (match_operand 0 "register_operand" "=r")
4978         (plus (mult (match_operand 1 "index_register_operand" "l")
4979                     (match_operand 2 "const248_operand" "i"))
4980               (match_operand 3 "nonmemory_operand" "ri")))]
4981   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4982     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4983    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4984    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4985    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4986        || GET_MODE (operands[3]) == VOIDmode)"
4987   "#"
4988   "&& reload_completed"
4989   [(const_int 0)]
4991   rtx pat;
4992   operands[0] = gen_lowpart (SImode, operands[0]);
4993   operands[1] = gen_lowpart (Pmode, operands[1]);
4994   operands[3] = gen_lowpart (Pmode, operands[3]);
4995   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4996                       operands[3]);
4997   if (Pmode != SImode)
4998     pat = gen_rtx_SUBREG (SImode, pat, 0);
4999   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5000   DONE;
5002   [(set_attr "type" "lea")
5003    (set_attr "mode" "SI")])
5005 (define_insn_and_split "*lea_general_2_zext"
5006   [(set (match_operand:DI 0 "register_operand" "=r")
5007         (zero_extend:DI
5008           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5009                             (match_operand:SI 2 "const248_operand" "n"))
5010                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5011   "TARGET_64BIT"
5012   "#"
5013   "&& reload_completed"
5014   [(set (match_dup 0)
5015         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5016                                                      (match_dup 2))
5017                                             (match_dup 3)) 0)))]
5019   operands[1] = gen_lowpart (Pmode, operands[1]);
5020   operands[3] = gen_lowpart (Pmode, operands[3]);
5022   [(set_attr "type" "lea")
5023    (set_attr "mode" "SI")])
5025 (define_insn_and_split "*lea_general_3"
5026   [(set (match_operand 0 "register_operand" "=r")
5027         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5028                           (match_operand 2 "const248_operand" "i"))
5029                     (match_operand 3 "register_operand" "r"))
5030               (match_operand 4 "immediate_operand" "i")))]
5031   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5032     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5033    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5034    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5035    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5036   "#"
5037   "&& reload_completed"
5038   [(const_int 0)]
5040   rtx pat;
5041   operands[0] = gen_lowpart (SImode, operands[0]);
5042   operands[1] = gen_lowpart (Pmode, operands[1]);
5043   operands[3] = gen_lowpart (Pmode, operands[3]);
5044   operands[4] = gen_lowpart (Pmode, operands[4]);
5045   pat = gen_rtx_PLUS (Pmode,
5046                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5047                                                          operands[2]),
5048                                     operands[3]),
5049                       operands[4]);
5050   if (Pmode != SImode)
5051     pat = gen_rtx_SUBREG (SImode, pat, 0);
5052   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5053   DONE;
5055   [(set_attr "type" "lea")
5056    (set_attr "mode" "SI")])
5058 (define_insn_and_split "*lea_general_3_zext"
5059   [(set (match_operand:DI 0 "register_operand" "=r")
5060         (zero_extend:DI
5061           (plus:SI (plus:SI (mult:SI
5062                               (match_operand:SI 1 "index_register_operand" "l")
5063                               (match_operand:SI 2 "const248_operand" "n"))
5064                             (match_operand:SI 3 "register_operand" "r"))
5065                    (match_operand:SI 4 "immediate_operand" "i"))))]
5066   "TARGET_64BIT"
5067   "#"
5068   "&& reload_completed"
5069   [(set (match_dup 0)
5070         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5071                                                               (match_dup 2))
5072                                                      (match_dup 3))
5073                                             (match_dup 4)) 0)))]
5075   operands[1] = gen_lowpart (Pmode, operands[1]);
5076   operands[3] = gen_lowpart (Pmode, operands[3]);
5077   operands[4] = gen_lowpart (Pmode, operands[4]);
5079   [(set_attr "type" "lea")
5080    (set_attr "mode" "SI")])
5082 (define_insn "*adddi_1_rex64"
5083   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5084         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5085                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5086    (clobber (reg:CC FLAGS_REG))]
5087   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5089   switch (get_attr_type (insn))
5090     {
5091     case TYPE_LEA:
5092       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5093       return "lea{q}\t{%a2, %0|%0, %a2}";
5095     case TYPE_INCDEC:
5096       if (! rtx_equal_p (operands[0], operands[1]))
5097         abort ();
5098       if (operands[2] == const1_rtx)
5099         return "inc{q}\t%0";
5100       else if (operands[2] == constm1_rtx)
5101         return "dec{q}\t%0";
5102       else
5103         abort ();
5105     default:
5106       if (! rtx_equal_p (operands[0], operands[1]))
5107         abort ();
5109       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5110          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5111       if (GET_CODE (operands[2]) == CONST_INT
5112           /* Avoid overflows.  */
5113           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5114           && (INTVAL (operands[2]) == 128
5115               || (INTVAL (operands[2]) < 0
5116                   && INTVAL (operands[2]) != -128)))
5117         {
5118           operands[2] = GEN_INT (-INTVAL (operands[2]));
5119           return "sub{q}\t{%2, %0|%0, %2}";
5120         }
5121       return "add{q}\t{%2, %0|%0, %2}";
5122     }
5124   [(set (attr "type")
5125      (cond [(eq_attr "alternative" "2")
5126               (const_string "lea")
5127             ; Current assemblers are broken and do not allow @GOTOFF in
5128             ; ought but a memory context.
5129             (match_operand:DI 2 "pic_symbolic_operand" "")
5130               (const_string "lea")
5131             (match_operand:DI 2 "incdec_operand" "")
5132               (const_string "incdec")
5133            ]
5134            (const_string "alu")))
5135    (set_attr "mode" "DI")])
5137 ;; Convert lea to the lea pattern to avoid flags dependency.
5138 (define_split
5139   [(set (match_operand:DI 0 "register_operand" "")
5140         (plus:DI (match_operand:DI 1 "register_operand" "")
5141                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5142    (clobber (reg:CC FLAGS_REG))]
5143   "TARGET_64BIT && reload_completed
5144    && true_regnum (operands[0]) != true_regnum (operands[1])"
5145   [(set (match_dup 0)
5146         (plus:DI (match_dup 1)
5147                  (match_dup 2)))]
5148   "")
5150 (define_insn "*adddi_2_rex64"
5151   [(set (reg FLAGS_REG)
5152         (compare
5153           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5154                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5155           (const_int 0)))                       
5156    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5157         (plus:DI (match_dup 1) (match_dup 2)))]
5158   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5159    && ix86_binary_operator_ok (PLUS, DImode, operands)
5160    /* Current assemblers are broken and do not allow @GOTOFF in
5161       ought but a memory context.  */
5162    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5164   switch (get_attr_type (insn))
5165     {
5166     case TYPE_INCDEC:
5167       if (! rtx_equal_p (operands[0], operands[1]))
5168         abort ();
5169       if (operands[2] == const1_rtx)
5170         return "inc{q}\t%0";
5171       else if (operands[2] == constm1_rtx)
5172         return "dec{q}\t%0";
5173       else
5174         abort ();
5176     default:
5177       if (! rtx_equal_p (operands[0], operands[1]))
5178         abort ();
5179       /* ???? We ought to handle there the 32bit case too
5180          - do we need new constraint?  */
5181       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5182          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5183       if (GET_CODE (operands[2]) == CONST_INT
5184           /* Avoid overflows.  */
5185           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5186           && (INTVAL (operands[2]) == 128
5187               || (INTVAL (operands[2]) < 0
5188                   && INTVAL (operands[2]) != -128)))
5189         {
5190           operands[2] = GEN_INT (-INTVAL (operands[2]));
5191           return "sub{q}\t{%2, %0|%0, %2}";
5192         }
5193       return "add{q}\t{%2, %0|%0, %2}";
5194     }
5196   [(set (attr "type")
5197      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5198         (const_string "incdec")
5199         (const_string "alu")))
5200    (set_attr "mode" "DI")])
5202 (define_insn "*adddi_3_rex64"
5203   [(set (reg FLAGS_REG)
5204         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5205                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5206    (clobber (match_scratch:DI 0 "=r"))]
5207   "TARGET_64BIT
5208    && ix86_match_ccmode (insn, CCZmode)
5209    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5210    /* Current assemblers are broken and do not allow @GOTOFF in
5211       ought but a memory context.  */
5212    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5214   switch (get_attr_type (insn))
5215     {
5216     case TYPE_INCDEC:
5217       if (! rtx_equal_p (operands[0], operands[1]))
5218         abort ();
5219       if (operands[2] == const1_rtx)
5220         return "inc{q}\t%0";
5221       else if (operands[2] == constm1_rtx)
5222         return "dec{q}\t%0";
5223       else
5224         abort ();
5226     default:
5227       if (! rtx_equal_p (operands[0], operands[1]))
5228         abort ();
5229       /* ???? We ought to handle there the 32bit case too
5230          - do we need new constraint?  */
5231       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5232          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5233       if (GET_CODE (operands[2]) == CONST_INT
5234           /* Avoid overflows.  */
5235           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5236           && (INTVAL (operands[2]) == 128
5237               || (INTVAL (operands[2]) < 0
5238                   && INTVAL (operands[2]) != -128)))
5239         {
5240           operands[2] = GEN_INT (-INTVAL (operands[2]));
5241           return "sub{q}\t{%2, %0|%0, %2}";
5242         }
5243       return "add{q}\t{%2, %0|%0, %2}";
5244     }
5246   [(set (attr "type")
5247      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5248         (const_string "incdec")
5249         (const_string "alu")))
5250    (set_attr "mode" "DI")])
5252 ; For comparisons against 1, -1 and 128, we may generate better code
5253 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5254 ; is matched then.  We can't accept general immediate, because for
5255 ; case of overflows,  the result is messed up.
5256 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5257 ; when negated.
5258 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5259 ; only for comparisons not depending on it.
5260 (define_insn "*adddi_4_rex64"
5261   [(set (reg FLAGS_REG)
5262         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5263                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5264    (clobber (match_scratch:DI 0 "=rm"))]
5265   "TARGET_64BIT
5266    &&  ix86_match_ccmode (insn, CCGCmode)"
5268   switch (get_attr_type (insn))
5269     {
5270     case TYPE_INCDEC:
5271       if (operands[2] == constm1_rtx)
5272         return "inc{q}\t%0";
5273       else if (operands[2] == const1_rtx)
5274         return "dec{q}\t%0";
5275       else
5276         abort();
5278     default:
5279       if (! rtx_equal_p (operands[0], operands[1]))
5280         abort ();
5281       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5282          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5283       if ((INTVAL (operands[2]) == -128
5284            || (INTVAL (operands[2]) > 0
5285                && INTVAL (operands[2]) != 128))
5286           /* Avoid overflows.  */
5287           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5288         return "sub{q}\t{%2, %0|%0, %2}";
5289       operands[2] = GEN_INT (-INTVAL (operands[2]));
5290       return "add{q}\t{%2, %0|%0, %2}";
5291     }
5293   [(set (attr "type")
5294      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5295         (const_string "incdec")
5296         (const_string "alu")))
5297    (set_attr "mode" "DI")])
5299 (define_insn "*adddi_5_rex64"
5300   [(set (reg FLAGS_REG)
5301         (compare
5302           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5303                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5304           (const_int 0)))                       
5305    (clobber (match_scratch:DI 0 "=r"))]
5306   "TARGET_64BIT
5307    && ix86_match_ccmode (insn, CCGOCmode)
5308    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5309    /* Current assemblers are broken and do not allow @GOTOFF in
5310       ought but a memory context.  */
5311    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5313   switch (get_attr_type (insn))
5314     {
5315     case TYPE_INCDEC:
5316       if (! rtx_equal_p (operands[0], operands[1]))
5317         abort ();
5318       if (operands[2] == const1_rtx)
5319         return "inc{q}\t%0";
5320       else if (operands[2] == constm1_rtx)
5321         return "dec{q}\t%0";
5322       else
5323         abort();
5325     default:
5326       if (! rtx_equal_p (operands[0], operands[1]))
5327         abort ();
5328       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5329          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5330       if (GET_CODE (operands[2]) == CONST_INT
5331           /* Avoid overflows.  */
5332           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5333           && (INTVAL (operands[2]) == 128
5334               || (INTVAL (operands[2]) < 0
5335                   && INTVAL (operands[2]) != -128)))
5336         {
5337           operands[2] = GEN_INT (-INTVAL (operands[2]));
5338           return "sub{q}\t{%2, %0|%0, %2}";
5339         }
5340       return "add{q}\t{%2, %0|%0, %2}";
5341     }
5343   [(set (attr "type")
5344      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5345         (const_string "incdec")
5346         (const_string "alu")))
5347    (set_attr "mode" "DI")])
5350 (define_insn "*addsi_1"
5351   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5352         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5353                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5354    (clobber (reg:CC FLAGS_REG))]
5355   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5357   switch (get_attr_type (insn))
5358     {
5359     case TYPE_LEA:
5360       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5361       return "lea{l}\t{%a2, %0|%0, %a2}";
5363     case TYPE_INCDEC:
5364       if (! rtx_equal_p (operands[0], operands[1]))
5365         abort ();
5366       if (operands[2] == const1_rtx)
5367         return "inc{l}\t%0";
5368       else if (operands[2] == constm1_rtx)
5369         return "dec{l}\t%0";
5370       else
5371         abort();
5373     default:
5374       if (! rtx_equal_p (operands[0], operands[1]))
5375         abort ();
5377       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5378          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5379       if (GET_CODE (operands[2]) == CONST_INT
5380           && (INTVAL (operands[2]) == 128
5381               || (INTVAL (operands[2]) < 0
5382                   && INTVAL (operands[2]) != -128)))
5383         {
5384           operands[2] = GEN_INT (-INTVAL (operands[2]));
5385           return "sub{l}\t{%2, %0|%0, %2}";
5386         }
5387       return "add{l}\t{%2, %0|%0, %2}";
5388     }
5390   [(set (attr "type")
5391      (cond [(eq_attr "alternative" "2")
5392               (const_string "lea")
5393             ; Current assemblers are broken and do not allow @GOTOFF in
5394             ; ought but a memory context.
5395             (match_operand:SI 2 "pic_symbolic_operand" "")
5396               (const_string "lea")
5397             (match_operand:SI 2 "incdec_operand" "")
5398               (const_string "incdec")
5399            ]
5400            (const_string "alu")))
5401    (set_attr "mode" "SI")])
5403 ;; Convert lea to the lea pattern to avoid flags dependency.
5404 (define_split
5405   [(set (match_operand 0 "register_operand" "")
5406         (plus (match_operand 1 "register_operand" "")
5407               (match_operand 2 "nonmemory_operand" "")))
5408    (clobber (reg:CC FLAGS_REG))]
5409   "reload_completed
5410    && true_regnum (operands[0]) != true_regnum (operands[1])"
5411   [(const_int 0)]
5413   rtx pat;
5414   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5415      may confuse gen_lowpart.  */
5416   if (GET_MODE (operands[0]) != Pmode)
5417     {
5418       operands[1] = gen_lowpart (Pmode, operands[1]);
5419       operands[2] = gen_lowpart (Pmode, operands[2]);
5420     }
5421   operands[0] = gen_lowpart (SImode, operands[0]);
5422   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5423   if (Pmode != SImode)
5424     pat = gen_rtx_SUBREG (SImode, pat, 0);
5425   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5426   DONE;
5429 ;; It may seem that nonimmediate operand is proper one for operand 1.
5430 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5431 ;; we take care in ix86_binary_operator_ok to not allow two memory
5432 ;; operands so proper swapping will be done in reload.  This allow
5433 ;; patterns constructed from addsi_1 to match.
5434 (define_insn "addsi_1_zext"
5435   [(set (match_operand:DI 0 "register_operand" "=r,r")
5436         (zero_extend:DI
5437           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5438                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5439    (clobber (reg:CC FLAGS_REG))]
5440   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5442   switch (get_attr_type (insn))
5443     {
5444     case TYPE_LEA:
5445       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5446       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5448     case TYPE_INCDEC:
5449       if (operands[2] == const1_rtx)
5450         return "inc{l}\t%k0";
5451       else if (operands[2] == constm1_rtx)
5452         return "dec{l}\t%k0";
5453       else
5454         abort();
5456     default:
5457       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5458          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5459       if (GET_CODE (operands[2]) == CONST_INT
5460           && (INTVAL (operands[2]) == 128
5461               || (INTVAL (operands[2]) < 0
5462                   && INTVAL (operands[2]) != -128)))
5463         {
5464           operands[2] = GEN_INT (-INTVAL (operands[2]));
5465           return "sub{l}\t{%2, %k0|%k0, %2}";
5466         }
5467       return "add{l}\t{%2, %k0|%k0, %2}";
5468     }
5470   [(set (attr "type")
5471      (cond [(eq_attr "alternative" "1")
5472               (const_string "lea")
5473             ; Current assemblers are broken and do not allow @GOTOFF in
5474             ; ought but a memory context.
5475             (match_operand:SI 2 "pic_symbolic_operand" "")
5476               (const_string "lea")
5477             (match_operand:SI 2 "incdec_operand" "")
5478               (const_string "incdec")
5479            ]
5480            (const_string "alu")))
5481    (set_attr "mode" "SI")])
5483 ;; Convert lea to the lea pattern to avoid flags dependency.
5484 (define_split
5485   [(set (match_operand:DI 0 "register_operand" "")
5486         (zero_extend:DI
5487           (plus:SI (match_operand:SI 1 "register_operand" "")
5488                    (match_operand:SI 2 "nonmemory_operand" ""))))
5489    (clobber (reg:CC FLAGS_REG))]
5490   "TARGET_64BIT && reload_completed
5491    && true_regnum (operands[0]) != true_regnum (operands[1])"
5492   [(set (match_dup 0)
5493         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5495   operands[1] = gen_lowpart (Pmode, operands[1]);
5496   operands[2] = gen_lowpart (Pmode, operands[2]);
5499 (define_insn "*addsi_2"
5500   [(set (reg FLAGS_REG)
5501         (compare
5502           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5503                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5504           (const_int 0)))                       
5505    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5506         (plus:SI (match_dup 1) (match_dup 2)))]
5507   "ix86_match_ccmode (insn, CCGOCmode)
5508    && ix86_binary_operator_ok (PLUS, SImode, operands)
5509    /* Current assemblers are broken and do not allow @GOTOFF in
5510       ought but a memory context.  */
5511    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5513   switch (get_attr_type (insn))
5514     {
5515     case TYPE_INCDEC:
5516       if (! rtx_equal_p (operands[0], operands[1]))
5517         abort ();
5518       if (operands[2] == const1_rtx)
5519         return "inc{l}\t%0";
5520       else if (operands[2] == constm1_rtx)
5521         return "dec{l}\t%0";
5522       else
5523         abort();
5525     default:
5526       if (! rtx_equal_p (operands[0], operands[1]))
5527         abort ();
5528       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5529          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5530       if (GET_CODE (operands[2]) == CONST_INT
5531           && (INTVAL (operands[2]) == 128
5532               || (INTVAL (operands[2]) < 0
5533                   && INTVAL (operands[2]) != -128)))
5534         {
5535           operands[2] = GEN_INT (-INTVAL (operands[2]));
5536           return "sub{l}\t{%2, %0|%0, %2}";
5537         }
5538       return "add{l}\t{%2, %0|%0, %2}";
5539     }
5541   [(set (attr "type")
5542      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5543         (const_string "incdec")
5544         (const_string "alu")))
5545    (set_attr "mode" "SI")])
5547 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5548 (define_insn "*addsi_2_zext"
5549   [(set (reg FLAGS_REG)
5550         (compare
5551           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5552                    (match_operand:SI 2 "general_operand" "rmni"))
5553           (const_int 0)))                       
5554    (set (match_operand:DI 0 "register_operand" "=r")
5555         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5556   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5557    && ix86_binary_operator_ok (PLUS, SImode, operands)
5558    /* Current assemblers are broken and do not allow @GOTOFF in
5559       ought but a memory context.  */
5560    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5562   switch (get_attr_type (insn))
5563     {
5564     case TYPE_INCDEC:
5565       if (operands[2] == const1_rtx)
5566         return "inc{l}\t%k0";
5567       else if (operands[2] == constm1_rtx)
5568         return "dec{l}\t%k0";
5569       else
5570         abort();
5572     default:
5573       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5574          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5575       if (GET_CODE (operands[2]) == CONST_INT
5576           && (INTVAL (operands[2]) == 128
5577               || (INTVAL (operands[2]) < 0
5578                   && INTVAL (operands[2]) != -128)))
5579         {
5580           operands[2] = GEN_INT (-INTVAL (operands[2]));
5581           return "sub{l}\t{%2, %k0|%k0, %2}";
5582         }
5583       return "add{l}\t{%2, %k0|%k0, %2}";
5584     }
5586   [(set (attr "type")
5587      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5588         (const_string "incdec")
5589         (const_string "alu")))
5590    (set_attr "mode" "SI")])
5592 (define_insn "*addsi_3"
5593   [(set (reg FLAGS_REG)
5594         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5595                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5596    (clobber (match_scratch:SI 0 "=r"))]
5597   "ix86_match_ccmode (insn, CCZmode)
5598    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5599    /* Current assemblers are broken and do not allow @GOTOFF in
5600       ought but a memory context.  */
5601    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5603   switch (get_attr_type (insn))
5604     {
5605     case TYPE_INCDEC:
5606       if (! rtx_equal_p (operands[0], operands[1]))
5607         abort ();
5608       if (operands[2] == const1_rtx)
5609         return "inc{l}\t%0";
5610       else if (operands[2] == constm1_rtx)
5611         return "dec{l}\t%0";
5612       else
5613         abort();
5615     default:
5616       if (! rtx_equal_p (operands[0], operands[1]))
5617         abort ();
5618       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5619          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5620       if (GET_CODE (operands[2]) == CONST_INT
5621           && (INTVAL (operands[2]) == 128
5622               || (INTVAL (operands[2]) < 0
5623                   && INTVAL (operands[2]) != -128)))
5624         {
5625           operands[2] = GEN_INT (-INTVAL (operands[2]));
5626           return "sub{l}\t{%2, %0|%0, %2}";
5627         }
5628       return "add{l}\t{%2, %0|%0, %2}";
5629     }
5631   [(set (attr "type")
5632      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5633         (const_string "incdec")
5634         (const_string "alu")))
5635    (set_attr "mode" "SI")])
5637 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5638 (define_insn "*addsi_3_zext"
5639   [(set (reg FLAGS_REG)
5640         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5641                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5642    (set (match_operand:DI 0 "register_operand" "=r")
5643         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5644   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5645    && ix86_binary_operator_ok (PLUS, SImode, operands)
5646    /* Current assemblers are broken and do not allow @GOTOFF in
5647       ought but a memory context.  */
5648    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5650   switch (get_attr_type (insn))
5651     {
5652     case TYPE_INCDEC:
5653       if (operands[2] == const1_rtx)
5654         return "inc{l}\t%k0";
5655       else if (operands[2] == constm1_rtx)
5656         return "dec{l}\t%k0";
5657       else
5658         abort();
5660     default:
5661       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5662          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5663       if (GET_CODE (operands[2]) == CONST_INT
5664           && (INTVAL (operands[2]) == 128
5665               || (INTVAL (operands[2]) < 0
5666                   && INTVAL (operands[2]) != -128)))
5667         {
5668           operands[2] = GEN_INT (-INTVAL (operands[2]));
5669           return "sub{l}\t{%2, %k0|%k0, %2}";
5670         }
5671       return "add{l}\t{%2, %k0|%k0, %2}";
5672     }
5674   [(set (attr "type")
5675      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5676         (const_string "incdec")
5677         (const_string "alu")))
5678    (set_attr "mode" "SI")])
5680 ; For comparisons against 1, -1 and 128, we may generate better code
5681 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5682 ; is matched then.  We can't accept general immediate, because for
5683 ; case of overflows,  the result is messed up.
5684 ; This pattern also don't hold of 0x80000000, since the value overflows
5685 ; when negated.
5686 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5687 ; only for comparisons not depending on it.
5688 (define_insn "*addsi_4"
5689   [(set (reg FLAGS_REG)
5690         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5691                  (match_operand:SI 2 "const_int_operand" "n")))
5692    (clobber (match_scratch:SI 0 "=rm"))]
5693   "ix86_match_ccmode (insn, CCGCmode)
5694    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5696   switch (get_attr_type (insn))
5697     {
5698     case TYPE_INCDEC:
5699       if (operands[2] == constm1_rtx)
5700         return "inc{l}\t%0";
5701       else if (operands[2] == const1_rtx)
5702         return "dec{l}\t%0";
5703       else
5704         abort();
5706     default:
5707       if (! rtx_equal_p (operands[0], operands[1]))
5708         abort ();
5709       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5710          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5711       if ((INTVAL (operands[2]) == -128
5712            || (INTVAL (operands[2]) > 0
5713                && INTVAL (operands[2]) != 128)))
5714         return "sub{l}\t{%2, %0|%0, %2}";
5715       operands[2] = GEN_INT (-INTVAL (operands[2]));
5716       return "add{l}\t{%2, %0|%0, %2}";
5717     }
5719   [(set (attr "type")
5720      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5721         (const_string "incdec")
5722         (const_string "alu")))
5723    (set_attr "mode" "SI")])
5725 (define_insn "*addsi_5"
5726   [(set (reg FLAGS_REG)
5727         (compare
5728           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5729                    (match_operand:SI 2 "general_operand" "rmni"))
5730           (const_int 0)))                       
5731    (clobber (match_scratch:SI 0 "=r"))]
5732   "ix86_match_ccmode (insn, CCGOCmode)
5733    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5734    /* Current assemblers are broken and do not allow @GOTOFF in
5735       ought but a memory context.  */
5736    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5738   switch (get_attr_type (insn))
5739     {
5740     case TYPE_INCDEC:
5741       if (! rtx_equal_p (operands[0], operands[1]))
5742         abort ();
5743       if (operands[2] == const1_rtx)
5744         return "inc{l}\t%0";
5745       else if (operands[2] == constm1_rtx)
5746         return "dec{l}\t%0";
5747       else
5748         abort();
5750     default:
5751       if (! rtx_equal_p (operands[0], operands[1]))
5752         abort ();
5753       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5754          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5755       if (GET_CODE (operands[2]) == CONST_INT
5756           && (INTVAL (operands[2]) == 128
5757               || (INTVAL (operands[2]) < 0
5758                   && INTVAL (operands[2]) != -128)))
5759         {
5760           operands[2] = GEN_INT (-INTVAL (operands[2]));
5761           return "sub{l}\t{%2, %0|%0, %2}";
5762         }
5763       return "add{l}\t{%2, %0|%0, %2}";
5764     }
5766   [(set (attr "type")
5767      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5768         (const_string "incdec")
5769         (const_string "alu")))
5770    (set_attr "mode" "SI")])
5772 (define_expand "addhi3"
5773   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5774                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5775                             (match_operand:HI 2 "general_operand" "")))
5776               (clobber (reg:CC FLAGS_REG))])]
5777   "TARGET_HIMODE_MATH"
5778   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5780 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5781 ;; type optimizations enabled by define-splits.  This is not important
5782 ;; for PII, and in fact harmful because of partial register stalls.
5784 (define_insn "*addhi_1_lea"
5785   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5786         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5787                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5788    (clobber (reg:CC FLAGS_REG))]
5789   "!TARGET_PARTIAL_REG_STALL
5790    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5792   switch (get_attr_type (insn))
5793     {
5794     case TYPE_LEA:
5795       return "#";
5796     case TYPE_INCDEC:
5797       if (operands[2] == const1_rtx)
5798         return "inc{w}\t%0";
5799       else if (operands[2] == constm1_rtx)
5800         return "dec{w}\t%0";
5801       abort();
5803     default:
5804       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5805          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5806       if (GET_CODE (operands[2]) == CONST_INT
5807           && (INTVAL (operands[2]) == 128
5808               || (INTVAL (operands[2]) < 0
5809                   && INTVAL (operands[2]) != -128)))
5810         {
5811           operands[2] = GEN_INT (-INTVAL (operands[2]));
5812           return "sub{w}\t{%2, %0|%0, %2}";
5813         }
5814       return "add{w}\t{%2, %0|%0, %2}";
5815     }
5817   [(set (attr "type")
5818      (if_then_else (eq_attr "alternative" "2")
5819         (const_string "lea")
5820         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5821            (const_string "incdec")
5822            (const_string "alu"))))
5823    (set_attr "mode" "HI,HI,SI")])
5825 (define_insn "*addhi_1"
5826   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5827         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5828                  (match_operand:HI 2 "general_operand" "ri,rm")))
5829    (clobber (reg:CC FLAGS_REG))]
5830   "TARGET_PARTIAL_REG_STALL
5831    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5833   switch (get_attr_type (insn))
5834     {
5835     case TYPE_INCDEC:
5836       if (operands[2] == const1_rtx)
5837         return "inc{w}\t%0";
5838       else if (operands[2] == constm1_rtx)
5839         return "dec{w}\t%0";
5840       abort();
5842     default:
5843       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5844          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5845       if (GET_CODE (operands[2]) == CONST_INT
5846           && (INTVAL (operands[2]) == 128
5847               || (INTVAL (operands[2]) < 0
5848                   && INTVAL (operands[2]) != -128)))
5849         {
5850           operands[2] = GEN_INT (-INTVAL (operands[2]));
5851           return "sub{w}\t{%2, %0|%0, %2}";
5852         }
5853       return "add{w}\t{%2, %0|%0, %2}";
5854     }
5856   [(set (attr "type")
5857      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5858         (const_string "incdec")
5859         (const_string "alu")))
5860    (set_attr "mode" "HI")])
5862 (define_insn "*addhi_2"
5863   [(set (reg FLAGS_REG)
5864         (compare
5865           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5866                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5867           (const_int 0)))                       
5868    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5869         (plus:HI (match_dup 1) (match_dup 2)))]
5870   "ix86_match_ccmode (insn, CCGOCmode)
5871    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5873   switch (get_attr_type (insn))
5874     {
5875     case TYPE_INCDEC:
5876       if (operands[2] == const1_rtx)
5877         return "inc{w}\t%0";
5878       else if (operands[2] == constm1_rtx)
5879         return "dec{w}\t%0";
5880       abort();
5882     default:
5883       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5884          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5885       if (GET_CODE (operands[2]) == CONST_INT
5886           && (INTVAL (operands[2]) == 128
5887               || (INTVAL (operands[2]) < 0
5888                   && INTVAL (operands[2]) != -128)))
5889         {
5890           operands[2] = GEN_INT (-INTVAL (operands[2]));
5891           return "sub{w}\t{%2, %0|%0, %2}";
5892         }
5893       return "add{w}\t{%2, %0|%0, %2}";
5894     }
5896   [(set (attr "type")
5897      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5898         (const_string "incdec")
5899         (const_string "alu")))
5900    (set_attr "mode" "HI")])
5902 (define_insn "*addhi_3"
5903   [(set (reg FLAGS_REG)
5904         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5905                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5906    (clobber (match_scratch:HI 0 "=r"))]
5907   "ix86_match_ccmode (insn, CCZmode)
5908    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5910   switch (get_attr_type (insn))
5911     {
5912     case TYPE_INCDEC:
5913       if (operands[2] == const1_rtx)
5914         return "inc{w}\t%0";
5915       else if (operands[2] == constm1_rtx)
5916         return "dec{w}\t%0";
5917       abort();
5919     default:
5920       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5921          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5922       if (GET_CODE (operands[2]) == CONST_INT
5923           && (INTVAL (operands[2]) == 128
5924               || (INTVAL (operands[2]) < 0
5925                   && INTVAL (operands[2]) != -128)))
5926         {
5927           operands[2] = GEN_INT (-INTVAL (operands[2]));
5928           return "sub{w}\t{%2, %0|%0, %2}";
5929         }
5930       return "add{w}\t{%2, %0|%0, %2}";
5931     }
5933   [(set (attr "type")
5934      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5935         (const_string "incdec")
5936         (const_string "alu")))
5937    (set_attr "mode" "HI")])
5939 ; See comments above addsi_4 for details.
5940 (define_insn "*addhi_4"
5941   [(set (reg FLAGS_REG)
5942         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5943                  (match_operand:HI 2 "const_int_operand" "n")))
5944    (clobber (match_scratch:HI 0 "=rm"))]
5945   "ix86_match_ccmode (insn, CCGCmode)
5946    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5948   switch (get_attr_type (insn))
5949     {
5950     case TYPE_INCDEC:
5951       if (operands[2] == constm1_rtx)
5952         return "inc{w}\t%0";
5953       else if (operands[2] == const1_rtx)
5954         return "dec{w}\t%0";
5955       else
5956         abort();
5958     default:
5959       if (! rtx_equal_p (operands[0], operands[1]))
5960         abort ();
5961       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5962          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5963       if ((INTVAL (operands[2]) == -128
5964            || (INTVAL (operands[2]) > 0
5965                && INTVAL (operands[2]) != 128)))
5966         return "sub{w}\t{%2, %0|%0, %2}";
5967       operands[2] = GEN_INT (-INTVAL (operands[2]));
5968       return "add{w}\t{%2, %0|%0, %2}";
5969     }
5971   [(set (attr "type")
5972      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5973         (const_string "incdec")
5974         (const_string "alu")))
5975    (set_attr "mode" "SI")])
5978 (define_insn "*addhi_5"
5979   [(set (reg FLAGS_REG)
5980         (compare
5981           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5982                    (match_operand:HI 2 "general_operand" "rmni"))
5983           (const_int 0)))                       
5984    (clobber (match_scratch:HI 0 "=r"))]
5985   "ix86_match_ccmode (insn, CCGOCmode)
5986    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5988   switch (get_attr_type (insn))
5989     {
5990     case TYPE_INCDEC:
5991       if (operands[2] == const1_rtx)
5992         return "inc{w}\t%0";
5993       else if (operands[2] == constm1_rtx)
5994         return "dec{w}\t%0";
5995       abort();
5997     default:
5998       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5999          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6000       if (GET_CODE (operands[2]) == CONST_INT
6001           && (INTVAL (operands[2]) == 128
6002               || (INTVAL (operands[2]) < 0
6003                   && INTVAL (operands[2]) != -128)))
6004         {
6005           operands[2] = GEN_INT (-INTVAL (operands[2]));
6006           return "sub{w}\t{%2, %0|%0, %2}";
6007         }
6008       return "add{w}\t{%2, %0|%0, %2}";
6009     }
6011   [(set (attr "type")
6012      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6013         (const_string "incdec")
6014         (const_string "alu")))
6015    (set_attr "mode" "HI")])
6017 (define_expand "addqi3"
6018   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6019                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6020                             (match_operand:QI 2 "general_operand" "")))
6021               (clobber (reg:CC FLAGS_REG))])]
6022   "TARGET_QIMODE_MATH"
6023   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6025 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6026 (define_insn "*addqi_1_lea"
6027   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6028         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6029                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6030    (clobber (reg:CC FLAGS_REG))]
6031   "!TARGET_PARTIAL_REG_STALL
6032    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6034   int widen = (which_alternative == 2);
6035   switch (get_attr_type (insn))
6036     {
6037     case TYPE_LEA:
6038       return "#";
6039     case TYPE_INCDEC:
6040       if (operands[2] == const1_rtx)
6041         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6042       else if (operands[2] == constm1_rtx)
6043         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6044       abort();
6046     default:
6047       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6048          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6049       if (GET_CODE (operands[2]) == CONST_INT
6050           && (INTVAL (operands[2]) == 128
6051               || (INTVAL (operands[2]) < 0
6052                   && INTVAL (operands[2]) != -128)))
6053         {
6054           operands[2] = GEN_INT (-INTVAL (operands[2]));
6055           if (widen)
6056             return "sub{l}\t{%2, %k0|%k0, %2}";
6057           else
6058             return "sub{b}\t{%2, %0|%0, %2}";
6059         }
6060       if (widen)
6061         return "add{l}\t{%k2, %k0|%k0, %k2}";
6062       else
6063         return "add{b}\t{%2, %0|%0, %2}";
6064     }
6066   [(set (attr "type")
6067      (if_then_else (eq_attr "alternative" "3")
6068         (const_string "lea")
6069         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6070            (const_string "incdec")
6071            (const_string "alu"))))
6072    (set_attr "mode" "QI,QI,SI,SI")])
6074 (define_insn "*addqi_1"
6075   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6076         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6077                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6078    (clobber (reg:CC FLAGS_REG))]
6079   "TARGET_PARTIAL_REG_STALL
6080    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6082   int widen = (which_alternative == 2);
6083   switch (get_attr_type (insn))
6084     {
6085     case TYPE_INCDEC:
6086       if (operands[2] == const1_rtx)
6087         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6088       else if (operands[2] == constm1_rtx)
6089         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6090       abort();
6092     default:
6093       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6094          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6095       if (GET_CODE (operands[2]) == CONST_INT
6096           && (INTVAL (operands[2]) == 128
6097               || (INTVAL (operands[2]) < 0
6098                   && INTVAL (operands[2]) != -128)))
6099         {
6100           operands[2] = GEN_INT (-INTVAL (operands[2]));
6101           if (widen)
6102             return "sub{l}\t{%2, %k0|%k0, %2}";
6103           else
6104             return "sub{b}\t{%2, %0|%0, %2}";
6105         }
6106       if (widen)
6107         return "add{l}\t{%k2, %k0|%k0, %k2}";
6108       else
6109         return "add{b}\t{%2, %0|%0, %2}";
6110     }
6112   [(set (attr "type")
6113      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6114         (const_string "incdec")
6115         (const_string "alu")))
6116    (set_attr "mode" "QI,QI,SI")])
6118 (define_insn "*addqi_1_slp"
6119   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6120         (plus:QI (match_dup 0)
6121                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6122    (clobber (reg:CC FLAGS_REG))]
6123   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6124    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6126   switch (get_attr_type (insn))
6127     {
6128     case TYPE_INCDEC:
6129       if (operands[1] == const1_rtx)
6130         return "inc{b}\t%0";
6131       else if (operands[1] == constm1_rtx)
6132         return "dec{b}\t%0";
6133       abort();
6135     default:
6136       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6137       if (GET_CODE (operands[1]) == CONST_INT
6138           && INTVAL (operands[1]) < 0)
6139         {
6140           operands[1] = GEN_INT (-INTVAL (operands[1]));
6141           return "sub{b}\t{%1, %0|%0, %1}";
6142         }
6143       return "add{b}\t{%1, %0|%0, %1}";
6144     }
6146   [(set (attr "type")
6147      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6148         (const_string "incdec")
6149         (const_string "alu1")))
6150    (set (attr "memory")
6151      (if_then_else (match_operand 1 "memory_operand" "")
6152         (const_string "load")
6153         (const_string "none")))
6154    (set_attr "mode" "QI")])
6156 (define_insn "*addqi_2"
6157   [(set (reg FLAGS_REG)
6158         (compare
6159           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6160                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6161           (const_int 0)))
6162    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6163         (plus:QI (match_dup 1) (match_dup 2)))]
6164   "ix86_match_ccmode (insn, CCGOCmode)
6165    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6167   switch (get_attr_type (insn))
6168     {
6169     case TYPE_INCDEC:
6170       if (operands[2] == const1_rtx)
6171         return "inc{b}\t%0";
6172       else if (operands[2] == constm1_rtx
6173                || (GET_CODE (operands[2]) == CONST_INT
6174                    && INTVAL (operands[2]) == 255))
6175         return "dec{b}\t%0";
6176       abort();
6178     default:
6179       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6180       if (GET_CODE (operands[2]) == CONST_INT
6181           && INTVAL (operands[2]) < 0)
6182         {
6183           operands[2] = GEN_INT (-INTVAL (operands[2]));
6184           return "sub{b}\t{%2, %0|%0, %2}";
6185         }
6186       return "add{b}\t{%2, %0|%0, %2}";
6187     }
6189   [(set (attr "type")
6190      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6191         (const_string "incdec")
6192         (const_string "alu")))
6193    (set_attr "mode" "QI")])
6195 (define_insn "*addqi_3"
6196   [(set (reg FLAGS_REG)
6197         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6198                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6199    (clobber (match_scratch:QI 0 "=q"))]
6200   "ix86_match_ccmode (insn, CCZmode)
6201    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6203   switch (get_attr_type (insn))
6204     {
6205     case TYPE_INCDEC:
6206       if (operands[2] == const1_rtx)
6207         return "inc{b}\t%0";
6208       else if (operands[2] == constm1_rtx
6209                || (GET_CODE (operands[2]) == CONST_INT
6210                    && INTVAL (operands[2]) == 255))
6211         return "dec{b}\t%0";
6212       abort();
6214     default:
6215       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6216       if (GET_CODE (operands[2]) == CONST_INT
6217           && INTVAL (operands[2]) < 0)
6218         {
6219           operands[2] = GEN_INT (-INTVAL (operands[2]));
6220           return "sub{b}\t{%2, %0|%0, %2}";
6221         }
6222       return "add{b}\t{%2, %0|%0, %2}";
6223     }
6225   [(set (attr "type")
6226      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6227         (const_string "incdec")
6228         (const_string "alu")))
6229    (set_attr "mode" "QI")])
6231 ; See comments above addsi_4 for details.
6232 (define_insn "*addqi_4"
6233   [(set (reg FLAGS_REG)
6234         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6235                  (match_operand:QI 2 "const_int_operand" "n")))
6236    (clobber (match_scratch:QI 0 "=qm"))]
6237   "ix86_match_ccmode (insn, CCGCmode)
6238    && (INTVAL (operands[2]) & 0xff) != 0x80"
6240   switch (get_attr_type (insn))
6241     {
6242     case TYPE_INCDEC:
6243       if (operands[2] == constm1_rtx
6244           || (GET_CODE (operands[2]) == CONST_INT
6245               && INTVAL (operands[2]) == 255))
6246         return "inc{b}\t%0";
6247       else if (operands[2] == const1_rtx)
6248         return "dec{b}\t%0";
6249       else
6250         abort();
6252     default:
6253       if (! rtx_equal_p (operands[0], operands[1]))
6254         abort ();
6255       if (INTVAL (operands[2]) < 0)
6256         {
6257           operands[2] = GEN_INT (-INTVAL (operands[2]));
6258           return "add{b}\t{%2, %0|%0, %2}";
6259         }
6260       return "sub{b}\t{%2, %0|%0, %2}";
6261     }
6263   [(set (attr "type")
6264      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6265         (const_string "incdec")
6266         (const_string "alu")))
6267    (set_attr "mode" "QI")])
6270 (define_insn "*addqi_5"
6271   [(set (reg FLAGS_REG)
6272         (compare
6273           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6274                    (match_operand:QI 2 "general_operand" "qmni"))
6275           (const_int 0)))
6276    (clobber (match_scratch:QI 0 "=q"))]
6277   "ix86_match_ccmode (insn, CCGOCmode)
6278    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6280   switch (get_attr_type (insn))
6281     {
6282     case TYPE_INCDEC:
6283       if (operands[2] == const1_rtx)
6284         return "inc{b}\t%0";
6285       else if (operands[2] == constm1_rtx
6286                || (GET_CODE (operands[2]) == CONST_INT
6287                    && INTVAL (operands[2]) == 255))
6288         return "dec{b}\t%0";
6289       abort();
6291     default:
6292       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6293       if (GET_CODE (operands[2]) == CONST_INT
6294           && INTVAL (operands[2]) < 0)
6295         {
6296           operands[2] = GEN_INT (-INTVAL (operands[2]));
6297           return "sub{b}\t{%2, %0|%0, %2}";
6298         }
6299       return "add{b}\t{%2, %0|%0, %2}";
6300     }
6302   [(set (attr "type")
6303      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6304         (const_string "incdec")
6305         (const_string "alu")))
6306    (set_attr "mode" "QI")])
6309 (define_insn "addqi_ext_1"
6310   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6311                          (const_int 8)
6312                          (const_int 8))
6313         (plus:SI
6314           (zero_extract:SI
6315             (match_operand 1 "ext_register_operand" "0")
6316             (const_int 8)
6317             (const_int 8))
6318           (match_operand:QI 2 "general_operand" "Qmn")))
6319    (clobber (reg:CC FLAGS_REG))]
6320   "!TARGET_64BIT"
6322   switch (get_attr_type (insn))
6323     {
6324     case TYPE_INCDEC:
6325       if (operands[2] == const1_rtx)
6326         return "inc{b}\t%h0";
6327       else if (operands[2] == constm1_rtx
6328                || (GET_CODE (operands[2]) == CONST_INT
6329                    && INTVAL (operands[2]) == 255))
6330         return "dec{b}\t%h0";
6331       abort();
6333     default:
6334       return "add{b}\t{%2, %h0|%h0, %2}";
6335     }
6337   [(set (attr "type")
6338      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6339         (const_string "incdec")
6340         (const_string "alu")))
6341    (set_attr "mode" "QI")])
6343 (define_insn "*addqi_ext_1_rex64"
6344   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6345                          (const_int 8)
6346                          (const_int 8))
6347         (plus:SI
6348           (zero_extract:SI
6349             (match_operand 1 "ext_register_operand" "0")
6350             (const_int 8)
6351             (const_int 8))
6352           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6353    (clobber (reg:CC FLAGS_REG))]
6354   "TARGET_64BIT"
6356   switch (get_attr_type (insn))
6357     {
6358     case TYPE_INCDEC:
6359       if (operands[2] == const1_rtx)
6360         return "inc{b}\t%h0";
6361       else if (operands[2] == constm1_rtx
6362                || (GET_CODE (operands[2]) == CONST_INT
6363                    && INTVAL (operands[2]) == 255))
6364         return "dec{b}\t%h0";
6365       abort();
6367     default:
6368       return "add{b}\t{%2, %h0|%h0, %2}";
6369     }
6371   [(set (attr "type")
6372      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6373         (const_string "incdec")
6374         (const_string "alu")))
6375    (set_attr "mode" "QI")])
6377 (define_insn "*addqi_ext_2"
6378   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6379                          (const_int 8)
6380                          (const_int 8))
6381         (plus:SI
6382           (zero_extract:SI
6383             (match_operand 1 "ext_register_operand" "%0")
6384             (const_int 8)
6385             (const_int 8))
6386           (zero_extract:SI
6387             (match_operand 2 "ext_register_operand" "Q")
6388             (const_int 8)
6389             (const_int 8))))
6390    (clobber (reg:CC FLAGS_REG))]
6391   ""
6392   "add{b}\t{%h2, %h0|%h0, %h2}"
6393   [(set_attr "type" "alu")
6394    (set_attr "mode" "QI")])
6396 ;; The patterns that match these are at the end of this file.
6398 (define_expand "addxf3"
6399   [(set (match_operand:XF 0 "register_operand" "")
6400         (plus:XF (match_operand:XF 1 "register_operand" "")
6401                  (match_operand:XF 2 "register_operand" "")))]
6402   "TARGET_80387"
6403   "")
6405 (define_expand "adddf3"
6406   [(set (match_operand:DF 0 "register_operand" "")
6407         (plus:DF (match_operand:DF 1 "register_operand" "")
6408                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6409   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6410   "")
6412 (define_expand "addsf3"
6413   [(set (match_operand:SF 0 "register_operand" "")
6414         (plus:SF (match_operand:SF 1 "register_operand" "")
6415                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6416   "TARGET_80387 || TARGET_SSE_MATH"
6417   "")
6419 ;; Subtract instructions
6421 ;; %%% splits for subsidi3
6423 (define_expand "subdi3"
6424   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6425                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6426                              (match_operand:DI 2 "x86_64_general_operand" "")))
6427               (clobber (reg:CC FLAGS_REG))])]
6428   ""
6429   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6431 (define_insn "*subdi3_1"
6432   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6433         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6434                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6435    (clobber (reg:CC FLAGS_REG))]
6436   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6437   "#")
6439 (define_split
6440   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6441         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6442                   (match_operand:DI 2 "general_operand" "")))
6443    (clobber (reg:CC FLAGS_REG))]
6444   "!TARGET_64BIT && reload_completed"
6445   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6446               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6447    (parallel [(set (match_dup 3)
6448                    (minus:SI (match_dup 4)
6449                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6450                                       (match_dup 5))))
6451               (clobber (reg:CC FLAGS_REG))])]
6452   "split_di (operands+0, 1, operands+0, operands+3);
6453    split_di (operands+1, 1, operands+1, operands+4);
6454    split_di (operands+2, 1, operands+2, operands+5);")
6456 (define_insn "subdi3_carry_rex64"
6457   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6458           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6459             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6460                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6461    (clobber (reg:CC FLAGS_REG))]
6462   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6463   "sbb{q}\t{%2, %0|%0, %2}"
6464   [(set_attr "type" "alu")
6465    (set_attr "pent_pair" "pu")
6466    (set_attr "mode" "DI")])
6468 (define_insn "*subdi_1_rex64"
6469   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6470         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6471                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6472    (clobber (reg:CC FLAGS_REG))]
6473   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6474   "sub{q}\t{%2, %0|%0, %2}"
6475   [(set_attr "type" "alu")
6476    (set_attr "mode" "DI")])
6478 (define_insn "*subdi_2_rex64"
6479   [(set (reg FLAGS_REG)
6480         (compare
6481           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6482                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6483           (const_int 0)))
6484    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6485         (minus:DI (match_dup 1) (match_dup 2)))]
6486   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6487    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6488   "sub{q}\t{%2, %0|%0, %2}"
6489   [(set_attr "type" "alu")
6490    (set_attr "mode" "DI")])
6492 (define_insn "*subdi_3_rex63"
6493   [(set (reg FLAGS_REG)
6494         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6495                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6496    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6497         (minus:DI (match_dup 1) (match_dup 2)))]
6498   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6499    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6500   "sub{q}\t{%2, %0|%0, %2}"
6501   [(set_attr "type" "alu")
6502    (set_attr "mode" "DI")])
6504 (define_insn "subqi3_carry"
6505   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6506           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6507             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6508                (match_operand:QI 2 "general_operand" "qi,qm"))))
6509    (clobber (reg:CC FLAGS_REG))]
6510   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6511   "sbb{b}\t{%2, %0|%0, %2}"
6512   [(set_attr "type" "alu")
6513    (set_attr "pent_pair" "pu")
6514    (set_attr "mode" "QI")])
6516 (define_insn "subhi3_carry"
6517   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6518           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6519             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6520                (match_operand:HI 2 "general_operand" "ri,rm"))))
6521    (clobber (reg:CC FLAGS_REG))]
6522   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6523   "sbb{w}\t{%2, %0|%0, %2}"
6524   [(set_attr "type" "alu")
6525    (set_attr "pent_pair" "pu")
6526    (set_attr "mode" "HI")])
6528 (define_insn "subsi3_carry"
6529   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6530           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6531             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6532                (match_operand:SI 2 "general_operand" "ri,rm"))))
6533    (clobber (reg:CC FLAGS_REG))]
6534   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6535   "sbb{l}\t{%2, %0|%0, %2}"
6536   [(set_attr "type" "alu")
6537    (set_attr "pent_pair" "pu")
6538    (set_attr "mode" "SI")])
6540 (define_insn "subsi3_carry_zext"
6541   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6542           (zero_extend:DI
6543             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6544               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6545                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6546    (clobber (reg:CC FLAGS_REG))]
6547   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6548   "sbb{l}\t{%2, %k0|%k0, %2}"
6549   [(set_attr "type" "alu")
6550    (set_attr "pent_pair" "pu")
6551    (set_attr "mode" "SI")])
6553 (define_expand "subsi3"
6554   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6555                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6556                              (match_operand:SI 2 "general_operand" "")))
6557               (clobber (reg:CC FLAGS_REG))])]
6558   ""
6559   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6561 (define_insn "*subsi_1"
6562   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6563         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6564                   (match_operand:SI 2 "general_operand" "ri,rm")))
6565    (clobber (reg:CC FLAGS_REG))]
6566   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6567   "sub{l}\t{%2, %0|%0, %2}"
6568   [(set_attr "type" "alu")
6569    (set_attr "mode" "SI")])
6571 (define_insn "*subsi_1_zext"
6572   [(set (match_operand:DI 0 "register_operand" "=r")
6573         (zero_extend:DI
6574           (minus:SI (match_operand:SI 1 "register_operand" "0")
6575                     (match_operand:SI 2 "general_operand" "rim"))))
6576    (clobber (reg:CC FLAGS_REG))]
6577   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6578   "sub{l}\t{%2, %k0|%k0, %2}"
6579   [(set_attr "type" "alu")
6580    (set_attr "mode" "SI")])
6582 (define_insn "*subsi_2"
6583   [(set (reg FLAGS_REG)
6584         (compare
6585           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6586                     (match_operand:SI 2 "general_operand" "ri,rm"))
6587           (const_int 0)))
6588    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6589         (minus:SI (match_dup 1) (match_dup 2)))]
6590   "ix86_match_ccmode (insn, CCGOCmode)
6591    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6592   "sub{l}\t{%2, %0|%0, %2}"
6593   [(set_attr "type" "alu")
6594    (set_attr "mode" "SI")])
6596 (define_insn "*subsi_2_zext"
6597   [(set (reg FLAGS_REG)
6598         (compare
6599           (minus:SI (match_operand:SI 1 "register_operand" "0")
6600                     (match_operand:SI 2 "general_operand" "rim"))
6601           (const_int 0)))
6602    (set (match_operand:DI 0 "register_operand" "=r")
6603         (zero_extend:DI
6604           (minus:SI (match_dup 1)
6605                     (match_dup 2))))]
6606   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6607    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6608   "sub{l}\t{%2, %k0|%k0, %2}"
6609   [(set_attr "type" "alu")
6610    (set_attr "mode" "SI")])
6612 (define_insn "*subsi_3"
6613   [(set (reg FLAGS_REG)
6614         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6615                  (match_operand:SI 2 "general_operand" "ri,rm")))
6616    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617         (minus:SI (match_dup 1) (match_dup 2)))]
6618   "ix86_match_ccmode (insn, CCmode)
6619    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6620   "sub{l}\t{%2, %0|%0, %2}"
6621   [(set_attr "type" "alu")
6622    (set_attr "mode" "SI")])
6624 (define_insn "*subsi_3_zext"
6625   [(set (reg FLAGS_REG)
6626         (compare (match_operand:SI 1 "register_operand" "0")
6627                  (match_operand:SI 2 "general_operand" "rim")))
6628    (set (match_operand:DI 0 "register_operand" "=r")
6629         (zero_extend:DI
6630           (minus:SI (match_dup 1)
6631                     (match_dup 2))))]
6632   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6633    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6634   "sub{q}\t{%2, %0|%0, %2}"
6635   [(set_attr "type" "alu")
6636    (set_attr "mode" "DI")])
6638 (define_expand "subhi3"
6639   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6640                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6641                              (match_operand:HI 2 "general_operand" "")))
6642               (clobber (reg:CC FLAGS_REG))])]
6643   "TARGET_HIMODE_MATH"
6644   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6646 (define_insn "*subhi_1"
6647   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6648         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6649                   (match_operand:HI 2 "general_operand" "ri,rm")))
6650    (clobber (reg:CC FLAGS_REG))]
6651   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6652   "sub{w}\t{%2, %0|%0, %2}"
6653   [(set_attr "type" "alu")
6654    (set_attr "mode" "HI")])
6656 (define_insn "*subhi_2"
6657   [(set (reg FLAGS_REG)
6658         (compare
6659           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6660                     (match_operand:HI 2 "general_operand" "ri,rm"))
6661           (const_int 0)))
6662    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6663         (minus:HI (match_dup 1) (match_dup 2)))]
6664   "ix86_match_ccmode (insn, CCGOCmode)
6665    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6666   "sub{w}\t{%2, %0|%0, %2}"
6667   [(set_attr "type" "alu")
6668    (set_attr "mode" "HI")])
6670 (define_insn "*subhi_3"
6671   [(set (reg FLAGS_REG)
6672         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6673                  (match_operand:HI 2 "general_operand" "ri,rm")))
6674    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6675         (minus:HI (match_dup 1) (match_dup 2)))]
6676   "ix86_match_ccmode (insn, CCmode)
6677    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6678   "sub{w}\t{%2, %0|%0, %2}"
6679   [(set_attr "type" "alu")
6680    (set_attr "mode" "HI")])
6682 (define_expand "subqi3"
6683   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6684                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6685                              (match_operand:QI 2 "general_operand" "")))
6686               (clobber (reg:CC FLAGS_REG))])]
6687   "TARGET_QIMODE_MATH"
6688   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6690 (define_insn "*subqi_1"
6691   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6692         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6693                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6694    (clobber (reg:CC FLAGS_REG))]
6695   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6696   "sub{b}\t{%2, %0|%0, %2}"
6697   [(set_attr "type" "alu")
6698    (set_attr "mode" "QI")])
6700 (define_insn "*subqi_1_slp"
6701   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6702         (minus:QI (match_dup 0)
6703                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6704    (clobber (reg:CC FLAGS_REG))]
6705   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6706    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6707   "sub{b}\t{%1, %0|%0, %1}"
6708   [(set_attr "type" "alu1")
6709    (set_attr "mode" "QI")])
6711 (define_insn "*subqi_2"
6712   [(set (reg FLAGS_REG)
6713         (compare
6714           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6715                     (match_operand:QI 2 "general_operand" "qi,qm"))
6716           (const_int 0)))
6717    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6718         (minus:HI (match_dup 1) (match_dup 2)))]
6719   "ix86_match_ccmode (insn, CCGOCmode)
6720    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6721   "sub{b}\t{%2, %0|%0, %2}"
6722   [(set_attr "type" "alu")
6723    (set_attr "mode" "QI")])
6725 (define_insn "*subqi_3"
6726   [(set (reg FLAGS_REG)
6727         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6728                  (match_operand:QI 2 "general_operand" "qi,qm")))
6729    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6730         (minus:HI (match_dup 1) (match_dup 2)))]
6731   "ix86_match_ccmode (insn, CCmode)
6732    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6733   "sub{b}\t{%2, %0|%0, %2}"
6734   [(set_attr "type" "alu")
6735    (set_attr "mode" "QI")])
6737 ;; The patterns that match these are at the end of this file.
6739 (define_expand "subxf3"
6740   [(set (match_operand:XF 0 "register_operand" "")
6741         (minus:XF (match_operand:XF 1 "register_operand" "")
6742                   (match_operand:XF 2 "register_operand" "")))]
6743   "TARGET_80387"
6744   "")
6746 (define_expand "subdf3"
6747   [(set (match_operand:DF 0 "register_operand" "")
6748         (minus:DF (match_operand:DF 1 "register_operand" "")
6749                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6750   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6751   "")
6753 (define_expand "subsf3"
6754   [(set (match_operand:SF 0 "register_operand" "")
6755         (minus:SF (match_operand:SF 1 "register_operand" "")
6756                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6757   "TARGET_80387 || TARGET_SSE_MATH"
6758   "")
6760 ;; Multiply instructions
6762 (define_expand "muldi3"
6763   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6764                    (mult:DI (match_operand:DI 1 "register_operand" "")
6765                             (match_operand:DI 2 "x86_64_general_operand" "")))
6766               (clobber (reg:CC FLAGS_REG))])]
6767   "TARGET_64BIT"
6768   "")
6770 (define_insn "*muldi3_1_rex64"
6771   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6772         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6773                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6774    (clobber (reg:CC FLAGS_REG))]
6775   "TARGET_64BIT
6776    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6777   "@
6778    imul{q}\t{%2, %1, %0|%0, %1, %2}
6779    imul{q}\t{%2, %1, %0|%0, %1, %2}
6780    imul{q}\t{%2, %0|%0, %2}"
6781   [(set_attr "type" "imul")
6782    (set_attr "prefix_0f" "0,0,1")
6783    (set (attr "athlon_decode")
6784         (cond [(eq_attr "cpu" "athlon")
6785                   (const_string "vector")
6786                (eq_attr "alternative" "1")
6787                   (const_string "vector")
6788                (and (eq_attr "alternative" "2")
6789                     (match_operand 1 "memory_operand" ""))
6790                   (const_string "vector")]
6791               (const_string "direct")))
6792    (set_attr "mode" "DI")])
6794 (define_expand "mulsi3"
6795   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6796                    (mult:SI (match_operand:SI 1 "register_operand" "")
6797                             (match_operand:SI 2 "general_operand" "")))
6798               (clobber (reg:CC FLAGS_REG))])]
6799   ""
6800   "")
6802 (define_insn "*mulsi3_1"
6803   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6804         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6805                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6806    (clobber (reg:CC FLAGS_REG))]
6807   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6808   "@
6809    imul{l}\t{%2, %1, %0|%0, %1, %2}
6810    imul{l}\t{%2, %1, %0|%0, %1, %2}
6811    imul{l}\t{%2, %0|%0, %2}"
6812   [(set_attr "type" "imul")
6813    (set_attr "prefix_0f" "0,0,1")
6814    (set (attr "athlon_decode")
6815         (cond [(eq_attr "cpu" "athlon")
6816                   (const_string "vector")
6817                (eq_attr "alternative" "1")
6818                   (const_string "vector")
6819                (and (eq_attr "alternative" "2")
6820                     (match_operand 1 "memory_operand" ""))
6821                   (const_string "vector")]
6822               (const_string "direct")))
6823    (set_attr "mode" "SI")])
6825 (define_insn "*mulsi3_1_zext"
6826   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6827         (zero_extend:DI
6828           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6829                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6830    (clobber (reg:CC FLAGS_REG))]
6831   "TARGET_64BIT
6832    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6833   "@
6834    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6835    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6836    imul{l}\t{%2, %k0|%k0, %2}"
6837   [(set_attr "type" "imul")
6838    (set_attr "prefix_0f" "0,0,1")
6839    (set (attr "athlon_decode")
6840         (cond [(eq_attr "cpu" "athlon")
6841                   (const_string "vector")
6842                (eq_attr "alternative" "1")
6843                   (const_string "vector")
6844                (and (eq_attr "alternative" "2")
6845                     (match_operand 1 "memory_operand" ""))
6846                   (const_string "vector")]
6847               (const_string "direct")))
6848    (set_attr "mode" "SI")])
6850 (define_expand "mulhi3"
6851   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6852                    (mult:HI (match_operand:HI 1 "register_operand" "")
6853                             (match_operand:HI 2 "general_operand" "")))
6854               (clobber (reg:CC FLAGS_REG))])]
6855   "TARGET_HIMODE_MATH"
6856   "")
6858 (define_insn "*mulhi3_1"
6859   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6860         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6861                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6862    (clobber (reg:CC FLAGS_REG))]
6863   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6864   "@
6865    imul{w}\t{%2, %1, %0|%0, %1, %2}
6866    imul{w}\t{%2, %1, %0|%0, %1, %2}
6867    imul{w}\t{%2, %0|%0, %2}"
6868   [(set_attr "type" "imul")
6869    (set_attr "prefix_0f" "0,0,1")
6870    (set (attr "athlon_decode")
6871         (cond [(eq_attr "cpu" "athlon")
6872                   (const_string "vector")
6873                (eq_attr "alternative" "1,2")
6874                   (const_string "vector")]
6875               (const_string "direct")))
6876    (set_attr "mode" "HI")])
6878 (define_expand "mulqi3"
6879   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6880                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6881                             (match_operand:QI 2 "register_operand" "")))
6882               (clobber (reg:CC FLAGS_REG))])]
6883   "TARGET_QIMODE_MATH"
6884   "")
6886 (define_insn "*mulqi3_1"
6887   [(set (match_operand:QI 0 "register_operand" "=a")
6888         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6889                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6890    (clobber (reg:CC FLAGS_REG))]
6891   "TARGET_QIMODE_MATH
6892    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6893   "mul{b}\t%2"
6894   [(set_attr "type" "imul")
6895    (set_attr "length_immediate" "0")
6896    (set (attr "athlon_decode")
6897      (if_then_else (eq_attr "cpu" "athlon")
6898         (const_string "vector")
6899         (const_string "direct")))
6900    (set_attr "mode" "QI")])
6902 (define_expand "umulqihi3"
6903   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6904                    (mult:HI (zero_extend:HI
6905                               (match_operand:QI 1 "nonimmediate_operand" ""))
6906                             (zero_extend:HI
6907                               (match_operand:QI 2 "register_operand" ""))))
6908               (clobber (reg:CC FLAGS_REG))])]
6909   "TARGET_QIMODE_MATH"
6910   "")
6912 (define_insn "*umulqihi3_1"
6913   [(set (match_operand:HI 0 "register_operand" "=a")
6914         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6915                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "TARGET_QIMODE_MATH
6918    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6919   "mul{b}\t%2"
6920   [(set_attr "type" "imul")
6921    (set_attr "length_immediate" "0")
6922    (set (attr "athlon_decode")
6923      (if_then_else (eq_attr "cpu" "athlon")
6924         (const_string "vector")
6925         (const_string "direct")))
6926    (set_attr "mode" "QI")])
6928 (define_expand "mulqihi3"
6929   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6930                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6931                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6932               (clobber (reg:CC FLAGS_REG))])]
6933   "TARGET_QIMODE_MATH"
6934   "")
6936 (define_insn "*mulqihi3_insn"
6937   [(set (match_operand:HI 0 "register_operand" "=a")
6938         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6939                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6940    (clobber (reg:CC FLAGS_REG))]
6941   "TARGET_QIMODE_MATH
6942    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6943   "imul{b}\t%2"
6944   [(set_attr "type" "imul")
6945    (set_attr "length_immediate" "0")
6946    (set (attr "athlon_decode")
6947      (if_then_else (eq_attr "cpu" "athlon")
6948         (const_string "vector")
6949         (const_string "direct")))
6950    (set_attr "mode" "QI")])
6952 (define_expand "umulditi3"
6953   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6954                    (mult:TI (zero_extend:TI
6955                               (match_operand:DI 1 "nonimmediate_operand" ""))
6956                             (zero_extend:TI
6957                               (match_operand:DI 2 "register_operand" ""))))
6958               (clobber (reg:CC FLAGS_REG))])]
6959   "TARGET_64BIT"
6960   "")
6962 (define_insn "*umulditi3_insn"
6963   [(set (match_operand:TI 0 "register_operand" "=A")
6964         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6965                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6966    (clobber (reg:CC FLAGS_REG))]
6967   "TARGET_64BIT
6968    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6969   "mul{q}\t%2"
6970   [(set_attr "type" "imul")
6971    (set_attr "length_immediate" "0")
6972    (set (attr "athlon_decode")
6973      (if_then_else (eq_attr "cpu" "athlon")
6974         (const_string "vector")
6975         (const_string "double")))
6976    (set_attr "mode" "DI")])
6978 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6979 (define_expand "umulsidi3"
6980   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6981                    (mult:DI (zero_extend:DI
6982                               (match_operand:SI 1 "nonimmediate_operand" ""))
6983                             (zero_extend:DI
6984                               (match_operand:SI 2 "register_operand" ""))))
6985               (clobber (reg:CC FLAGS_REG))])]
6986   "!TARGET_64BIT"
6987   "")
6989 (define_insn "*umulsidi3_insn"
6990   [(set (match_operand:DI 0 "register_operand" "=A")
6991         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6992                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6993    (clobber (reg:CC FLAGS_REG))]
6994   "!TARGET_64BIT
6995    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6996   "mul{l}\t%2"
6997   [(set_attr "type" "imul")
6998    (set_attr "length_immediate" "0")
6999    (set (attr "athlon_decode")
7000      (if_then_else (eq_attr "cpu" "athlon")
7001         (const_string "vector")
7002         (const_string "double")))
7003    (set_attr "mode" "SI")])
7005 (define_expand "mulditi3"
7006   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7007                    (mult:TI (sign_extend:TI
7008                               (match_operand:DI 1 "nonimmediate_operand" ""))
7009                             (sign_extend:TI
7010                               (match_operand:DI 2 "register_operand" ""))))
7011               (clobber (reg:CC FLAGS_REG))])]
7012   "TARGET_64BIT"
7013   "")
7015 (define_insn "*mulditi3_insn"
7016   [(set (match_operand:TI 0 "register_operand" "=A")
7017         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7018                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7019    (clobber (reg:CC FLAGS_REG))]
7020   "TARGET_64BIT
7021    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7022   "imul{q}\t%2"
7023   [(set_attr "type" "imul")
7024    (set_attr "length_immediate" "0")
7025    (set (attr "athlon_decode")
7026      (if_then_else (eq_attr "cpu" "athlon")
7027         (const_string "vector")
7028         (const_string "double")))
7029    (set_attr "mode" "DI")])
7031 (define_expand "mulsidi3"
7032   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7033                    (mult:DI (sign_extend:DI
7034                               (match_operand:SI 1 "nonimmediate_operand" ""))
7035                             (sign_extend:DI
7036                               (match_operand:SI 2 "register_operand" ""))))
7037               (clobber (reg:CC FLAGS_REG))])]
7038   "!TARGET_64BIT"
7039   "")
7041 (define_insn "*mulsidi3_insn"
7042   [(set (match_operand:DI 0 "register_operand" "=A")
7043         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7044                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7045    (clobber (reg:CC FLAGS_REG))]
7046   "!TARGET_64BIT
7047    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7048   "imul{l}\t%2"
7049   [(set_attr "type" "imul")
7050    (set_attr "length_immediate" "0")
7051    (set (attr "athlon_decode")
7052      (if_then_else (eq_attr "cpu" "athlon")
7053         (const_string "vector")
7054         (const_string "double")))
7055    (set_attr "mode" "SI")])
7057 (define_expand "umuldi3_highpart"
7058   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7059                    (truncate:DI
7060                      (lshiftrt:TI
7061                        (mult:TI (zero_extend:TI
7062                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7063                                 (zero_extend:TI
7064                                   (match_operand:DI 2 "register_operand" "")))
7065                        (const_int 64))))
7066               (clobber (match_scratch:DI 3 ""))
7067               (clobber (reg:CC FLAGS_REG))])]
7068   "TARGET_64BIT"
7069   "")
7071 (define_insn "*umuldi3_highpart_rex64"
7072   [(set (match_operand:DI 0 "register_operand" "=d")
7073         (truncate:DI
7074           (lshiftrt:TI
7075             (mult:TI (zero_extend:TI
7076                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7077                      (zero_extend:TI
7078                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7079             (const_int 64))))
7080    (clobber (match_scratch:DI 3 "=1"))
7081    (clobber (reg:CC FLAGS_REG))]
7082   "TARGET_64BIT
7083    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7084   "mul{q}\t%2"
7085   [(set_attr "type" "imul")
7086    (set_attr "length_immediate" "0")
7087    (set (attr "athlon_decode")
7088      (if_then_else (eq_attr "cpu" "athlon")
7089         (const_string "vector")
7090         (const_string "double")))
7091    (set_attr "mode" "DI")])
7093 (define_expand "umulsi3_highpart"
7094   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7095                    (truncate:SI
7096                      (lshiftrt:DI
7097                        (mult:DI (zero_extend:DI
7098                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7099                                 (zero_extend:DI
7100                                   (match_operand:SI 2 "register_operand" "")))
7101                        (const_int 32))))
7102               (clobber (match_scratch:SI 3 ""))
7103               (clobber (reg:CC FLAGS_REG))])]
7104   ""
7105   "")
7107 (define_insn "*umulsi3_highpart_insn"
7108   [(set (match_operand:SI 0 "register_operand" "=d")
7109         (truncate:SI
7110           (lshiftrt:DI
7111             (mult:DI (zero_extend:DI
7112                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7113                      (zero_extend:DI
7114                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7115             (const_int 32))))
7116    (clobber (match_scratch:SI 3 "=1"))
7117    (clobber (reg:CC FLAGS_REG))]
7118   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7119   "mul{l}\t%2"
7120   [(set_attr "type" "imul")
7121    (set_attr "length_immediate" "0")
7122    (set (attr "athlon_decode")
7123      (if_then_else (eq_attr "cpu" "athlon")
7124         (const_string "vector")
7125         (const_string "double")))
7126    (set_attr "mode" "SI")])
7128 (define_insn "*umulsi3_highpart_zext"
7129   [(set (match_operand:DI 0 "register_operand" "=d")
7130         (zero_extend:DI (truncate:SI
7131           (lshiftrt:DI
7132             (mult:DI (zero_extend:DI
7133                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7134                      (zero_extend:DI
7135                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7136             (const_int 32)))))
7137    (clobber (match_scratch:SI 3 "=1"))
7138    (clobber (reg:CC FLAGS_REG))]
7139   "TARGET_64BIT
7140    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7141   "mul{l}\t%2"
7142   [(set_attr "type" "imul")
7143    (set_attr "length_immediate" "0")
7144    (set (attr "athlon_decode")
7145      (if_then_else (eq_attr "cpu" "athlon")
7146         (const_string "vector")
7147         (const_string "double")))
7148    (set_attr "mode" "SI")])
7150 (define_expand "smuldi3_highpart"
7151   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7152                    (truncate:DI
7153                      (lshiftrt:TI
7154                        (mult:TI (sign_extend:TI
7155                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7156                                 (sign_extend:TI
7157                                   (match_operand:DI 2 "register_operand" "")))
7158                        (const_int 64))))
7159               (clobber (match_scratch:DI 3 ""))
7160               (clobber (reg:CC FLAGS_REG))])]
7161   "TARGET_64BIT"
7162   "")
7164 (define_insn "*smuldi3_highpart_rex64"
7165   [(set (match_operand:DI 0 "register_operand" "=d")
7166         (truncate:DI
7167           (lshiftrt:TI
7168             (mult:TI (sign_extend:TI
7169                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7170                      (sign_extend:TI
7171                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7172             (const_int 64))))
7173    (clobber (match_scratch:DI 3 "=1"))
7174    (clobber (reg:CC FLAGS_REG))]
7175   "TARGET_64BIT
7176    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7177   "imul{q}\t%2"
7178   [(set_attr "type" "imul")
7179    (set (attr "athlon_decode")
7180      (if_then_else (eq_attr "cpu" "athlon")
7181         (const_string "vector")
7182         (const_string "double")))
7183    (set_attr "mode" "DI")])
7185 (define_expand "smulsi3_highpart"
7186   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7187                    (truncate:SI
7188                      (lshiftrt:DI
7189                        (mult:DI (sign_extend:DI
7190                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7191                                 (sign_extend:DI
7192                                   (match_operand:SI 2 "register_operand" "")))
7193                        (const_int 32))))
7194               (clobber (match_scratch:SI 3 ""))
7195               (clobber (reg:CC FLAGS_REG))])]
7196   ""
7197   "")
7199 (define_insn "*smulsi3_highpart_insn"
7200   [(set (match_operand:SI 0 "register_operand" "=d")
7201         (truncate:SI
7202           (lshiftrt:DI
7203             (mult:DI (sign_extend:DI
7204                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7205                      (sign_extend:DI
7206                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7207             (const_int 32))))
7208    (clobber (match_scratch:SI 3 "=1"))
7209    (clobber (reg:CC FLAGS_REG))]
7210   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7211   "imul{l}\t%2"
7212   [(set_attr "type" "imul")
7213    (set (attr "athlon_decode")
7214      (if_then_else (eq_attr "cpu" "athlon")
7215         (const_string "vector")
7216         (const_string "double")))
7217    (set_attr "mode" "SI")])
7219 (define_insn "*smulsi3_highpart_zext"
7220   [(set (match_operand:DI 0 "register_operand" "=d")
7221         (zero_extend:DI (truncate:SI
7222           (lshiftrt:DI
7223             (mult:DI (sign_extend:DI
7224                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7225                      (sign_extend:DI
7226                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7227             (const_int 32)))))
7228    (clobber (match_scratch:SI 3 "=1"))
7229    (clobber (reg:CC FLAGS_REG))]
7230   "TARGET_64BIT
7231    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7232   "imul{l}\t%2"
7233   [(set_attr "type" "imul")
7234    (set (attr "athlon_decode")
7235      (if_then_else (eq_attr "cpu" "athlon")
7236         (const_string "vector")
7237         (const_string "double")))
7238    (set_attr "mode" "SI")])
7240 ;; The patterns that match these are at the end of this file.
7242 (define_expand "mulxf3"
7243   [(set (match_operand:XF 0 "register_operand" "")
7244         (mult:XF (match_operand:XF 1 "register_operand" "")
7245                  (match_operand:XF 2 "register_operand" "")))]
7246   "TARGET_80387"
7247   "")
7249 (define_expand "muldf3"
7250   [(set (match_operand:DF 0 "register_operand" "")
7251         (mult:DF (match_operand:DF 1 "register_operand" "")
7252                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7253   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7254   "")
7256 (define_expand "mulsf3"
7257   [(set (match_operand:SF 0 "register_operand" "")
7258         (mult:SF (match_operand:SF 1 "register_operand" "")
7259                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7260   "TARGET_80387 || TARGET_SSE_MATH"
7261   "")
7263 ;; Divide instructions
7265 (define_insn "divqi3"
7266   [(set (match_operand:QI 0 "register_operand" "=a")
7267         (div:QI (match_operand:HI 1 "register_operand" "0")
7268                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7269    (clobber (reg:CC FLAGS_REG))]
7270   "TARGET_QIMODE_MATH"
7271   "idiv{b}\t%2"
7272   [(set_attr "type" "idiv")
7273    (set_attr "mode" "QI")])
7275 (define_insn "udivqi3"
7276   [(set (match_operand:QI 0 "register_operand" "=a")
7277         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7278                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7279    (clobber (reg:CC FLAGS_REG))]
7280   "TARGET_QIMODE_MATH"
7281   "div{b}\t%2"
7282   [(set_attr "type" "idiv")
7283    (set_attr "mode" "QI")])
7285 ;; The patterns that match these are at the end of this file.
7287 (define_expand "divxf3"
7288   [(set (match_operand:XF 0 "register_operand" "")
7289         (div:XF (match_operand:XF 1 "register_operand" "")
7290                 (match_operand:XF 2 "register_operand" "")))]
7291   "TARGET_80387"
7292   "")
7294 (define_expand "divdf3"
7295   [(set (match_operand:DF 0 "register_operand" "")
7296         (div:DF (match_operand:DF 1 "register_operand" "")
7297                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7298    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7299    "")
7301 (define_expand "divsf3"
7302   [(set (match_operand:SF 0 "register_operand" "")
7303         (div:SF (match_operand:SF 1 "register_operand" "")
7304                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7305   "TARGET_80387 || TARGET_SSE_MATH"
7306   "")
7308 ;; Remainder instructions.
7310 (define_expand "divmoddi4"
7311   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7312                    (div:DI (match_operand:DI 1 "register_operand" "")
7313                            (match_operand:DI 2 "nonimmediate_operand" "")))
7314               (set (match_operand:DI 3 "register_operand" "")
7315                    (mod:DI (match_dup 1) (match_dup 2)))
7316               (clobber (reg:CC FLAGS_REG))])]
7317   "TARGET_64BIT"
7318   "")
7320 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7321 ;; Penalize eax case slightly because it results in worse scheduling
7322 ;; of code.
7323 (define_insn "*divmoddi4_nocltd_rex64"
7324   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7325         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7326                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7327    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7328         (mod:DI (match_dup 2) (match_dup 3)))
7329    (clobber (reg:CC FLAGS_REG))]
7330   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7331   "#"
7332   [(set_attr "type" "multi")])
7334 (define_insn "*divmoddi4_cltd_rex64"
7335   [(set (match_operand:DI 0 "register_operand" "=a")
7336         (div:DI (match_operand:DI 2 "register_operand" "a")
7337                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7338    (set (match_operand:DI 1 "register_operand" "=&d")
7339         (mod:DI (match_dup 2) (match_dup 3)))
7340    (clobber (reg:CC FLAGS_REG))]
7341   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7342   "#"
7343   [(set_attr "type" "multi")])
7345 (define_insn "*divmoddi_noext_rex64"
7346   [(set (match_operand:DI 0 "register_operand" "=a")
7347         (div:DI (match_operand:DI 1 "register_operand" "0")
7348                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7349    (set (match_operand:DI 3 "register_operand" "=d")
7350         (mod:DI (match_dup 1) (match_dup 2)))
7351    (use (match_operand:DI 4 "register_operand" "3"))
7352    (clobber (reg:CC FLAGS_REG))]
7353   "TARGET_64BIT"
7354   "idiv{q}\t%2"
7355   [(set_attr "type" "idiv")
7356    (set_attr "mode" "DI")])
7358 (define_split
7359   [(set (match_operand:DI 0 "register_operand" "")
7360         (div:DI (match_operand:DI 1 "register_operand" "")
7361                 (match_operand:DI 2 "nonimmediate_operand" "")))
7362    (set (match_operand:DI 3 "register_operand" "")
7363         (mod:DI (match_dup 1) (match_dup 2)))
7364    (clobber (reg:CC FLAGS_REG))]
7365   "TARGET_64BIT && reload_completed"
7366   [(parallel [(set (match_dup 3)
7367                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7368               (clobber (reg:CC FLAGS_REG))])
7369    (parallel [(set (match_dup 0)
7370                    (div:DI (reg:DI 0) (match_dup 2)))
7371               (set (match_dup 3)
7372                    (mod:DI (reg:DI 0) (match_dup 2)))
7373               (use (match_dup 3))
7374               (clobber (reg:CC FLAGS_REG))])]
7376   /* Avoid use of cltd in favor of a mov+shift.  */
7377   if (!TARGET_USE_CLTD && !optimize_size)
7378     {
7379       if (true_regnum (operands[1]))
7380         emit_move_insn (operands[0], operands[1]);
7381       else
7382         emit_move_insn (operands[3], operands[1]);
7383       operands[4] = operands[3];
7384     }
7385   else
7386     {
7387       if (true_regnum (operands[1]))
7388         abort();
7389       operands[4] = operands[1];
7390     }
7394 (define_expand "divmodsi4"
7395   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7396                    (div:SI (match_operand:SI 1 "register_operand" "")
7397                            (match_operand:SI 2 "nonimmediate_operand" "")))
7398               (set (match_operand:SI 3 "register_operand" "")
7399                    (mod:SI (match_dup 1) (match_dup 2)))
7400               (clobber (reg:CC FLAGS_REG))])]
7401   ""
7402   "")
7404 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7405 ;; Penalize eax case slightly because it results in worse scheduling
7406 ;; of code.
7407 (define_insn "*divmodsi4_nocltd"
7408   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7409         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7410                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7411    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7412         (mod:SI (match_dup 2) (match_dup 3)))
7413    (clobber (reg:CC FLAGS_REG))]
7414   "!optimize_size && !TARGET_USE_CLTD"
7415   "#"
7416   [(set_attr "type" "multi")])
7418 (define_insn "*divmodsi4_cltd"
7419   [(set (match_operand:SI 0 "register_operand" "=a")
7420         (div:SI (match_operand:SI 2 "register_operand" "a")
7421                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7422    (set (match_operand:SI 1 "register_operand" "=&d")
7423         (mod:SI (match_dup 2) (match_dup 3)))
7424    (clobber (reg:CC FLAGS_REG))]
7425   "optimize_size || TARGET_USE_CLTD"
7426   "#"
7427   [(set_attr "type" "multi")])
7429 (define_insn "*divmodsi_noext"
7430   [(set (match_operand:SI 0 "register_operand" "=a")
7431         (div:SI (match_operand:SI 1 "register_operand" "0")
7432                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7433    (set (match_operand:SI 3 "register_operand" "=d")
7434         (mod:SI (match_dup 1) (match_dup 2)))
7435    (use (match_operand:SI 4 "register_operand" "3"))
7436    (clobber (reg:CC FLAGS_REG))]
7437   ""
7438   "idiv{l}\t%2"
7439   [(set_attr "type" "idiv")
7440    (set_attr "mode" "SI")])
7442 (define_split
7443   [(set (match_operand:SI 0 "register_operand" "")
7444         (div:SI (match_operand:SI 1 "register_operand" "")
7445                 (match_operand:SI 2 "nonimmediate_operand" "")))
7446    (set (match_operand:SI 3 "register_operand" "")
7447         (mod:SI (match_dup 1) (match_dup 2)))
7448    (clobber (reg:CC FLAGS_REG))]
7449   "reload_completed"
7450   [(parallel [(set (match_dup 3)
7451                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7452               (clobber (reg:CC FLAGS_REG))])
7453    (parallel [(set (match_dup 0)
7454                    (div:SI (reg:SI 0) (match_dup 2)))
7455               (set (match_dup 3)
7456                    (mod:SI (reg:SI 0) (match_dup 2)))
7457               (use (match_dup 3))
7458               (clobber (reg:CC FLAGS_REG))])]
7460   /* Avoid use of cltd in favor of a mov+shift.  */
7461   if (!TARGET_USE_CLTD && !optimize_size)
7462     {
7463       if (true_regnum (operands[1]))
7464         emit_move_insn (operands[0], operands[1]);
7465       else
7466         emit_move_insn (operands[3], operands[1]);
7467       operands[4] = operands[3];
7468     }
7469   else
7470     {
7471       if (true_regnum (operands[1]))
7472         abort();
7473       operands[4] = operands[1];
7474     }
7476 ;; %%% Split me.
7477 (define_insn "divmodhi4"
7478   [(set (match_operand:HI 0 "register_operand" "=a")
7479         (div:HI (match_operand:HI 1 "register_operand" "0")
7480                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7481    (set (match_operand:HI 3 "register_operand" "=&d")
7482         (mod:HI (match_dup 1) (match_dup 2)))
7483    (clobber (reg:CC FLAGS_REG))]
7484   "TARGET_HIMODE_MATH"
7485   "cwtd\;idiv{w}\t%2"
7486   [(set_attr "type" "multi")
7487    (set_attr "length_immediate" "0")
7488    (set_attr "mode" "SI")])
7490 (define_insn "udivmoddi4"
7491   [(set (match_operand:DI 0 "register_operand" "=a")
7492         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7493                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7494    (set (match_operand:DI 3 "register_operand" "=&d")
7495         (umod:DI (match_dup 1) (match_dup 2)))
7496    (clobber (reg:CC FLAGS_REG))]
7497   "TARGET_64BIT"
7498   "xor{q}\t%3, %3\;div{q}\t%2"
7499   [(set_attr "type" "multi")
7500    (set_attr "length_immediate" "0")
7501    (set_attr "mode" "DI")])
7503 (define_insn "*udivmoddi4_noext"
7504   [(set (match_operand:DI 0 "register_operand" "=a")
7505         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7506                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7507    (set (match_operand:DI 3 "register_operand" "=d")
7508         (umod:DI (match_dup 1) (match_dup 2)))
7509    (use (match_dup 3))
7510    (clobber (reg:CC FLAGS_REG))]
7511   "TARGET_64BIT"
7512   "div{q}\t%2"
7513   [(set_attr "type" "idiv")
7514    (set_attr "mode" "DI")])
7516 (define_split
7517   [(set (match_operand:DI 0 "register_operand" "")
7518         (udiv:DI (match_operand:DI 1 "register_operand" "")
7519                  (match_operand:DI 2 "nonimmediate_operand" "")))
7520    (set (match_operand:DI 3 "register_operand" "")
7521         (umod:DI (match_dup 1) (match_dup 2)))
7522    (clobber (reg:CC FLAGS_REG))]
7523   "TARGET_64BIT && reload_completed"
7524   [(set (match_dup 3) (const_int 0))
7525    (parallel [(set (match_dup 0)
7526                    (udiv:DI (match_dup 1) (match_dup 2)))
7527               (set (match_dup 3)
7528                    (umod:DI (match_dup 1) (match_dup 2)))
7529               (use (match_dup 3))
7530               (clobber (reg:CC FLAGS_REG))])]
7531   "")
7533 (define_insn "udivmodsi4"
7534   [(set (match_operand:SI 0 "register_operand" "=a")
7535         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7536                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7537    (set (match_operand:SI 3 "register_operand" "=&d")
7538         (umod:SI (match_dup 1) (match_dup 2)))
7539    (clobber (reg:CC FLAGS_REG))]
7540   ""
7541   "xor{l}\t%3, %3\;div{l}\t%2"
7542   [(set_attr "type" "multi")
7543    (set_attr "length_immediate" "0")
7544    (set_attr "mode" "SI")])
7546 (define_insn "*udivmodsi4_noext"
7547   [(set (match_operand:SI 0 "register_operand" "=a")
7548         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7549                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7550    (set (match_operand:SI 3 "register_operand" "=d")
7551         (umod:SI (match_dup 1) (match_dup 2)))
7552    (use (match_dup 3))
7553    (clobber (reg:CC FLAGS_REG))]
7554   ""
7555   "div{l}\t%2"
7556   [(set_attr "type" "idiv")
7557    (set_attr "mode" "SI")])
7559 (define_split
7560   [(set (match_operand:SI 0 "register_operand" "")
7561         (udiv:SI (match_operand:SI 1 "register_operand" "")
7562                  (match_operand:SI 2 "nonimmediate_operand" "")))
7563    (set (match_operand:SI 3 "register_operand" "")
7564         (umod:SI (match_dup 1) (match_dup 2)))
7565    (clobber (reg:CC FLAGS_REG))]
7566   "reload_completed"
7567   [(set (match_dup 3) (const_int 0))
7568    (parallel [(set (match_dup 0)
7569                    (udiv:SI (match_dup 1) (match_dup 2)))
7570               (set (match_dup 3)
7571                    (umod:SI (match_dup 1) (match_dup 2)))
7572               (use (match_dup 3))
7573               (clobber (reg:CC FLAGS_REG))])]
7574   "")
7576 (define_expand "udivmodhi4"
7577   [(set (match_dup 4) (const_int 0))
7578    (parallel [(set (match_operand:HI 0 "register_operand" "")
7579                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7580                             (match_operand:HI 2 "nonimmediate_operand" "")))
7581               (set (match_operand:HI 3 "register_operand" "")
7582                    (umod:HI (match_dup 1) (match_dup 2)))
7583               (use (match_dup 4))
7584               (clobber (reg:CC FLAGS_REG))])]
7585   "TARGET_HIMODE_MATH"
7586   "operands[4] = gen_reg_rtx (HImode);")
7588 (define_insn "*udivmodhi_noext"
7589   [(set (match_operand:HI 0 "register_operand" "=a")
7590         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7591                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7592    (set (match_operand:HI 3 "register_operand" "=d")
7593         (umod:HI (match_dup 1) (match_dup 2)))
7594    (use (match_operand:HI 4 "register_operand" "3"))
7595    (clobber (reg:CC FLAGS_REG))]
7596   ""
7597   "div{w}\t%2"
7598   [(set_attr "type" "idiv")
7599    (set_attr "mode" "HI")])
7601 ;; We cannot use div/idiv for double division, because it causes
7602 ;; "division by zero" on the overflow and that's not what we expect
7603 ;; from truncate.  Because true (non truncating) double division is
7604 ;; never generated, we can't create this insn anyway.
7606 ;(define_insn ""
7607 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7608 ;       (truncate:SI
7609 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7610 ;                  (zero_extend:DI
7611 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7612 ;   (set (match_operand:SI 3 "register_operand" "=d")
7613 ;       (truncate:SI
7614 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7615 ;   (clobber (reg:CC FLAGS_REG))]
7616 ;  ""
7617 ;  "div{l}\t{%2, %0|%0, %2}"
7618 ;  [(set_attr "type" "idiv")])
7620 ;;- Logical AND instructions
7622 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7623 ;; Note that this excludes ah.
7625 (define_insn "*testdi_1_rex64"
7626   [(set (reg FLAGS_REG)
7627         (compare
7628           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7629                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7630           (const_int 0)))]
7631   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7632    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7633   "@
7634    test{l}\t{%k1, %k0|%k0, %k1}
7635    test{l}\t{%k1, %k0|%k0, %k1}
7636    test{q}\t{%1, %0|%0, %1}
7637    test{q}\t{%1, %0|%0, %1}
7638    test{q}\t{%1, %0|%0, %1}"
7639   [(set_attr "type" "test")
7640    (set_attr "modrm" "0,1,0,1,1")
7641    (set_attr "mode" "SI,SI,DI,DI,DI")
7642    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7644 (define_insn "testsi_1"
7645   [(set (reg FLAGS_REG)
7646         (compare
7647           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7648                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7649           (const_int 0)))]
7650   "ix86_match_ccmode (insn, CCNOmode)
7651    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7652   "test{l}\t{%1, %0|%0, %1}"
7653   [(set_attr "type" "test")
7654    (set_attr "modrm" "0,1,1")
7655    (set_attr "mode" "SI")
7656    (set_attr "pent_pair" "uv,np,uv")])
7658 (define_expand "testsi_ccno_1"
7659   [(set (reg:CCNO FLAGS_REG)
7660         (compare:CCNO
7661           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7662                   (match_operand:SI 1 "nonmemory_operand" ""))
7663           (const_int 0)))]
7664   ""
7665   "")
7667 (define_insn "*testhi_1"
7668   [(set (reg FLAGS_REG)
7669         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7670                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7671                  (const_int 0)))]
7672   "ix86_match_ccmode (insn, CCNOmode)
7673    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7674   "test{w}\t{%1, %0|%0, %1}"
7675   [(set_attr "type" "test")
7676    (set_attr "modrm" "0,1,1")
7677    (set_attr "mode" "HI")
7678    (set_attr "pent_pair" "uv,np,uv")])
7680 (define_expand "testqi_ccz_1"
7681   [(set (reg:CCZ FLAGS_REG)
7682         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7683                              (match_operand:QI 1 "nonmemory_operand" ""))
7684                  (const_int 0)))]
7685   ""
7686   "")
7688 (define_insn "*testqi_1_maybe_si"
7689   [(set (reg FLAGS_REG)
7690         (compare
7691           (and:QI
7692             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7693             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7694           (const_int 0)))]
7695    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7696     && ix86_match_ccmode (insn,
7697                          GET_CODE (operands[1]) == CONST_INT
7698                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7700   if (which_alternative == 3)
7701     {
7702       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7703         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7704       return "test{l}\t{%1, %k0|%k0, %1}";
7705     }
7706   return "test{b}\t{%1, %0|%0, %1}";
7708   [(set_attr "type" "test")
7709    (set_attr "modrm" "0,1,1,1")
7710    (set_attr "mode" "QI,QI,QI,SI")
7711    (set_attr "pent_pair" "uv,np,uv,np")])
7713 (define_insn "*testqi_1"
7714   [(set (reg FLAGS_REG)
7715         (compare
7716           (and:QI
7717             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7718             (match_operand:QI 1 "general_operand" "n,n,qn"))
7719           (const_int 0)))]
7720   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7721    && ix86_match_ccmode (insn, CCNOmode)"
7722   "test{b}\t{%1, %0|%0, %1}"
7723   [(set_attr "type" "test")
7724    (set_attr "modrm" "0,1,1")
7725    (set_attr "mode" "QI")
7726    (set_attr "pent_pair" "uv,np,uv")])
7728 (define_expand "testqi_ext_ccno_0"
7729   [(set (reg:CCNO FLAGS_REG)
7730         (compare:CCNO
7731           (and:SI
7732             (zero_extract:SI
7733               (match_operand 0 "ext_register_operand" "")
7734               (const_int 8)
7735               (const_int 8))
7736             (match_operand 1 "const_int_operand" ""))
7737           (const_int 0)))]
7738   ""
7739   "")
7741 (define_insn "*testqi_ext_0"
7742   [(set (reg FLAGS_REG)
7743         (compare
7744           (and:SI
7745             (zero_extract:SI
7746               (match_operand 0 "ext_register_operand" "Q")
7747               (const_int 8)
7748               (const_int 8))
7749             (match_operand 1 "const_int_operand" "n"))
7750           (const_int 0)))]
7751   "ix86_match_ccmode (insn, CCNOmode)"
7752   "test{b}\t{%1, %h0|%h0, %1}"
7753   [(set_attr "type" "test")
7754    (set_attr "mode" "QI")
7755    (set_attr "length_immediate" "1")
7756    (set_attr "pent_pair" "np")])
7758 (define_insn "*testqi_ext_1"
7759   [(set (reg FLAGS_REG)
7760         (compare
7761           (and:SI
7762             (zero_extract:SI
7763               (match_operand 0 "ext_register_operand" "Q")
7764               (const_int 8)
7765               (const_int 8))
7766             (zero_extend:SI
7767               (match_operand:QI 1 "general_operand" "Qm")))
7768           (const_int 0)))]
7769   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7770    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7771   "test{b}\t{%1, %h0|%h0, %1}"
7772   [(set_attr "type" "test")
7773    (set_attr "mode" "QI")])
7775 (define_insn "*testqi_ext_1_rex64"
7776   [(set (reg FLAGS_REG)
7777         (compare
7778           (and:SI
7779             (zero_extract:SI
7780               (match_operand 0 "ext_register_operand" "Q")
7781               (const_int 8)
7782               (const_int 8))
7783             (zero_extend:SI
7784               (match_operand:QI 1 "register_operand" "Q")))
7785           (const_int 0)))]
7786   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7787   "test{b}\t{%1, %h0|%h0, %1}"
7788   [(set_attr "type" "test")
7789    (set_attr "mode" "QI")])
7791 (define_insn "*testqi_ext_2"
7792   [(set (reg FLAGS_REG)
7793         (compare
7794           (and:SI
7795             (zero_extract:SI
7796               (match_operand 0 "ext_register_operand" "Q")
7797               (const_int 8)
7798               (const_int 8))
7799             (zero_extract:SI
7800               (match_operand 1 "ext_register_operand" "Q")
7801               (const_int 8)
7802               (const_int 8)))
7803           (const_int 0)))]
7804   "ix86_match_ccmode (insn, CCNOmode)"
7805   "test{b}\t{%h1, %h0|%h0, %h1}"
7806   [(set_attr "type" "test")
7807    (set_attr "mode" "QI")])
7809 ;; Combine likes to form bit extractions for some tests.  Humor it.
7810 (define_insn "*testqi_ext_3"
7811   [(set (reg FLAGS_REG)
7812         (compare (zero_extract:SI
7813                    (match_operand 0 "nonimmediate_operand" "rm")
7814                    (match_operand:SI 1 "const_int_operand" "")
7815                    (match_operand:SI 2 "const_int_operand" ""))
7816                  (const_int 0)))]
7817   "ix86_match_ccmode (insn, CCNOmode)
7818    && (GET_MODE (operands[0]) == SImode
7819        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7820        || GET_MODE (operands[0]) == HImode
7821        || GET_MODE (operands[0]) == QImode)"
7822   "#")
7824 (define_insn "*testqi_ext_3_rex64"
7825   [(set (reg FLAGS_REG)
7826         (compare (zero_extract:DI
7827                    (match_operand 0 "nonimmediate_operand" "rm")
7828                    (match_operand:DI 1 "const_int_operand" "")
7829                    (match_operand:DI 2 "const_int_operand" ""))
7830                  (const_int 0)))]
7831   "TARGET_64BIT
7832    && ix86_match_ccmode (insn, CCNOmode)
7833    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7834    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7835    /* Ensure that resulting mask is zero or sign extended operand.  */
7836    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7837        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7838            && INTVAL (operands[1]) > 32))
7839    && (GET_MODE (operands[0]) == SImode
7840        || GET_MODE (operands[0]) == DImode
7841        || GET_MODE (operands[0]) == HImode
7842        || GET_MODE (operands[0]) == QImode)"
7843   "#")
7845 (define_split
7846   [(set (match_operand 0 "flags_reg_operand" "")
7847         (match_operator 1 "compare_operator"
7848           [(zero_extract
7849              (match_operand 2 "nonimmediate_operand" "")
7850              (match_operand 3 "const_int_operand" "")
7851              (match_operand 4 "const_int_operand" ""))
7852            (const_int 0)]))]
7853   "ix86_match_ccmode (insn, CCNOmode)"
7854   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7856   rtx val = operands[2];
7857   HOST_WIDE_INT len = INTVAL (operands[3]);
7858   HOST_WIDE_INT pos = INTVAL (operands[4]);
7859   HOST_WIDE_INT mask;
7860   enum machine_mode mode, submode;
7862   mode = GET_MODE (val);
7863   if (GET_CODE (val) == MEM)
7864     {
7865       /* ??? Combine likes to put non-volatile mem extractions in QImode
7866          no matter the size of the test.  So find a mode that works.  */
7867       if (! MEM_VOLATILE_P (val))
7868         {
7869           mode = smallest_mode_for_size (pos + len, MODE_INT);
7870           val = adjust_address (val, mode, 0);
7871         }
7872     }
7873   else if (GET_CODE (val) == SUBREG
7874            && (submode = GET_MODE (SUBREG_REG (val)),
7875                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7876            && pos + len <= GET_MODE_BITSIZE (submode))
7877     {
7878       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7879       mode = submode;
7880       val = SUBREG_REG (val);
7881     }
7882   else if (mode == HImode && pos + len <= 8)
7883     {
7884       /* Small HImode tests can be converted to QImode.  */
7885       mode = QImode;
7886       val = gen_lowpart (QImode, val);
7887     }
7889   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7890   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7892   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7895 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7896 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7897 ;; this is relatively important trick.
7898 ;; Do the conversion only post-reload to avoid limiting of the register class
7899 ;; to QI regs.
7900 (define_split
7901   [(set (match_operand 0 "flags_reg_operand" "")
7902         (match_operator 1 "compare_operator"
7903           [(and (match_operand 2 "register_operand" "")
7904                 (match_operand 3 "const_int_operand" ""))
7905            (const_int 0)]))]
7906    "reload_completed
7907     && QI_REG_P (operands[2])
7908     && GET_MODE (operands[2]) != QImode
7909     && ((ix86_match_ccmode (insn, CCZmode)
7910          && !(INTVAL (operands[3]) & ~(255 << 8)))
7911         || (ix86_match_ccmode (insn, CCNOmode)
7912             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7913   [(set (match_dup 0)
7914         (match_op_dup 1
7915           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7916                    (match_dup 3))
7917            (const_int 0)]))]
7918   "operands[2] = gen_lowpart (SImode, operands[2]);
7919    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7921 (define_split
7922   [(set (match_operand 0 "flags_reg_operand" "")
7923         (match_operator 1 "compare_operator"
7924           [(and (match_operand 2 "nonimmediate_operand" "")
7925                 (match_operand 3 "const_int_operand" ""))
7926            (const_int 0)]))]
7927    "reload_completed
7928     && GET_MODE (operands[2]) != QImode
7929     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7930     && ((ix86_match_ccmode (insn, CCZmode)
7931          && !(INTVAL (operands[3]) & ~255))
7932         || (ix86_match_ccmode (insn, CCNOmode)
7933             && !(INTVAL (operands[3]) & ~127)))"
7934   [(set (match_dup 0)
7935         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7936                          (const_int 0)]))]
7937   "operands[2] = gen_lowpart (QImode, operands[2]);
7938    operands[3] = gen_lowpart (QImode, operands[3]);")
7941 ;; %%% This used to optimize known byte-wide and operations to memory,
7942 ;; and sometimes to QImode registers.  If this is considered useful,
7943 ;; it should be done with splitters.
7945 (define_expand "anddi3"
7946   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7947         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7948                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7949    (clobber (reg:CC FLAGS_REG))]
7950   "TARGET_64BIT"
7951   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7953 (define_insn "*anddi_1_rex64"
7954   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7955         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7956                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7957    (clobber (reg:CC FLAGS_REG))]
7958   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7960   switch (get_attr_type (insn))
7961     {
7962     case TYPE_IMOVX:
7963       {
7964         enum machine_mode mode;
7966         if (GET_CODE (operands[2]) != CONST_INT)
7967           abort ();
7968         if (INTVAL (operands[2]) == 0xff)
7969           mode = QImode;
7970         else if (INTVAL (operands[2]) == 0xffff)
7971           mode = HImode;
7972         else
7973           abort ();
7974         
7975         operands[1] = gen_lowpart (mode, operands[1]);
7976         if (mode == QImode)
7977           return "movz{bq|x}\t{%1,%0|%0, %1}";
7978         else
7979           return "movz{wq|x}\t{%1,%0|%0, %1}";
7980       }
7982     default:
7983       if (! rtx_equal_p (operands[0], operands[1]))
7984         abort ();
7985       if (get_attr_mode (insn) == MODE_SI)
7986         return "and{l}\t{%k2, %k0|%k0, %k2}";
7987       else
7988         return "and{q}\t{%2, %0|%0, %2}";
7989     }
7991   [(set_attr "type" "alu,alu,alu,imovx")
7992    (set_attr "length_immediate" "*,*,*,0")
7993    (set_attr "mode" "SI,DI,DI,DI")])
7995 (define_insn "*anddi_2"
7996   [(set (reg FLAGS_REG)
7997         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7998                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7999                  (const_int 0)))
8000    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8001         (and:DI (match_dup 1) (match_dup 2)))]
8002   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8003    && ix86_binary_operator_ok (AND, DImode, operands)"
8004   "@
8005    and{l}\t{%k2, %k0|%k0, %k2}
8006    and{q}\t{%2, %0|%0, %2}
8007    and{q}\t{%2, %0|%0, %2}"
8008   [(set_attr "type" "alu")
8009    (set_attr "mode" "SI,DI,DI")])
8011 (define_expand "andsi3"
8012   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8013         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8014                 (match_operand:SI 2 "general_operand" "")))
8015    (clobber (reg:CC FLAGS_REG))]
8016   ""
8017   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8019 (define_insn "*andsi_1"
8020   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8021         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8022                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8023    (clobber (reg:CC FLAGS_REG))]
8024   "ix86_binary_operator_ok (AND, SImode, operands)"
8026   switch (get_attr_type (insn))
8027     {
8028     case TYPE_IMOVX:
8029       {
8030         enum machine_mode mode;
8032         if (GET_CODE (operands[2]) != CONST_INT)
8033           abort ();
8034         if (INTVAL (operands[2]) == 0xff)
8035           mode = QImode;
8036         else if (INTVAL (operands[2]) == 0xffff)
8037           mode = HImode;
8038         else
8039           abort ();
8040         
8041         operands[1] = gen_lowpart (mode, operands[1]);
8042         if (mode == QImode)
8043           return "movz{bl|x}\t{%1,%0|%0, %1}";
8044         else
8045           return "movz{wl|x}\t{%1,%0|%0, %1}";
8046       }
8048     default:
8049       if (! rtx_equal_p (operands[0], operands[1]))
8050         abort ();
8051       return "and{l}\t{%2, %0|%0, %2}";
8052     }
8054   [(set_attr "type" "alu,alu,imovx")
8055    (set_attr "length_immediate" "*,*,0")
8056    (set_attr "mode" "SI")])
8058 (define_split
8059   [(set (match_operand 0 "register_operand" "")
8060         (and (match_dup 0)
8061              (const_int -65536)))
8062    (clobber (reg:CC FLAGS_REG))]
8063   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8064   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8065   "operands[1] = gen_lowpart (HImode, operands[0]);")
8067 (define_split
8068   [(set (match_operand 0 "ext_register_operand" "")
8069         (and (match_dup 0)
8070              (const_int -256)))
8071    (clobber (reg:CC FLAGS_REG))]
8072   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8073   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8074   "operands[1] = gen_lowpart (QImode, operands[0]);")
8076 (define_split
8077   [(set (match_operand 0 "ext_register_operand" "")
8078         (and (match_dup 0)
8079              (const_int -65281)))
8080    (clobber (reg:CC FLAGS_REG))]
8081   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8082   [(parallel [(set (zero_extract:SI (match_dup 0)
8083                                     (const_int 8)
8084                                     (const_int 8))
8085                    (xor:SI 
8086                      (zero_extract:SI (match_dup 0)
8087                                       (const_int 8)
8088                                       (const_int 8))
8089                      (zero_extract:SI (match_dup 0)
8090                                       (const_int 8)
8091                                       (const_int 8))))
8092               (clobber (reg:CC FLAGS_REG))])]
8093   "operands[0] = gen_lowpart (SImode, operands[0]);")
8095 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8096 (define_insn "*andsi_1_zext"
8097   [(set (match_operand:DI 0 "register_operand" "=r")
8098         (zero_extend:DI
8099           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8100                   (match_operand:SI 2 "general_operand" "rim"))))
8101    (clobber (reg:CC FLAGS_REG))]
8102   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8103   "and{l}\t{%2, %k0|%k0, %2}"
8104   [(set_attr "type" "alu")
8105    (set_attr "mode" "SI")])
8107 (define_insn "*andsi_2"
8108   [(set (reg FLAGS_REG)
8109         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8110                          (match_operand:SI 2 "general_operand" "rim,ri"))
8111                  (const_int 0)))
8112    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8113         (and:SI (match_dup 1) (match_dup 2)))]
8114   "ix86_match_ccmode (insn, CCNOmode)
8115    && ix86_binary_operator_ok (AND, SImode, operands)"
8116   "and{l}\t{%2, %0|%0, %2}"
8117   [(set_attr "type" "alu")
8118    (set_attr "mode" "SI")])
8120 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8121 (define_insn "*andsi_2_zext"
8122   [(set (reg FLAGS_REG)
8123         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8124                          (match_operand:SI 2 "general_operand" "rim"))
8125                  (const_int 0)))
8126    (set (match_operand:DI 0 "register_operand" "=r")
8127         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8128   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8129    && ix86_binary_operator_ok (AND, SImode, operands)"
8130   "and{l}\t{%2, %k0|%k0, %2}"
8131   [(set_attr "type" "alu")
8132    (set_attr "mode" "SI")])
8134 (define_expand "andhi3"
8135   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8136         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8137                 (match_operand:HI 2 "general_operand" "")))
8138    (clobber (reg:CC FLAGS_REG))]
8139   "TARGET_HIMODE_MATH"
8140   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8142 (define_insn "*andhi_1"
8143   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8144         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8145                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8146    (clobber (reg:CC FLAGS_REG))]
8147   "ix86_binary_operator_ok (AND, HImode, operands)"
8149   switch (get_attr_type (insn))
8150     {
8151     case TYPE_IMOVX:
8152       if (GET_CODE (operands[2]) != CONST_INT)
8153         abort ();
8154       if (INTVAL (operands[2]) == 0xff)
8155         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8156       abort ();
8158     default:
8159       if (! rtx_equal_p (operands[0], operands[1]))
8160         abort ();
8162       return "and{w}\t{%2, %0|%0, %2}";
8163     }
8165   [(set_attr "type" "alu,alu,imovx")
8166    (set_attr "length_immediate" "*,*,0")
8167    (set_attr "mode" "HI,HI,SI")])
8169 (define_insn "*andhi_2"
8170   [(set (reg FLAGS_REG)
8171         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8172                          (match_operand:HI 2 "general_operand" "rim,ri"))
8173                  (const_int 0)))
8174    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8175         (and:HI (match_dup 1) (match_dup 2)))]
8176   "ix86_match_ccmode (insn, CCNOmode)
8177    && ix86_binary_operator_ok (AND, HImode, operands)"
8178   "and{w}\t{%2, %0|%0, %2}"
8179   [(set_attr "type" "alu")
8180    (set_attr "mode" "HI")])
8182 (define_expand "andqi3"
8183   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8184         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8185                 (match_operand:QI 2 "general_operand" "")))
8186    (clobber (reg:CC FLAGS_REG))]
8187   "TARGET_QIMODE_MATH"
8188   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8190 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8191 (define_insn "*andqi_1"
8192   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8193         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8194                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8195    (clobber (reg:CC FLAGS_REG))]
8196   "ix86_binary_operator_ok (AND, QImode, operands)"
8197   "@
8198    and{b}\t{%2, %0|%0, %2}
8199    and{b}\t{%2, %0|%0, %2}
8200    and{l}\t{%k2, %k0|%k0, %k2}"
8201   [(set_attr "type" "alu")
8202    (set_attr "mode" "QI,QI,SI")])
8204 (define_insn "*andqi_1_slp"
8205   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8206         (and:QI (match_dup 0)
8207                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8208    (clobber (reg:CC FLAGS_REG))]
8209   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8210    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8211   "and{b}\t{%1, %0|%0, %1}"
8212   [(set_attr "type" "alu1")
8213    (set_attr "mode" "QI")])
8215 (define_insn "*andqi_2_maybe_si"
8216   [(set (reg FLAGS_REG)
8217         (compare (and:QI
8218                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8219                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8220                  (const_int 0)))
8221    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8222         (and:QI (match_dup 1) (match_dup 2)))]
8223   "ix86_binary_operator_ok (AND, QImode, operands)
8224    && ix86_match_ccmode (insn,
8225                          GET_CODE (operands[2]) == CONST_INT
8226                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8228   if (which_alternative == 2)
8229     {
8230       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8231         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8232       return "and{l}\t{%2, %k0|%k0, %2}";
8233     }
8234   return "and{b}\t{%2, %0|%0, %2}";
8236   [(set_attr "type" "alu")
8237    (set_attr "mode" "QI,QI,SI")])
8239 (define_insn "*andqi_2"
8240   [(set (reg FLAGS_REG)
8241         (compare (and:QI
8242                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8243                    (match_operand:QI 2 "general_operand" "qim,qi"))
8244                  (const_int 0)))
8245    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8246         (and:QI (match_dup 1) (match_dup 2)))]
8247   "ix86_match_ccmode (insn, CCNOmode)
8248    && ix86_binary_operator_ok (AND, QImode, operands)"
8249   "and{b}\t{%2, %0|%0, %2}"
8250   [(set_attr "type" "alu")
8251    (set_attr "mode" "QI")])
8253 (define_insn "*andqi_2_slp"
8254   [(set (reg FLAGS_REG)
8255         (compare (and:QI
8256                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8257                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8258                  (const_int 0)))
8259    (set (strict_low_part (match_dup 0))
8260         (and:QI (match_dup 0) (match_dup 1)))]
8261   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8262    && ix86_match_ccmode (insn, CCNOmode)
8263    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8264   "and{b}\t{%1, %0|%0, %1}"
8265   [(set_attr "type" "alu1")
8266    (set_attr "mode" "QI")])
8268 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8269 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8270 ;; for a QImode operand, which of course failed.
8272 (define_insn "andqi_ext_0"
8273   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8274                          (const_int 8)
8275                          (const_int 8))
8276         (and:SI 
8277           (zero_extract:SI
8278             (match_operand 1 "ext_register_operand" "0")
8279             (const_int 8)
8280             (const_int 8))
8281           (match_operand 2 "const_int_operand" "n")))
8282    (clobber (reg:CC FLAGS_REG))]
8283   ""
8284   "and{b}\t{%2, %h0|%h0, %2}"
8285   [(set_attr "type" "alu")
8286    (set_attr "length_immediate" "1")
8287    (set_attr "mode" "QI")])
8289 ;; Generated by peephole translating test to and.  This shows up
8290 ;; often in fp comparisons.
8292 (define_insn "*andqi_ext_0_cc"
8293   [(set (reg FLAGS_REG)
8294         (compare
8295           (and:SI
8296             (zero_extract:SI
8297               (match_operand 1 "ext_register_operand" "0")
8298               (const_int 8)
8299               (const_int 8))
8300             (match_operand 2 "const_int_operand" "n"))
8301           (const_int 0)))
8302    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8303                          (const_int 8)
8304                          (const_int 8))
8305         (and:SI 
8306           (zero_extract:SI
8307             (match_dup 1)
8308             (const_int 8)
8309             (const_int 8))
8310           (match_dup 2)))]
8311   "ix86_match_ccmode (insn, CCNOmode)"
8312   "and{b}\t{%2, %h0|%h0, %2}"
8313   [(set_attr "type" "alu")
8314    (set_attr "length_immediate" "1")
8315    (set_attr "mode" "QI")])
8317 (define_insn "*andqi_ext_1"
8318   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8319                          (const_int 8)
8320                          (const_int 8))
8321         (and:SI 
8322           (zero_extract:SI
8323             (match_operand 1 "ext_register_operand" "0")
8324             (const_int 8)
8325             (const_int 8))
8326           (zero_extend:SI
8327             (match_operand:QI 2 "general_operand" "Qm"))))
8328    (clobber (reg:CC FLAGS_REG))]
8329   "!TARGET_64BIT"
8330   "and{b}\t{%2, %h0|%h0, %2}"
8331   [(set_attr "type" "alu")
8332    (set_attr "length_immediate" "0")
8333    (set_attr "mode" "QI")])
8335 (define_insn "*andqi_ext_1_rex64"
8336   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8337                          (const_int 8)
8338                          (const_int 8))
8339         (and:SI 
8340           (zero_extract:SI
8341             (match_operand 1 "ext_register_operand" "0")
8342             (const_int 8)
8343             (const_int 8))
8344           (zero_extend:SI
8345             (match_operand 2 "ext_register_operand" "Q"))))
8346    (clobber (reg:CC FLAGS_REG))]
8347   "TARGET_64BIT"
8348   "and{b}\t{%2, %h0|%h0, %2}"
8349   [(set_attr "type" "alu")
8350    (set_attr "length_immediate" "0")
8351    (set_attr "mode" "QI")])
8353 (define_insn "*andqi_ext_2"
8354   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8355                          (const_int 8)
8356                          (const_int 8))
8357         (and:SI
8358           (zero_extract:SI
8359             (match_operand 1 "ext_register_operand" "%0")
8360             (const_int 8)
8361             (const_int 8))
8362           (zero_extract:SI
8363             (match_operand 2 "ext_register_operand" "Q")
8364             (const_int 8)
8365             (const_int 8))))
8366    (clobber (reg:CC FLAGS_REG))]
8367   ""
8368   "and{b}\t{%h2, %h0|%h0, %h2}"
8369   [(set_attr "type" "alu")
8370    (set_attr "length_immediate" "0")
8371    (set_attr "mode" "QI")])
8373 ;; Convert wide AND instructions with immediate operand to shorter QImode
8374 ;; equivalents when possible.
8375 ;; Don't do the splitting with memory operands, since it introduces risk
8376 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8377 ;; for size, but that can (should?) be handled by generic code instead.
8378 (define_split
8379   [(set (match_operand 0 "register_operand" "")
8380         (and (match_operand 1 "register_operand" "")
8381              (match_operand 2 "const_int_operand" "")))
8382    (clobber (reg:CC FLAGS_REG))]
8383    "reload_completed
8384     && QI_REG_P (operands[0])
8385     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8386     && !(~INTVAL (operands[2]) & ~(255 << 8))
8387     && GET_MODE (operands[0]) != QImode"
8388   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8389                    (and:SI (zero_extract:SI (match_dup 1)
8390                                             (const_int 8) (const_int 8))
8391                            (match_dup 2)))
8392               (clobber (reg:CC FLAGS_REG))])]
8393   "operands[0] = gen_lowpart (SImode, operands[0]);
8394    operands[1] = gen_lowpart (SImode, operands[1]);
8395    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8397 ;; Since AND can be encoded with sign extended immediate, this is only
8398 ;; profitable when 7th bit is not set.
8399 (define_split
8400   [(set (match_operand 0 "register_operand" "")
8401         (and (match_operand 1 "general_operand" "")
8402              (match_operand 2 "const_int_operand" "")))
8403    (clobber (reg:CC FLAGS_REG))]
8404    "reload_completed
8405     && ANY_QI_REG_P (operands[0])
8406     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8407     && !(~INTVAL (operands[2]) & ~255)
8408     && !(INTVAL (operands[2]) & 128)
8409     && GET_MODE (operands[0]) != QImode"
8410   [(parallel [(set (strict_low_part (match_dup 0))
8411                    (and:QI (match_dup 1)
8412                            (match_dup 2)))
8413               (clobber (reg:CC FLAGS_REG))])]
8414   "operands[0] = gen_lowpart (QImode, operands[0]);
8415    operands[1] = gen_lowpart (QImode, operands[1]);
8416    operands[2] = gen_lowpart (QImode, operands[2]);")
8418 ;; Logical inclusive OR instructions
8420 ;; %%% This used to optimize known byte-wide and operations to memory.
8421 ;; If this is considered useful, it should be done with splitters.
8423 (define_expand "iordi3"
8424   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8425         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8426                 (match_operand:DI 2 "x86_64_general_operand" "")))
8427    (clobber (reg:CC FLAGS_REG))]
8428   "TARGET_64BIT"
8429   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8431 (define_insn "*iordi_1_rex64"
8432   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8433         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8434                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8435    (clobber (reg:CC FLAGS_REG))]
8436   "TARGET_64BIT
8437    && ix86_binary_operator_ok (IOR, DImode, operands)"
8438   "or{q}\t{%2, %0|%0, %2}"
8439   [(set_attr "type" "alu")
8440    (set_attr "mode" "DI")])
8442 (define_insn "*iordi_2_rex64"
8443   [(set (reg FLAGS_REG)
8444         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8445                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8446                  (const_int 0)))
8447    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8448         (ior:DI (match_dup 1) (match_dup 2)))]
8449   "TARGET_64BIT
8450    && ix86_match_ccmode (insn, CCNOmode)
8451    && ix86_binary_operator_ok (IOR, DImode, operands)"
8452   "or{q}\t{%2, %0|%0, %2}"
8453   [(set_attr "type" "alu")
8454    (set_attr "mode" "DI")])
8456 (define_insn "*iordi_3_rex64"
8457   [(set (reg FLAGS_REG)
8458         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8459                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8460                  (const_int 0)))
8461    (clobber (match_scratch:DI 0 "=r"))]
8462   "TARGET_64BIT
8463    && ix86_match_ccmode (insn, CCNOmode)
8464    && ix86_binary_operator_ok (IOR, DImode, operands)"
8465   "or{q}\t{%2, %0|%0, %2}"
8466   [(set_attr "type" "alu")
8467    (set_attr "mode" "DI")])
8470 (define_expand "iorsi3"
8471   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8472         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8473                 (match_operand:SI 2 "general_operand" "")))
8474    (clobber (reg:CC FLAGS_REG))]
8475   ""
8476   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8478 (define_insn "*iorsi_1"
8479   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8480         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8481                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8482    (clobber (reg:CC FLAGS_REG))]
8483   "ix86_binary_operator_ok (IOR, SImode, operands)"
8484   "or{l}\t{%2, %0|%0, %2}"
8485   [(set_attr "type" "alu")
8486    (set_attr "mode" "SI")])
8488 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8489 (define_insn "*iorsi_1_zext"
8490   [(set (match_operand:DI 0 "register_operand" "=rm")
8491         (zero_extend:DI
8492           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8493                   (match_operand:SI 2 "general_operand" "rim"))))
8494    (clobber (reg:CC FLAGS_REG))]
8495   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8496   "or{l}\t{%2, %k0|%k0, %2}"
8497   [(set_attr "type" "alu")
8498    (set_attr "mode" "SI")])
8500 (define_insn "*iorsi_1_zext_imm"
8501   [(set (match_operand:DI 0 "register_operand" "=rm")
8502         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8503                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8504    (clobber (reg:CC FLAGS_REG))]
8505   "TARGET_64BIT"
8506   "or{l}\t{%2, %k0|%k0, %2}"
8507   [(set_attr "type" "alu")
8508    (set_attr "mode" "SI")])
8510 (define_insn "*iorsi_2"
8511   [(set (reg FLAGS_REG)
8512         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8513                          (match_operand:SI 2 "general_operand" "rim,ri"))
8514                  (const_int 0)))
8515    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8516         (ior:SI (match_dup 1) (match_dup 2)))]
8517   "ix86_match_ccmode (insn, CCNOmode)
8518    && ix86_binary_operator_ok (IOR, SImode, operands)"
8519   "or{l}\t{%2, %0|%0, %2}"
8520   [(set_attr "type" "alu")
8521    (set_attr "mode" "SI")])
8523 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8524 ;; ??? Special case for immediate operand is missing - it is tricky.
8525 (define_insn "*iorsi_2_zext"
8526   [(set (reg FLAGS_REG)
8527         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8528                          (match_operand:SI 2 "general_operand" "rim"))
8529                  (const_int 0)))
8530    (set (match_operand:DI 0 "register_operand" "=r")
8531         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8532   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8533    && ix86_binary_operator_ok (IOR, SImode, operands)"
8534   "or{l}\t{%2, %k0|%k0, %2}"
8535   [(set_attr "type" "alu")
8536    (set_attr "mode" "SI")])
8538 (define_insn "*iorsi_2_zext_imm"
8539   [(set (reg FLAGS_REG)
8540         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8541                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8542                  (const_int 0)))
8543    (set (match_operand:DI 0 "register_operand" "=r")
8544         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8545   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8546    && ix86_binary_operator_ok (IOR, SImode, operands)"
8547   "or{l}\t{%2, %k0|%k0, %2}"
8548   [(set_attr "type" "alu")
8549    (set_attr "mode" "SI")])
8551 (define_insn "*iorsi_3"
8552   [(set (reg FLAGS_REG)
8553         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8554                          (match_operand:SI 2 "general_operand" "rim"))
8555                  (const_int 0)))
8556    (clobber (match_scratch:SI 0 "=r"))]
8557   "ix86_match_ccmode (insn, CCNOmode)
8558    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8559   "or{l}\t{%2, %0|%0, %2}"
8560   [(set_attr "type" "alu")
8561    (set_attr "mode" "SI")])
8563 (define_expand "iorhi3"
8564   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8565         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8566                 (match_operand:HI 2 "general_operand" "")))
8567    (clobber (reg:CC FLAGS_REG))]
8568   "TARGET_HIMODE_MATH"
8569   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8571 (define_insn "*iorhi_1"
8572   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8573         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8574                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8575    (clobber (reg:CC FLAGS_REG))]
8576   "ix86_binary_operator_ok (IOR, HImode, operands)"
8577   "or{w}\t{%2, %0|%0, %2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "HI")])
8581 (define_insn "*iorhi_2"
8582   [(set (reg FLAGS_REG)
8583         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8584                          (match_operand:HI 2 "general_operand" "rim,ri"))
8585                  (const_int 0)))
8586    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8587         (ior:HI (match_dup 1) (match_dup 2)))]
8588   "ix86_match_ccmode (insn, CCNOmode)
8589    && ix86_binary_operator_ok (IOR, HImode, operands)"
8590   "or{w}\t{%2, %0|%0, %2}"
8591   [(set_attr "type" "alu")
8592    (set_attr "mode" "HI")])
8594 (define_insn "*iorhi_3"
8595   [(set (reg FLAGS_REG)
8596         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8597                          (match_operand:HI 2 "general_operand" "rim"))
8598                  (const_int 0)))
8599    (clobber (match_scratch:HI 0 "=r"))]
8600   "ix86_match_ccmode (insn, CCNOmode)
8601    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8602   "or{w}\t{%2, %0|%0, %2}"
8603   [(set_attr "type" "alu")
8604    (set_attr "mode" "HI")])
8606 (define_expand "iorqi3"
8607   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8608         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8609                 (match_operand:QI 2 "general_operand" "")))
8610    (clobber (reg:CC FLAGS_REG))]
8611   "TARGET_QIMODE_MATH"
8612   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8614 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8615 (define_insn "*iorqi_1"
8616   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8617         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8618                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8619    (clobber (reg:CC FLAGS_REG))]
8620   "ix86_binary_operator_ok (IOR, QImode, operands)"
8621   "@
8622    or{b}\t{%2, %0|%0, %2}
8623    or{b}\t{%2, %0|%0, %2}
8624    or{l}\t{%k2, %k0|%k0, %k2}"
8625   [(set_attr "type" "alu")
8626    (set_attr "mode" "QI,QI,SI")])
8628 (define_insn "*iorqi_1_slp"
8629   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8630         (ior:QI (match_dup 0)
8631                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8632    (clobber (reg:CC FLAGS_REG))]
8633   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8634    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8635   "or{b}\t{%1, %0|%0, %1}"
8636   [(set_attr "type" "alu1")
8637    (set_attr "mode" "QI")])
8639 (define_insn "*iorqi_2"
8640   [(set (reg FLAGS_REG)
8641         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8642                          (match_operand:QI 2 "general_operand" "qim,qi"))
8643                  (const_int 0)))
8644    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8645         (ior:QI (match_dup 1) (match_dup 2)))]
8646   "ix86_match_ccmode (insn, CCNOmode)
8647    && ix86_binary_operator_ok (IOR, QImode, operands)"
8648   "or{b}\t{%2, %0|%0, %2}"
8649   [(set_attr "type" "alu")
8650    (set_attr "mode" "QI")])
8652 (define_insn "*iorqi_2_slp"
8653   [(set (reg FLAGS_REG)
8654         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8655                          (match_operand:QI 1 "general_operand" "qim,qi"))
8656                  (const_int 0)))
8657    (set (strict_low_part (match_dup 0))
8658         (ior:QI (match_dup 0) (match_dup 1)))]
8659   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8660    && ix86_match_ccmode (insn, CCNOmode)
8661    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8662   "or{b}\t{%1, %0|%0, %1}"
8663   [(set_attr "type" "alu1")
8664    (set_attr "mode" "QI")])
8666 (define_insn "*iorqi_3"
8667   [(set (reg FLAGS_REG)
8668         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8669                          (match_operand:QI 2 "general_operand" "qim"))
8670                  (const_int 0)))
8671    (clobber (match_scratch:QI 0 "=q"))]
8672   "ix86_match_ccmode (insn, CCNOmode)
8673    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8674   "or{b}\t{%2, %0|%0, %2}"
8675   [(set_attr "type" "alu")
8676    (set_attr "mode" "QI")])
8678 (define_insn "iorqi_ext_0"
8679   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8680                          (const_int 8)
8681                          (const_int 8))
8682         (ior:SI 
8683           (zero_extract:SI
8684             (match_operand 1 "ext_register_operand" "0")
8685             (const_int 8)
8686             (const_int 8))
8687           (match_operand 2 "const_int_operand" "n")))
8688    (clobber (reg:CC FLAGS_REG))]
8689   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8690   "or{b}\t{%2, %h0|%h0, %2}"
8691   [(set_attr "type" "alu")
8692    (set_attr "length_immediate" "1")
8693    (set_attr "mode" "QI")])
8695 (define_insn "*iorqi_ext_1"
8696   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8697                          (const_int 8)
8698                          (const_int 8))
8699         (ior:SI 
8700           (zero_extract:SI
8701             (match_operand 1 "ext_register_operand" "0")
8702             (const_int 8)
8703             (const_int 8))
8704           (zero_extend:SI
8705             (match_operand:QI 2 "general_operand" "Qm"))))
8706    (clobber (reg:CC FLAGS_REG))]
8707   "!TARGET_64BIT
8708    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8709   "or{b}\t{%2, %h0|%h0, %2}"
8710   [(set_attr "type" "alu")
8711    (set_attr "length_immediate" "0")
8712    (set_attr "mode" "QI")])
8714 (define_insn "*iorqi_ext_1_rex64"
8715   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8716                          (const_int 8)
8717                          (const_int 8))
8718         (ior:SI 
8719           (zero_extract:SI
8720             (match_operand 1 "ext_register_operand" "0")
8721             (const_int 8)
8722             (const_int 8))
8723           (zero_extend:SI
8724             (match_operand 2 "ext_register_operand" "Q"))))
8725    (clobber (reg:CC FLAGS_REG))]
8726   "TARGET_64BIT
8727    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8728   "or{b}\t{%2, %h0|%h0, %2}"
8729   [(set_attr "type" "alu")
8730    (set_attr "length_immediate" "0")
8731    (set_attr "mode" "QI")])
8733 (define_insn "*iorqi_ext_2"
8734   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8735                          (const_int 8)
8736                          (const_int 8))
8737         (ior:SI 
8738           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8739                            (const_int 8)
8740                            (const_int 8))
8741           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8742                            (const_int 8)
8743                            (const_int 8))))
8744    (clobber (reg:CC FLAGS_REG))]
8745   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8746   "ior{b}\t{%h2, %h0|%h0, %h2}"
8747   [(set_attr "type" "alu")
8748    (set_attr "length_immediate" "0")
8749    (set_attr "mode" "QI")])
8751 (define_split
8752   [(set (match_operand 0 "register_operand" "")
8753         (ior (match_operand 1 "register_operand" "")
8754              (match_operand 2 "const_int_operand" "")))
8755    (clobber (reg:CC FLAGS_REG))]
8756    "reload_completed
8757     && QI_REG_P (operands[0])
8758     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8759     && !(INTVAL (operands[2]) & ~(255 << 8))
8760     && GET_MODE (operands[0]) != QImode"
8761   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8762                    (ior:SI (zero_extract:SI (match_dup 1)
8763                                             (const_int 8) (const_int 8))
8764                            (match_dup 2)))
8765               (clobber (reg:CC FLAGS_REG))])]
8766   "operands[0] = gen_lowpart (SImode, operands[0]);
8767    operands[1] = gen_lowpart (SImode, operands[1]);
8768    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8770 ;; Since OR can be encoded with sign extended immediate, this is only
8771 ;; profitable when 7th bit is set.
8772 (define_split
8773   [(set (match_operand 0 "register_operand" "")
8774         (ior (match_operand 1 "general_operand" "")
8775              (match_operand 2 "const_int_operand" "")))
8776    (clobber (reg:CC FLAGS_REG))]
8777    "reload_completed
8778     && ANY_QI_REG_P (operands[0])
8779     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8780     && !(INTVAL (operands[2]) & ~255)
8781     && (INTVAL (operands[2]) & 128)
8782     && GET_MODE (operands[0]) != QImode"
8783   [(parallel [(set (strict_low_part (match_dup 0))
8784                    (ior:QI (match_dup 1)
8785                            (match_dup 2)))
8786               (clobber (reg:CC FLAGS_REG))])]
8787   "operands[0] = gen_lowpart (QImode, operands[0]);
8788    operands[1] = gen_lowpart (QImode, operands[1]);
8789    operands[2] = gen_lowpart (QImode, operands[2]);")
8791 ;; Logical XOR instructions
8793 ;; %%% This used to optimize known byte-wide and operations to memory.
8794 ;; If this is considered useful, it should be done with splitters.
8796 (define_expand "xordi3"
8797   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8798         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8799                 (match_operand:DI 2 "x86_64_general_operand" "")))
8800    (clobber (reg:CC FLAGS_REG))]
8801   "TARGET_64BIT"
8802   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8804 (define_insn "*xordi_1_rex64"
8805   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8806         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8807                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8808    (clobber (reg:CC FLAGS_REG))]
8809   "TARGET_64BIT
8810    && ix86_binary_operator_ok (XOR, DImode, operands)"
8811   "@
8812    xor{q}\t{%2, %0|%0, %2}
8813    xor{q}\t{%2, %0|%0, %2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "mode" "DI,DI")])
8817 (define_insn "*xordi_2_rex64"
8818   [(set (reg FLAGS_REG)
8819         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8820                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8821                  (const_int 0)))
8822    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8823         (xor:DI (match_dup 1) (match_dup 2)))]
8824   "TARGET_64BIT
8825    && ix86_match_ccmode (insn, CCNOmode)
8826    && ix86_binary_operator_ok (XOR, DImode, operands)"
8827   "@
8828    xor{q}\t{%2, %0|%0, %2}
8829    xor{q}\t{%2, %0|%0, %2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "mode" "DI,DI")])
8833 (define_insn "*xordi_3_rex64"
8834   [(set (reg FLAGS_REG)
8835         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8836                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8837                  (const_int 0)))
8838    (clobber (match_scratch:DI 0 "=r"))]
8839   "TARGET_64BIT
8840    && ix86_match_ccmode (insn, CCNOmode)
8841    && ix86_binary_operator_ok (XOR, DImode, operands)"
8842   "xor{q}\t{%2, %0|%0, %2}"
8843   [(set_attr "type" "alu")
8844    (set_attr "mode" "DI")])
8846 (define_expand "xorsi3"
8847   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8848         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8849                 (match_operand:SI 2 "general_operand" "")))
8850    (clobber (reg:CC FLAGS_REG))]
8851   ""
8852   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8854 (define_insn "*xorsi_1"
8855   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8856         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8857                 (match_operand:SI 2 "general_operand" "ri,rm")))
8858    (clobber (reg:CC FLAGS_REG))]
8859   "ix86_binary_operator_ok (XOR, SImode, operands)"
8860   "xor{l}\t{%2, %0|%0, %2}"
8861   [(set_attr "type" "alu")
8862    (set_attr "mode" "SI")])
8864 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8865 ;; Add speccase for immediates
8866 (define_insn "*xorsi_1_zext"
8867   [(set (match_operand:DI 0 "register_operand" "=r")
8868         (zero_extend:DI
8869           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8870                   (match_operand:SI 2 "general_operand" "rim"))))
8871    (clobber (reg:CC FLAGS_REG))]
8872   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8873   "xor{l}\t{%2, %k0|%k0, %2}"
8874   [(set_attr "type" "alu")
8875    (set_attr "mode" "SI")])
8877 (define_insn "*xorsi_1_zext_imm"
8878   [(set (match_operand:DI 0 "register_operand" "=r")
8879         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8880                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8881    (clobber (reg:CC FLAGS_REG))]
8882   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8883   "xor{l}\t{%2, %k0|%k0, %2}"
8884   [(set_attr "type" "alu")
8885    (set_attr "mode" "SI")])
8887 (define_insn "*xorsi_2"
8888   [(set (reg FLAGS_REG)
8889         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8890                          (match_operand:SI 2 "general_operand" "rim,ri"))
8891                  (const_int 0)))
8892    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8893         (xor:SI (match_dup 1) (match_dup 2)))]
8894   "ix86_match_ccmode (insn, CCNOmode)
8895    && ix86_binary_operator_ok (XOR, SImode, operands)"
8896   "xor{l}\t{%2, %0|%0, %2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "mode" "SI")])
8900 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8901 ;; ??? Special case for immediate operand is missing - it is tricky.
8902 (define_insn "*xorsi_2_zext"
8903   [(set (reg FLAGS_REG)
8904         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8905                          (match_operand:SI 2 "general_operand" "rim"))
8906                  (const_int 0)))
8907    (set (match_operand:DI 0 "register_operand" "=r")
8908         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8909   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8910    && ix86_binary_operator_ok (XOR, SImode, operands)"
8911   "xor{l}\t{%2, %k0|%k0, %2}"
8912   [(set_attr "type" "alu")
8913    (set_attr "mode" "SI")])
8915 (define_insn "*xorsi_2_zext_imm"
8916   [(set (reg FLAGS_REG)
8917         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8918                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8919                  (const_int 0)))
8920    (set (match_operand:DI 0 "register_operand" "=r")
8921         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8922   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8923    && ix86_binary_operator_ok (XOR, SImode, operands)"
8924   "xor{l}\t{%2, %k0|%k0, %2}"
8925   [(set_attr "type" "alu")
8926    (set_attr "mode" "SI")])
8928 (define_insn "*xorsi_3"
8929   [(set (reg FLAGS_REG)
8930         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8931                          (match_operand:SI 2 "general_operand" "rim"))
8932                  (const_int 0)))
8933    (clobber (match_scratch:SI 0 "=r"))]
8934   "ix86_match_ccmode (insn, CCNOmode)
8935    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8936   "xor{l}\t{%2, %0|%0, %2}"
8937   [(set_attr "type" "alu")
8938    (set_attr "mode" "SI")])
8940 (define_expand "xorhi3"
8941   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8942         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8943                 (match_operand:HI 2 "general_operand" "")))
8944    (clobber (reg:CC FLAGS_REG))]
8945   "TARGET_HIMODE_MATH"
8946   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8948 (define_insn "*xorhi_1"
8949   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8950         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8951                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8952    (clobber (reg:CC FLAGS_REG))]
8953   "ix86_binary_operator_ok (XOR, HImode, operands)"
8954   "xor{w}\t{%2, %0|%0, %2}"
8955   [(set_attr "type" "alu")
8956    (set_attr "mode" "HI")])
8958 (define_insn "*xorhi_2"
8959   [(set (reg FLAGS_REG)
8960         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8961                          (match_operand:HI 2 "general_operand" "rim,ri"))
8962                  (const_int 0)))
8963    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8964         (xor:HI (match_dup 1) (match_dup 2)))]
8965   "ix86_match_ccmode (insn, CCNOmode)
8966    && ix86_binary_operator_ok (XOR, HImode, operands)"
8967   "xor{w}\t{%2, %0|%0, %2}"
8968   [(set_attr "type" "alu")
8969    (set_attr "mode" "HI")])
8971 (define_insn "*xorhi_3"
8972   [(set (reg FLAGS_REG)
8973         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8974                          (match_operand:HI 2 "general_operand" "rim"))
8975                  (const_int 0)))
8976    (clobber (match_scratch:HI 0 "=r"))]
8977   "ix86_match_ccmode (insn, CCNOmode)
8978    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8979   "xor{w}\t{%2, %0|%0, %2}"
8980   [(set_attr "type" "alu")
8981    (set_attr "mode" "HI")])
8983 (define_expand "xorqi3"
8984   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8985         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8986                 (match_operand:QI 2 "general_operand" "")))
8987    (clobber (reg:CC FLAGS_REG))]
8988   "TARGET_QIMODE_MATH"
8989   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8991 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8992 (define_insn "*xorqi_1"
8993   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8994         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8995                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8996    (clobber (reg:CC FLAGS_REG))]
8997   "ix86_binary_operator_ok (XOR, QImode, operands)"
8998   "@
8999    xor{b}\t{%2, %0|%0, %2}
9000    xor{b}\t{%2, %0|%0, %2}
9001    xor{l}\t{%k2, %k0|%k0, %k2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "QI,QI,SI")])
9005 (define_insn "*xorqi_1_slp"
9006   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9007         (xor:QI (match_dup 0)
9008                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9009    (clobber (reg:CC FLAGS_REG))]
9010   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9011    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9012   "xor{b}\t{%1, %0|%0, %1}"
9013   [(set_attr "type" "alu1")
9014    (set_attr "mode" "QI")])
9016 (define_insn "xorqi_ext_0"
9017   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9018                          (const_int 8)
9019                          (const_int 8))
9020         (xor:SI 
9021           (zero_extract:SI
9022             (match_operand 1 "ext_register_operand" "0")
9023             (const_int 8)
9024             (const_int 8))
9025           (match_operand 2 "const_int_operand" "n")))
9026    (clobber (reg:CC FLAGS_REG))]
9027   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9028   "xor{b}\t{%2, %h0|%h0, %2}"
9029   [(set_attr "type" "alu")
9030    (set_attr "length_immediate" "1")
9031    (set_attr "mode" "QI")])
9033 (define_insn "*xorqi_ext_1"
9034   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9035                          (const_int 8)
9036                          (const_int 8))
9037         (xor:SI 
9038           (zero_extract:SI
9039             (match_operand 1 "ext_register_operand" "0")
9040             (const_int 8)
9041             (const_int 8))
9042           (zero_extend:SI
9043             (match_operand:QI 2 "general_operand" "Qm"))))
9044    (clobber (reg:CC FLAGS_REG))]
9045   "!TARGET_64BIT
9046    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9047   "xor{b}\t{%2, %h0|%h0, %2}"
9048   [(set_attr "type" "alu")
9049    (set_attr "length_immediate" "0")
9050    (set_attr "mode" "QI")])
9052 (define_insn "*xorqi_ext_1_rex64"
9053   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9054                          (const_int 8)
9055                          (const_int 8))
9056         (xor:SI 
9057           (zero_extract:SI
9058             (match_operand 1 "ext_register_operand" "0")
9059             (const_int 8)
9060             (const_int 8))
9061           (zero_extend:SI
9062             (match_operand 2 "ext_register_operand" "Q"))))
9063    (clobber (reg:CC FLAGS_REG))]
9064   "TARGET_64BIT
9065    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9066   "xor{b}\t{%2, %h0|%h0, %2}"
9067   [(set_attr "type" "alu")
9068    (set_attr "length_immediate" "0")
9069    (set_attr "mode" "QI")])
9071 (define_insn "*xorqi_ext_2"
9072   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9073                          (const_int 8)
9074                          (const_int 8))
9075         (xor:SI 
9076           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9077                            (const_int 8)
9078                            (const_int 8))
9079           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9080                            (const_int 8)
9081                            (const_int 8))))
9082    (clobber (reg:CC FLAGS_REG))]
9083   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9084   "xor{b}\t{%h2, %h0|%h0, %h2}"
9085   [(set_attr "type" "alu")
9086    (set_attr "length_immediate" "0")
9087    (set_attr "mode" "QI")])
9089 (define_insn "*xorqi_cc_1"
9090   [(set (reg FLAGS_REG)
9091         (compare
9092           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9093                   (match_operand:QI 2 "general_operand" "qim,qi"))
9094           (const_int 0)))
9095    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9096         (xor:QI (match_dup 1) (match_dup 2)))]
9097   "ix86_match_ccmode (insn, CCNOmode)
9098    && ix86_binary_operator_ok (XOR, QImode, operands)"
9099   "xor{b}\t{%2, %0|%0, %2}"
9100   [(set_attr "type" "alu")
9101    (set_attr "mode" "QI")])
9103 (define_insn "*xorqi_2_slp"
9104   [(set (reg FLAGS_REG)
9105         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9106                          (match_operand:QI 1 "general_operand" "qim,qi"))
9107                  (const_int 0)))
9108    (set (strict_low_part (match_dup 0))
9109         (xor:QI (match_dup 0) (match_dup 1)))]
9110   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9111    && ix86_match_ccmode (insn, CCNOmode)
9112    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9113   "xor{b}\t{%1, %0|%0, %1}"
9114   [(set_attr "type" "alu1")
9115    (set_attr "mode" "QI")])
9117 (define_insn "*xorqi_cc_2"
9118   [(set (reg FLAGS_REG)
9119         (compare
9120           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9121                   (match_operand:QI 2 "general_operand" "qim"))
9122           (const_int 0)))
9123    (clobber (match_scratch:QI 0 "=q"))]
9124   "ix86_match_ccmode (insn, CCNOmode)
9125    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9126   "xor{b}\t{%2, %0|%0, %2}"
9127   [(set_attr "type" "alu")
9128    (set_attr "mode" "QI")])
9130 (define_insn "*xorqi_cc_ext_1"
9131   [(set (reg FLAGS_REG)
9132         (compare
9133           (xor:SI
9134             (zero_extract:SI
9135               (match_operand 1 "ext_register_operand" "0")
9136               (const_int 8)
9137               (const_int 8))
9138             (match_operand:QI 2 "general_operand" "qmn"))
9139           (const_int 0)))
9140    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9141                          (const_int 8)
9142                          (const_int 8))
9143         (xor:SI 
9144           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9145           (match_dup 2)))]
9146   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9147   "xor{b}\t{%2, %h0|%h0, %2}"
9148   [(set_attr "type" "alu")
9149    (set_attr "mode" "QI")])
9151 (define_insn "*xorqi_cc_ext_1_rex64"
9152   [(set (reg FLAGS_REG)
9153         (compare
9154           (xor:SI
9155             (zero_extract:SI
9156               (match_operand 1 "ext_register_operand" "0")
9157               (const_int 8)
9158               (const_int 8))
9159             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9160           (const_int 0)))
9161    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9162                          (const_int 8)
9163                          (const_int 8))
9164         (xor:SI 
9165           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9166           (match_dup 2)))]
9167   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9168   "xor{b}\t{%2, %h0|%h0, %2}"
9169   [(set_attr "type" "alu")
9170    (set_attr "mode" "QI")])
9172 (define_expand "xorqi_cc_ext_1"
9173   [(parallel [
9174      (set (reg:CCNO FLAGS_REG)
9175           (compare:CCNO
9176             (xor:SI
9177               (zero_extract:SI
9178                 (match_operand 1 "ext_register_operand" "")
9179                 (const_int 8)
9180                 (const_int 8))
9181               (match_operand:QI 2 "general_operand" ""))
9182             (const_int 0)))
9183      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9184                            (const_int 8)
9185                            (const_int 8))
9186           (xor:SI 
9187             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9188             (match_dup 2)))])]
9189   ""
9190   "")
9192 (define_split
9193   [(set (match_operand 0 "register_operand" "")
9194         (xor (match_operand 1 "register_operand" "")
9195              (match_operand 2 "const_int_operand" "")))
9196    (clobber (reg:CC FLAGS_REG))]
9197    "reload_completed
9198     && QI_REG_P (operands[0])
9199     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9200     && !(INTVAL (operands[2]) & ~(255 << 8))
9201     && GET_MODE (operands[0]) != QImode"
9202   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9203                    (xor:SI (zero_extract:SI (match_dup 1)
9204                                             (const_int 8) (const_int 8))
9205                            (match_dup 2)))
9206               (clobber (reg:CC FLAGS_REG))])]
9207   "operands[0] = gen_lowpart (SImode, operands[0]);
9208    operands[1] = gen_lowpart (SImode, operands[1]);
9209    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9211 ;; Since XOR can be encoded with sign extended immediate, this is only
9212 ;; profitable when 7th bit is set.
9213 (define_split
9214   [(set (match_operand 0 "register_operand" "")
9215         (xor (match_operand 1 "general_operand" "")
9216              (match_operand 2 "const_int_operand" "")))
9217    (clobber (reg:CC FLAGS_REG))]
9218    "reload_completed
9219     && ANY_QI_REG_P (operands[0])
9220     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9221     && !(INTVAL (operands[2]) & ~255)
9222     && (INTVAL (operands[2]) & 128)
9223     && GET_MODE (operands[0]) != QImode"
9224   [(parallel [(set (strict_low_part (match_dup 0))
9225                    (xor:QI (match_dup 1)
9226                            (match_dup 2)))
9227               (clobber (reg:CC FLAGS_REG))])]
9228   "operands[0] = gen_lowpart (QImode, operands[0]);
9229    operands[1] = gen_lowpart (QImode, operands[1]);
9230    operands[2] = gen_lowpart (QImode, operands[2]);")
9232 ;; Negation instructions
9234 (define_expand "negdi2"
9235   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9236                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9237               (clobber (reg:CC FLAGS_REG))])]
9238   ""
9239   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9241 (define_insn "*negdi2_1"
9242   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9243         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9244    (clobber (reg:CC FLAGS_REG))]
9245   "!TARGET_64BIT
9246    && ix86_unary_operator_ok (NEG, DImode, operands)"
9247   "#")
9249 (define_split
9250   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9251         (neg:DI (match_operand:DI 1 "general_operand" "")))
9252    (clobber (reg:CC FLAGS_REG))]
9253   "!TARGET_64BIT && reload_completed"
9254   [(parallel
9255     [(set (reg:CCZ FLAGS_REG)
9256           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9257      (set (match_dup 0) (neg:SI (match_dup 2)))])
9258    (parallel
9259     [(set (match_dup 1)
9260           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9261                             (match_dup 3))
9262                    (const_int 0)))
9263      (clobber (reg:CC FLAGS_REG))])
9264    (parallel
9265     [(set (match_dup 1)
9266           (neg:SI (match_dup 1)))
9267      (clobber (reg:CC FLAGS_REG))])]
9268   "split_di (operands+1, 1, operands+2, operands+3);
9269    split_di (operands+0, 1, operands+0, operands+1);")
9271 (define_insn "*negdi2_1_rex64"
9272   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9273         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9274    (clobber (reg:CC FLAGS_REG))]
9275   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9276   "neg{q}\t%0"
9277   [(set_attr "type" "negnot")
9278    (set_attr "mode" "DI")])
9280 ;; The problem with neg is that it does not perform (compare x 0),
9281 ;; it really performs (compare 0 x), which leaves us with the zero
9282 ;; flag being the only useful item.
9284 (define_insn "*negdi2_cmpz_rex64"
9285   [(set (reg:CCZ FLAGS_REG)
9286         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9287                      (const_int 0)))
9288    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9289         (neg:DI (match_dup 1)))]
9290   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9291   "neg{q}\t%0"
9292   [(set_attr "type" "negnot")
9293    (set_attr "mode" "DI")])
9296 (define_expand "negsi2"
9297   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9298                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9299               (clobber (reg:CC FLAGS_REG))])]
9300   ""
9301   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9303 (define_insn "*negsi2_1"
9304   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9305         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9306    (clobber (reg:CC FLAGS_REG))]
9307   "ix86_unary_operator_ok (NEG, SImode, operands)"
9308   "neg{l}\t%0"
9309   [(set_attr "type" "negnot")
9310    (set_attr "mode" "SI")])
9312 ;; Combine is quite creative about this pattern.
9313 (define_insn "*negsi2_1_zext"
9314   [(set (match_operand:DI 0 "register_operand" "=r")
9315         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9316                                         (const_int 32)))
9317                      (const_int 32)))
9318    (clobber (reg:CC FLAGS_REG))]
9319   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9320   "neg{l}\t%k0"
9321   [(set_attr "type" "negnot")
9322    (set_attr "mode" "SI")])
9324 ;; The problem with neg is that it does not perform (compare x 0),
9325 ;; it really performs (compare 0 x), which leaves us with the zero
9326 ;; flag being the only useful item.
9328 (define_insn "*negsi2_cmpz"
9329   [(set (reg:CCZ FLAGS_REG)
9330         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9331                      (const_int 0)))
9332    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9333         (neg:SI (match_dup 1)))]
9334   "ix86_unary_operator_ok (NEG, SImode, operands)"
9335   "neg{l}\t%0"
9336   [(set_attr "type" "negnot")
9337    (set_attr "mode" "SI")])
9339 (define_insn "*negsi2_cmpz_zext"
9340   [(set (reg:CCZ FLAGS_REG)
9341         (compare:CCZ (lshiftrt:DI
9342                        (neg:DI (ashift:DI
9343                                  (match_operand:DI 1 "register_operand" "0")
9344                                  (const_int 32)))
9345                        (const_int 32))
9346                      (const_int 0)))
9347    (set (match_operand:DI 0 "register_operand" "=r")
9348         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9349                                         (const_int 32)))
9350                      (const_int 32)))]
9351   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9352   "neg{l}\t%k0"
9353   [(set_attr "type" "negnot")
9354    (set_attr "mode" "SI")])
9356 (define_expand "neghi2"
9357   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9358                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9359               (clobber (reg:CC FLAGS_REG))])]
9360   "TARGET_HIMODE_MATH"
9361   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9363 (define_insn "*neghi2_1"
9364   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9365         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9366    (clobber (reg:CC FLAGS_REG))]
9367   "ix86_unary_operator_ok (NEG, HImode, operands)"
9368   "neg{w}\t%0"
9369   [(set_attr "type" "negnot")
9370    (set_attr "mode" "HI")])
9372 (define_insn "*neghi2_cmpz"
9373   [(set (reg:CCZ FLAGS_REG)
9374         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9375                      (const_int 0)))
9376    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9377         (neg:HI (match_dup 1)))]
9378   "ix86_unary_operator_ok (NEG, HImode, operands)"
9379   "neg{w}\t%0"
9380   [(set_attr "type" "negnot")
9381    (set_attr "mode" "HI")])
9383 (define_expand "negqi2"
9384   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9385                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9386               (clobber (reg:CC FLAGS_REG))])]
9387   "TARGET_QIMODE_MATH"
9388   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9390 (define_insn "*negqi2_1"
9391   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9392         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9393    (clobber (reg:CC FLAGS_REG))]
9394   "ix86_unary_operator_ok (NEG, QImode, operands)"
9395   "neg{b}\t%0"
9396   [(set_attr "type" "negnot")
9397    (set_attr "mode" "QI")])
9399 (define_insn "*negqi2_cmpz"
9400   [(set (reg:CCZ FLAGS_REG)
9401         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9402                      (const_int 0)))
9403    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9404         (neg:QI (match_dup 1)))]
9405   "ix86_unary_operator_ok (NEG, QImode, operands)"
9406   "neg{b}\t%0"
9407   [(set_attr "type" "negnot")
9408    (set_attr "mode" "QI")])
9410 ;; Changing of sign for FP values is doable using integer unit too.
9412 (define_expand "negsf2"
9413   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9414         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9415   "TARGET_80387 || TARGET_SSE_MATH"
9416   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9418 (define_expand "abssf2"
9419   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9420         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9421   "TARGET_80387 || TARGET_SSE_MATH"
9422   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9424 (define_insn "*absnegsf2_mixed"
9425   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9426         (match_operator:SF 3 "absneg_operator"
9427           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9428    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9429    (clobber (reg:CC FLAGS_REG))]
9430   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9431    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9432   "#")
9434 (define_insn "*absnegsf2_sse"
9435   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9436         (match_operator:SF 3 "absneg_operator"
9437           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9438    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9439    (clobber (reg:CC FLAGS_REG))]
9440   "TARGET_SSE_MATH
9441    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9442   "#")
9444 (define_insn "*absnegsf2_i387"
9445   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9446         (match_operator:SF 3 "absneg_operator"
9447           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9448    (use (match_operand 2 "" ""))
9449    (clobber (reg:CC FLAGS_REG))]
9450   "TARGET_80387 && !TARGET_SSE_MATH
9451    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9452   "#")
9454 (define_expand "copysignsf3"
9455   [(match_operand:SF 0 "register_operand" "")
9456    (match_operand:SF 1 "nonmemory_operand" "")
9457    (match_operand:SF 2 "register_operand" "")]
9458   "TARGET_SSE_MATH"
9460   ix86_expand_copysign (operands);
9461   DONE;
9464 (define_insn_and_split "copysignsf3_const"
9465   [(set (match_operand:SF 0 "register_operand"          "=x")
9466         (unspec:SF
9467           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9468            (match_operand:SF 2 "register_operand"       "0")
9469            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9470           UNSPEC_COPYSIGN))]
9471   "TARGET_SSE_MATH"
9472   "#"
9473   "&& reload_completed"
9474   [(const_int 0)]
9476   ix86_split_copysign_const (operands);
9477   DONE;
9480 (define_insn "copysignsf3_var"
9481   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9482         (unspec:SF
9483           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9484            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9485            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9486            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9487           UNSPEC_COPYSIGN))
9488    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9489   "TARGET_SSE_MATH"
9490   "#")
9492 (define_split
9493   [(set (match_operand:SF 0 "register_operand" "")
9494         (unspec:SF
9495           [(match_operand:SF 2 "register_operand" "")
9496            (match_operand:SF 3 "register_operand" "")
9497            (match_operand:V4SF 4 "" "")
9498            (match_operand:V4SF 5 "" "")]
9499           UNSPEC_COPYSIGN))
9500    (clobber (match_scratch:V4SF 1 ""))]
9501   "TARGET_SSE_MATH && reload_completed"
9502   [(const_int 0)]
9504   ix86_split_copysign_var (operands);
9505   DONE;
9508 (define_expand "negdf2"
9509   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9510         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9511   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9512   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9514 (define_expand "absdf2"
9515   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9516         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9517   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9518   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9520 (define_insn "*absnegdf2_mixed"
9521   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9522         (match_operator:DF 3 "absneg_operator"
9523           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9524    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9525    (clobber (reg:CC FLAGS_REG))]
9526   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9527    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9528   "#")
9530 (define_insn "*absnegdf2_sse"
9531   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9532         (match_operator:DF 3 "absneg_operator"
9533           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9534    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9535    (clobber (reg:CC FLAGS_REG))]
9536   "TARGET_SSE2 && TARGET_SSE_MATH
9537    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9538   "#")
9540 (define_insn "*absnegdf2_i387"
9541   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9542         (match_operator:DF 3 "absneg_operator"
9543           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9544    (use (match_operand 2 "" ""))
9545    (clobber (reg:CC FLAGS_REG))]
9546   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9547    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9548   "#")
9550 (define_expand "copysigndf3"
9551   [(match_operand:DF 0 "register_operand" "")
9552    (match_operand:DF 1 "nonmemory_operand" "")
9553    (match_operand:DF 2 "register_operand" "")]
9554   "TARGET_SSE2 && TARGET_SSE_MATH"
9556   ix86_expand_copysign (operands);
9557   DONE;
9560 (define_insn_and_split "copysigndf3_const"
9561   [(set (match_operand:DF 0 "register_operand"          "=x")
9562         (unspec:DF
9563           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9564            (match_operand:DF 2 "register_operand"       "0")
9565            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9566           UNSPEC_COPYSIGN))]
9567   "TARGET_SSE2 && TARGET_SSE_MATH"
9568   "#"
9569   "&& reload_completed"
9570   [(const_int 0)]
9572   ix86_split_copysign_const (operands);
9573   DONE;
9576 (define_insn "copysigndf3_var"
9577   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9578         (unspec:DF
9579           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9580            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9581            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9582            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9583           UNSPEC_COPYSIGN))
9584    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9585   "TARGET_SSE2 && TARGET_SSE_MATH"
9586   "#")
9588 (define_split
9589   [(set (match_operand:DF 0 "register_operand" "")
9590         (unspec:DF
9591           [(match_operand:DF 2 "register_operand" "")
9592            (match_operand:DF 3 "register_operand" "")
9593            (match_operand:V2DF 4 "" "")
9594            (match_operand:V2DF 5 "" "")]
9595           UNSPEC_COPYSIGN))
9596    (clobber (match_scratch:V2DF 1 ""))]
9597   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9598   [(const_int 0)]
9600   ix86_split_copysign_var (operands);
9601   DONE;
9604 (define_expand "negxf2"
9605   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9606         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9607   "TARGET_80387"
9608   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9610 (define_expand "absxf2"
9611   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9612         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9613   "TARGET_80387"
9614   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9616 (define_insn "*absnegxf2_i387"
9617   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9618         (match_operator:XF 3 "absneg_operator"
9619           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9620    (use (match_operand 2 "" ""))
9621    (clobber (reg:CC FLAGS_REG))]
9622   "TARGET_80387
9623    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9624   "#")
9626 ;; Splitters for fp abs and neg.
9628 (define_split
9629   [(set (match_operand 0 "fp_register_operand" "")
9630         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9631    (use (match_operand 2 "" ""))
9632    (clobber (reg:CC FLAGS_REG))]
9633   "reload_completed"
9634   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9636 (define_split
9637   [(set (match_operand 0 "register_operand" "")
9638         (match_operator 3 "absneg_operator"
9639           [(match_operand 1 "register_operand" "")]))
9640    (use (match_operand 2 "nonimmediate_operand" ""))
9641    (clobber (reg:CC FLAGS_REG))]
9642   "reload_completed && SSE_REG_P (operands[0])"
9643   [(set (match_dup 0) (match_dup 3))]
9645   enum machine_mode mode = GET_MODE (operands[0]);
9646   enum machine_mode vmode = GET_MODE (operands[2]);
9647   rtx tmp;
9648   
9649   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9650   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9651   if (operands_match_p (operands[0], operands[2]))
9652     {
9653       tmp = operands[1];
9654       operands[1] = operands[2];
9655       operands[2] = tmp;
9656     }
9657   if (GET_CODE (operands[3]) == ABS)
9658     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9659   else
9660     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9661   operands[3] = tmp;
9664 (define_split
9665   [(set (match_operand:SF 0 "register_operand" "")
9666         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9667    (use (match_operand:V4SF 2 "" ""))
9668    (clobber (reg:CC FLAGS_REG))]
9669   "reload_completed"
9670   [(parallel [(set (match_dup 0) (match_dup 1))
9671               (clobber (reg:CC FLAGS_REG))])]
9673   rtx tmp;
9674   operands[0] = gen_lowpart (SImode, operands[0]);
9675   if (GET_CODE (operands[1]) == ABS)
9676     {
9677       tmp = gen_int_mode (0x7fffffff, SImode);
9678       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9679     }
9680   else
9681     {
9682       tmp = gen_int_mode (0x80000000, SImode);
9683       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9684     }
9685   operands[1] = tmp;
9688 (define_split
9689   [(set (match_operand:DF 0 "register_operand" "")
9690         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9691    (use (match_operand 2 "" ""))
9692    (clobber (reg:CC FLAGS_REG))]
9693   "reload_completed"
9694   [(parallel [(set (match_dup 0) (match_dup 1))
9695               (clobber (reg:CC FLAGS_REG))])]
9697   rtx tmp;
9698   if (TARGET_64BIT)
9699     {
9700       tmp = gen_lowpart (DImode, operands[0]);
9701       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9702       operands[0] = tmp;
9704       if (GET_CODE (operands[1]) == ABS)
9705         tmp = const0_rtx;
9706       else
9707         tmp = gen_rtx_NOT (DImode, tmp);
9708     }
9709   else
9710     {
9711       operands[0] = gen_highpart (SImode, operands[0]);
9712       if (GET_CODE (operands[1]) == ABS)
9713         {
9714           tmp = gen_int_mode (0x7fffffff, SImode);
9715           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9716         }
9717       else
9718         {
9719           tmp = gen_int_mode (0x80000000, SImode);
9720           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9721         }
9722     }
9723   operands[1] = tmp;
9726 (define_split
9727   [(set (match_operand:XF 0 "register_operand" "")
9728         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9729    (use (match_operand 2 "" ""))
9730    (clobber (reg:CC FLAGS_REG))]
9731   "reload_completed"
9732   [(parallel [(set (match_dup 0) (match_dup 1))
9733               (clobber (reg:CC FLAGS_REG))])]
9735   rtx tmp;
9736   operands[0] = gen_rtx_REG (SImode,
9737                              true_regnum (operands[0])
9738                              + (TARGET_64BIT ? 1 : 2));
9739   if (GET_CODE (operands[1]) == ABS)
9740     {
9741       tmp = GEN_INT (0x7fff);
9742       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9743     }
9744   else
9745     {
9746       tmp = GEN_INT (0x8000);
9747       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9748     }
9749   operands[1] = tmp;
9752 (define_split
9753   [(set (match_operand 0 "memory_operand" "")
9754         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9755    (use (match_operand 2 "" ""))
9756    (clobber (reg:CC FLAGS_REG))]
9757   "reload_completed"
9758   [(parallel [(set (match_dup 0) (match_dup 1))
9759               (clobber (reg:CC FLAGS_REG))])]
9761   enum machine_mode mode = GET_MODE (operands[0]);
9762   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9763   rtx tmp;
9765   operands[0] = adjust_address (operands[0], QImode, size - 1);
9766   if (GET_CODE (operands[1]) == ABS)
9767     {
9768       tmp = gen_int_mode (0x7f, QImode);
9769       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9770     }
9771   else
9772     {
9773       tmp = gen_int_mode (0x80, QImode);
9774       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9775     }
9776   operands[1] = tmp;
9779 ;; Conditionalize these after reload. If they match before reload, we 
9780 ;; lose the clobber and ability to use integer instructions.
9782 (define_insn "*negsf2_1"
9783   [(set (match_operand:SF 0 "register_operand" "=f")
9784         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9785   "TARGET_80387 && reload_completed"
9786   "fchs"
9787   [(set_attr "type" "fsgn")
9788    (set_attr "mode" "SF")])
9790 (define_insn "*negdf2_1"
9791   [(set (match_operand:DF 0 "register_operand" "=f")
9792         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9793   "TARGET_80387 && reload_completed"
9794   "fchs"
9795   [(set_attr "type" "fsgn")
9796    (set_attr "mode" "DF")])
9798 (define_insn "*negxf2_1"
9799   [(set (match_operand:XF 0 "register_operand" "=f")
9800         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9801   "TARGET_80387 && reload_completed"
9802   "fchs"
9803   [(set_attr "type" "fsgn")
9804    (set_attr "mode" "XF")])
9806 (define_insn "*abssf2_1"
9807   [(set (match_operand:SF 0 "register_operand" "=f")
9808         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9809   "TARGET_80387 && reload_completed"
9810   "fabs"
9811   [(set_attr "type" "fsgn")
9812    (set_attr "mode" "SF")])
9814 (define_insn "*absdf2_1"
9815   [(set (match_operand:DF 0 "register_operand" "=f")
9816         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9817   "TARGET_80387 && reload_completed"
9818   "fabs"
9819   [(set_attr "type" "fsgn")
9820    (set_attr "mode" "DF")])
9822 (define_insn "*absxf2_1"
9823   [(set (match_operand:XF 0 "register_operand" "=f")
9824         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9825   "TARGET_80387 && reload_completed"
9826   "fabs"
9827   [(set_attr "type" "fsgn")
9828    (set_attr "mode" "DF")])
9830 (define_insn "*negextendsfdf2"
9831   [(set (match_operand:DF 0 "register_operand" "=f")
9832         (neg:DF (float_extend:DF
9833                   (match_operand:SF 1 "register_operand" "0"))))]
9834   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9835   "fchs"
9836   [(set_attr "type" "fsgn")
9837    (set_attr "mode" "DF")])
9839 (define_insn "*negextenddfxf2"
9840   [(set (match_operand:XF 0 "register_operand" "=f")
9841         (neg:XF (float_extend:XF
9842                   (match_operand:DF 1 "register_operand" "0"))))]
9843   "TARGET_80387"
9844   "fchs"
9845   [(set_attr "type" "fsgn")
9846    (set_attr "mode" "XF")])
9848 (define_insn "*negextendsfxf2"
9849   [(set (match_operand:XF 0 "register_operand" "=f")
9850         (neg:XF (float_extend:XF
9851                   (match_operand:SF 1 "register_operand" "0"))))]
9852   "TARGET_80387"
9853   "fchs"
9854   [(set_attr "type" "fsgn")
9855    (set_attr "mode" "XF")])
9857 (define_insn "*absextendsfdf2"
9858   [(set (match_operand:DF 0 "register_operand" "=f")
9859         (abs:DF (float_extend:DF
9860                   (match_operand:SF 1 "register_operand" "0"))))]
9861   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9862   "fabs"
9863   [(set_attr "type" "fsgn")
9864    (set_attr "mode" "DF")])
9866 (define_insn "*absextenddfxf2"
9867   [(set (match_operand:XF 0 "register_operand" "=f")
9868         (abs:XF (float_extend:XF
9869           (match_operand:DF 1 "register_operand" "0"))))]
9870   "TARGET_80387"
9871   "fabs"
9872   [(set_attr "type" "fsgn")
9873    (set_attr "mode" "XF")])
9875 (define_insn "*absextendsfxf2"
9876   [(set (match_operand:XF 0 "register_operand" "=f")
9877         (abs:XF (float_extend:XF
9878           (match_operand:SF 1 "register_operand" "0"))))]
9879   "TARGET_80387"
9880   "fabs"
9881   [(set_attr "type" "fsgn")
9882    (set_attr "mode" "XF")])
9884 ;; One complement instructions
9886 (define_expand "one_cmpldi2"
9887   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9888         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9889   "TARGET_64BIT"
9890   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9892 (define_insn "*one_cmpldi2_1_rex64"
9893   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9894         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9895   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9896   "not{q}\t%0"
9897   [(set_attr "type" "negnot")
9898    (set_attr "mode" "DI")])
9900 (define_insn "*one_cmpldi2_2_rex64"
9901   [(set (reg FLAGS_REG)
9902         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9903                  (const_int 0)))
9904    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9905         (not:DI (match_dup 1)))]
9906   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9907    && ix86_unary_operator_ok (NOT, DImode, operands)"
9908   "#"
9909   [(set_attr "type" "alu1")
9910    (set_attr "mode" "DI")])
9912 (define_split
9913   [(set (match_operand 0 "flags_reg_operand" "")
9914         (match_operator 2 "compare_operator"
9915           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9916            (const_int 0)]))
9917    (set (match_operand:DI 1 "nonimmediate_operand" "")
9918         (not:DI (match_dup 3)))]
9919   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9920   [(parallel [(set (match_dup 0)
9921                    (match_op_dup 2
9922                      [(xor:DI (match_dup 3) (const_int -1))
9923                       (const_int 0)]))
9924               (set (match_dup 1)
9925                    (xor:DI (match_dup 3) (const_int -1)))])]
9926   "")
9928 (define_expand "one_cmplsi2"
9929   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9930         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9931   ""
9932   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9934 (define_insn "*one_cmplsi2_1"
9935   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9936         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9937   "ix86_unary_operator_ok (NOT, SImode, operands)"
9938   "not{l}\t%0"
9939   [(set_attr "type" "negnot")
9940    (set_attr "mode" "SI")])
9942 ;; ??? Currently never generated - xor is used instead.
9943 (define_insn "*one_cmplsi2_1_zext"
9944   [(set (match_operand:DI 0 "register_operand" "=r")
9945         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9946   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9947   "not{l}\t%k0"
9948   [(set_attr "type" "negnot")
9949    (set_attr "mode" "SI")])
9951 (define_insn "*one_cmplsi2_2"
9952   [(set (reg FLAGS_REG)
9953         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9954                  (const_int 0)))
9955    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9956         (not:SI (match_dup 1)))]
9957   "ix86_match_ccmode (insn, CCNOmode)
9958    && ix86_unary_operator_ok (NOT, SImode, operands)"
9959   "#"
9960   [(set_attr "type" "alu1")
9961    (set_attr "mode" "SI")])
9963 (define_split
9964   [(set (match_operand 0 "flags_reg_operand" "")
9965         (match_operator 2 "compare_operator"
9966           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9967            (const_int 0)]))
9968    (set (match_operand:SI 1 "nonimmediate_operand" "")
9969         (not:SI (match_dup 3)))]
9970   "ix86_match_ccmode (insn, CCNOmode)"
9971   [(parallel [(set (match_dup 0)
9972                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9973                                     (const_int 0)]))
9974               (set (match_dup 1)
9975                    (xor:SI (match_dup 3) (const_int -1)))])]
9976   "")
9978 ;; ??? Currently never generated - xor is used instead.
9979 (define_insn "*one_cmplsi2_2_zext"
9980   [(set (reg FLAGS_REG)
9981         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9982                  (const_int 0)))
9983    (set (match_operand:DI 0 "register_operand" "=r")
9984         (zero_extend:DI (not:SI (match_dup 1))))]
9985   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9986    && ix86_unary_operator_ok (NOT, SImode, operands)"
9987   "#"
9988   [(set_attr "type" "alu1")
9989    (set_attr "mode" "SI")])
9991 (define_split
9992   [(set (match_operand 0 "flags_reg_operand" "")
9993         (match_operator 2 "compare_operator"
9994           [(not:SI (match_operand:SI 3 "register_operand" ""))
9995            (const_int 0)]))
9996    (set (match_operand:DI 1 "register_operand" "")
9997         (zero_extend:DI (not:SI (match_dup 3))))]
9998   "ix86_match_ccmode (insn, CCNOmode)"
9999   [(parallel [(set (match_dup 0)
10000                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10001                                     (const_int 0)]))
10002               (set (match_dup 1)
10003                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10004   "")
10006 (define_expand "one_cmplhi2"
10007   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10008         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10009   "TARGET_HIMODE_MATH"
10010   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10012 (define_insn "*one_cmplhi2_1"
10013   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10014         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10015   "ix86_unary_operator_ok (NOT, HImode, operands)"
10016   "not{w}\t%0"
10017   [(set_attr "type" "negnot")
10018    (set_attr "mode" "HI")])
10020 (define_insn "*one_cmplhi2_2"
10021   [(set (reg FLAGS_REG)
10022         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10023                  (const_int 0)))
10024    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10025         (not:HI (match_dup 1)))]
10026   "ix86_match_ccmode (insn, CCNOmode)
10027    && ix86_unary_operator_ok (NEG, HImode, operands)"
10028   "#"
10029   [(set_attr "type" "alu1")
10030    (set_attr "mode" "HI")])
10032 (define_split
10033   [(set (match_operand 0 "flags_reg_operand" "")
10034         (match_operator 2 "compare_operator"
10035           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10036            (const_int 0)]))
10037    (set (match_operand:HI 1 "nonimmediate_operand" "")
10038         (not:HI (match_dup 3)))]
10039   "ix86_match_ccmode (insn, CCNOmode)"
10040   [(parallel [(set (match_dup 0)
10041                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10042                                     (const_int 0)]))
10043               (set (match_dup 1)
10044                    (xor:HI (match_dup 3) (const_int -1)))])]
10045   "")
10047 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10048 (define_expand "one_cmplqi2"
10049   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10050         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10051   "TARGET_QIMODE_MATH"
10052   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10054 (define_insn "*one_cmplqi2_1"
10055   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10056         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10057   "ix86_unary_operator_ok (NOT, QImode, operands)"
10058   "@
10059    not{b}\t%0
10060    not{l}\t%k0"
10061   [(set_attr "type" "negnot")
10062    (set_attr "mode" "QI,SI")])
10064 (define_insn "*one_cmplqi2_2"
10065   [(set (reg FLAGS_REG)
10066         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10067                  (const_int 0)))
10068    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10069         (not:QI (match_dup 1)))]
10070   "ix86_match_ccmode (insn, CCNOmode)
10071    && ix86_unary_operator_ok (NOT, QImode, operands)"
10072   "#"
10073   [(set_attr "type" "alu1")
10074    (set_attr "mode" "QI")])
10076 (define_split
10077   [(set (match_operand 0 "flags_reg_operand" "")
10078         (match_operator 2 "compare_operator"
10079           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10080            (const_int 0)]))
10081    (set (match_operand:QI 1 "nonimmediate_operand" "")
10082         (not:QI (match_dup 3)))]
10083   "ix86_match_ccmode (insn, CCNOmode)"
10084   [(parallel [(set (match_dup 0)
10085                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10086                                     (const_int 0)]))
10087               (set (match_dup 1)
10088                    (xor:QI (match_dup 3) (const_int -1)))])]
10089   "")
10091 ;; Arithmetic shift instructions
10093 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10094 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10095 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10096 ;; from the assembler input.
10098 ;; This instruction shifts the target reg/mem as usual, but instead of
10099 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10100 ;; is a left shift double, bits are taken from the high order bits of
10101 ;; reg, else if the insn is a shift right double, bits are taken from the
10102 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10103 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10105 ;; Since sh[lr]d does not change the `reg' operand, that is done
10106 ;; separately, making all shifts emit pairs of shift double and normal
10107 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10108 ;; support a 63 bit shift, each shift where the count is in a reg expands
10109 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10111 ;; If the shift count is a constant, we need never emit more than one
10112 ;; shift pair, instead using moves and sign extension for counts greater
10113 ;; than 31.
10115 (define_expand "ashldi3"
10116   [(set (match_operand:DI 0 "shiftdi_operand" "")
10117         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10118                    (match_operand:QI 2 "nonmemory_operand" "")))]
10119   ""
10120   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10122 (define_insn "*ashldi3_1_rex64"
10123   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10124         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10125                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10126    (clobber (reg:CC FLAGS_REG))]
10127   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10129   switch (get_attr_type (insn))
10130     {
10131     case TYPE_ALU:
10132       if (operands[2] != const1_rtx)
10133         abort ();
10134       if (!rtx_equal_p (operands[0], operands[1]))
10135         abort ();
10136       return "add{q}\t{%0, %0|%0, %0}";
10138     case TYPE_LEA:
10139       if (GET_CODE (operands[2]) != CONST_INT
10140           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10141         abort ();
10142       operands[1] = gen_rtx_MULT (DImode, operands[1],
10143                                   GEN_INT (1 << INTVAL (operands[2])));
10144       return "lea{q}\t{%a1, %0|%0, %a1}";
10146     default:
10147       if (REG_P (operands[2]))
10148         return "sal{q}\t{%b2, %0|%0, %b2}";
10149       else if (operands[2] == const1_rtx
10150                && (TARGET_SHIFT1 || optimize_size))
10151         return "sal{q}\t%0";
10152       else
10153         return "sal{q}\t{%2, %0|%0, %2}";
10154     }
10156   [(set (attr "type")
10157      (cond [(eq_attr "alternative" "1")
10158               (const_string "lea")
10159             (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 ;; Convert lea to the lea pattern to avoid flags dependency.
10169 (define_split
10170   [(set (match_operand:DI 0 "register_operand" "")
10171         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10172                    (match_operand:QI 2 "immediate_operand" "")))
10173    (clobber (reg:CC FLAGS_REG))]
10174   "TARGET_64BIT && reload_completed
10175    && true_regnum (operands[0]) != true_regnum (operands[1])"
10176   [(set (match_dup 0)
10177         (mult:DI (match_dup 1)
10178                  (match_dup 2)))]
10179   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10181 ;; This pattern can't accept a variable shift count, since shifts by
10182 ;; zero don't affect the flags.  We assume that shifts by constant
10183 ;; zero are optimized away.
10184 (define_insn "*ashldi3_cmp_rex64"
10185   [(set (reg FLAGS_REG)
10186         (compare
10187           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10188                      (match_operand:QI 2 "immediate_operand" "e"))
10189           (const_int 0)))
10190    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10191         (ashift:DI (match_dup 1) (match_dup 2)))]
10192   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10193    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10195   switch (get_attr_type (insn))
10196     {
10197     case TYPE_ALU:
10198       if (operands[2] != const1_rtx)
10199         abort ();
10200       return "add{q}\t{%0, %0|%0, %0}";
10202     default:
10203       if (REG_P (operands[2]))
10204         return "sal{q}\t{%b2, %0|%0, %b2}";
10205       else if (operands[2] == const1_rtx
10206                && (TARGET_SHIFT1 || optimize_size))
10207         return "sal{q}\t%0";
10208       else
10209         return "sal{q}\t{%2, %0|%0, %2}";
10210     }
10212   [(set (attr "type")
10213      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10214                           (const_int 0))
10215                       (match_operand 0 "register_operand" ""))
10216                  (match_operand 2 "const1_operand" ""))
10217               (const_string "alu")
10218            ]
10219            (const_string "ishift")))
10220    (set_attr "mode" "DI")])
10222 (define_insn "*ashldi3_1"
10223   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10224         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10225                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10226    (clobber (reg:CC FLAGS_REG))]
10227   "!TARGET_64BIT"
10228   "#"
10229   [(set_attr "type" "multi")])
10231 ;; By default we don't ask for a scratch register, because when DImode
10232 ;; values are manipulated, registers are already at a premium.  But if
10233 ;; we have one handy, we won't turn it away.
10234 (define_peephole2
10235   [(match_scratch:SI 3 "r")
10236    (parallel [(set (match_operand:DI 0 "register_operand" "")
10237                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10238                               (match_operand:QI 2 "nonmemory_operand" "")))
10239               (clobber (reg:CC FLAGS_REG))])
10240    (match_dup 3)]
10241   "!TARGET_64BIT && TARGET_CMOVE"
10242   [(const_int 0)]
10243   "ix86_split_ashldi (operands, operands[3]); DONE;")
10245 (define_split
10246   [(set (match_operand:DI 0 "register_operand" "")
10247         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10248                    (match_operand:QI 2 "nonmemory_operand" "")))
10249    (clobber (reg:CC FLAGS_REG))]
10250   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10251   [(const_int 0)]
10252   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10254 (define_insn "x86_shld_1"
10255   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10256         (ior:SI (ashift:SI (match_dup 0)
10257                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10258                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10259                   (minus:QI (const_int 32) (match_dup 2)))))
10260    (clobber (reg:CC FLAGS_REG))]
10261   ""
10262   "@
10263    shld{l}\t{%2, %1, %0|%0, %1, %2}
10264    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10265   [(set_attr "type" "ishift")
10266    (set_attr "prefix_0f" "1")
10267    (set_attr "mode" "SI")
10268    (set_attr "pent_pair" "np")
10269    (set_attr "athlon_decode" "vector")])
10271 (define_expand "x86_shift_adj_1"
10272   [(set (reg:CCZ FLAGS_REG)
10273         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10274                              (const_int 32))
10275                      (const_int 0)))
10276    (set (match_operand:SI 0 "register_operand" "")
10277         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10278                          (match_operand:SI 1 "register_operand" "")
10279                          (match_dup 0)))
10280    (set (match_dup 1)
10281         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10282                          (match_operand:SI 3 "register_operand" "r")
10283                          (match_dup 1)))]
10284   "TARGET_CMOVE"
10285   "")
10287 (define_expand "x86_shift_adj_2"
10288   [(use (match_operand:SI 0 "register_operand" ""))
10289    (use (match_operand:SI 1 "register_operand" ""))
10290    (use (match_operand:QI 2 "register_operand" ""))]
10291   ""
10293   rtx label = gen_label_rtx ();
10294   rtx tmp;
10296   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10298   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10299   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10300   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10301                               gen_rtx_LABEL_REF (VOIDmode, label),
10302                               pc_rtx);
10303   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10304   JUMP_LABEL (tmp) = label;
10306   emit_move_insn (operands[0], operands[1]);
10307   ix86_expand_clear (operands[1]);
10309   emit_label (label);
10310   LABEL_NUSES (label) = 1;
10312   DONE;
10315 (define_expand "ashlsi3"
10316   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10317         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10318                    (match_operand:QI 2 "nonmemory_operand" "")))
10319    (clobber (reg:CC FLAGS_REG))]
10320   ""
10321   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10323 (define_insn "*ashlsi3_1"
10324   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10325         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10326                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10327    (clobber (reg:CC FLAGS_REG))]
10328   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10330   switch (get_attr_type (insn))
10331     {
10332     case TYPE_ALU:
10333       if (operands[2] != const1_rtx)
10334         abort ();
10335       if (!rtx_equal_p (operands[0], operands[1]))
10336         abort ();
10337       return "add{l}\t{%0, %0|%0, %0}";
10339     case TYPE_LEA:
10340       return "#";
10342     default:
10343       if (REG_P (operands[2]))
10344         return "sal{l}\t{%b2, %0|%0, %b2}";
10345       else if (operands[2] == const1_rtx
10346                && (TARGET_SHIFT1 || optimize_size))
10347         return "sal{l}\t%0";
10348       else
10349         return "sal{l}\t{%2, %0|%0, %2}";
10350     }
10352   [(set (attr "type")
10353      (cond [(eq_attr "alternative" "1")
10354               (const_string "lea")
10355             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10356                           (const_int 0))
10357                       (match_operand 0 "register_operand" ""))
10358                  (match_operand 2 "const1_operand" ""))
10359               (const_string "alu")
10360            ]
10361            (const_string "ishift")))
10362    (set_attr "mode" "SI")])
10364 ;; Convert lea to the lea pattern to avoid flags dependency.
10365 (define_split
10366   [(set (match_operand 0 "register_operand" "")
10367         (ashift (match_operand 1 "index_register_operand" "")
10368                 (match_operand:QI 2 "const_int_operand" "")))
10369    (clobber (reg:CC FLAGS_REG))]
10370   "reload_completed
10371    && true_regnum (operands[0]) != true_regnum (operands[1])
10372    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10373   [(const_int 0)]
10375   rtx pat;
10376   enum machine_mode mode = GET_MODE (operands[0]);
10378   if (GET_MODE_SIZE (mode) < 4)
10379     operands[0] = gen_lowpart (SImode, operands[0]);
10380   if (mode != Pmode)
10381     operands[1] = gen_lowpart (Pmode, operands[1]);
10382   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10384   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10385   if (Pmode != SImode)
10386     pat = gen_rtx_SUBREG (SImode, pat, 0);
10387   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10388   DONE;
10391 ;; Rare case of shifting RSP is handled by generating move and shift
10392 (define_split
10393   [(set (match_operand 0 "register_operand" "")
10394         (ashift (match_operand 1 "register_operand" "")
10395                 (match_operand:QI 2 "const_int_operand" "")))
10396    (clobber (reg:CC FLAGS_REG))]
10397   "reload_completed
10398    && true_regnum (operands[0]) != true_regnum (operands[1])"
10399   [(const_int 0)]
10401   rtx pat, clob;
10402   emit_move_insn (operands[1], operands[0]);
10403   pat = gen_rtx_SET (VOIDmode, operands[0],
10404                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10405                                      operands[0], operands[2]));
10406   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10407   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10408   DONE;
10411 (define_insn "*ashlsi3_1_zext"
10412   [(set (match_operand:DI 0 "register_operand" "=r,r")
10413         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10414                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10415    (clobber (reg:CC FLAGS_REG))]
10416   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10418   switch (get_attr_type (insn))
10419     {
10420     case TYPE_ALU:
10421       if (operands[2] != const1_rtx)
10422         abort ();
10423       return "add{l}\t{%k0, %k0|%k0, %k0}";
10425     case TYPE_LEA:
10426       return "#";
10428     default:
10429       if (REG_P (operands[2]))
10430         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10431       else if (operands[2] == const1_rtx
10432                && (TARGET_SHIFT1 || optimize_size))
10433         return "sal{l}\t%k0";
10434       else
10435         return "sal{l}\t{%2, %k0|%k0, %2}";
10436     }
10438   [(set (attr "type")
10439      (cond [(eq_attr "alternative" "1")
10440               (const_string "lea")
10441             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10442                      (const_int 0))
10443                  (match_operand 2 "const1_operand" ""))
10444               (const_string "alu")
10445            ]
10446            (const_string "ishift")))
10447    (set_attr "mode" "SI")])
10449 ;; Convert lea to the lea pattern to avoid flags dependency.
10450 (define_split
10451   [(set (match_operand:DI 0 "register_operand" "")
10452         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10453                                 (match_operand:QI 2 "const_int_operand" ""))))
10454    (clobber (reg:CC FLAGS_REG))]
10455   "TARGET_64BIT && reload_completed
10456    && true_regnum (operands[0]) != true_regnum (operands[1])"
10457   [(set (match_dup 0) (zero_extend:DI
10458                         (subreg:SI (mult:SI (match_dup 1)
10459                                             (match_dup 2)) 0)))]
10461   operands[1] = gen_lowpart (Pmode, operands[1]);
10462   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10465 ;; This pattern can't accept a variable shift count, since shifts by
10466 ;; zero don't affect the flags.  We assume that shifts by constant
10467 ;; zero are optimized away.
10468 (define_insn "*ashlsi3_cmp"
10469   [(set (reg FLAGS_REG)
10470         (compare
10471           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10472                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10473           (const_int 0)))
10474    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10475         (ashift:SI (match_dup 1) (match_dup 2)))]
10476   "ix86_match_ccmode (insn, CCGOCmode)
10477    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10479   switch (get_attr_type (insn))
10480     {
10481     case TYPE_ALU:
10482       if (operands[2] != const1_rtx)
10483         abort ();
10484       return "add{l}\t{%0, %0|%0, %0}";
10486     default:
10487       if (REG_P (operands[2]))
10488         return "sal{l}\t{%b2, %0|%0, %b2}";
10489       else if (operands[2] == const1_rtx
10490                && (TARGET_SHIFT1 || optimize_size))
10491         return "sal{l}\t%0";
10492       else
10493         return "sal{l}\t{%2, %0|%0, %2}";
10494     }
10496   [(set (attr "type")
10497      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10498                           (const_int 0))
10499                       (match_operand 0 "register_operand" ""))
10500                  (match_operand 2 "const1_operand" ""))
10501               (const_string "alu")
10502            ]
10503            (const_string "ishift")))
10504    (set_attr "mode" "SI")])
10506 (define_insn "*ashlsi3_cmp_zext"
10507   [(set (reg FLAGS_REG)
10508         (compare
10509           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10510                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10511           (const_int 0)))
10512    (set (match_operand:DI 0 "register_operand" "=r")
10513         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10514   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10515    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10517   switch (get_attr_type (insn))
10518     {
10519     case TYPE_ALU:
10520       if (operands[2] != const1_rtx)
10521         abort ();
10522       return "add{l}\t{%k0, %k0|%k0, %k0}";
10524     default:
10525       if (REG_P (operands[2]))
10526         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10527       else if (operands[2] == const1_rtx
10528                && (TARGET_SHIFT1 || optimize_size))
10529         return "sal{l}\t%k0";
10530       else
10531         return "sal{l}\t{%2, %k0|%k0, %2}";
10532     }
10534   [(set (attr "type")
10535      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10536                      (const_int 0))
10537                  (match_operand 2 "const1_operand" ""))
10538               (const_string "alu")
10539            ]
10540            (const_string "ishift")))
10541    (set_attr "mode" "SI")])
10543 (define_expand "ashlhi3"
10544   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10545         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10546                    (match_operand:QI 2 "nonmemory_operand" "")))
10547    (clobber (reg:CC FLAGS_REG))]
10548   "TARGET_HIMODE_MATH"
10549   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10551 (define_insn "*ashlhi3_1_lea"
10552   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10553         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10554                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10555    (clobber (reg:CC FLAGS_REG))]
10556   "!TARGET_PARTIAL_REG_STALL
10557    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10559   switch (get_attr_type (insn))
10560     {
10561     case TYPE_LEA:
10562       return "#";
10563     case TYPE_ALU:
10564       if (operands[2] != const1_rtx)
10565         abort ();
10566       return "add{w}\t{%0, %0|%0, %0}";
10568     default:
10569       if (REG_P (operands[2]))
10570         return "sal{w}\t{%b2, %0|%0, %b2}";
10571       else if (operands[2] == const1_rtx
10572                && (TARGET_SHIFT1 || optimize_size))
10573         return "sal{w}\t%0";
10574       else
10575         return "sal{w}\t{%2, %0|%0, %2}";
10576     }
10578   [(set (attr "type")
10579      (cond [(eq_attr "alternative" "1")
10580               (const_string "lea")
10581             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10582                           (const_int 0))
10583                       (match_operand 0 "register_operand" ""))
10584                  (match_operand 2 "const1_operand" ""))
10585               (const_string "alu")
10586            ]
10587            (const_string "ishift")))
10588    (set_attr "mode" "HI,SI")])
10590 (define_insn "*ashlhi3_1"
10591   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10592         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10593                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10594    (clobber (reg:CC FLAGS_REG))]
10595   "TARGET_PARTIAL_REG_STALL
10596    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10598   switch (get_attr_type (insn))
10599     {
10600     case TYPE_ALU:
10601       if (operands[2] != const1_rtx)
10602         abort ();
10603       return "add{w}\t{%0, %0|%0, %0}";
10605     default:
10606       if (REG_P (operands[2]))
10607         return "sal{w}\t{%b2, %0|%0, %b2}";
10608       else if (operands[2] == const1_rtx
10609                && (TARGET_SHIFT1 || optimize_size))
10610         return "sal{w}\t%0";
10611       else
10612         return "sal{w}\t{%2, %0|%0, %2}";
10613     }
10615   [(set (attr "type")
10616      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10617                           (const_int 0))
10618                       (match_operand 0 "register_operand" ""))
10619                  (match_operand 2 "const1_operand" ""))
10620               (const_string "alu")
10621            ]
10622            (const_string "ishift")))
10623    (set_attr "mode" "HI")])
10625 ;; This pattern can't accept a variable shift count, since shifts by
10626 ;; zero don't affect the flags.  We assume that shifts by constant
10627 ;; zero are optimized away.
10628 (define_insn "*ashlhi3_cmp"
10629   [(set (reg FLAGS_REG)
10630         (compare
10631           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10632                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10633           (const_int 0)))
10634    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10635         (ashift:HI (match_dup 1) (match_dup 2)))]
10636   "ix86_match_ccmode (insn, CCGOCmode)
10637    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10639   switch (get_attr_type (insn))
10640     {
10641     case TYPE_ALU:
10642       if (operands[2] != const1_rtx)
10643         abort ();
10644       return "add{w}\t{%0, %0|%0, %0}";
10646     default:
10647       if (REG_P (operands[2]))
10648         return "sal{w}\t{%b2, %0|%0, %b2}";
10649       else if (operands[2] == const1_rtx
10650                && (TARGET_SHIFT1 || optimize_size))
10651         return "sal{w}\t%0";
10652       else
10653         return "sal{w}\t{%2, %0|%0, %2}";
10654     }
10656   [(set (attr "type")
10657      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10658                           (const_int 0))
10659                       (match_operand 0 "register_operand" ""))
10660                  (match_operand 2 "const1_operand" ""))
10661               (const_string "alu")
10662            ]
10663            (const_string "ishift")))
10664    (set_attr "mode" "HI")])
10666 (define_expand "ashlqi3"
10667   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10668         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10669                    (match_operand:QI 2 "nonmemory_operand" "")))
10670    (clobber (reg:CC FLAGS_REG))]
10671   "TARGET_QIMODE_MATH"
10672   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10674 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10676 (define_insn "*ashlqi3_1_lea"
10677   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10678         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10679                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10680    (clobber (reg:CC FLAGS_REG))]
10681   "!TARGET_PARTIAL_REG_STALL
10682    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10684   switch (get_attr_type (insn))
10685     {
10686     case TYPE_LEA:
10687       return "#";
10688     case TYPE_ALU:
10689       if (operands[2] != const1_rtx)
10690         abort ();
10691       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10692         return "add{l}\t{%k0, %k0|%k0, %k0}";
10693       else
10694         return "add{b}\t{%0, %0|%0, %0}";
10696     default:
10697       if (REG_P (operands[2]))
10698         {
10699           if (get_attr_mode (insn) == MODE_SI)
10700             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10701           else
10702             return "sal{b}\t{%b2, %0|%0, %b2}";
10703         }
10704       else if (operands[2] == const1_rtx
10705                && (TARGET_SHIFT1 || optimize_size))
10706         {
10707           if (get_attr_mode (insn) == MODE_SI)
10708             return "sal{l}\t%0";
10709           else
10710             return "sal{b}\t%0";
10711         }
10712       else
10713         {
10714           if (get_attr_mode (insn) == MODE_SI)
10715             return "sal{l}\t{%2, %k0|%k0, %2}";
10716           else
10717             return "sal{b}\t{%2, %0|%0, %2}";
10718         }
10719     }
10721   [(set (attr "type")
10722      (cond [(eq_attr "alternative" "2")
10723               (const_string "lea")
10724             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10725                           (const_int 0))
10726                       (match_operand 0 "register_operand" ""))
10727                  (match_operand 2 "const1_operand" ""))
10728               (const_string "alu")
10729            ]
10730            (const_string "ishift")))
10731    (set_attr "mode" "QI,SI,SI")])
10733 (define_insn "*ashlqi3_1"
10734   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10735         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10736                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10737    (clobber (reg:CC FLAGS_REG))]
10738   "TARGET_PARTIAL_REG_STALL
10739    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10741   switch (get_attr_type (insn))
10742     {
10743     case TYPE_ALU:
10744       if (operands[2] != const1_rtx)
10745         abort ();
10746       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10747         return "add{l}\t{%k0, %k0|%k0, %k0}";
10748       else
10749         return "add{b}\t{%0, %0|%0, %0}";
10751     default:
10752       if (REG_P (operands[2]))
10753         {
10754           if (get_attr_mode (insn) == MODE_SI)
10755             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10756           else
10757             return "sal{b}\t{%b2, %0|%0, %b2}";
10758         }
10759       else if (operands[2] == const1_rtx
10760                && (TARGET_SHIFT1 || optimize_size))
10761         {
10762           if (get_attr_mode (insn) == MODE_SI)
10763             return "sal{l}\t%0";
10764           else
10765             return "sal{b}\t%0";
10766         }
10767       else
10768         {
10769           if (get_attr_mode (insn) == MODE_SI)
10770             return "sal{l}\t{%2, %k0|%k0, %2}";
10771           else
10772             return "sal{b}\t{%2, %0|%0, %2}";
10773         }
10774     }
10776   [(set (attr "type")
10777      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10778                           (const_int 0))
10779                       (match_operand 0 "register_operand" ""))
10780                  (match_operand 2 "const1_operand" ""))
10781               (const_string "alu")
10782            ]
10783            (const_string "ishift")))
10784    (set_attr "mode" "QI,SI")])
10786 ;; This pattern can't accept a variable shift count, since shifts by
10787 ;; zero don't affect the flags.  We assume that shifts by constant
10788 ;; zero are optimized away.
10789 (define_insn "*ashlqi3_cmp"
10790   [(set (reg FLAGS_REG)
10791         (compare
10792           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10793                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10794           (const_int 0)))
10795    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10796         (ashift:QI (match_dup 1) (match_dup 2)))]
10797   "ix86_match_ccmode (insn, CCGOCmode)
10798    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10800   switch (get_attr_type (insn))
10801     {
10802     case TYPE_ALU:
10803       if (operands[2] != const1_rtx)
10804         abort ();
10805       return "add{b}\t{%0, %0|%0, %0}";
10807     default:
10808       if (REG_P (operands[2]))
10809         return "sal{b}\t{%b2, %0|%0, %b2}";
10810       else if (operands[2] == const1_rtx
10811                && (TARGET_SHIFT1 || optimize_size))
10812         return "sal{b}\t%0";
10813       else
10814         return "sal{b}\t{%2, %0|%0, %2}";
10815     }
10817   [(set (attr "type")
10818      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10819                           (const_int 0))
10820                       (match_operand 0 "register_operand" ""))
10821                  (match_operand 2 "const1_operand" ""))
10822               (const_string "alu")
10823            ]
10824            (const_string "ishift")))
10825    (set_attr "mode" "QI")])
10827 ;; See comment above `ashldi3' about how this works.
10829 (define_expand "ashrdi3"
10830   [(set (match_operand:DI 0 "shiftdi_operand" "")
10831         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10832                      (match_operand:QI 2 "nonmemory_operand" "")))]
10833   ""
10834   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10836 (define_insn "*ashrdi3_63_rex64"
10837   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10838         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10839                      (match_operand:DI 2 "const_int_operand" "i,i")))
10840    (clobber (reg:CC FLAGS_REG))]
10841   "TARGET_64BIT && INTVAL (operands[2]) == 63
10842    && (TARGET_USE_CLTD || optimize_size)
10843    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10844   "@
10845    {cqto|cqo}
10846    sar{q}\t{%2, %0|%0, %2}"
10847   [(set_attr "type" "imovx,ishift")
10848    (set_attr "prefix_0f" "0,*")
10849    (set_attr "length_immediate" "0,*")
10850    (set_attr "modrm" "0,1")
10851    (set_attr "mode" "DI")])
10853 (define_insn "*ashrdi3_1_one_bit_rex64"
10854   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10855         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10856                      (match_operand:QI 2 "const1_operand" "")))
10857    (clobber (reg:CC FLAGS_REG))]
10858   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10859    && (TARGET_SHIFT1 || optimize_size)"
10860   "sar{q}\t%0"
10861   [(set_attr "type" "ishift")
10862    (set (attr "length") 
10863      (if_then_else (match_operand:DI 0 "register_operand" "") 
10864         (const_string "2")
10865         (const_string "*")))])
10867 (define_insn "*ashrdi3_1_rex64"
10868   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10869         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10870                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10871    (clobber (reg:CC FLAGS_REG))]
10872   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10873   "@
10874    sar{q}\t{%2, %0|%0, %2}
10875    sar{q}\t{%b2, %0|%0, %b2}"
10876   [(set_attr "type" "ishift")
10877    (set_attr "mode" "DI")])
10879 ;; This pattern can't accept a variable shift count, since shifts by
10880 ;; zero don't affect the flags.  We assume that shifts by constant
10881 ;; zero are optimized away.
10882 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10883   [(set (reg FLAGS_REG)
10884         (compare
10885           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10886                        (match_operand:QI 2 "const1_operand" ""))
10887           (const_int 0)))
10888    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10889         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10890   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10891    && (TARGET_SHIFT1 || optimize_size)
10892    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10893   "sar{q}\t%0"
10894   [(set_attr "type" "ishift")
10895    (set (attr "length") 
10896      (if_then_else (match_operand:DI 0 "register_operand" "") 
10897         (const_string "2")
10898         (const_string "*")))])
10900 ;; This pattern can't accept a variable shift count, since shifts by
10901 ;; zero don't affect the flags.  We assume that shifts by constant
10902 ;; zero are optimized away.
10903 (define_insn "*ashrdi3_cmp_rex64"
10904   [(set (reg FLAGS_REG)
10905         (compare
10906           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10907                        (match_operand:QI 2 "const_int_operand" "n"))
10908           (const_int 0)))
10909    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10910         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10911   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10912    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10913   "sar{q}\t{%2, %0|%0, %2}"
10914   [(set_attr "type" "ishift")
10915    (set_attr "mode" "DI")])
10917 (define_insn "*ashrdi3_1"
10918   [(set (match_operand:DI 0 "register_operand" "=r")
10919         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10920                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10921    (clobber (reg:CC FLAGS_REG))]
10922   "!TARGET_64BIT"
10923   "#"
10924   [(set_attr "type" "multi")])
10926 ;; By default we don't ask for a scratch register, because when DImode
10927 ;; values are manipulated, registers are already at a premium.  But if
10928 ;; we have one handy, we won't turn it away.
10929 (define_peephole2
10930   [(match_scratch:SI 3 "r")
10931    (parallel [(set (match_operand:DI 0 "register_operand" "")
10932                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10933                                 (match_operand:QI 2 "nonmemory_operand" "")))
10934               (clobber (reg:CC FLAGS_REG))])
10935    (match_dup 3)]
10936   "!TARGET_64BIT && TARGET_CMOVE"
10937   [(const_int 0)]
10938   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10940 (define_split
10941   [(set (match_operand:DI 0 "register_operand" "")
10942         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10943                      (match_operand:QI 2 "nonmemory_operand" "")))
10944    (clobber (reg:CC FLAGS_REG))]
10945   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10946   [(const_int 0)]
10947   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10949 (define_insn "x86_shrd_1"
10950   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10951         (ior:SI (ashiftrt:SI (match_dup 0)
10952                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10953                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10954                   (minus:QI (const_int 32) (match_dup 2)))))
10955    (clobber (reg:CC FLAGS_REG))]
10956   ""
10957   "@
10958    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10959    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10960   [(set_attr "type" "ishift")
10961    (set_attr "prefix_0f" "1")
10962    (set_attr "pent_pair" "np")
10963    (set_attr "mode" "SI")])
10965 (define_expand "x86_shift_adj_3"
10966   [(use (match_operand:SI 0 "register_operand" ""))
10967    (use (match_operand:SI 1 "register_operand" ""))
10968    (use (match_operand:QI 2 "register_operand" ""))]
10969   ""
10971   rtx label = gen_label_rtx ();
10972   rtx tmp;
10974   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10976   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10977   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10978   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10979                               gen_rtx_LABEL_REF (VOIDmode, label),
10980                               pc_rtx);
10981   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10982   JUMP_LABEL (tmp) = label;
10984   emit_move_insn (operands[0], operands[1]);
10985   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10987   emit_label (label);
10988   LABEL_NUSES (label) = 1;
10990   DONE;
10993 (define_insn "ashrsi3_31"
10994   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10995         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10996                      (match_operand:SI 2 "const_int_operand" "i,i")))
10997    (clobber (reg:CC FLAGS_REG))]
10998   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10999    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11000   "@
11001    {cltd|cdq}
11002    sar{l}\t{%2, %0|%0, %2}"
11003   [(set_attr "type" "imovx,ishift")
11004    (set_attr "prefix_0f" "0,*")
11005    (set_attr "length_immediate" "0,*")
11006    (set_attr "modrm" "0,1")
11007    (set_attr "mode" "SI")])
11009 (define_insn "*ashrsi3_31_zext"
11010   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11011         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11012                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11013    (clobber (reg:CC FLAGS_REG))]
11014   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11015    && INTVAL (operands[2]) == 31
11016    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11017   "@
11018    {cltd|cdq}
11019    sar{l}\t{%2, %k0|%k0, %2}"
11020   [(set_attr "type" "imovx,ishift")
11021    (set_attr "prefix_0f" "0,*")
11022    (set_attr "length_immediate" "0,*")
11023    (set_attr "modrm" "0,1")
11024    (set_attr "mode" "SI")])
11026 (define_expand "ashrsi3"
11027   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11028         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11029                      (match_operand:QI 2 "nonmemory_operand" "")))
11030    (clobber (reg:CC FLAGS_REG))]
11031   ""
11032   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11034 (define_insn "*ashrsi3_1_one_bit"
11035   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11036         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11037                      (match_operand:QI 2 "const1_operand" "")))
11038    (clobber (reg:CC FLAGS_REG))]
11039   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11040    && (TARGET_SHIFT1 || optimize_size)"
11041   "sar{l}\t%0"
11042   [(set_attr "type" "ishift")
11043    (set (attr "length") 
11044      (if_then_else (match_operand:SI 0 "register_operand" "") 
11045         (const_string "2")
11046         (const_string "*")))])
11048 (define_insn "*ashrsi3_1_one_bit_zext"
11049   [(set (match_operand:DI 0 "register_operand" "=r")
11050         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11051                                      (match_operand:QI 2 "const1_operand" ""))))
11052    (clobber (reg:CC FLAGS_REG))]
11053   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11054    && (TARGET_SHIFT1 || optimize_size)"
11055   "sar{l}\t%k0"
11056   [(set_attr "type" "ishift")
11057    (set_attr "length" "2")])
11059 (define_insn "*ashrsi3_1"
11060   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11061         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11062                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11063    (clobber (reg:CC FLAGS_REG))]
11064   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11065   "@
11066    sar{l}\t{%2, %0|%0, %2}
11067    sar{l}\t{%b2, %0|%0, %b2}"
11068   [(set_attr "type" "ishift")
11069    (set_attr "mode" "SI")])
11071 (define_insn "*ashrsi3_1_zext"
11072   [(set (match_operand:DI 0 "register_operand" "=r,r")
11073         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11074                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11075    (clobber (reg:CC FLAGS_REG))]
11076   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11077   "@
11078    sar{l}\t{%2, %k0|%k0, %2}
11079    sar{l}\t{%b2, %k0|%k0, %b2}"
11080   [(set_attr "type" "ishift")
11081    (set_attr "mode" "SI")])
11083 ;; This pattern can't accept a variable shift count, since shifts by
11084 ;; zero don't affect the flags.  We assume that shifts by constant
11085 ;; zero are optimized away.
11086 (define_insn "*ashrsi3_one_bit_cmp"
11087   [(set (reg FLAGS_REG)
11088         (compare
11089           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11090                        (match_operand:QI 2 "const1_operand" ""))
11091           (const_int 0)))
11092    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11093         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11094   "ix86_match_ccmode (insn, CCGOCmode)
11095    && (TARGET_SHIFT1 || optimize_size)
11096    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11097   "sar{l}\t%0"
11098   [(set_attr "type" "ishift")
11099    (set (attr "length") 
11100      (if_then_else (match_operand:SI 0 "register_operand" "") 
11101         (const_string "2")
11102         (const_string "*")))])
11104 (define_insn "*ashrsi3_one_bit_cmp_zext"
11105   [(set (reg FLAGS_REG)
11106         (compare
11107           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11108                        (match_operand:QI 2 "const1_operand" ""))
11109           (const_int 0)))
11110    (set (match_operand:DI 0 "register_operand" "=r")
11111         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11112   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11113    && (TARGET_SHIFT1 || optimize_size)
11114    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11115   "sar{l}\t%k0"
11116   [(set_attr "type" "ishift")
11117    (set_attr "length" "2")])
11119 ;; This pattern can't accept a variable shift count, since shifts by
11120 ;; zero don't affect the flags.  We assume that shifts by constant
11121 ;; zero are optimized away.
11122 (define_insn "*ashrsi3_cmp"
11123   [(set (reg FLAGS_REG)
11124         (compare
11125           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11126                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11127           (const_int 0)))
11128    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11129         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11130   "ix86_match_ccmode (insn, CCGOCmode)
11131    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11132   "sar{l}\t{%2, %0|%0, %2}"
11133   [(set_attr "type" "ishift")
11134    (set_attr "mode" "SI")])
11136 (define_insn "*ashrsi3_cmp_zext"
11137   [(set (reg FLAGS_REG)
11138         (compare
11139           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11140                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11141           (const_int 0)))
11142    (set (match_operand:DI 0 "register_operand" "=r")
11143         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11144   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11145    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11146   "sar{l}\t{%2, %k0|%k0, %2}"
11147   [(set_attr "type" "ishift")
11148    (set_attr "mode" "SI")])
11150 (define_expand "ashrhi3"
11151   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11152         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11153                      (match_operand:QI 2 "nonmemory_operand" "")))
11154    (clobber (reg:CC FLAGS_REG))]
11155   "TARGET_HIMODE_MATH"
11156   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11158 (define_insn "*ashrhi3_1_one_bit"
11159   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11160         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11161                      (match_operand:QI 2 "const1_operand" "")))
11162    (clobber (reg:CC FLAGS_REG))]
11163   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11164    && (TARGET_SHIFT1 || optimize_size)"
11165   "sar{w}\t%0"
11166   [(set_attr "type" "ishift")
11167    (set (attr "length") 
11168      (if_then_else (match_operand 0 "register_operand" "") 
11169         (const_string "2")
11170         (const_string "*")))])
11172 (define_insn "*ashrhi3_1"
11173   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11174         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11175                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11176    (clobber (reg:CC FLAGS_REG))]
11177   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11178   "@
11179    sar{w}\t{%2, %0|%0, %2}
11180    sar{w}\t{%b2, %0|%0, %b2}"
11181   [(set_attr "type" "ishift")
11182    (set_attr "mode" "HI")])
11184 ;; This pattern can't accept a variable shift count, since shifts by
11185 ;; zero don't affect the flags.  We assume that shifts by constant
11186 ;; zero are optimized away.
11187 (define_insn "*ashrhi3_one_bit_cmp"
11188   [(set (reg FLAGS_REG)
11189         (compare
11190           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11191                        (match_operand:QI 2 "const1_operand" ""))
11192           (const_int 0)))
11193    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11194         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11195   "ix86_match_ccmode (insn, CCGOCmode)
11196    && (TARGET_SHIFT1 || optimize_size)
11197    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11198   "sar{w}\t%0"
11199   [(set_attr "type" "ishift")
11200    (set (attr "length") 
11201      (if_then_else (match_operand 0 "register_operand" "") 
11202         (const_string "2")
11203         (const_string "*")))])
11205 ;; This pattern can't accept a variable shift count, since shifts by
11206 ;; zero don't affect the flags.  We assume that shifts by constant
11207 ;; zero are optimized away.
11208 (define_insn "*ashrhi3_cmp"
11209   [(set (reg FLAGS_REG)
11210         (compare
11211           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11212                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11213           (const_int 0)))
11214    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11215         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11216   "ix86_match_ccmode (insn, CCGOCmode)
11217    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11218   "sar{w}\t{%2, %0|%0, %2}"
11219   [(set_attr "type" "ishift")
11220    (set_attr "mode" "HI")])
11222 (define_expand "ashrqi3"
11223   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11224         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11225                      (match_operand:QI 2 "nonmemory_operand" "")))
11226    (clobber (reg:CC FLAGS_REG))]
11227   "TARGET_QIMODE_MATH"
11228   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11230 (define_insn "*ashrqi3_1_one_bit"
11231   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11232         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11233                      (match_operand:QI 2 "const1_operand" "")))
11234    (clobber (reg:CC FLAGS_REG))]
11235   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11236    && (TARGET_SHIFT1 || optimize_size)"
11237   "sar{b}\t%0"
11238   [(set_attr "type" "ishift")
11239    (set (attr "length") 
11240      (if_then_else (match_operand 0 "register_operand" "") 
11241         (const_string "2")
11242         (const_string "*")))])
11244 (define_insn "*ashrqi3_1_one_bit_slp"
11245   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11246         (ashiftrt:QI (match_dup 0)
11247                      (match_operand:QI 1 "const1_operand" "")))
11248    (clobber (reg:CC FLAGS_REG))]
11249   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11250    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11251    && (TARGET_SHIFT1 || optimize_size)"
11252   "sar{b}\t%0"
11253   [(set_attr "type" "ishift1")
11254    (set (attr "length") 
11255      (if_then_else (match_operand 0 "register_operand" "") 
11256         (const_string "2")
11257         (const_string "*")))])
11259 (define_insn "*ashrqi3_1"
11260   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11261         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11262                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11263    (clobber (reg:CC FLAGS_REG))]
11264   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11265   "@
11266    sar{b}\t{%2, %0|%0, %2}
11267    sar{b}\t{%b2, %0|%0, %b2}"
11268   [(set_attr "type" "ishift")
11269    (set_attr "mode" "QI")])
11271 (define_insn "*ashrqi3_1_slp"
11272   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11273         (ashiftrt:QI (match_dup 0)
11274                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11275    (clobber (reg:CC FLAGS_REG))]
11276   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11277    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11278   "@
11279    sar{b}\t{%1, %0|%0, %1}
11280    sar{b}\t{%b1, %0|%0, %b1}"
11281   [(set_attr "type" "ishift1")
11282    (set_attr "mode" "QI")])
11284 ;; This pattern can't accept a variable shift count, since shifts by
11285 ;; zero don't affect the flags.  We assume that shifts by constant
11286 ;; zero are optimized away.
11287 (define_insn "*ashrqi3_one_bit_cmp"
11288   [(set (reg FLAGS_REG)
11289         (compare
11290           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11291                        (match_operand:QI 2 "const1_operand" "I"))
11292           (const_int 0)))
11293    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11294         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11295   "ix86_match_ccmode (insn, CCGOCmode)
11296    && (TARGET_SHIFT1 || optimize_size)
11297    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11298   "sar{b}\t%0"
11299   [(set_attr "type" "ishift")
11300    (set (attr "length") 
11301      (if_then_else (match_operand 0 "register_operand" "") 
11302         (const_string "2")
11303         (const_string "*")))])
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 "*ashrqi3_cmp"
11309   [(set (reg FLAGS_REG)
11310         (compare
11311           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11312                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11313           (const_int 0)))
11314    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11315         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11316   "ix86_match_ccmode (insn, CCGOCmode)
11317    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11318   "sar{b}\t{%2, %0|%0, %2}"
11319   [(set_attr "type" "ishift")
11320    (set_attr "mode" "QI")])
11322 ;; Logical shift instructions
11324 ;; See comment above `ashldi3' about how this works.
11326 (define_expand "lshrdi3"
11327   [(set (match_operand:DI 0 "shiftdi_operand" "")
11328         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11329                      (match_operand:QI 2 "nonmemory_operand" "")))]
11330   ""
11331   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11333 (define_insn "*lshrdi3_1_one_bit_rex64"
11334   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11335         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11336                      (match_operand:QI 2 "const1_operand" "")))
11337    (clobber (reg:CC FLAGS_REG))]
11338   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11339    && (TARGET_SHIFT1 || optimize_size)"
11340   "shr{q}\t%0"
11341   [(set_attr "type" "ishift")
11342    (set (attr "length") 
11343      (if_then_else (match_operand:DI 0 "register_operand" "") 
11344         (const_string "2")
11345         (const_string "*")))])
11347 (define_insn "*lshrdi3_1_rex64"
11348   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11349         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11350                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11351    (clobber (reg:CC FLAGS_REG))]
11352   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11353   "@
11354    shr{q}\t{%2, %0|%0, %2}
11355    shr{q}\t{%b2, %0|%0, %b2}"
11356   [(set_attr "type" "ishift")
11357    (set_attr "mode" "DI")])
11359 ;; This pattern can't accept a variable shift count, since shifts by
11360 ;; zero don't affect the flags.  We assume that shifts by constant
11361 ;; zero are optimized away.
11362 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11363   [(set (reg FLAGS_REG)
11364         (compare
11365           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11366                        (match_operand:QI 2 "const1_operand" ""))
11367           (const_int 0)))
11368    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11369         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11370   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11371    && (TARGET_SHIFT1 || optimize_size)
11372    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11373   "shr{q}\t%0"
11374   [(set_attr "type" "ishift")
11375    (set (attr "length") 
11376      (if_then_else (match_operand:DI 0 "register_operand" "") 
11377         (const_string "2")
11378         (const_string "*")))])
11380 ;; This pattern can't accept a variable shift count, since shifts by
11381 ;; zero don't affect the flags.  We assume that shifts by constant
11382 ;; zero are optimized away.
11383 (define_insn "*lshrdi3_cmp_rex64"
11384   [(set (reg FLAGS_REG)
11385         (compare
11386           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11387                        (match_operand:QI 2 "const_int_operand" "e"))
11388           (const_int 0)))
11389    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11390         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11391   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11392    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11393   "shr{q}\t{%2, %0|%0, %2}"
11394   [(set_attr "type" "ishift")
11395    (set_attr "mode" "DI")])
11397 (define_insn "*lshrdi3_1"
11398   [(set (match_operand:DI 0 "register_operand" "=r")
11399         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11400                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "!TARGET_64BIT"
11403   "#"
11404   [(set_attr "type" "multi")])
11406 ;; By default we don't ask for a scratch register, because when DImode
11407 ;; values are manipulated, registers are already at a premium.  But if
11408 ;; we have one handy, we won't turn it away.
11409 (define_peephole2
11410   [(match_scratch:SI 3 "r")
11411    (parallel [(set (match_operand:DI 0 "register_operand" "")
11412                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11413                                 (match_operand:QI 2 "nonmemory_operand" "")))
11414               (clobber (reg:CC FLAGS_REG))])
11415    (match_dup 3)]
11416   "!TARGET_64BIT && TARGET_CMOVE"
11417   [(const_int 0)]
11418   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11420 (define_split 
11421   [(set (match_operand:DI 0 "register_operand" "")
11422         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11423                      (match_operand:QI 2 "nonmemory_operand" "")))
11424    (clobber (reg:CC FLAGS_REG))]
11425   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11426   [(const_int 0)]
11427   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11429 (define_expand "lshrsi3"
11430   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11431         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11432                      (match_operand:QI 2 "nonmemory_operand" "")))
11433    (clobber (reg:CC FLAGS_REG))]
11434   ""
11435   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11437 (define_insn "*lshrsi3_1_one_bit"
11438   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11439         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11440                      (match_operand:QI 2 "const1_operand" "")))
11441    (clobber (reg:CC FLAGS_REG))]
11442   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11443    && (TARGET_SHIFT1 || optimize_size)"
11444   "shr{l}\t%0"
11445   [(set_attr "type" "ishift")
11446    (set (attr "length") 
11447      (if_then_else (match_operand:SI 0 "register_operand" "") 
11448         (const_string "2")
11449         (const_string "*")))])
11451 (define_insn "*lshrsi3_1_one_bit_zext"
11452   [(set (match_operand:DI 0 "register_operand" "=r")
11453         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11454                      (match_operand:QI 2 "const1_operand" "")))
11455    (clobber (reg:CC FLAGS_REG))]
11456   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11457    && (TARGET_SHIFT1 || optimize_size)"
11458   "shr{l}\t%k0"
11459   [(set_attr "type" "ishift")
11460    (set_attr "length" "2")])
11462 (define_insn "*lshrsi3_1"
11463   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11464         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11465                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11466    (clobber (reg:CC FLAGS_REG))]
11467   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11468   "@
11469    shr{l}\t{%2, %0|%0, %2}
11470    shr{l}\t{%b2, %0|%0, %b2}"
11471   [(set_attr "type" "ishift")
11472    (set_attr "mode" "SI")])
11474 (define_insn "*lshrsi3_1_zext"
11475   [(set (match_operand:DI 0 "register_operand" "=r,r")
11476         (zero_extend:DI
11477           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11478                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11479    (clobber (reg:CC FLAGS_REG))]
11480   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11481   "@
11482    shr{l}\t{%2, %k0|%k0, %2}
11483    shr{l}\t{%b2, %k0|%k0, %b2}"
11484   [(set_attr "type" "ishift")
11485    (set_attr "mode" "SI")])
11487 ;; This pattern can't accept a variable shift count, since shifts by
11488 ;; zero don't affect the flags.  We assume that shifts by constant
11489 ;; zero are optimized away.
11490 (define_insn "*lshrsi3_one_bit_cmp"
11491   [(set (reg FLAGS_REG)
11492         (compare
11493           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11494                        (match_operand:QI 2 "const1_operand" ""))
11495           (const_int 0)))
11496    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11497         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11498   "ix86_match_ccmode (insn, CCGOCmode)
11499    && (TARGET_SHIFT1 || optimize_size)
11500    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11501   "shr{l}\t%0"
11502   [(set_attr "type" "ishift")
11503    (set (attr "length") 
11504      (if_then_else (match_operand:SI 0 "register_operand" "") 
11505         (const_string "2")
11506         (const_string "*")))])
11508 (define_insn "*lshrsi3_cmp_one_bit_zext"
11509   [(set (reg FLAGS_REG)
11510         (compare
11511           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11512                        (match_operand:QI 2 "const1_operand" ""))
11513           (const_int 0)))
11514    (set (match_operand:DI 0 "register_operand" "=r")
11515         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11516   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11517    && (TARGET_SHIFT1 || optimize_size)
11518    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11519   "shr{l}\t%k0"
11520   [(set_attr "type" "ishift")
11521    (set_attr "length" "2")])
11523 ;; This pattern can't accept a variable shift count, since shifts by
11524 ;; zero don't affect the flags.  We assume that shifts by constant
11525 ;; zero are optimized away.
11526 (define_insn "*lshrsi3_cmp"
11527   [(set (reg FLAGS_REG)
11528         (compare
11529           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11530                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11531           (const_int 0)))
11532    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11533         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11534   "ix86_match_ccmode (insn, CCGOCmode)
11535    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11536   "shr{l}\t{%2, %0|%0, %2}"
11537   [(set_attr "type" "ishift")
11538    (set_attr "mode" "SI")])
11540 (define_insn "*lshrsi3_cmp_zext"
11541   [(set (reg FLAGS_REG)
11542         (compare
11543           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11544                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11545           (const_int 0)))
11546    (set (match_operand:DI 0 "register_operand" "=r")
11547         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11548   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11549    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11550   "shr{l}\t{%2, %k0|%k0, %2}"
11551   [(set_attr "type" "ishift")
11552    (set_attr "mode" "SI")])
11554 (define_expand "lshrhi3"
11555   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11556         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11557                      (match_operand:QI 2 "nonmemory_operand" "")))
11558    (clobber (reg:CC FLAGS_REG))]
11559   "TARGET_HIMODE_MATH"
11560   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11562 (define_insn "*lshrhi3_1_one_bit"
11563   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11564         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11565                      (match_operand:QI 2 "const1_operand" "")))
11566    (clobber (reg:CC FLAGS_REG))]
11567   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11568    && (TARGET_SHIFT1 || optimize_size)"
11569   "shr{w}\t%0"
11570   [(set_attr "type" "ishift")
11571    (set (attr "length") 
11572      (if_then_else (match_operand 0 "register_operand" "") 
11573         (const_string "2")
11574         (const_string "*")))])
11576 (define_insn "*lshrhi3_1"
11577   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11578         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11579                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11580    (clobber (reg:CC FLAGS_REG))]
11581   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11582   "@
11583    shr{w}\t{%2, %0|%0, %2}
11584    shr{w}\t{%b2, %0|%0, %b2}"
11585   [(set_attr "type" "ishift")
11586    (set_attr "mode" "HI")])
11588 ;; This pattern can't accept a variable shift count, since shifts by
11589 ;; zero don't affect the flags.  We assume that shifts by constant
11590 ;; zero are optimized away.
11591 (define_insn "*lshrhi3_one_bit_cmp"
11592   [(set (reg FLAGS_REG)
11593         (compare
11594           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11595                        (match_operand:QI 2 "const1_operand" ""))
11596           (const_int 0)))
11597    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11598         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11599   "ix86_match_ccmode (insn, CCGOCmode)
11600    && (TARGET_SHIFT1 || optimize_size)
11601    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11602   "shr{w}\t%0"
11603   [(set_attr "type" "ishift")
11604    (set (attr "length") 
11605      (if_then_else (match_operand:SI 0 "register_operand" "") 
11606         (const_string "2")
11607         (const_string "*")))])
11609 ;; This pattern can't accept a variable shift count, since shifts by
11610 ;; zero don't affect the flags.  We assume that shifts by constant
11611 ;; zero are optimized away.
11612 (define_insn "*lshrhi3_cmp"
11613   [(set (reg FLAGS_REG)
11614         (compare
11615           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11616                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11617           (const_int 0)))
11618    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11619         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11620   "ix86_match_ccmode (insn, CCGOCmode)
11621    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11622   "shr{w}\t{%2, %0|%0, %2}"
11623   [(set_attr "type" "ishift")
11624    (set_attr "mode" "HI")])
11626 (define_expand "lshrqi3"
11627   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11628         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11629                      (match_operand:QI 2 "nonmemory_operand" "")))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "TARGET_QIMODE_MATH"
11632   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11634 (define_insn "*lshrqi3_1_one_bit"
11635   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11636         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11637                      (match_operand:QI 2 "const1_operand" "")))
11638    (clobber (reg:CC FLAGS_REG))]
11639   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11640    && (TARGET_SHIFT1 || optimize_size)"
11641   "shr{b}\t%0"
11642   [(set_attr "type" "ishift")
11643    (set (attr "length") 
11644      (if_then_else (match_operand 0 "register_operand" "") 
11645         (const_string "2")
11646         (const_string "*")))])
11648 (define_insn "*lshrqi3_1_one_bit_slp"
11649   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11650         (lshiftrt:QI (match_dup 0)
11651                      (match_operand:QI 1 "const1_operand" "")))
11652    (clobber (reg:CC FLAGS_REG))]
11653   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11654    && (TARGET_SHIFT1 || optimize_size)"
11655   "shr{b}\t%0"
11656   [(set_attr "type" "ishift1")
11657    (set (attr "length") 
11658      (if_then_else (match_operand 0 "register_operand" "") 
11659         (const_string "2")
11660         (const_string "*")))])
11662 (define_insn "*lshrqi3_1"
11663   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11664         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11665                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11666    (clobber (reg:CC FLAGS_REG))]
11667   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11668   "@
11669    shr{b}\t{%2, %0|%0, %2}
11670    shr{b}\t{%b2, %0|%0, %b2}"
11671   [(set_attr "type" "ishift")
11672    (set_attr "mode" "QI")])
11674 (define_insn "*lshrqi3_1_slp"
11675   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11676         (lshiftrt:QI (match_dup 0)
11677                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11678    (clobber (reg:CC FLAGS_REG))]
11679   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11680    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11681   "@
11682    shr{b}\t{%1, %0|%0, %1}
11683    shr{b}\t{%b1, %0|%0, %b1}"
11684   [(set_attr "type" "ishift1")
11685    (set_attr "mode" "QI")])
11687 ;; This pattern can't accept a variable shift count, since shifts by
11688 ;; zero don't affect the flags.  We assume that shifts by constant
11689 ;; zero are optimized away.
11690 (define_insn "*lshrqi2_one_bit_cmp"
11691   [(set (reg FLAGS_REG)
11692         (compare
11693           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11694                        (match_operand:QI 2 "const1_operand" ""))
11695           (const_int 0)))
11696    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11697         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11698   "ix86_match_ccmode (insn, CCGOCmode)
11699    && (TARGET_SHIFT1 || optimize_size)
11700    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11701   "shr{b}\t%0"
11702   [(set_attr "type" "ishift")
11703    (set (attr "length") 
11704      (if_then_else (match_operand:SI 0 "register_operand" "") 
11705         (const_string "2")
11706         (const_string "*")))])
11708 ;; This pattern can't accept a variable shift count, since shifts by
11709 ;; zero don't affect the flags.  We assume that shifts by constant
11710 ;; zero are optimized away.
11711 (define_insn "*lshrqi2_cmp"
11712   [(set (reg FLAGS_REG)
11713         (compare
11714           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11715                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11716           (const_int 0)))
11717    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11718         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11719   "ix86_match_ccmode (insn, CCGOCmode)
11720    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11721   "shr{b}\t{%2, %0|%0, %2}"
11722   [(set_attr "type" "ishift")
11723    (set_attr "mode" "QI")])
11725 ;; Rotate instructions
11727 (define_expand "rotldi3"
11728   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11729         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11730                    (match_operand:QI 2 "nonmemory_operand" "")))
11731    (clobber (reg:CC FLAGS_REG))]
11732   "TARGET_64BIT"
11733   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11735 (define_insn "*rotlsi3_1_one_bit_rex64"
11736   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11737         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11738                    (match_operand:QI 2 "const1_operand" "")))
11739    (clobber (reg:CC FLAGS_REG))]
11740   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11741    && (TARGET_SHIFT1 || optimize_size)"
11742   "rol{q}\t%0"
11743   [(set_attr "type" "rotate")
11744    (set (attr "length") 
11745      (if_then_else (match_operand:DI 0 "register_operand" "") 
11746         (const_string "2")
11747         (const_string "*")))])
11749 (define_insn "*rotldi3_1_rex64"
11750   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11751         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11752                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11753    (clobber (reg:CC FLAGS_REG))]
11754   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11755   "@
11756    rol{q}\t{%2, %0|%0, %2}
11757    rol{q}\t{%b2, %0|%0, %b2}"
11758   [(set_attr "type" "rotate")
11759    (set_attr "mode" "DI")])
11761 (define_expand "rotlsi3"
11762   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11763         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11764                    (match_operand:QI 2 "nonmemory_operand" "")))
11765    (clobber (reg:CC FLAGS_REG))]
11766   ""
11767   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11769 (define_insn "*rotlsi3_1_one_bit"
11770   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11771         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11772                    (match_operand:QI 2 "const1_operand" "")))
11773    (clobber (reg:CC FLAGS_REG))]
11774   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11775    && (TARGET_SHIFT1 || optimize_size)"
11776   "rol{l}\t%0"
11777   [(set_attr "type" "rotate")
11778    (set (attr "length") 
11779      (if_then_else (match_operand:SI 0 "register_operand" "") 
11780         (const_string "2")
11781         (const_string "*")))])
11783 (define_insn "*rotlsi3_1_one_bit_zext"
11784   [(set (match_operand:DI 0 "register_operand" "=r")
11785         (zero_extend:DI
11786           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11787                      (match_operand:QI 2 "const1_operand" ""))))
11788    (clobber (reg:CC FLAGS_REG))]
11789   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11790    && (TARGET_SHIFT1 || optimize_size)"
11791   "rol{l}\t%k0"
11792   [(set_attr "type" "rotate")
11793    (set_attr "length" "2")])
11795 (define_insn "*rotlsi3_1"
11796   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11797         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11798                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11799    (clobber (reg:CC FLAGS_REG))]
11800   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11801   "@
11802    rol{l}\t{%2, %0|%0, %2}
11803    rol{l}\t{%b2, %0|%0, %b2}"
11804   [(set_attr "type" "rotate")
11805    (set_attr "mode" "SI")])
11807 (define_insn "*rotlsi3_1_zext"
11808   [(set (match_operand:DI 0 "register_operand" "=r,r")
11809         (zero_extend:DI
11810           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11811                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11812    (clobber (reg:CC FLAGS_REG))]
11813   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11814   "@
11815    rol{l}\t{%2, %k0|%k0, %2}
11816    rol{l}\t{%b2, %k0|%k0, %b2}"
11817   [(set_attr "type" "rotate")
11818    (set_attr "mode" "SI")])
11820 (define_expand "rotlhi3"
11821   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11822         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11823                    (match_operand:QI 2 "nonmemory_operand" "")))
11824    (clobber (reg:CC FLAGS_REG))]
11825   "TARGET_HIMODE_MATH"
11826   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11828 (define_insn "*rotlhi3_1_one_bit"
11829   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11830         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11831                    (match_operand:QI 2 "const1_operand" "")))
11832    (clobber (reg:CC FLAGS_REG))]
11833   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11834    && (TARGET_SHIFT1 || optimize_size)"
11835   "rol{w}\t%0"
11836   [(set_attr "type" "rotate")
11837    (set (attr "length") 
11838      (if_then_else (match_operand 0 "register_operand" "") 
11839         (const_string "2")
11840         (const_string "*")))])
11842 (define_insn "*rotlhi3_1"
11843   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11844         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11845                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11846    (clobber (reg:CC FLAGS_REG))]
11847   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11848   "@
11849    rol{w}\t{%2, %0|%0, %2}
11850    rol{w}\t{%b2, %0|%0, %b2}"
11851   [(set_attr "type" "rotate")
11852    (set_attr "mode" "HI")])
11854 (define_expand "rotlqi3"
11855   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11856         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11857                    (match_operand:QI 2 "nonmemory_operand" "")))
11858    (clobber (reg:CC FLAGS_REG))]
11859   "TARGET_QIMODE_MATH"
11860   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11862 (define_insn "*rotlqi3_1_one_bit_slp"
11863   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11864         (rotate:QI (match_dup 0)
11865                    (match_operand:QI 1 "const1_operand" "")))
11866    (clobber (reg:CC FLAGS_REG))]
11867   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11868    && (TARGET_SHIFT1 || optimize_size)"
11869   "rol{b}\t%0"
11870   [(set_attr "type" "rotate1")
11871    (set (attr "length") 
11872      (if_then_else (match_operand 0 "register_operand" "") 
11873         (const_string "2")
11874         (const_string "*")))])
11876 (define_insn "*rotlqi3_1_one_bit"
11877   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11878         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11879                    (match_operand:QI 2 "const1_operand" "")))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11882    && (TARGET_SHIFT1 || optimize_size)"
11883   "rol{b}\t%0"
11884   [(set_attr "type" "rotate")
11885    (set (attr "length") 
11886      (if_then_else (match_operand 0 "register_operand" "") 
11887         (const_string "2")
11888         (const_string "*")))])
11890 (define_insn "*rotlqi3_1_slp"
11891   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11892         (rotate:QI (match_dup 0)
11893                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11894    (clobber (reg:CC FLAGS_REG))]
11895   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11896    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11897   "@
11898    rol{b}\t{%1, %0|%0, %1}
11899    rol{b}\t{%b1, %0|%0, %b1}"
11900   [(set_attr "type" "rotate1")
11901    (set_attr "mode" "QI")])
11903 (define_insn "*rotlqi3_1"
11904   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11905         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11906                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11907    (clobber (reg:CC FLAGS_REG))]
11908   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11909   "@
11910    rol{b}\t{%2, %0|%0, %2}
11911    rol{b}\t{%b2, %0|%0, %b2}"
11912   [(set_attr "type" "rotate")
11913    (set_attr "mode" "QI")])
11915 (define_expand "rotrdi3"
11916   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11917         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11918                      (match_operand:QI 2 "nonmemory_operand" "")))
11919    (clobber (reg:CC FLAGS_REG))]
11920   "TARGET_64BIT"
11921   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11923 (define_insn "*rotrdi3_1_one_bit_rex64"
11924   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11925         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11926                      (match_operand:QI 2 "const1_operand" "")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11929    && (TARGET_SHIFT1 || optimize_size)"
11930   "ror{q}\t%0"
11931   [(set_attr "type" "rotate")
11932    (set (attr "length") 
11933      (if_then_else (match_operand:DI 0 "register_operand" "") 
11934         (const_string "2")
11935         (const_string "*")))])
11937 (define_insn "*rotrdi3_1_rex64"
11938   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11939         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11940                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11941    (clobber (reg:CC FLAGS_REG))]
11942   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11943   "@
11944    ror{q}\t{%2, %0|%0, %2}
11945    ror{q}\t{%b2, %0|%0, %b2}"
11946   [(set_attr "type" "rotate")
11947    (set_attr "mode" "DI")])
11949 (define_expand "rotrsi3"
11950   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11951         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11952                      (match_operand:QI 2 "nonmemory_operand" "")))
11953    (clobber (reg:CC FLAGS_REG))]
11954   ""
11955   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11957 (define_insn "*rotrsi3_1_one_bit"
11958   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11959         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11960                      (match_operand:QI 2 "const1_operand" "")))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11963    && (TARGET_SHIFT1 || optimize_size)"
11964   "ror{l}\t%0"
11965   [(set_attr "type" "rotate")
11966    (set (attr "length") 
11967      (if_then_else (match_operand:SI 0 "register_operand" "") 
11968         (const_string "2")
11969         (const_string "*")))])
11971 (define_insn "*rotrsi3_1_one_bit_zext"
11972   [(set (match_operand:DI 0 "register_operand" "=r")
11973         (zero_extend:DI
11974           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11975                        (match_operand:QI 2 "const1_operand" ""))))
11976    (clobber (reg:CC FLAGS_REG))]
11977   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11978    && (TARGET_SHIFT1 || optimize_size)"
11979   "ror{l}\t%k0"
11980   [(set_attr "type" "rotate")
11981    (set (attr "length") 
11982      (if_then_else (match_operand:SI 0 "register_operand" "") 
11983         (const_string "2")
11984         (const_string "*")))])
11986 (define_insn "*rotrsi3_1"
11987   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11988         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11989                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11990    (clobber (reg:CC FLAGS_REG))]
11991   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11992   "@
11993    ror{l}\t{%2, %0|%0, %2}
11994    ror{l}\t{%b2, %0|%0, %b2}"
11995   [(set_attr "type" "rotate")
11996    (set_attr "mode" "SI")])
11998 (define_insn "*rotrsi3_1_zext"
11999   [(set (match_operand:DI 0 "register_operand" "=r,r")
12000         (zero_extend:DI
12001           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12002                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12005   "@
12006    ror{l}\t{%2, %k0|%k0, %2}
12007    ror{l}\t{%b2, %k0|%k0, %b2}"
12008   [(set_attr "type" "rotate")
12009    (set_attr "mode" "SI")])
12011 (define_expand "rotrhi3"
12012   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12013         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12014                      (match_operand:QI 2 "nonmemory_operand" "")))
12015    (clobber (reg:CC FLAGS_REG))]
12016   "TARGET_HIMODE_MATH"
12017   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12019 (define_insn "*rotrhi3_one_bit"
12020   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12021         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12022                      (match_operand:QI 2 "const1_operand" "")))
12023    (clobber (reg:CC FLAGS_REG))]
12024   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12025    && (TARGET_SHIFT1 || optimize_size)"
12026   "ror{w}\t%0"
12027   [(set_attr "type" "rotate")
12028    (set (attr "length") 
12029      (if_then_else (match_operand 0 "register_operand" "") 
12030         (const_string "2")
12031         (const_string "*")))])
12033 (define_insn "*rotrhi3"
12034   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12035         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12036                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12037    (clobber (reg:CC FLAGS_REG))]
12038   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12039   "@
12040    ror{w}\t{%2, %0|%0, %2}
12041    ror{w}\t{%b2, %0|%0, %b2}"
12042   [(set_attr "type" "rotate")
12043    (set_attr "mode" "HI")])
12045 (define_expand "rotrqi3"
12046   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12047         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12048                      (match_operand:QI 2 "nonmemory_operand" "")))
12049    (clobber (reg:CC FLAGS_REG))]
12050   "TARGET_QIMODE_MATH"
12051   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12053 (define_insn "*rotrqi3_1_one_bit"
12054   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12055         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12056                      (match_operand:QI 2 "const1_operand" "")))
12057    (clobber (reg:CC FLAGS_REG))]
12058   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12059    && (TARGET_SHIFT1 || optimize_size)"
12060   "ror{b}\t%0"
12061   [(set_attr "type" "rotate")
12062    (set (attr "length") 
12063      (if_then_else (match_operand 0 "register_operand" "") 
12064         (const_string "2")
12065         (const_string "*")))])
12067 (define_insn "*rotrqi3_1_one_bit_slp"
12068   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12069         (rotatert:QI (match_dup 0)
12070                      (match_operand:QI 1 "const1_operand" "")))
12071    (clobber (reg:CC FLAGS_REG))]
12072   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12073    && (TARGET_SHIFT1 || optimize_size)"
12074   "ror{b}\t%0"
12075   [(set_attr "type" "rotate1")
12076    (set (attr "length") 
12077      (if_then_else (match_operand 0 "register_operand" "") 
12078         (const_string "2")
12079         (const_string "*")))])
12081 (define_insn "*rotrqi3_1"
12082   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12083         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12084                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12085    (clobber (reg:CC FLAGS_REG))]
12086   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12087   "@
12088    ror{b}\t{%2, %0|%0, %2}
12089    ror{b}\t{%b2, %0|%0, %b2}"
12090   [(set_attr "type" "rotate")
12091    (set_attr "mode" "QI")])
12093 (define_insn "*rotrqi3_1_slp"
12094   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12095         (rotatert:QI (match_dup 0)
12096                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12097    (clobber (reg:CC FLAGS_REG))]
12098   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12099    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12100   "@
12101    ror{b}\t{%1, %0|%0, %1}
12102    ror{b}\t{%b1, %0|%0, %b1}"
12103   [(set_attr "type" "rotate1")
12104    (set_attr "mode" "QI")])
12106 ;; Bit set / bit test instructions
12108 (define_expand "extv"
12109   [(set (match_operand:SI 0 "register_operand" "")
12110         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12111                          (match_operand:SI 2 "immediate_operand" "")
12112                          (match_operand:SI 3 "immediate_operand" "")))]
12113   ""
12115   /* Handle extractions from %ah et al.  */
12116   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12117     FAIL;
12119   /* From mips.md: extract_bit_field doesn't verify that our source
12120      matches the predicate, so check it again here.  */
12121   if (! ext_register_operand (operands[1], VOIDmode))
12122     FAIL;
12125 (define_expand "extzv"
12126   [(set (match_operand:SI 0 "register_operand" "")
12127         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12128                          (match_operand:SI 2 "immediate_operand" "")
12129                          (match_operand:SI 3 "immediate_operand" "")))]
12130   ""
12132   /* Handle extractions from %ah et al.  */
12133   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12134     FAIL;
12136   /* From mips.md: extract_bit_field doesn't verify that our source
12137      matches the predicate, so check it again here.  */
12138   if (! ext_register_operand (operands[1], VOIDmode))
12139     FAIL;
12142 (define_expand "insv"
12143   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12144                       (match_operand 1 "immediate_operand" "")
12145                       (match_operand 2 "immediate_operand" ""))
12146         (match_operand 3 "register_operand" ""))]
12147   ""
12149   /* Handle extractions from %ah et al.  */
12150   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12151     FAIL;
12153   /* From mips.md: insert_bit_field doesn't verify that our source
12154      matches the predicate, so check it again here.  */
12155   if (! ext_register_operand (operands[0], VOIDmode))
12156     FAIL;
12158   if (TARGET_64BIT)
12159     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12160   else
12161     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12163   DONE;
12166 ;; %%% bts, btr, btc, bt.
12167 ;; In general these instructions are *slow* when applied to memory,
12168 ;; since they enforce atomic operation.  When applied to registers,
12169 ;; it depends on the cpu implementation.  They're never faster than
12170 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12171 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12172 ;; within the instruction itself, so operating on bits in the high
12173 ;; 32-bits of a register becomes easier.
12175 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12176 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12177 ;; negdf respectively, so they can never be disabled entirely.
12179 (define_insn "*btsq"
12180   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12181                          (const_int 1)
12182                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12183         (const_int 1))
12184    (clobber (reg:CC FLAGS_REG))]
12185   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12186   "bts{q} %1,%0"
12187   [(set_attr "type" "alu1")])
12189 (define_insn "*btrq"
12190   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12191                          (const_int 1)
12192                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12193         (const_int 0))
12194    (clobber (reg:CC FLAGS_REG))]
12195   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12196   "btr{q} %1,%0"
12197   [(set_attr "type" "alu1")])
12199 (define_insn "*btcq"
12200   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12201                          (const_int 1)
12202                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12203         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12204    (clobber (reg:CC FLAGS_REG))]
12205   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12206   "btc{q} %1,%0"
12207   [(set_attr "type" "alu1")])
12209 ;; Allow Nocona to avoid these instructions if a register is available.
12211 (define_peephole2
12212   [(match_scratch:DI 2 "r")
12213    (parallel [(set (zero_extract:DI
12214                      (match_operand:DI 0 "register_operand" "")
12215                      (const_int 1)
12216                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12217                    (const_int 1))
12218               (clobber (reg:CC FLAGS_REG))])]
12219   "TARGET_64BIT && !TARGET_USE_BT"
12220   [(const_int 0)]
12222   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12223   rtx op1;
12225   if (HOST_BITS_PER_WIDE_INT >= 64)
12226     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12227   else if (i < HOST_BITS_PER_WIDE_INT)
12228     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12229   else
12230     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12232   op1 = immed_double_const (lo, hi, DImode);
12233   if (i >= 31)
12234     {
12235       emit_move_insn (operands[2], op1);
12236       op1 = operands[2];
12237     }
12239   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12240   DONE;
12243 (define_peephole2
12244   [(match_scratch:DI 2 "r")
12245    (parallel [(set (zero_extract:DI
12246                      (match_operand:DI 0 "register_operand" "")
12247                      (const_int 1)
12248                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12249                    (const_int 0))
12250               (clobber (reg:CC FLAGS_REG))])]
12251   "TARGET_64BIT && !TARGET_USE_BT"
12252   [(const_int 0)]
12254   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12255   rtx op1;
12257   if (HOST_BITS_PER_WIDE_INT >= 64)
12258     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12259   else if (i < HOST_BITS_PER_WIDE_INT)
12260     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12261   else
12262     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12264   op1 = immed_double_const (~lo, ~hi, DImode);
12265   if (i >= 32)
12266     {
12267       emit_move_insn (operands[2], op1);
12268       op1 = operands[2];
12269     }
12271   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12272   DONE;
12275 (define_peephole2
12276   [(match_scratch:DI 2 "r")
12277    (parallel [(set (zero_extract:DI
12278                      (match_operand:DI 0 "register_operand" "")
12279                      (const_int 1)
12280                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12281               (not:DI (zero_extract:DI
12282                         (match_dup 0) (const_int 1) (match_dup 1))))
12283               (clobber (reg:CC FLAGS_REG))])]
12284   "TARGET_64BIT && !TARGET_USE_BT"
12285   [(const_int 0)]
12287   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12288   rtx op1;
12290   if (HOST_BITS_PER_WIDE_INT >= 64)
12291     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12292   else if (i < HOST_BITS_PER_WIDE_INT)
12293     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12294   else
12295     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12297   op1 = immed_double_const (lo, hi, DImode);
12298   if (i >= 31)
12299     {
12300       emit_move_insn (operands[2], op1);
12301       op1 = operands[2];
12302     }
12304   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12305   DONE;
12308 ;; Store-flag instructions.
12310 ;; For all sCOND expanders, also expand the compare or test insn that
12311 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12313 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12314 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12315 ;; way, which can later delete the movzx if only QImode is needed.
12317 (define_expand "seq"
12318   [(set (match_operand:QI 0 "register_operand" "")
12319         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12320   ""
12321   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12323 (define_expand "sne"
12324   [(set (match_operand:QI 0 "register_operand" "")
12325         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12326   ""
12327   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12329 (define_expand "sgt"
12330   [(set (match_operand:QI 0 "register_operand" "")
12331         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12332   ""
12333   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12335 (define_expand "sgtu"
12336   [(set (match_operand:QI 0 "register_operand" "")
12337         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12338   ""
12339   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12341 (define_expand "slt"
12342   [(set (match_operand:QI 0 "register_operand" "")
12343         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12344   ""
12345   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12347 (define_expand "sltu"
12348   [(set (match_operand:QI 0 "register_operand" "")
12349         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12350   ""
12351   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12353 (define_expand "sge"
12354   [(set (match_operand:QI 0 "register_operand" "")
12355         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12356   ""
12357   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12359 (define_expand "sgeu"
12360   [(set (match_operand:QI 0 "register_operand" "")
12361         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12362   ""
12363   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12365 (define_expand "sle"
12366   [(set (match_operand:QI 0 "register_operand" "")
12367         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12368   ""
12369   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12371 (define_expand "sleu"
12372   [(set (match_operand:QI 0 "register_operand" "")
12373         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12374   ""
12375   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12377 (define_expand "sunordered"
12378   [(set (match_operand:QI 0 "register_operand" "")
12379         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12380   "TARGET_80387 || TARGET_SSE"
12381   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12383 (define_expand "sordered"
12384   [(set (match_operand:QI 0 "register_operand" "")
12385         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12386   "TARGET_80387"
12387   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12389 (define_expand "suneq"
12390   [(set (match_operand:QI 0 "register_operand" "")
12391         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12392   "TARGET_80387 || TARGET_SSE"
12393   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12395 (define_expand "sunge"
12396   [(set (match_operand:QI 0 "register_operand" "")
12397         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12398   "TARGET_80387 || TARGET_SSE"
12399   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12401 (define_expand "sungt"
12402   [(set (match_operand:QI 0 "register_operand" "")
12403         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12404   "TARGET_80387 || TARGET_SSE"
12405   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12407 (define_expand "sunle"
12408   [(set (match_operand:QI 0 "register_operand" "")
12409         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12410   "TARGET_80387 || TARGET_SSE"
12411   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12413 (define_expand "sunlt"
12414   [(set (match_operand:QI 0 "register_operand" "")
12415         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12416   "TARGET_80387 || TARGET_SSE"
12417   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12419 (define_expand "sltgt"
12420   [(set (match_operand:QI 0 "register_operand" "")
12421         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12422   "TARGET_80387 || TARGET_SSE"
12423   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12425 (define_insn "*setcc_1"
12426   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12427         (match_operator:QI 1 "ix86_comparison_operator"
12428           [(reg FLAGS_REG) (const_int 0)]))]
12429   ""
12430   "set%C1\t%0"
12431   [(set_attr "type" "setcc")
12432    (set_attr "mode" "QI")])
12434 (define_insn "*setcc_2"
12435   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12436         (match_operator:QI 1 "ix86_comparison_operator"
12437           [(reg FLAGS_REG) (const_int 0)]))]
12438   ""
12439   "set%C1\t%0"
12440   [(set_attr "type" "setcc")
12441    (set_attr "mode" "QI")])
12443 ;; In general it is not safe to assume too much about CCmode registers,
12444 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12445 ;; conditions this is safe on x86, so help combine not create
12447 ;;      seta    %al
12448 ;;      testb   %al, %al
12449 ;;      sete    %al
12451 (define_split 
12452   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12453         (ne:QI (match_operator 1 "ix86_comparison_operator"
12454                  [(reg FLAGS_REG) (const_int 0)])
12455             (const_int 0)))]
12456   ""
12457   [(set (match_dup 0) (match_dup 1))]
12459   PUT_MODE (operands[1], QImode);
12462 (define_split 
12463   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12464         (ne:QI (match_operator 1 "ix86_comparison_operator"
12465                  [(reg FLAGS_REG) (const_int 0)])
12466             (const_int 0)))]
12467   ""
12468   [(set (match_dup 0) (match_dup 1))]
12470   PUT_MODE (operands[1], QImode);
12473 (define_split 
12474   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12475         (eq:QI (match_operator 1 "ix86_comparison_operator"
12476                  [(reg FLAGS_REG) (const_int 0)])
12477             (const_int 0)))]
12478   ""
12479   [(set (match_dup 0) (match_dup 1))]
12481   rtx new_op1 = copy_rtx (operands[1]);
12482   operands[1] = new_op1;
12483   PUT_MODE (new_op1, QImode);
12484   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12485                                              GET_MODE (XEXP (new_op1, 0))));
12487   /* Make sure that (a) the CCmode we have for the flags is strong
12488      enough for the reversed compare or (b) we have a valid FP compare.  */
12489   if (! ix86_comparison_operator (new_op1, VOIDmode))
12490     FAIL;
12493 (define_split 
12494   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12495         (eq:QI (match_operator 1 "ix86_comparison_operator"
12496                  [(reg FLAGS_REG) (const_int 0)])
12497             (const_int 0)))]
12498   ""
12499   [(set (match_dup 0) (match_dup 1))]
12501   rtx new_op1 = copy_rtx (operands[1]);
12502   operands[1] = new_op1;
12503   PUT_MODE (new_op1, QImode);
12504   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12505                                              GET_MODE (XEXP (new_op1, 0))));
12507   /* Make sure that (a) the CCmode we have for the flags is strong
12508      enough for the reversed compare or (b) we have a valid FP compare.  */
12509   if (! ix86_comparison_operator (new_op1, VOIDmode))
12510     FAIL;
12513 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12514 ;; subsequent logical operations are used to imitate conditional moves.
12515 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12516 ;; it directly.  Further holding this value in pseudo register might bring
12517 ;; problem in implicit normalization in spill code.
12518 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12519 ;; instructions after reload by splitting the conditional move patterns.
12521 (define_insn "*sse_setccsf"
12522   [(set (match_operand:SF 0 "register_operand" "=x")
12523         (match_operator:SF 1 "sse_comparison_operator"
12524           [(match_operand:SF 2 "register_operand" "0")
12525            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12526   "TARGET_SSE && reload_completed"
12527   "cmp%D1ss\t{%3, %0|%0, %3}"
12528   [(set_attr "type" "ssecmp")
12529    (set_attr "mode" "SF")])
12531 (define_insn "*sse_setccdf"
12532   [(set (match_operand:DF 0 "register_operand" "=Y")
12533         (match_operator:DF 1 "sse_comparison_operator"
12534           [(match_operand:DF 2 "register_operand" "0")
12535            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12536   "TARGET_SSE2 && reload_completed"
12537   "cmp%D1sd\t{%3, %0|%0, %3}"
12538   [(set_attr "type" "ssecmp")
12539    (set_attr "mode" "DF")])
12541 ;; Basic conditional jump instructions.
12542 ;; We ignore the overflow flag for signed branch instructions.
12544 ;; For all bCOND expanders, also expand the compare or test insn that
12545 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12547 (define_expand "beq"
12548   [(set (pc)
12549         (if_then_else (match_dup 1)
12550                       (label_ref (match_operand 0 "" ""))
12551                       (pc)))]
12552   ""
12553   "ix86_expand_branch (EQ, operands[0]); DONE;")
12555 (define_expand "bne"
12556   [(set (pc)
12557         (if_then_else (match_dup 1)
12558                       (label_ref (match_operand 0 "" ""))
12559                       (pc)))]
12560   ""
12561   "ix86_expand_branch (NE, operands[0]); DONE;")
12563 (define_expand "bgt"
12564   [(set (pc)
12565         (if_then_else (match_dup 1)
12566                       (label_ref (match_operand 0 "" ""))
12567                       (pc)))]
12568   ""
12569   "ix86_expand_branch (GT, operands[0]); DONE;")
12571 (define_expand "bgtu"
12572   [(set (pc)
12573         (if_then_else (match_dup 1)
12574                       (label_ref (match_operand 0 "" ""))
12575                       (pc)))]
12576   ""
12577   "ix86_expand_branch (GTU, operands[0]); DONE;")
12579 (define_expand "blt"
12580   [(set (pc)
12581         (if_then_else (match_dup 1)
12582                       (label_ref (match_operand 0 "" ""))
12583                       (pc)))]
12584   ""
12585   "ix86_expand_branch (LT, operands[0]); DONE;")
12587 (define_expand "bltu"
12588   [(set (pc)
12589         (if_then_else (match_dup 1)
12590                       (label_ref (match_operand 0 "" ""))
12591                       (pc)))]
12592   ""
12593   "ix86_expand_branch (LTU, operands[0]); DONE;")
12595 (define_expand "bge"
12596   [(set (pc)
12597         (if_then_else (match_dup 1)
12598                       (label_ref (match_operand 0 "" ""))
12599                       (pc)))]
12600   ""
12601   "ix86_expand_branch (GE, operands[0]); DONE;")
12603 (define_expand "bgeu"
12604   [(set (pc)
12605         (if_then_else (match_dup 1)
12606                       (label_ref (match_operand 0 "" ""))
12607                       (pc)))]
12608   ""
12609   "ix86_expand_branch (GEU, operands[0]); DONE;")
12611 (define_expand "ble"
12612   [(set (pc)
12613         (if_then_else (match_dup 1)
12614                       (label_ref (match_operand 0 "" ""))
12615                       (pc)))]
12616   ""
12617   "ix86_expand_branch (LE, operands[0]); DONE;")
12619 (define_expand "bleu"
12620   [(set (pc)
12621         (if_then_else (match_dup 1)
12622                       (label_ref (match_operand 0 "" ""))
12623                       (pc)))]
12624   ""
12625   "ix86_expand_branch (LEU, operands[0]); DONE;")
12627 (define_expand "bunordered"
12628   [(set (pc)
12629         (if_then_else (match_dup 1)
12630                       (label_ref (match_operand 0 "" ""))
12631                       (pc)))]
12632   "TARGET_80387 || TARGET_SSE_MATH"
12633   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12635 (define_expand "bordered"
12636   [(set (pc)
12637         (if_then_else (match_dup 1)
12638                       (label_ref (match_operand 0 "" ""))
12639                       (pc)))]
12640   "TARGET_80387 || TARGET_SSE_MATH"
12641   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12643 (define_expand "buneq"
12644   [(set (pc)
12645         (if_then_else (match_dup 1)
12646                       (label_ref (match_operand 0 "" ""))
12647                       (pc)))]
12648   "TARGET_80387 || TARGET_SSE_MATH"
12649   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12651 (define_expand "bunge"
12652   [(set (pc)
12653         (if_then_else (match_dup 1)
12654                       (label_ref (match_operand 0 "" ""))
12655                       (pc)))]
12656   "TARGET_80387 || TARGET_SSE_MATH"
12657   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12659 (define_expand "bungt"
12660   [(set (pc)
12661         (if_then_else (match_dup 1)
12662                       (label_ref (match_operand 0 "" ""))
12663                       (pc)))]
12664   "TARGET_80387 || TARGET_SSE_MATH"
12665   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12667 (define_expand "bunle"
12668   [(set (pc)
12669         (if_then_else (match_dup 1)
12670                       (label_ref (match_operand 0 "" ""))
12671                       (pc)))]
12672   "TARGET_80387 || TARGET_SSE_MATH"
12673   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12675 (define_expand "bunlt"
12676   [(set (pc)
12677         (if_then_else (match_dup 1)
12678                       (label_ref (match_operand 0 "" ""))
12679                       (pc)))]
12680   "TARGET_80387 || TARGET_SSE_MATH"
12681   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12683 (define_expand "bltgt"
12684   [(set (pc)
12685         (if_then_else (match_dup 1)
12686                       (label_ref (match_operand 0 "" ""))
12687                       (pc)))]
12688   "TARGET_80387 || TARGET_SSE_MATH"
12689   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12691 (define_insn "*jcc_1"
12692   [(set (pc)
12693         (if_then_else (match_operator 1 "ix86_comparison_operator"
12694                                       [(reg FLAGS_REG) (const_int 0)])
12695                       (label_ref (match_operand 0 "" ""))
12696                       (pc)))]
12697   ""
12698   "%+j%C1\t%l0"
12699   [(set_attr "type" "ibr")
12700    (set_attr "modrm" "0")
12701    (set (attr "length")
12702            (if_then_else (and (ge (minus (match_dup 0) (pc))
12703                                   (const_int -126))
12704                               (lt (minus (match_dup 0) (pc))
12705                                   (const_int 128)))
12706              (const_int 2)
12707              (const_int 6)))])
12709 (define_insn "*jcc_2"
12710   [(set (pc)
12711         (if_then_else (match_operator 1 "ix86_comparison_operator"
12712                                       [(reg FLAGS_REG) (const_int 0)])
12713                       (pc)
12714                       (label_ref (match_operand 0 "" ""))))]
12715   ""
12716   "%+j%c1\t%l0"
12717   [(set_attr "type" "ibr")
12718    (set_attr "modrm" "0")
12719    (set (attr "length")
12720            (if_then_else (and (ge (minus (match_dup 0) (pc))
12721                                   (const_int -126))
12722                               (lt (minus (match_dup 0) (pc))
12723                                   (const_int 128)))
12724              (const_int 2)
12725              (const_int 6)))])
12727 ;; In general it is not safe to assume too much about CCmode registers,
12728 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12729 ;; conditions this is safe on x86, so help combine not create
12731 ;;      seta    %al
12732 ;;      testb   %al, %al
12733 ;;      je      Lfoo
12735 (define_split 
12736   [(set (pc)
12737         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12738                                       [(reg FLAGS_REG) (const_int 0)])
12739                           (const_int 0))
12740                       (label_ref (match_operand 1 "" ""))
12741                       (pc)))]
12742   ""
12743   [(set (pc)
12744         (if_then_else (match_dup 0)
12745                       (label_ref (match_dup 1))
12746                       (pc)))]
12748   PUT_MODE (operands[0], VOIDmode);
12750   
12751 (define_split 
12752   [(set (pc)
12753         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12754                                       [(reg FLAGS_REG) (const_int 0)])
12755                           (const_int 0))
12756                       (label_ref (match_operand 1 "" ""))
12757                       (pc)))]
12758   ""
12759   [(set (pc)
12760         (if_then_else (match_dup 0)
12761                       (label_ref (match_dup 1))
12762                       (pc)))]
12764   rtx new_op0 = copy_rtx (operands[0]);
12765   operands[0] = new_op0;
12766   PUT_MODE (new_op0, VOIDmode);
12767   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12768                                              GET_MODE (XEXP (new_op0, 0))));
12770   /* Make sure that (a) the CCmode we have for the flags is strong
12771      enough for the reversed compare or (b) we have a valid FP compare.  */
12772   if (! ix86_comparison_operator (new_op0, VOIDmode))
12773     FAIL;
12776 ;; Define combination compare-and-branch fp compare instructions to use
12777 ;; during early optimization.  Splitting the operation apart early makes
12778 ;; for bad code when we want to reverse the operation.
12780 (define_insn "*fp_jcc_1_mixed"
12781   [(set (pc)
12782         (if_then_else (match_operator 0 "comparison_operator"
12783                         [(match_operand 1 "register_operand" "f#x,x#f")
12784                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12785           (label_ref (match_operand 3 "" ""))
12786           (pc)))
12787    (clobber (reg:CCFP FPSR_REG))
12788    (clobber (reg:CCFP FLAGS_REG))]
12789   "TARGET_MIX_SSE_I387
12790    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12791    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12792    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12793   "#")
12795 (define_insn "*fp_jcc_1_sse"
12796   [(set (pc)
12797         (if_then_else (match_operator 0 "comparison_operator"
12798                         [(match_operand 1 "register_operand" "x")
12799                          (match_operand 2 "nonimmediate_operand" "xm")])
12800           (label_ref (match_operand 3 "" ""))
12801           (pc)))
12802    (clobber (reg:CCFP FPSR_REG))
12803    (clobber (reg:CCFP FLAGS_REG))]
12804   "TARGET_SSE_MATH
12805    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12806    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12807    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12808   "#")
12810 (define_insn "*fp_jcc_1_387"
12811   [(set (pc)
12812         (if_then_else (match_operator 0 "comparison_operator"
12813                         [(match_operand 1 "register_operand" "f")
12814                          (match_operand 2 "register_operand" "f")])
12815           (label_ref (match_operand 3 "" ""))
12816           (pc)))
12817    (clobber (reg:CCFP FPSR_REG))
12818    (clobber (reg:CCFP FLAGS_REG))]
12819   "TARGET_CMOVE && TARGET_80387
12820    && FLOAT_MODE_P (GET_MODE (operands[1]))
12821    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12822    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12823   "#")
12825 (define_insn "*fp_jcc_2_mixed"
12826   [(set (pc)
12827         (if_then_else (match_operator 0 "comparison_operator"
12828                         [(match_operand 1 "register_operand" "f#x,x#f")
12829                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12830           (pc)
12831           (label_ref (match_operand 3 "" ""))))
12832    (clobber (reg:CCFP FPSR_REG))
12833    (clobber (reg:CCFP FLAGS_REG))]
12834   "TARGET_MIX_SSE_I387
12835    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12836    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12837    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12838   "#")
12840 (define_insn "*fp_jcc_2_sse"
12841   [(set (pc)
12842         (if_then_else (match_operator 0 "comparison_operator"
12843                         [(match_operand 1 "register_operand" "x")
12844                          (match_operand 2 "nonimmediate_operand" "xm")])
12845           (pc)
12846           (label_ref (match_operand 3 "" ""))))
12847    (clobber (reg:CCFP FPSR_REG))
12848    (clobber (reg:CCFP FLAGS_REG))]
12849   "TARGET_SSE_MATH
12850    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12851    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12852    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12853   "#")
12855 (define_insn "*fp_jcc_2_387"
12856   [(set (pc)
12857         (if_then_else (match_operator 0 "comparison_operator"
12858                         [(match_operand 1 "register_operand" "f")
12859                          (match_operand 2 "register_operand" "f")])
12860           (pc)
12861           (label_ref (match_operand 3 "" ""))))
12862    (clobber (reg:CCFP FPSR_REG))
12863    (clobber (reg:CCFP FLAGS_REG))]
12864   "TARGET_CMOVE && 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_3_387"
12871   [(set (pc)
12872         (if_then_else (match_operator 0 "comparison_operator"
12873                         [(match_operand 1 "register_operand" "f")
12874                          (match_operand 2 "nonimmediate_operand" "fm")])
12875           (label_ref (match_operand 3 "" ""))
12876           (pc)))
12877    (clobber (reg:CCFP FPSR_REG))
12878    (clobber (reg:CCFP FLAGS_REG))
12879    (clobber (match_scratch:HI 4 "=a"))]
12880   "TARGET_80387
12881    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12882    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12883    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12884    && SELECT_CC_MODE (GET_CODE (operands[0]),
12885                       operands[1], operands[2]) == CCFPmode
12886    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12887   "#")
12889 (define_insn "*fp_jcc_4_387"
12890   [(set (pc)
12891         (if_then_else (match_operator 0 "comparison_operator"
12892                         [(match_operand 1 "register_operand" "f")
12893                          (match_operand 2 "nonimmediate_operand" "fm")])
12894           (pc)
12895           (label_ref (match_operand 3 "" ""))))
12896    (clobber (reg:CCFP FPSR_REG))
12897    (clobber (reg:CCFP FLAGS_REG))
12898    (clobber (match_scratch:HI 4 "=a"))]
12899   "TARGET_80387
12900    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12901    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12902    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12903    && SELECT_CC_MODE (GET_CODE (operands[0]),
12904                       operands[1], operands[2]) == CCFPmode
12905    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12906   "#")
12908 (define_insn "*fp_jcc_5_387"
12909   [(set (pc)
12910         (if_then_else (match_operator 0 "comparison_operator"
12911                         [(match_operand 1 "register_operand" "f")
12912                          (match_operand 2 "register_operand" "f")])
12913           (label_ref (match_operand 3 "" ""))
12914           (pc)))
12915    (clobber (reg:CCFP FPSR_REG))
12916    (clobber (reg:CCFP FLAGS_REG))
12917    (clobber (match_scratch:HI 4 "=a"))]
12918   "TARGET_80387
12919    && FLOAT_MODE_P (GET_MODE (operands[1]))
12920    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12921    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12922   "#")
12924 (define_insn "*fp_jcc_6_387"
12925   [(set (pc)
12926         (if_then_else (match_operator 0 "comparison_operator"
12927                         [(match_operand 1 "register_operand" "f")
12928                          (match_operand 2 "register_operand" "f")])
12929           (pc)
12930           (label_ref (match_operand 3 "" ""))))
12931    (clobber (reg:CCFP FPSR_REG))
12932    (clobber (reg:CCFP FLAGS_REG))
12933    (clobber (match_scratch:HI 4 "=a"))]
12934   "TARGET_80387
12935    && FLOAT_MODE_P (GET_MODE (operands[1]))
12936    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12937    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12938   "#")
12940 (define_insn "*fp_jcc_7_387"
12941   [(set (pc)
12942         (if_then_else (match_operator 0 "comparison_operator"
12943                         [(match_operand 1 "register_operand" "f")
12944                          (match_operand 2 "const_double_operand" "C")])
12945           (label_ref (match_operand 3 "" ""))
12946           (pc)))
12947    (clobber (reg:CCFP FPSR_REG))
12948    (clobber (reg:CCFP FLAGS_REG))
12949    (clobber (match_scratch:HI 4 "=a"))]
12950   "TARGET_80387
12951    && FLOAT_MODE_P (GET_MODE (operands[1]))
12952    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
12953    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12954    && SELECT_CC_MODE (GET_CODE (operands[0]),
12955                       operands[1], operands[2]) == CCFPmode
12956    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12957   "#")
12959 ;; The order of operands in *fp_jcc_8 is forced by combine in
12960 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12961 ;; with a precedence over other operators and is always put in the first
12962 ;; place. Swap condition and operands to match ficom instruction.
12964 (define_insn "*fp_jcc_8_387"
12965   [(set (pc)
12966         (if_then_else (match_operator 0 "comparison_operator"
12967                         [(match_operator 1 "float_operator"
12968                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
12969                            (match_operand 3 "register_operand" "f,f")])
12970           (label_ref (match_operand 4 "" ""))
12971           (pc)))
12972    (clobber (reg:CCFP FPSR_REG))
12973    (clobber (reg:CCFP FLAGS_REG))
12974    (clobber (match_scratch:HI 5 "=a,a"))]
12975   "TARGET_80387 && TARGET_USE_FIOP
12976    && FLOAT_MODE_P (GET_MODE (operands[3]))
12977    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12978    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12979    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12980    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12981   "#")
12983 (define_split
12984   [(set (pc)
12985         (if_then_else (match_operator 0 "comparison_operator"
12986                         [(match_operand 1 "register_operand" "")
12987                          (match_operand 2 "nonimmediate_operand" "")])
12988           (match_operand 3 "" "")
12989           (match_operand 4 "" "")))
12990    (clobber (reg:CCFP FPSR_REG))
12991    (clobber (reg:CCFP FLAGS_REG))]
12992   "reload_completed"
12993   [(const_int 0)]
12995   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12996                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12997   DONE;
13000 (define_split
13001   [(set (pc)
13002         (if_then_else (match_operator 0 "comparison_operator"
13003                         [(match_operand 1 "register_operand" "")
13004                          (match_operand 2 "general_operand" "")])
13005           (match_operand 3 "" "")
13006           (match_operand 4 "" "")))
13007    (clobber (reg:CCFP FPSR_REG))
13008    (clobber (reg:CCFP FLAGS_REG))
13009    (clobber (match_scratch:HI 5 "=a"))]
13010   "reload_completed"
13011   [(const_int 0)]
13013   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13014                         operands[3], operands[4], operands[5], NULL_RTX);
13015   DONE;
13018 (define_split
13019   [(set (pc)
13020         (if_then_else (match_operator 0 "comparison_operator"
13021                         [(match_operator 1 "float_operator"
13022                            [(match_operand:SI 2 "memory_operand" "")])
13023                            (match_operand 3 "register_operand" "")])
13024           (match_operand 4 "" "")
13025           (match_operand 5 "" "")))
13026    (clobber (reg:CCFP FPSR_REG))
13027    (clobber (reg:CCFP FLAGS_REG))
13028    (clobber (match_scratch:HI 6 "=a"))]
13029   "reload_completed"
13030   [(const_int 0)]
13032   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13033   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13034                         operands[3], operands[7],
13035                         operands[4], operands[5], operands[6], NULL_RTX);
13036   DONE;
13039 ;; %%% Kill this when reload knows how to do it.
13040 (define_split
13041   [(set (pc)
13042         (if_then_else (match_operator 0 "comparison_operator"
13043                         [(match_operator 1 "float_operator"
13044                            [(match_operand:SI 2 "register_operand" "")])
13045                            (match_operand 3 "register_operand" "")])
13046           (match_operand 4 "" "")
13047           (match_operand 5 "" "")))
13048    (clobber (reg:CCFP FPSR_REG))
13049    (clobber (reg:CCFP FLAGS_REG))
13050    (clobber (match_scratch:HI 6 "=a"))]
13051   "reload_completed"
13052   [(const_int 0)]
13054   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13055   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13056   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13057                         operands[3], operands[7],
13058                         operands[4], operands[5], operands[6], operands[2]);
13059   DONE;
13062 ;; Unconditional and other jump instructions
13064 (define_insn "jump"
13065   [(set (pc)
13066         (label_ref (match_operand 0 "" "")))]
13067   ""
13068   "jmp\t%l0"
13069   [(set_attr "type" "ibr")
13070    (set (attr "length")
13071            (if_then_else (and (ge (minus (match_dup 0) (pc))
13072                                   (const_int -126))
13073                               (lt (minus (match_dup 0) (pc))
13074                                   (const_int 128)))
13075              (const_int 2)
13076              (const_int 5)))
13077    (set_attr "modrm" "0")])
13079 (define_expand "indirect_jump"
13080   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13081   ""
13082   "")
13084 (define_insn "*indirect_jump"
13085   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13086   "!TARGET_64BIT"
13087   "jmp\t%A0"
13088   [(set_attr "type" "ibr")
13089    (set_attr "length_immediate" "0")])
13091 (define_insn "*indirect_jump_rtx64"
13092   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13093   "TARGET_64BIT"
13094   "jmp\t%A0"
13095   [(set_attr "type" "ibr")
13096    (set_attr "length_immediate" "0")])
13098 (define_expand "tablejump"
13099   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13100               (use (label_ref (match_operand 1 "" "")))])]
13101   ""
13103   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13104      relative.  Convert the relative address to an absolute address.  */
13105   if (flag_pic)
13106     {
13107       rtx op0, op1;
13108       enum rtx_code code;
13110       if (TARGET_64BIT)
13111         {
13112           code = PLUS;
13113           op0 = operands[0];
13114           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13115         }
13116       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13117         {
13118           code = PLUS;
13119           op0 = operands[0];
13120           op1 = pic_offset_table_rtx;
13121         }
13122       else
13123         {
13124           code = MINUS;
13125           op0 = pic_offset_table_rtx;
13126           op1 = operands[0];
13127         }
13129       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13130                                          OPTAB_DIRECT);
13131     }
13134 (define_insn "*tablejump_1"
13135   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13136    (use (label_ref (match_operand 1 "" "")))]
13137   "!TARGET_64BIT"
13138   "jmp\t%A0"
13139   [(set_attr "type" "ibr")
13140    (set_attr "length_immediate" "0")])
13142 (define_insn "*tablejump_1_rtx64"
13143   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13144    (use (label_ref (match_operand 1 "" "")))]
13145   "TARGET_64BIT"
13146   "jmp\t%A0"
13147   [(set_attr "type" "ibr")
13148    (set_attr "length_immediate" "0")])
13150 ;; Loop instruction
13152 ;; This is all complicated by the fact that since this is a jump insn
13153 ;; we must handle our own reloads.
13155 (define_expand "doloop_end"
13156   [(use (match_operand 0 "" ""))        ; loop pseudo
13157    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13158    (use (match_operand 2 "" ""))        ; max iterations
13159    (use (match_operand 3 "" ""))        ; loop level 
13160    (use (match_operand 4 "" ""))]       ; label
13161   "!TARGET_64BIT && TARGET_USE_LOOP"
13162   "                                 
13164   /* Only use cloop on innermost loops.  */
13165   if (INTVAL (operands[3]) > 1)
13166     FAIL;
13167   if (GET_MODE (operands[0]) != SImode)
13168     FAIL;
13169   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13170                                            operands[0]));
13171   DONE;
13174 (define_insn "doloop_end_internal"
13175   [(set (pc)
13176         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13177                           (const_int 1))
13178                       (label_ref (match_operand 0 "" ""))
13179                       (pc)))
13180    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13181         (plus:SI (match_dup 1)
13182                  (const_int -1)))
13183    (clobber (match_scratch:SI 3 "=X,X,r"))
13184    (clobber (reg:CC FLAGS_REG))]
13185   "!TARGET_64BIT && TARGET_USE_LOOP
13186    && (reload_in_progress || reload_completed
13187        || register_operand (operands[2], VOIDmode))"
13189   if (which_alternative != 0)
13190     return "#";
13191   if (get_attr_length (insn) == 2)
13192     return "%+loop\t%l0";
13193   else
13194     return "dec{l}\t%1\;%+jne\t%l0";
13196   [(set (attr "length")
13197         (if_then_else (and (eq_attr "alternative" "0")
13198                            (and (ge (minus (match_dup 0) (pc))
13199                                     (const_int -126))
13200                                 (lt (minus (match_dup 0) (pc))
13201                                     (const_int 128))))
13202                       (const_int 2)
13203                       (const_int 16)))
13204    ;; We don't know the type before shorten branches.  Optimistically expect
13205    ;; the loop instruction to match.
13206    (set (attr "type") (const_string "ibr"))])
13208 (define_split
13209   [(set (pc)
13210         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13211                           (const_int 1))
13212                       (match_operand 0 "" "")
13213                       (pc)))
13214    (set (match_dup 1)
13215         (plus:SI (match_dup 1)
13216                  (const_int -1)))
13217    (clobber (match_scratch:SI 2 ""))
13218    (clobber (reg:CC FLAGS_REG))]
13219   "!TARGET_64BIT && TARGET_USE_LOOP
13220    && reload_completed
13221    && REGNO (operands[1]) != 2"
13222   [(parallel [(set (reg:CCZ FLAGS_REG)
13223                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13224                                  (const_int 0)))
13225               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13226    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13227                            (match_dup 0)
13228                            (pc)))]
13229   "")
13230   
13231 (define_split
13232   [(set (pc)
13233         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13234                           (const_int 1))
13235                       (match_operand 0 "" "")
13236                       (pc)))
13237    (set (match_operand:SI 2 "nonimmediate_operand" "")
13238         (plus:SI (match_dup 1)
13239                  (const_int -1)))
13240    (clobber (match_scratch:SI 3 ""))
13241    (clobber (reg:CC FLAGS_REG))]
13242   "!TARGET_64BIT && TARGET_USE_LOOP
13243    && reload_completed
13244    && (! REG_P (operands[2])
13245        || ! rtx_equal_p (operands[1], operands[2]))"
13246   [(set (match_dup 3) (match_dup 1))
13247    (parallel [(set (reg:CCZ FLAGS_REG)
13248                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13249                                 (const_int 0)))
13250               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13251    (set (match_dup 2) (match_dup 3))
13252    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13253                            (match_dup 0)
13254                            (pc)))]
13255   "")
13257 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13259 (define_peephole2
13260   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13261    (set (match_operand:QI 1 "register_operand" "")
13262         (match_operator:QI 2 "ix86_comparison_operator"
13263           [(reg FLAGS_REG) (const_int 0)]))
13264    (set (match_operand 3 "q_regs_operand" "")
13265         (zero_extend (match_dup 1)))]
13266   "(peep2_reg_dead_p (3, operands[1])
13267     || operands_match_p (operands[1], operands[3]))
13268    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13269   [(set (match_dup 4) (match_dup 0))
13270    (set (strict_low_part (match_dup 5))
13271         (match_dup 2))]
13273   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13274   operands[5] = gen_lowpart (QImode, operands[3]);
13275   ix86_expand_clear (operands[3]);
13278 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13280 (define_peephole2
13281   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13282    (set (match_operand:QI 1 "register_operand" "")
13283         (match_operator:QI 2 "ix86_comparison_operator"
13284           [(reg FLAGS_REG) (const_int 0)]))
13285    (parallel [(set (match_operand 3 "q_regs_operand" "")
13286                    (zero_extend (match_dup 1)))
13287               (clobber (reg:CC FLAGS_REG))])]
13288   "(peep2_reg_dead_p (3, operands[1])
13289     || operands_match_p (operands[1], operands[3]))
13290    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13291   [(set (match_dup 4) (match_dup 0))
13292    (set (strict_low_part (match_dup 5))
13293         (match_dup 2))]
13295   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13296   operands[5] = gen_lowpart (QImode, operands[3]);
13297   ix86_expand_clear (operands[3]);
13300 ;; Call instructions.
13302 ;; The predicates normally associated with named expanders are not properly
13303 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13304 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13306 ;; Call subroutine returning no value.
13308 (define_expand "call_pop"
13309   [(parallel [(call (match_operand:QI 0 "" "")
13310                     (match_operand:SI 1 "" ""))
13311               (set (reg:SI SP_REG)
13312                    (plus:SI (reg:SI SP_REG)
13313                             (match_operand:SI 3 "" "")))])]
13314   "!TARGET_64BIT"
13316   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13317   DONE;
13320 (define_insn "*call_pop_0"
13321   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13322          (match_operand:SI 1 "" ""))
13323    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13324                             (match_operand:SI 2 "immediate_operand" "")))]
13325   "!TARGET_64BIT"
13327   if (SIBLING_CALL_P (insn))
13328     return "jmp\t%P0";
13329   else
13330     return "call\t%P0";
13332   [(set_attr "type" "call")])
13333   
13334 (define_insn "*call_pop_1"
13335   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13336          (match_operand:SI 1 "" ""))
13337    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13338                             (match_operand:SI 2 "immediate_operand" "i")))]
13339   "!TARGET_64BIT"
13341   if (constant_call_address_operand (operands[0], Pmode))
13342     {
13343       if (SIBLING_CALL_P (insn))
13344         return "jmp\t%P0";
13345       else
13346         return "call\t%P0";
13347     }
13348   if (SIBLING_CALL_P (insn))
13349     return "jmp\t%A0";
13350   else
13351     return "call\t%A0";
13353   [(set_attr "type" "call")])
13355 (define_expand "call"
13356   [(call (match_operand:QI 0 "" "")
13357          (match_operand 1 "" ""))
13358    (use (match_operand 2 "" ""))]
13359   ""
13361   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13362   DONE;
13365 (define_expand "sibcall"
13366   [(call (match_operand:QI 0 "" "")
13367          (match_operand 1 "" ""))
13368    (use (match_operand 2 "" ""))]
13369   ""
13371   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13372   DONE;
13375 (define_insn "*call_0"
13376   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13377          (match_operand 1 "" ""))]
13378   ""
13380   if (SIBLING_CALL_P (insn))
13381     return "jmp\t%P0";
13382   else
13383     return "call\t%P0";
13385   [(set_attr "type" "call")])
13387 (define_insn "*call_1"
13388   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13389          (match_operand 1 "" ""))]
13390   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13392   if (constant_call_address_operand (operands[0], Pmode))
13393     return "call\t%P0";
13394   return "call\t%A0";
13396   [(set_attr "type" "call")])
13398 (define_insn "*sibcall_1"
13399   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13400          (match_operand 1 "" ""))]
13401   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13403   if (constant_call_address_operand (operands[0], Pmode))
13404     return "jmp\t%P0";
13405   return "jmp\t%A0";
13407   [(set_attr "type" "call")])
13409 (define_insn "*call_1_rex64"
13410   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13411          (match_operand 1 "" ""))]
13412   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13414   if (constant_call_address_operand (operands[0], Pmode))
13415     return "call\t%P0";
13416   return "call\t%A0";
13418   [(set_attr "type" "call")])
13420 (define_insn "*sibcall_1_rex64"
13421   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13422          (match_operand 1 "" ""))]
13423   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13424   "jmp\t%P0"
13425   [(set_attr "type" "call")])
13427 (define_insn "*sibcall_1_rex64_v"
13428   [(call (mem:QI (reg:DI 40))
13429          (match_operand 0 "" ""))]
13430   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13431   "jmp\t*%%r11"
13432   [(set_attr "type" "call")])
13435 ;; Call subroutine, returning value in operand 0
13437 (define_expand "call_value_pop"
13438   [(parallel [(set (match_operand 0 "" "")
13439                    (call (match_operand:QI 1 "" "")
13440                          (match_operand:SI 2 "" "")))
13441               (set (reg:SI SP_REG)
13442                    (plus:SI (reg:SI SP_REG)
13443                             (match_operand:SI 4 "" "")))])]
13444   "!TARGET_64BIT"
13446   ix86_expand_call (operands[0], operands[1], operands[2],
13447                     operands[3], operands[4], 0);
13448   DONE;
13451 (define_expand "call_value"
13452   [(set (match_operand 0 "" "")
13453         (call (match_operand:QI 1 "" "")
13454               (match_operand:SI 2 "" "")))
13455    (use (match_operand:SI 3 "" ""))]
13456   ;; Operand 2 not used on the i386.
13457   ""
13459   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13460   DONE;
13463 (define_expand "sibcall_value"
13464   [(set (match_operand 0 "" "")
13465         (call (match_operand:QI 1 "" "")
13466               (match_operand:SI 2 "" "")))
13467    (use (match_operand:SI 3 "" ""))]
13468   ;; Operand 2 not used on the i386.
13469   ""
13471   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13472   DONE;
13475 ;; Call subroutine returning any type.
13477 (define_expand "untyped_call"
13478   [(parallel [(call (match_operand 0 "" "")
13479                     (const_int 0))
13480               (match_operand 1 "" "")
13481               (match_operand 2 "" "")])]
13482   ""
13484   int i;
13486   /* In order to give reg-stack an easier job in validating two
13487      coprocessor registers as containing a possible return value,
13488      simply pretend the untyped call returns a complex long double
13489      value.  */
13491   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13492                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13493                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13494                     NULL, 0);
13496   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13497     {
13498       rtx set = XVECEXP (operands[2], 0, i);
13499       emit_move_insn (SET_DEST (set), SET_SRC (set));
13500     }
13502   /* The optimizer does not know that the call sets the function value
13503      registers we stored in the result block.  We avoid problems by
13504      claiming that all hard registers are used and clobbered at this
13505      point.  */
13506   emit_insn (gen_blockage (const0_rtx));
13508   DONE;
13511 ;; Prologue and epilogue instructions
13513 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13514 ;; all of memory.  This blocks insns from being moved across this point.
13516 (define_insn "blockage"
13517   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13518   ""
13519   ""
13520   [(set_attr "length" "0")])
13522 ;; Insn emitted into the body of a function to return from a function.
13523 ;; This is only done if the function's epilogue is known to be simple.
13524 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13526 (define_expand "return"
13527   [(return)]
13528   "ix86_can_use_return_insn_p ()"
13530   if (current_function_pops_args)
13531     {
13532       rtx popc = GEN_INT (current_function_pops_args);
13533       emit_jump_insn (gen_return_pop_internal (popc));
13534       DONE;
13535     }
13538 (define_insn "return_internal"
13539   [(return)]
13540   "reload_completed"
13541   "ret"
13542   [(set_attr "length" "1")
13543    (set_attr "length_immediate" "0")
13544    (set_attr "modrm" "0")])
13546 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13547 ;; instruction Athlon and K8 have.
13549 (define_insn "return_internal_long"
13550   [(return)
13551    (unspec [(const_int 0)] UNSPEC_REP)]
13552   "reload_completed"
13553   "rep {;} ret"
13554   [(set_attr "length" "1")
13555    (set_attr "length_immediate" "0")
13556    (set_attr "prefix_rep" "1")
13557    (set_attr "modrm" "0")])
13559 (define_insn "return_pop_internal"
13560   [(return)
13561    (use (match_operand:SI 0 "const_int_operand" ""))]
13562   "reload_completed"
13563   "ret\t%0"
13564   [(set_attr "length" "3")
13565    (set_attr "length_immediate" "2")
13566    (set_attr "modrm" "0")])
13568 (define_insn "return_indirect_internal"
13569   [(return)
13570    (use (match_operand:SI 0 "register_operand" "r"))]
13571   "reload_completed"
13572   "jmp\t%A0"
13573   [(set_attr "type" "ibr")
13574    (set_attr "length_immediate" "0")])
13576 (define_insn "nop"
13577   [(const_int 0)]
13578   ""
13579   "nop"
13580   [(set_attr "length" "1")
13581    (set_attr "length_immediate" "0")
13582    (set_attr "modrm" "0")])
13584 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13585 ;; branch prediction penalty for the third jump in a 16-byte
13586 ;; block on K8.
13588 (define_insn "align"
13589   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13590   ""
13592 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13593   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13594 #else
13595   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13596      The align insn is used to avoid 3 jump instructions in the row to improve
13597      branch prediction and the benefits hardly outweight the cost of extra 8
13598      nops on the average inserted by full alignment pseudo operation.  */
13599 #endif
13600   return "";
13602   [(set_attr "length" "16")])
13604 (define_expand "prologue"
13605   [(const_int 1)]
13606   ""
13607   "ix86_expand_prologue (); DONE;")
13609 (define_insn "set_got"
13610   [(set (match_operand:SI 0 "register_operand" "=r")
13611         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13612    (clobber (reg:CC FLAGS_REG))]
13613   "!TARGET_64BIT"
13614   { return output_set_got (operands[0]); }
13615   [(set_attr "type" "multi")
13616    (set_attr "length" "12")])
13618 (define_expand "epilogue"
13619   [(const_int 1)]
13620   ""
13621   "ix86_expand_epilogue (1); DONE;")
13623 (define_expand "sibcall_epilogue"
13624   [(const_int 1)]
13625   ""
13626   "ix86_expand_epilogue (0); DONE;")
13628 (define_expand "eh_return"
13629   [(use (match_operand 0 "register_operand" ""))]
13630   ""
13632   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13634   /* Tricky bit: we write the address of the handler to which we will
13635      be returning into someone else's stack frame, one word below the
13636      stack address we wish to restore.  */
13637   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13638   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13639   tmp = gen_rtx_MEM (Pmode, tmp);
13640   emit_move_insn (tmp, ra);
13642   if (Pmode == SImode)
13643     emit_jump_insn (gen_eh_return_si (sa));
13644   else
13645     emit_jump_insn (gen_eh_return_di (sa));
13646   emit_barrier ();
13647   DONE;
13650 (define_insn_and_split "eh_return_si"
13651   [(set (pc) 
13652         (unspec [(match_operand:SI 0 "register_operand" "c")]
13653                  UNSPEC_EH_RETURN))]
13654   "!TARGET_64BIT"
13655   "#"
13656   "reload_completed"
13657   [(const_int 1)]
13658   "ix86_expand_epilogue (2); DONE;")
13660 (define_insn_and_split "eh_return_di"
13661   [(set (pc) 
13662         (unspec [(match_operand:DI 0 "register_operand" "c")]
13663                  UNSPEC_EH_RETURN))]
13664   "TARGET_64BIT"
13665   "#"
13666   "reload_completed"
13667   [(const_int 1)]
13668   "ix86_expand_epilogue (2); DONE;")
13670 (define_insn "leave"
13671   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13672    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13673    (clobber (mem:BLK (scratch)))]
13674   "!TARGET_64BIT"
13675   "leave"
13676   [(set_attr "type" "leave")])
13678 (define_insn "leave_rex64"
13679   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13680    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13681    (clobber (mem:BLK (scratch)))]
13682   "TARGET_64BIT"
13683   "leave"
13684   [(set_attr "type" "leave")])
13686 (define_expand "ffssi2"
13687   [(parallel
13688      [(set (match_operand:SI 0 "register_operand" "") 
13689            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13690       (clobber (match_scratch:SI 2 ""))
13691       (clobber (reg:CC FLAGS_REG))])]
13692   ""
13693   "")
13695 (define_insn_and_split "*ffs_cmove"
13696   [(set (match_operand:SI 0 "register_operand" "=r") 
13697         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13698    (clobber (match_scratch:SI 2 "=&r"))
13699    (clobber (reg:CC FLAGS_REG))]
13700   "TARGET_CMOVE"
13701   "#"
13702   "&& reload_completed"
13703   [(set (match_dup 2) (const_int -1))
13704    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13705               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13706    (set (match_dup 0) (if_then_else:SI
13707                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13708                         (match_dup 2)
13709                         (match_dup 0)))
13710    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13711               (clobber (reg:CC FLAGS_REG))])]
13712   "")
13714 (define_insn_and_split "*ffs_no_cmove"
13715   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13716         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13717    (clobber (match_scratch:SI 2 "=&q"))
13718    (clobber (reg:CC FLAGS_REG))]
13719   ""
13720   "#"
13721   "reload_completed"
13722   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13723               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13724    (set (strict_low_part (match_dup 3))
13725         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13726    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13727               (clobber (reg:CC FLAGS_REG))])
13728    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13729               (clobber (reg:CC FLAGS_REG))])
13730    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13731               (clobber (reg:CC FLAGS_REG))])]
13733   operands[3] = gen_lowpart (QImode, operands[2]);
13734   ix86_expand_clear (operands[2]);
13737 (define_insn "*ffssi_1"
13738   [(set (reg:CCZ FLAGS_REG)
13739         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13740                      (const_int 0)))
13741    (set (match_operand:SI 0 "register_operand" "=r")
13742         (ctz:SI (match_dup 1)))]
13743   ""
13744   "bsf{l}\t{%1, %0|%0, %1}"
13745   [(set_attr "prefix_0f" "1")])
13747 (define_expand "ffsdi2"
13748   [(parallel
13749      [(set (match_operand:DI 0 "register_operand" "") 
13750            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13751       (clobber (match_scratch:DI 2 ""))
13752       (clobber (reg:CC FLAGS_REG))])]
13753   "TARGET_64BIT && TARGET_CMOVE"
13754   "")
13756 (define_insn_and_split "*ffs_rex64"
13757   [(set (match_operand:DI 0 "register_operand" "=r") 
13758         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13759    (clobber (match_scratch:DI 2 "=&r"))
13760    (clobber (reg:CC FLAGS_REG))]
13761   "TARGET_64BIT && TARGET_CMOVE"
13762   "#"
13763   "&& reload_completed"
13764   [(set (match_dup 2) (const_int -1))
13765    (parallel [(set (reg:CCZ FLAGS_REG)
13766                    (compare:CCZ (match_dup 1) (const_int 0)))
13767               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13768    (set (match_dup 0) (if_then_else:DI
13769                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13770                         (match_dup 2)
13771                         (match_dup 0)))
13772    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13773               (clobber (reg:CC FLAGS_REG))])]
13774   "")
13776 (define_insn "*ffsdi_1"
13777   [(set (reg:CCZ FLAGS_REG)
13778         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13779                      (const_int 0)))
13780    (set (match_operand:DI 0 "register_operand" "=r")
13781         (ctz:DI (match_dup 1)))]
13782   "TARGET_64BIT"
13783   "bsf{q}\t{%1, %0|%0, %1}"
13784   [(set_attr "prefix_0f" "1")])
13786 (define_insn "ctzsi2"
13787   [(set (match_operand:SI 0 "register_operand" "=r")
13788         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13789    (clobber (reg:CC FLAGS_REG))]
13790   ""
13791   "bsf{l}\t{%1, %0|%0, %1}"
13792   [(set_attr "prefix_0f" "1")])
13794 (define_insn "ctzdi2"
13795   [(set (match_operand:DI 0 "register_operand" "=r")
13796         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13797    (clobber (reg:CC FLAGS_REG))]
13798   "TARGET_64BIT"
13799   "bsf{q}\t{%1, %0|%0, %1}"
13800   [(set_attr "prefix_0f" "1")])
13802 (define_expand "clzsi2"
13803   [(parallel
13804      [(set (match_operand:SI 0 "register_operand" "")
13805            (minus:SI (const_int 31)
13806                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13807       (clobber (reg:CC FLAGS_REG))])
13808    (parallel
13809      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13810       (clobber (reg:CC FLAGS_REG))])]
13811   ""
13812   "")
13814 (define_insn "*bsr"
13815   [(set (match_operand:SI 0 "register_operand" "=r")
13816         (minus:SI (const_int 31)
13817                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13818    (clobber (reg:CC FLAGS_REG))]
13819   ""
13820   "bsr{l}\t{%1, %0|%0, %1}"
13821   [(set_attr "prefix_0f" "1")])
13823 (define_expand "clzdi2"
13824   [(parallel
13825      [(set (match_operand:DI 0 "register_operand" "")
13826            (minus:DI (const_int 63)
13827                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13828       (clobber (reg:CC FLAGS_REG))])
13829    (parallel
13830      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13831       (clobber (reg:CC FLAGS_REG))])]
13832   "TARGET_64BIT"
13833   "")
13835 (define_insn "*bsr_rex64"
13836   [(set (match_operand:DI 0 "register_operand" "=r")
13837         (minus:DI (const_int 63)
13838                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13839    (clobber (reg:CC FLAGS_REG))]
13840   "TARGET_64BIT"
13841   "bsr{q}\t{%1, %0|%0, %1}"
13842   [(set_attr "prefix_0f" "1")])
13844 ;; Thread-local storage patterns for ELF.
13846 ;; Note that these code sequences must appear exactly as shown
13847 ;; in order to allow linker relaxation.
13849 (define_insn "*tls_global_dynamic_32_gnu"
13850   [(set (match_operand:SI 0 "register_operand" "=a")
13851         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13852                     (match_operand:SI 2 "tls_symbolic_operand" "")
13853                     (match_operand:SI 3 "call_insn_operand" "")]
13854                     UNSPEC_TLS_GD))
13855    (clobber (match_scratch:SI 4 "=d"))
13856    (clobber (match_scratch:SI 5 "=c"))
13857    (clobber (reg:CC FLAGS_REG))]
13858   "!TARGET_64BIT && TARGET_GNU_TLS"
13859   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13860   [(set_attr "type" "multi")
13861    (set_attr "length" "12")])
13863 (define_insn "*tls_global_dynamic_32_sun"
13864   [(set (match_operand:SI 0 "register_operand" "=a")
13865         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13866                     (match_operand:SI 2 "tls_symbolic_operand" "")
13867                     (match_operand:SI 3 "call_insn_operand" "")]
13868                     UNSPEC_TLS_GD))
13869    (clobber (match_scratch:SI 4 "=d"))
13870    (clobber (match_scratch:SI 5 "=c"))
13871    (clobber (reg:CC FLAGS_REG))]
13872   "!TARGET_64BIT && TARGET_SUN_TLS"
13873   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13874         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13875   [(set_attr "type" "multi")
13876    (set_attr "length" "14")])
13878 (define_expand "tls_global_dynamic_32"
13879   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13880                    (unspec:SI
13881                     [(match_dup 2)
13882                      (match_operand:SI 1 "tls_symbolic_operand" "")
13883                      (match_dup 3)]
13884                     UNSPEC_TLS_GD))
13885               (clobber (match_scratch:SI 4 ""))
13886               (clobber (match_scratch:SI 5 ""))
13887               (clobber (reg:CC FLAGS_REG))])]
13888   ""
13890   if (flag_pic)
13891     operands[2] = pic_offset_table_rtx;
13892   else
13893     {
13894       operands[2] = gen_reg_rtx (Pmode);
13895       emit_insn (gen_set_got (operands[2]));
13896     }
13897   operands[3] = ix86_tls_get_addr ();
13900 (define_insn "*tls_global_dynamic_64"
13901   [(set (match_operand:DI 0 "register_operand" "=a")
13902         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13903                       (match_operand:DI 3 "" "")))
13904    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13905               UNSPEC_TLS_GD)]
13906   "TARGET_64BIT"
13907   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13908   [(set_attr "type" "multi")
13909    (set_attr "length" "16")])
13911 (define_expand "tls_global_dynamic_64"
13912   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13913                    (call (mem:QI (match_dup 2)) (const_int 0)))
13914               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13915                          UNSPEC_TLS_GD)])]
13916   ""
13918   operands[2] = ix86_tls_get_addr ();
13921 (define_insn "*tls_local_dynamic_base_32_gnu"
13922   [(set (match_operand:SI 0 "register_operand" "=a")
13923         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13924                     (match_operand:SI 2 "call_insn_operand" "")]
13925                    UNSPEC_TLS_LD_BASE))
13926    (clobber (match_scratch:SI 3 "=d"))
13927    (clobber (match_scratch:SI 4 "=c"))
13928    (clobber (reg:CC FLAGS_REG))]
13929   "!TARGET_64BIT && TARGET_GNU_TLS"
13930   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13931   [(set_attr "type" "multi")
13932    (set_attr "length" "11")])
13934 (define_insn "*tls_local_dynamic_base_32_sun"
13935   [(set (match_operand:SI 0 "register_operand" "=a")
13936         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13937                     (match_operand:SI 2 "call_insn_operand" "")]
13938                    UNSPEC_TLS_LD_BASE))
13939    (clobber (match_scratch:SI 3 "=d"))
13940    (clobber (match_scratch:SI 4 "=c"))
13941    (clobber (reg:CC FLAGS_REG))]
13942   "!TARGET_64BIT && TARGET_SUN_TLS"
13943   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13944         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13945   [(set_attr "type" "multi")
13946    (set_attr "length" "13")])
13948 (define_expand "tls_local_dynamic_base_32"
13949   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13950                    (unspec:SI [(match_dup 1) (match_dup 2)]
13951                               UNSPEC_TLS_LD_BASE))
13952               (clobber (match_scratch:SI 3 ""))
13953               (clobber (match_scratch:SI 4 ""))
13954               (clobber (reg:CC FLAGS_REG))])]
13955   ""
13957   if (flag_pic)
13958     operands[1] = pic_offset_table_rtx;
13959   else
13960     {
13961       operands[1] = gen_reg_rtx (Pmode);
13962       emit_insn (gen_set_got (operands[1]));
13963     }
13964   operands[2] = ix86_tls_get_addr ();
13967 (define_insn "*tls_local_dynamic_base_64"
13968   [(set (match_operand:DI 0 "register_operand" "=a")
13969         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13970                       (match_operand:DI 2 "" "")))
13971    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13972   "TARGET_64BIT"
13973   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13974   [(set_attr "type" "multi")
13975    (set_attr "length" "12")])
13977 (define_expand "tls_local_dynamic_base_64"
13978   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13979                    (call (mem:QI (match_dup 1)) (const_int 0)))
13980               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13981   ""
13983   operands[1] = ix86_tls_get_addr ();
13986 ;; Local dynamic of a single variable is a lose.  Show combine how
13987 ;; to convert that back to global dynamic.
13989 (define_insn_and_split "*tls_local_dynamic_32_once"
13990   [(set (match_operand:SI 0 "register_operand" "=a")
13991         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13992                              (match_operand:SI 2 "call_insn_operand" "")]
13993                             UNSPEC_TLS_LD_BASE)
13994                  (const:SI (unspec:SI
13995                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13996                             UNSPEC_DTPOFF))))
13997    (clobber (match_scratch:SI 4 "=d"))
13998    (clobber (match_scratch:SI 5 "=c"))
13999    (clobber (reg:CC FLAGS_REG))]
14000   ""
14001   "#"
14002   ""
14003   [(parallel [(set (match_dup 0)
14004                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14005                               UNSPEC_TLS_GD))
14006               (clobber (match_dup 4))
14007               (clobber (match_dup 5))
14008               (clobber (reg:CC FLAGS_REG))])]
14009   "")
14011 ;; Load and add the thread base pointer from %gs:0.
14013 (define_insn "*load_tp_si"
14014   [(set (match_operand:SI 0 "register_operand" "=r")
14015         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14016   "!TARGET_64BIT"
14017   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14018   [(set_attr "type" "imov")
14019    (set_attr "modrm" "0")
14020    (set_attr "length" "7")
14021    (set_attr "memory" "load")
14022    (set_attr "imm_disp" "false")])
14024 (define_insn "*add_tp_si"
14025   [(set (match_operand:SI 0 "register_operand" "=r")
14026         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14027                  (match_operand:SI 1 "register_operand" "0")))
14028    (clobber (reg:CC FLAGS_REG))]
14029   "!TARGET_64BIT"
14030   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14031   [(set_attr "type" "alu")
14032    (set_attr "modrm" "0")
14033    (set_attr "length" "7")
14034    (set_attr "memory" "load")
14035    (set_attr "imm_disp" "false")])
14037 (define_insn "*load_tp_di"
14038   [(set (match_operand:DI 0 "register_operand" "=r")
14039         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14040   "TARGET_64BIT"
14041   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14042   [(set_attr "type" "imov")
14043    (set_attr "modrm" "0")
14044    (set_attr "length" "7")
14045    (set_attr "memory" "load")
14046    (set_attr "imm_disp" "false")])
14048 (define_insn "*add_tp_di"
14049   [(set (match_operand:DI 0 "register_operand" "=r")
14050         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14051                  (match_operand:DI 1 "register_operand" "0")))
14052    (clobber (reg:CC FLAGS_REG))]
14053   "TARGET_64BIT"
14054   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14055   [(set_attr "type" "alu")
14056    (set_attr "modrm" "0")
14057    (set_attr "length" "7")
14058    (set_attr "memory" "load")
14059    (set_attr "imm_disp" "false")])
14061 ;; These patterns match the binary 387 instructions for addM3, subM3,
14062 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14063 ;; SFmode.  The first is the normal insn, the second the same insn but
14064 ;; with one operand a conversion, and the third the same insn but with
14065 ;; the other operand a conversion.  The conversion may be SFmode or
14066 ;; SImode if the target mode DFmode, but only SImode if the target mode
14067 ;; is SFmode.
14069 ;; Gcc is slightly more smart about handling normal two address instructions
14070 ;; so use special patterns for add and mull.
14072 (define_insn "*fop_sf_comm_mixed"
14073   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14074         (match_operator:SF 3 "binary_fp_operator"
14075                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14076                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14077   "TARGET_MIX_SSE_I387
14078    && COMMUTATIVE_ARITH_P (operands[3])
14079    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14080   "* return output_387_binary_op (insn, operands);"
14081   [(set (attr "type") 
14082         (if_then_else (eq_attr "alternative" "1")
14083            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14084               (const_string "ssemul")
14085               (const_string "sseadd"))
14086            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14087               (const_string "fmul")
14088               (const_string "fop"))))
14089    (set_attr "mode" "SF")])
14091 (define_insn "*fop_sf_comm_sse"
14092   [(set (match_operand:SF 0 "register_operand" "=x")
14093         (match_operator:SF 3 "binary_fp_operator"
14094                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14095                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14096   "TARGET_SSE_MATH
14097    && COMMUTATIVE_ARITH_P (operands[3])
14098    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14099   "* return output_387_binary_op (insn, operands);"
14100   [(set (attr "type") 
14101         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14102            (const_string "ssemul")
14103            (const_string "sseadd")))
14104    (set_attr "mode" "SF")])
14106 (define_insn "*fop_sf_comm_i387"
14107   [(set (match_operand:SF 0 "register_operand" "=f")
14108         (match_operator:SF 3 "binary_fp_operator"
14109                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14110                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14111   "TARGET_80387
14112    && COMMUTATIVE_ARITH_P (operands[3])
14113    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14114   "* return output_387_binary_op (insn, operands);"
14115   [(set (attr "type") 
14116         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14117            (const_string "fmul")
14118            (const_string "fop")))
14119    (set_attr "mode" "SF")])
14121 (define_insn "*fop_sf_1_mixed"
14122   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14123         (match_operator:SF 3 "binary_fp_operator"
14124                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14125                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14126   "TARGET_MIX_SSE_I387
14127    && !COMMUTATIVE_ARITH_P (operands[3])
14128    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14129   "* return output_387_binary_op (insn, operands);"
14130   [(set (attr "type") 
14131         (cond [(and (eq_attr "alternative" "2")
14132                     (match_operand:SF 3 "mult_operator" ""))
14133                  (const_string "ssemul")
14134                (and (eq_attr "alternative" "2")
14135                     (match_operand:SF 3 "div_operator" ""))
14136                  (const_string "ssediv")
14137                (eq_attr "alternative" "2")
14138                  (const_string "sseadd")
14139                (match_operand:SF 3 "mult_operator" "") 
14140                  (const_string "fmul")
14141                (match_operand:SF 3 "div_operator" "") 
14142                  (const_string "fdiv")
14143               ]
14144               (const_string "fop")))
14145    (set_attr "mode" "SF")])
14147 (define_insn "*fop_sf_1_sse"
14148   [(set (match_operand:SF 0 "register_operand" "=x")
14149         (match_operator:SF 3 "binary_fp_operator"
14150                         [(match_operand:SF 1 "register_operand" "0")
14151                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14152   "TARGET_SSE_MATH
14153    && !COMMUTATIVE_ARITH_P (operands[3])"
14154   "* return output_387_binary_op (insn, operands);"
14155   [(set (attr "type") 
14156         (cond [(match_operand:SF 3 "mult_operator" "")
14157                  (const_string "ssemul")
14158                (match_operand:SF 3 "div_operator" "")
14159                  (const_string "ssediv")
14160               ]
14161               (const_string "sseadd")))
14162    (set_attr "mode" "SF")])
14164 ;; This pattern is not fully shadowed by the pattern above.
14165 (define_insn "*fop_sf_1_i387"
14166   [(set (match_operand:SF 0 "register_operand" "=f,f")
14167         (match_operator:SF 3 "binary_fp_operator"
14168                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14169                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14170   "TARGET_80387 && !TARGET_SSE_MATH
14171    && !COMMUTATIVE_ARITH_P (operands[3])
14172    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14173   "* return output_387_binary_op (insn, operands);"
14174   [(set (attr "type") 
14175         (cond [(match_operand:SF 3 "mult_operator" "") 
14176                  (const_string "fmul")
14177                (match_operand:SF 3 "div_operator" "") 
14178                  (const_string "fdiv")
14179               ]
14180               (const_string "fop")))
14181    (set_attr "mode" "SF")])
14184 ;; ??? Add SSE splitters for these!
14185 (define_insn "*fop_sf_2_i387"
14186   [(set (match_operand:SF 0 "register_operand" "=f,f")
14187         (match_operator:SF 3 "binary_fp_operator"
14188           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14189            (match_operand:SF 2 "register_operand" "0,0")]))]
14190   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14191   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14192   [(set (attr "type") 
14193         (cond [(match_operand:SF 3 "mult_operator" "") 
14194                  (const_string "fmul")
14195                (match_operand:SF 3 "div_operator" "") 
14196                  (const_string "fdiv")
14197               ]
14198               (const_string "fop")))
14199    (set_attr "fp_int_src" "true")
14200    (set_attr "mode" "SI")])
14202 (define_insn "*fop_sf_3_i387"
14203   [(set (match_operand:SF 0 "register_operand" "=f,f")
14204         (match_operator:SF 3 "binary_fp_operator"
14205           [(match_operand:SF 1 "register_operand" "0,0")
14206            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14207   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14208   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14209   [(set (attr "type") 
14210         (cond [(match_operand:SF 3 "mult_operator" "") 
14211                  (const_string "fmul")
14212                (match_operand:SF 3 "div_operator" "") 
14213                  (const_string "fdiv")
14214               ]
14215               (const_string "fop")))
14216    (set_attr "fp_int_src" "true")
14217    (set_attr "mode" "SI")])
14219 (define_insn "*fop_df_comm_mixed"
14220   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14221         (match_operator:DF 3 "binary_fp_operator"
14222                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14223                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14224   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14225    && COMMUTATIVE_ARITH_P (operands[3])
14226    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14227   "* return output_387_binary_op (insn, operands);"
14228   [(set (attr "type") 
14229         (if_then_else (eq_attr "alternative" "1")
14230            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14231               (const_string "ssemul")
14232               (const_string "sseadd"))
14233            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14234               (const_string "fmul")
14235               (const_string "fop"))))
14236    (set_attr "mode" "DF")])
14238 (define_insn "*fop_df_comm_sse"
14239   [(set (match_operand:DF 0 "register_operand" "=Y")
14240         (match_operator:DF 3 "binary_fp_operator"
14241                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14242                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14243   "TARGET_SSE2 && TARGET_SSE_MATH
14244    && COMMUTATIVE_ARITH_P (operands[3])
14245    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14246   "* return output_387_binary_op (insn, operands);"
14247   [(set (attr "type") 
14248         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14249            (const_string "ssemul")
14250            (const_string "sseadd")))
14251    (set_attr "mode" "DF")])
14253 (define_insn "*fop_df_comm_i387"
14254   [(set (match_operand:DF 0 "register_operand" "=f")
14255         (match_operator:DF 3 "binary_fp_operator"
14256                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14257                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14258   "TARGET_80387
14259    && COMMUTATIVE_ARITH_P (operands[3])
14260    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14261   "* return output_387_binary_op (insn, operands);"
14262   [(set (attr "type") 
14263         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14264            (const_string "fmul")
14265            (const_string "fop")))
14266    (set_attr "mode" "DF")])
14268 (define_insn "*fop_df_1_mixed"
14269   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14270         (match_operator:DF 3 "binary_fp_operator"
14271                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14272                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14273   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14274    && !COMMUTATIVE_ARITH_P (operands[3])
14275    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14276   "* return output_387_binary_op (insn, operands);"
14277   [(set (attr "type") 
14278         (cond [(and (eq_attr "alternative" "2")
14279                     (match_operand:SF 3 "mult_operator" ""))
14280                  (const_string "ssemul")
14281                (and (eq_attr "alternative" "2")
14282                     (match_operand:SF 3 "div_operator" ""))
14283                  (const_string "ssediv")
14284                (eq_attr "alternative" "2")
14285                  (const_string "sseadd")
14286                (match_operand:DF 3 "mult_operator" "") 
14287                  (const_string "fmul")
14288                (match_operand:DF 3 "div_operator" "") 
14289                  (const_string "fdiv")
14290               ]
14291               (const_string "fop")))
14292    (set_attr "mode" "DF")])
14294 (define_insn "*fop_df_1_sse"
14295   [(set (match_operand:DF 0 "register_operand" "=Y")
14296         (match_operator:DF 3 "binary_fp_operator"
14297                         [(match_operand:DF 1 "register_operand" "0")
14298                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14299   "TARGET_SSE2 && TARGET_SSE_MATH
14300    && !COMMUTATIVE_ARITH_P (operands[3])"
14301   "* return output_387_binary_op (insn, operands);"
14302   [(set_attr "mode" "DF")
14303    (set (attr "type") 
14304         (cond [(match_operand:SF 3 "mult_operator" "")
14305                  (const_string "ssemul")
14306                (match_operand:SF 3 "div_operator" "")
14307                  (const_string "ssediv")
14308               ]
14309               (const_string "sseadd")))])
14311 ;; This pattern is not fully shadowed by the pattern above.
14312 (define_insn "*fop_df_1_i387"
14313   [(set (match_operand:DF 0 "register_operand" "=f,f")
14314         (match_operator:DF 3 "binary_fp_operator"
14315                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14316                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14317   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14318    && !COMMUTATIVE_ARITH_P (operands[3])
14319    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14320   "* return output_387_binary_op (insn, operands);"
14321   [(set (attr "type") 
14322         (cond [(match_operand:DF 3 "mult_operator" "") 
14323                  (const_string "fmul")
14324                (match_operand:DF 3 "div_operator" "")
14325                  (const_string "fdiv")
14326               ]
14327               (const_string "fop")))
14328    (set_attr "mode" "DF")])
14330 ;; ??? Add SSE splitters for these!
14331 (define_insn "*fop_df_2_i387"
14332   [(set (match_operand:DF 0 "register_operand" "=f,f")
14333         (match_operator:DF 3 "binary_fp_operator"
14334            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14335             (match_operand:DF 2 "register_operand" "0,0")]))]
14336   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14337   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14338   [(set (attr "type") 
14339         (cond [(match_operand:DF 3 "mult_operator" "") 
14340                  (const_string "fmul")
14341                (match_operand:DF 3 "div_operator" "") 
14342                  (const_string "fdiv")
14343               ]
14344               (const_string "fop")))
14345    (set_attr "fp_int_src" "true")
14346    (set_attr "mode" "SI")])
14348 (define_insn "*fop_df_3_i387"
14349   [(set (match_operand:DF 0 "register_operand" "=f,f")
14350         (match_operator:DF 3 "binary_fp_operator"
14351            [(match_operand:DF 1 "register_operand" "0,0")
14352             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14353   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14354   "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
14363    (set_attr "mode" "SI")])
14365 (define_insn "*fop_df_4_i387"
14366   [(set (match_operand:DF 0 "register_operand" "=f,f")
14367         (match_operator:DF 3 "binary_fp_operator"
14368            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14369             (match_operand:DF 2 "register_operand" "0,f")]))]
14370   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14371    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14372   "* return output_387_binary_op (insn, operands);"
14373   [(set (attr "type") 
14374         (cond [(match_operand:DF 3 "mult_operator" "") 
14375                  (const_string "fmul")
14376                (match_operand:DF 3 "div_operator" "") 
14377                  (const_string "fdiv")
14378               ]
14379               (const_string "fop")))
14380    (set_attr "mode" "SF")])
14382 (define_insn "*fop_df_5_i387"
14383   [(set (match_operand:DF 0 "register_operand" "=f,f")
14384         (match_operator:DF 3 "binary_fp_operator"
14385           [(match_operand:DF 1 "register_operand" "0,f")
14386            (float_extend:DF
14387             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14388   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14389   "* return output_387_binary_op (insn, operands);"
14390   [(set (attr "type") 
14391         (cond [(match_operand:DF 3 "mult_operator" "") 
14392                  (const_string "fmul")
14393                (match_operand:DF 3 "div_operator" "") 
14394                  (const_string "fdiv")
14395               ]
14396               (const_string "fop")))
14397    (set_attr "mode" "SF")])
14399 (define_insn "*fop_df_6_i387"
14400   [(set (match_operand:DF 0 "register_operand" "=f,f")
14401         (match_operator:DF 3 "binary_fp_operator"
14402           [(float_extend:DF
14403             (match_operand:SF 1 "register_operand" "0,f"))
14404            (float_extend:DF
14405             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14406   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14407   "* return output_387_binary_op (insn, operands);"
14408   [(set (attr "type") 
14409         (cond [(match_operand:DF 3 "mult_operator" "") 
14410                  (const_string "fmul")
14411                (match_operand:DF 3 "div_operator" "") 
14412                  (const_string "fdiv")
14413               ]
14414               (const_string "fop")))
14415    (set_attr "mode" "SF")])
14417 (define_insn "*fop_xf_comm_i387"
14418   [(set (match_operand:XF 0 "register_operand" "=f")
14419         (match_operator:XF 3 "binary_fp_operator"
14420                         [(match_operand:XF 1 "register_operand" "%0")
14421                          (match_operand:XF 2 "register_operand" "f")]))]
14422   "TARGET_80387
14423    && COMMUTATIVE_ARITH_P (operands[3])"
14424   "* return output_387_binary_op (insn, operands);"
14425   [(set (attr "type") 
14426         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14427            (const_string "fmul")
14428            (const_string "fop")))
14429    (set_attr "mode" "XF")])
14431 (define_insn "*fop_xf_1_i387"
14432   [(set (match_operand:XF 0 "register_operand" "=f,f")
14433         (match_operator:XF 3 "binary_fp_operator"
14434                         [(match_operand:XF 1 "register_operand" "0,f")
14435                          (match_operand:XF 2 "register_operand" "f,0")]))]
14436   "TARGET_80387
14437    && !COMMUTATIVE_ARITH_P (operands[3])"
14438   "* return output_387_binary_op (insn, operands);"
14439   [(set (attr "type") 
14440         (cond [(match_operand:XF 3 "mult_operator" "") 
14441                  (const_string "fmul")
14442                (match_operand:XF 3 "div_operator" "") 
14443                  (const_string "fdiv")
14444               ]
14445               (const_string "fop")))
14446    (set_attr "mode" "XF")])
14448 (define_insn "*fop_xf_2_i387"
14449   [(set (match_operand:XF 0 "register_operand" "=f,f")
14450         (match_operator:XF 3 "binary_fp_operator"
14451            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14452             (match_operand:XF 2 "register_operand" "0,0")]))]
14453   "TARGET_80387 && TARGET_USE_FIOP"
14454   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14455   [(set (attr "type") 
14456         (cond [(match_operand:XF 3 "mult_operator" "") 
14457                  (const_string "fmul")
14458                (match_operand:XF 3 "div_operator" "") 
14459                  (const_string "fdiv")
14460               ]
14461               (const_string "fop")))
14462    (set_attr "fp_int_src" "true")
14463    (set_attr "mode" "SI")])
14465 (define_insn "*fop_xf_3_i387"
14466   [(set (match_operand:XF 0 "register_operand" "=f,f")
14467         (match_operator:XF 3 "binary_fp_operator"
14468           [(match_operand:XF 1 "register_operand" "0,0")
14469            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14470   "TARGET_80387 && TARGET_USE_FIOP"
14471   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14472   [(set (attr "type") 
14473         (cond [(match_operand:XF 3 "mult_operator" "") 
14474                  (const_string "fmul")
14475                (match_operand:XF 3 "div_operator" "") 
14476                  (const_string "fdiv")
14477               ]
14478               (const_string "fop")))
14479    (set_attr "fp_int_src" "true")
14480    (set_attr "mode" "SI")])
14482 (define_insn "*fop_xf_4_i387"
14483   [(set (match_operand:XF 0 "register_operand" "=f,f")
14484         (match_operator:XF 3 "binary_fp_operator"
14485            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14486             (match_operand:XF 2 "register_operand" "0,f")]))]
14487   "TARGET_80387"
14488   "* return output_387_binary_op (insn, operands);"
14489   [(set (attr "type") 
14490         (cond [(match_operand:XF 3 "mult_operator" "") 
14491                  (const_string "fmul")
14492                (match_operand:XF 3 "div_operator" "") 
14493                  (const_string "fdiv")
14494               ]
14495               (const_string "fop")))
14496    (set_attr "mode" "SF")])
14498 (define_insn "*fop_xf_5_i387"
14499   [(set (match_operand:XF 0 "register_operand" "=f,f")
14500         (match_operator:XF 3 "binary_fp_operator"
14501           [(match_operand:XF 1 "register_operand" "0,f")
14502            (float_extend:XF
14503             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14504   "TARGET_80387"
14505   "* return output_387_binary_op (insn, operands);"
14506   [(set (attr "type") 
14507         (cond [(match_operand:XF 3 "mult_operator" "") 
14508                  (const_string "fmul")
14509                (match_operand:XF 3 "div_operator" "") 
14510                  (const_string "fdiv")
14511               ]
14512               (const_string "fop")))
14513    (set_attr "mode" "SF")])
14515 (define_insn "*fop_xf_6_i387"
14516   [(set (match_operand:XF 0 "register_operand" "=f,f")
14517         (match_operator:XF 3 "binary_fp_operator"
14518           [(float_extend:XF
14519             (match_operand 1 "register_operand" "0,f"))
14520            (float_extend:XF
14521             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14522   "TARGET_80387"
14523   "* return output_387_binary_op (insn, operands);"
14524   [(set (attr "type") 
14525         (cond [(match_operand:XF 3 "mult_operator" "") 
14526                  (const_string "fmul")
14527                (match_operand:XF 3 "div_operator" "") 
14528                  (const_string "fdiv")
14529               ]
14530               (const_string "fop")))
14531    (set_attr "mode" "SF")])
14533 (define_split
14534   [(set (match_operand 0 "register_operand" "")
14535         (match_operator 3 "binary_fp_operator"
14536            [(float (match_operand:SI 1 "register_operand" ""))
14537             (match_operand 2 "register_operand" "")]))]
14538   "TARGET_80387 && reload_completed
14539    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14540   [(const_int 0)]
14542   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14543   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14544   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14545                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14546                                           GET_MODE (operands[3]),
14547                                           operands[4],
14548                                           operands[2])));
14549   ix86_free_from_memory (GET_MODE (operands[1]));
14550   DONE;
14553 (define_split
14554   [(set (match_operand 0 "register_operand" "")
14555         (match_operator 3 "binary_fp_operator"
14556            [(match_operand 1 "register_operand" "")
14557             (float (match_operand:SI 2 "register_operand" ""))]))]
14558   "TARGET_80387 && reload_completed
14559    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14560   [(const_int 0)]
14562   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14563   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14564   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14565                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14566                                           GET_MODE (operands[3]),
14567                                           operands[1],
14568                                           operands[4])));
14569   ix86_free_from_memory (GET_MODE (operands[2]));
14570   DONE;
14573 ;; FPU special functions.
14575 (define_expand "sqrtsf2"
14576   [(set (match_operand:SF 0 "register_operand" "")
14577         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14578   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14580   if (!TARGET_SSE_MATH)
14581     operands[1] = force_reg (SFmode, operands[1]);
14584 (define_insn "*sqrtsf2_mixed"
14585   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14586         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14587   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14588   "@
14589    fsqrt
14590    sqrtss\t{%1, %0|%0, %1}"
14591   [(set_attr "type" "fpspc,sse")
14592    (set_attr "mode" "SF,SF")
14593    (set_attr "athlon_decode" "direct,*")])
14595 (define_insn "*sqrtsf2_sse"
14596   [(set (match_operand:SF 0 "register_operand" "=x")
14597         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14598   "TARGET_SSE_MATH"
14599   "sqrtss\t{%1, %0|%0, %1}"
14600   [(set_attr "type" "sse")
14601    (set_attr "mode" "SF")
14602    (set_attr "athlon_decode" "*")])
14604 (define_insn "*sqrtsf2_i387"
14605   [(set (match_operand:SF 0 "register_operand" "=f")
14606         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14607   "TARGET_USE_FANCY_MATH_387"
14608   "fsqrt"
14609   [(set_attr "type" "fpspc")
14610    (set_attr "mode" "SF")
14611    (set_attr "athlon_decode" "direct")])
14613 (define_expand "sqrtdf2"
14614   [(set (match_operand:DF 0 "register_operand" "")
14615         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14616   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14618   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14619     operands[1] = force_reg (DFmode, operands[1]);
14622 (define_insn "*sqrtdf2_mixed"
14623   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14624         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14625   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14626   "@
14627    fsqrt
14628    sqrtsd\t{%1, %0|%0, %1}"
14629   [(set_attr "type" "fpspc,sse")
14630    (set_attr "mode" "DF,DF")
14631    (set_attr "athlon_decode" "direct,*")])
14633 (define_insn "*sqrtdf2_sse"
14634   [(set (match_operand:DF 0 "register_operand" "=Y")
14635         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14636   "TARGET_SSE2 && TARGET_SSE_MATH"
14637   "sqrtsd\t{%1, %0|%0, %1}"
14638   [(set_attr "type" "sse")
14639    (set_attr "mode" "DF")
14640    (set_attr "athlon_decode" "*")])
14642 (define_insn "*sqrtdf2_i387"
14643   [(set (match_operand:DF 0 "register_operand" "=f")
14644         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14645   "TARGET_USE_FANCY_MATH_387"
14646   "fsqrt"
14647   [(set_attr "type" "fpspc")
14648    (set_attr "mode" "DF")
14649    (set_attr "athlon_decode" "direct")])
14651 (define_insn "*sqrtextendsfdf2_i387"
14652   [(set (match_operand:DF 0 "register_operand" "=f")
14653         (sqrt:DF (float_extend:DF
14654                   (match_operand:SF 1 "register_operand" "0"))))]
14655   "TARGET_USE_FANCY_MATH_387
14656    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14657   "fsqrt"
14658   [(set_attr "type" "fpspc")
14659    (set_attr "mode" "DF")
14660    (set_attr "athlon_decode" "direct")])
14662 (define_insn "sqrtxf2"
14663   [(set (match_operand:XF 0 "register_operand" "=f")
14664         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14665   "TARGET_USE_FANCY_MATH_387 
14666    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14667   "fsqrt"
14668   [(set_attr "type" "fpspc")
14669    (set_attr "mode" "XF")
14670    (set_attr "athlon_decode" "direct")])
14672 (define_insn "*sqrtextendsfxf2_i387"
14673   [(set (match_operand:XF 0 "register_operand" "=f")
14674         (sqrt:XF (float_extend:XF
14675                   (match_operand:SF 1 "register_operand" "0"))))]
14676   "TARGET_USE_FANCY_MATH_387"
14677   "fsqrt"
14678   [(set_attr "type" "fpspc")
14679    (set_attr "mode" "XF")
14680    (set_attr "athlon_decode" "direct")])
14682 (define_insn "*sqrtextenddfxf2_i387"
14683   [(set (match_operand:XF 0 "register_operand" "=f")
14684         (sqrt:XF (float_extend:XF
14685                   (match_operand:DF 1 "register_operand" "0"))))]
14686   "TARGET_USE_FANCY_MATH_387"
14687   "fsqrt"
14688   [(set_attr "type" "fpspc")
14689    (set_attr "mode" "XF")
14690    (set_attr "athlon_decode" "direct")])
14692 (define_insn "fpremxf4"
14693   [(set (match_operand:XF 0 "register_operand" "=f")
14694         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14695                     (match_operand:XF 3 "register_operand" "1")]
14696                    UNSPEC_FPREM_F))
14697    (set (match_operand:XF 1 "register_operand" "=u")
14698         (unspec:XF [(match_dup 2) (match_dup 3)]
14699                    UNSPEC_FPREM_U))
14700    (set (reg:CCFP FPSR_REG)
14701         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14702   "TARGET_USE_FANCY_MATH_387
14703    && flag_unsafe_math_optimizations"
14704   "fprem"
14705   [(set_attr "type" "fpspc")
14706    (set_attr "mode" "XF")])
14708 (define_expand "fmodsf3"
14709   [(use (match_operand:SF 0 "register_operand" ""))
14710    (use (match_operand:SF 1 "register_operand" ""))
14711    (use (match_operand:SF 2 "register_operand" ""))]
14712   "TARGET_USE_FANCY_MATH_387
14713    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14714    && flag_unsafe_math_optimizations"
14716   rtx label = gen_label_rtx ();
14718   rtx op1 = gen_reg_rtx (XFmode);
14719   rtx op2 = gen_reg_rtx (XFmode);
14721   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14722   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14724   emit_label (label);
14726   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14727   ix86_emit_fp_unordered_jump (label);
14729   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14730   DONE;
14733 (define_expand "fmoddf3"
14734   [(use (match_operand:DF 0 "register_operand" ""))
14735    (use (match_operand:DF 1 "register_operand" ""))
14736    (use (match_operand:DF 2 "register_operand" ""))]
14737   "TARGET_USE_FANCY_MATH_387
14738    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14739    && flag_unsafe_math_optimizations"
14741   rtx label = gen_label_rtx ();
14743   rtx op1 = gen_reg_rtx (XFmode);
14744   rtx op2 = gen_reg_rtx (XFmode);
14746   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14747   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14749   emit_label (label);
14751   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14752   ix86_emit_fp_unordered_jump (label);
14754   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14755   DONE;
14758 (define_expand "fmodxf3"
14759   [(use (match_operand:XF 0 "register_operand" ""))
14760    (use (match_operand:XF 1 "register_operand" ""))
14761    (use (match_operand:XF 2 "register_operand" ""))]
14762   "TARGET_USE_FANCY_MATH_387
14763    && flag_unsafe_math_optimizations"
14765   rtx label = gen_label_rtx ();
14767   emit_label (label);
14769   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14770                            operands[1], operands[2]));
14771   ix86_emit_fp_unordered_jump (label);
14773   emit_move_insn (operands[0], operands[1]);
14774   DONE;
14777 (define_insn "fprem1xf4"
14778   [(set (match_operand:XF 0 "register_operand" "=f")
14779         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14780                     (match_operand:XF 3 "register_operand" "1")]
14781                    UNSPEC_FPREM1_F))
14782    (set (match_operand:XF 1 "register_operand" "=u")
14783         (unspec:XF [(match_dup 2) (match_dup 3)]
14784                    UNSPEC_FPREM1_U))
14785    (set (reg:CCFP FPSR_REG)
14786         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14787   "TARGET_USE_FANCY_MATH_387
14788    && flag_unsafe_math_optimizations"
14789   "fprem1"
14790   [(set_attr "type" "fpspc")
14791    (set_attr "mode" "XF")])
14793 (define_expand "dremsf3"
14794   [(use (match_operand:SF 0 "register_operand" ""))
14795    (use (match_operand:SF 1 "register_operand" ""))
14796    (use (match_operand:SF 2 "register_operand" ""))]
14797   "TARGET_USE_FANCY_MATH_387
14798    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14799    && flag_unsafe_math_optimizations"
14801   rtx label = gen_label_rtx ();
14803   rtx op1 = gen_reg_rtx (XFmode);
14804   rtx op2 = gen_reg_rtx (XFmode);
14806   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14807   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14809   emit_label (label);
14811   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14812   ix86_emit_fp_unordered_jump (label);
14814   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14815   DONE;
14818 (define_expand "dremdf3"
14819   [(use (match_operand:DF 0 "register_operand" ""))
14820    (use (match_operand:DF 1 "register_operand" ""))
14821    (use (match_operand:DF 2 "register_operand" ""))]
14822   "TARGET_USE_FANCY_MATH_387
14823    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14824    && flag_unsafe_math_optimizations"
14826   rtx label = gen_label_rtx ();
14828   rtx op1 = gen_reg_rtx (XFmode);
14829   rtx op2 = gen_reg_rtx (XFmode);
14831   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14832   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14834   emit_label (label);
14836   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14837   ix86_emit_fp_unordered_jump (label);
14839   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14840   DONE;
14843 (define_expand "dremxf3"
14844   [(use (match_operand:XF 0 "register_operand" ""))
14845    (use (match_operand:XF 1 "register_operand" ""))
14846    (use (match_operand:XF 2 "register_operand" ""))]
14847   "TARGET_USE_FANCY_MATH_387
14848    && flag_unsafe_math_optimizations"
14850   rtx label = gen_label_rtx ();
14852   emit_label (label);
14854   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14855                             operands[1], operands[2]));
14856   ix86_emit_fp_unordered_jump (label);
14858   emit_move_insn (operands[0], operands[1]);
14859   DONE;
14862 (define_insn "*sindf2"
14863   [(set (match_operand:DF 0 "register_operand" "=f")
14864         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14865   "TARGET_USE_FANCY_MATH_387
14866    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14867    && flag_unsafe_math_optimizations"
14868   "fsin"
14869   [(set_attr "type" "fpspc")
14870    (set_attr "mode" "DF")])
14872 (define_insn "*sinsf2"
14873   [(set (match_operand:SF 0 "register_operand" "=f")
14874         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14875   "TARGET_USE_FANCY_MATH_387
14876    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14877    && flag_unsafe_math_optimizations"
14878   "fsin"
14879   [(set_attr "type" "fpspc")
14880    (set_attr "mode" "SF")])
14882 (define_insn "*sinextendsfdf2"
14883   [(set (match_operand:DF 0 "register_operand" "=f")
14884         (unspec:DF [(float_extend:DF
14885                      (match_operand:SF 1 "register_operand" "0"))]
14886                    UNSPEC_SIN))]
14887   "TARGET_USE_FANCY_MATH_387
14888    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14889    && flag_unsafe_math_optimizations"
14890   "fsin"
14891   [(set_attr "type" "fpspc")
14892    (set_attr "mode" "DF")])
14894 (define_insn "*sinxf2"
14895   [(set (match_operand:XF 0 "register_operand" "=f")
14896         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14897   "TARGET_USE_FANCY_MATH_387
14898    && flag_unsafe_math_optimizations"
14899   "fsin"
14900   [(set_attr "type" "fpspc")
14901    (set_attr "mode" "XF")])
14903 (define_insn "*cosdf2"
14904   [(set (match_operand:DF 0 "register_operand" "=f")
14905         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14906   "TARGET_USE_FANCY_MATH_387
14907    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14908    && flag_unsafe_math_optimizations"
14909   "fcos"
14910   [(set_attr "type" "fpspc")
14911    (set_attr "mode" "DF")])
14913 (define_insn "*cossf2"
14914   [(set (match_operand:SF 0 "register_operand" "=f")
14915         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14916   "TARGET_USE_FANCY_MATH_387
14917    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14918    && flag_unsafe_math_optimizations"
14919   "fcos"
14920   [(set_attr "type" "fpspc")
14921    (set_attr "mode" "SF")])
14923 (define_insn "*cosextendsfdf2"
14924   [(set (match_operand:DF 0 "register_operand" "=f")
14925         (unspec:DF [(float_extend:DF
14926                      (match_operand:SF 1 "register_operand" "0"))]
14927                    UNSPEC_COS))]
14928   "TARGET_USE_FANCY_MATH_387
14929    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14930    && flag_unsafe_math_optimizations"
14931   "fcos"
14932   [(set_attr "type" "fpspc")
14933    (set_attr "mode" "DF")])
14935 (define_insn "*cosxf2"
14936   [(set (match_operand:XF 0 "register_operand" "=f")
14937         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14938   "TARGET_USE_FANCY_MATH_387
14939    && flag_unsafe_math_optimizations"
14940   "fcos"
14941   [(set_attr "type" "fpspc")
14942    (set_attr "mode" "XF")])
14944 ;; With sincos pattern defined, sin and cos builtin function will be
14945 ;; expanded to sincos pattern with one of its outputs left unused. 
14946 ;; Cse pass  will detected, if two sincos patterns can be combined,
14947 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14948 ;; depending on the unused output.
14950 (define_insn "sincosdf3"
14951   [(set (match_operand:DF 0 "register_operand" "=f")
14952         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14953                    UNSPEC_SINCOS_COS))
14954    (set (match_operand:DF 1 "register_operand" "=u")
14955         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14956   "TARGET_USE_FANCY_MATH_387
14957    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14958    && flag_unsafe_math_optimizations"
14959   "fsincos"
14960   [(set_attr "type" "fpspc")
14961    (set_attr "mode" "DF")])
14963 (define_split
14964   [(set (match_operand:DF 0 "register_operand" "")
14965         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14966                    UNSPEC_SINCOS_COS))
14967    (set (match_operand:DF 1 "register_operand" "")
14968         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14969   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14970    && !reload_completed && !reload_in_progress"
14971   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14972   "")
14974 (define_split
14975   [(set (match_operand:DF 0 "register_operand" "")
14976         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14977                    UNSPEC_SINCOS_COS))
14978    (set (match_operand:DF 1 "register_operand" "")
14979         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14980   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14981    && !reload_completed && !reload_in_progress"
14982   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14983   "")
14985 (define_insn "sincossf3"
14986   [(set (match_operand:SF 0 "register_operand" "=f")
14987         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14988                    UNSPEC_SINCOS_COS))
14989    (set (match_operand:SF 1 "register_operand" "=u")
14990         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14991   "TARGET_USE_FANCY_MATH_387
14992    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14993    && flag_unsafe_math_optimizations"
14994   "fsincos"
14995   [(set_attr "type" "fpspc")
14996    (set_attr "mode" "SF")])
14998 (define_split
14999   [(set (match_operand:SF 0 "register_operand" "")
15000         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15001                    UNSPEC_SINCOS_COS))
15002    (set (match_operand:SF 1 "register_operand" "")
15003         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15004   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15005    && !reload_completed && !reload_in_progress"
15006   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15007   "")
15009 (define_split
15010   [(set (match_operand:SF 0 "register_operand" "")
15011         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15012                    UNSPEC_SINCOS_COS))
15013    (set (match_operand:SF 1 "register_operand" "")
15014         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15015   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15016    && !reload_completed && !reload_in_progress"
15017   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15018   "")
15020 (define_insn "*sincosextendsfdf3"
15021   [(set (match_operand:DF 0 "register_operand" "=f")
15022         (unspec:DF [(float_extend:DF
15023                      (match_operand:SF 2 "register_operand" "0"))]
15024                    UNSPEC_SINCOS_COS))
15025    (set (match_operand:DF 1 "register_operand" "=u")
15026         (unspec:DF [(float_extend:DF
15027                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15028   "TARGET_USE_FANCY_MATH_387
15029    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15030    && flag_unsafe_math_optimizations"
15031   "fsincos"
15032   [(set_attr "type" "fpspc")
15033    (set_attr "mode" "DF")])
15035 (define_split
15036   [(set (match_operand:DF 0 "register_operand" "")
15037         (unspec:DF [(float_extend:DF
15038                      (match_operand:SF 2 "register_operand" ""))]
15039                    UNSPEC_SINCOS_COS))
15040    (set (match_operand:DF 1 "register_operand" "")
15041         (unspec:DF [(float_extend:DF
15042                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15043   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15044    && !reload_completed && !reload_in_progress"
15045   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15046                                    (match_dup 2))] UNSPEC_SIN))]
15047   "")
15049 (define_split
15050   [(set (match_operand:DF 0 "register_operand" "")
15051         (unspec:DF [(float_extend:DF
15052                      (match_operand:SF 2 "register_operand" ""))]
15053                    UNSPEC_SINCOS_COS))
15054    (set (match_operand:DF 1 "register_operand" "")
15055         (unspec:DF [(float_extend:DF
15056                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15057   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15058    && !reload_completed && !reload_in_progress"
15059   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15060                                    (match_dup 2))] UNSPEC_COS))]
15061   "")
15063 (define_insn "sincosxf3"
15064   [(set (match_operand:XF 0 "register_operand" "=f")
15065         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15066                    UNSPEC_SINCOS_COS))
15067    (set (match_operand:XF 1 "register_operand" "=u")
15068         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15069   "TARGET_USE_FANCY_MATH_387
15070    && flag_unsafe_math_optimizations"
15071   "fsincos"
15072   [(set_attr "type" "fpspc")
15073    (set_attr "mode" "XF")])
15075 (define_split
15076   [(set (match_operand:XF 0 "register_operand" "")
15077         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15078                    UNSPEC_SINCOS_COS))
15079    (set (match_operand:XF 1 "register_operand" "")
15080         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15081   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15082    && !reload_completed && !reload_in_progress"
15083   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15084   "")
15086 (define_split
15087   [(set (match_operand:XF 0 "register_operand" "")
15088         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15089                    UNSPEC_SINCOS_COS))
15090    (set (match_operand:XF 1 "register_operand" "")
15091         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15092   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15093    && !reload_completed && !reload_in_progress"
15094   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15095   "")
15097 (define_insn "*tandf3_1"
15098   [(set (match_operand:DF 0 "register_operand" "=f")
15099         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15100                    UNSPEC_TAN_ONE))
15101    (set (match_operand:DF 1 "register_operand" "=u")
15102         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15103   "TARGET_USE_FANCY_MATH_387
15104    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15105    && flag_unsafe_math_optimizations"
15106   "fptan"
15107   [(set_attr "type" "fpspc")
15108    (set_attr "mode" "DF")])
15110 ;; optimize sequence: fptan
15111 ;;                    fstp    %st(0)
15112 ;;                    fld1
15113 ;; into fptan insn.
15115 (define_peephole2
15116   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15117                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15118                              UNSPEC_TAN_ONE))
15119              (set (match_operand:DF 1 "register_operand" "")
15120                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15121    (set (match_dup 0)
15122         (match_operand:DF 3 "immediate_operand" ""))]
15123   "standard_80387_constant_p (operands[3]) == 2"
15124   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15125              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15126   "")
15128 (define_expand "tandf2"
15129   [(parallel [(set (match_dup 2)
15130                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15131                               UNSPEC_TAN_ONE))
15132               (set (match_operand:DF 0 "register_operand" "")
15133                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15134   "TARGET_USE_FANCY_MATH_387
15135    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15136    && flag_unsafe_math_optimizations"
15138   operands[2] = gen_reg_rtx (DFmode);
15141 (define_insn "*tansf3_1"
15142   [(set (match_operand:SF 0 "register_operand" "=f")
15143         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15144                    UNSPEC_TAN_ONE))
15145    (set (match_operand:SF 1 "register_operand" "=u")
15146         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15147   "TARGET_USE_FANCY_MATH_387
15148    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15149    && flag_unsafe_math_optimizations"
15150   "fptan"
15151   [(set_attr "type" "fpspc")
15152    (set_attr "mode" "SF")])
15154 ;; optimize sequence: fptan
15155 ;;                    fstp    %st(0)
15156 ;;                    fld1
15157 ;; into fptan insn.
15159 (define_peephole2
15160   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15161                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15162                              UNSPEC_TAN_ONE))
15163              (set (match_operand:SF 1 "register_operand" "")
15164                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15165    (set (match_dup 0)
15166         (match_operand:SF 3 "immediate_operand" ""))]
15167   "standard_80387_constant_p (operands[3]) == 2"
15168   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15169              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15170   "")
15172 (define_expand "tansf2"
15173   [(parallel [(set (match_dup 2)
15174                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15175                               UNSPEC_TAN_ONE))
15176               (set (match_operand:SF 0 "register_operand" "")
15177                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15178   "TARGET_USE_FANCY_MATH_387
15179    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15180    && flag_unsafe_math_optimizations"
15182   operands[2] = gen_reg_rtx (SFmode);
15185 (define_insn "*tanxf3_1"
15186   [(set (match_operand:XF 0 "register_operand" "=f")
15187         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15188                    UNSPEC_TAN_ONE))
15189    (set (match_operand:XF 1 "register_operand" "=u")
15190         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15191   "TARGET_USE_FANCY_MATH_387
15192    && flag_unsafe_math_optimizations"
15193   "fptan"
15194   [(set_attr "type" "fpspc")
15195    (set_attr "mode" "XF")])
15197 ;; optimize sequence: fptan
15198 ;;                    fstp    %st(0)
15199 ;;                    fld1
15200 ;; into fptan insn.
15202 (define_peephole2
15203   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15204                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15205                              UNSPEC_TAN_ONE))
15206              (set (match_operand:XF 1 "register_operand" "")
15207                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15208    (set (match_dup 0)
15209         (match_operand:XF 3 "immediate_operand" ""))]
15210   "standard_80387_constant_p (operands[3]) == 2"
15211   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15212              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15213   "")
15215 (define_expand "tanxf2"
15216   [(parallel [(set (match_dup 2)
15217                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15218                               UNSPEC_TAN_ONE))
15219               (set (match_operand:XF 0 "register_operand" "")
15220                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15221   "TARGET_USE_FANCY_MATH_387
15222    && flag_unsafe_math_optimizations"
15224   operands[2] = gen_reg_rtx (XFmode);
15227 (define_insn "atan2df3_1"
15228   [(set (match_operand:DF 0 "register_operand" "=f")
15229         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15230                     (match_operand:DF 1 "register_operand" "u")]
15231                    UNSPEC_FPATAN))
15232    (clobber (match_scratch:DF 3 "=1"))]
15233   "TARGET_USE_FANCY_MATH_387
15234    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15235    && flag_unsafe_math_optimizations"
15236   "fpatan"
15237   [(set_attr "type" "fpspc")
15238    (set_attr "mode" "DF")])
15240 (define_expand "atan2df3"
15241   [(use (match_operand:DF 0 "register_operand" ""))
15242    (use (match_operand:DF 2 "register_operand" ""))
15243    (use (match_operand:DF 1 "register_operand" ""))]
15244   "TARGET_USE_FANCY_MATH_387
15245    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15246    && flag_unsafe_math_optimizations"
15248   rtx copy = gen_reg_rtx (DFmode);
15249   emit_move_insn (copy, operands[1]);
15250   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15251   DONE;
15254 (define_expand "atandf2"
15255   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15256                    (unspec:DF [(match_dup 2)
15257                                (match_operand:DF 1 "register_operand" "")]
15258                     UNSPEC_FPATAN))
15259               (clobber (match_scratch:DF 3 ""))])]
15260   "TARGET_USE_FANCY_MATH_387
15261    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15262    && flag_unsafe_math_optimizations"
15264   operands[2] = gen_reg_rtx (DFmode);
15265   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15268 (define_insn "atan2sf3_1"
15269   [(set (match_operand:SF 0 "register_operand" "=f")
15270         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15271                     (match_operand:SF 1 "register_operand" "u")]
15272                    UNSPEC_FPATAN))
15273    (clobber (match_scratch:SF 3 "=1"))]
15274   "TARGET_USE_FANCY_MATH_387
15275    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15276    && flag_unsafe_math_optimizations"
15277   "fpatan"
15278   [(set_attr "type" "fpspc")
15279    (set_attr "mode" "SF")])
15281 (define_expand "atan2sf3"
15282   [(use (match_operand:SF 0 "register_operand" ""))
15283    (use (match_operand:SF 2 "register_operand" ""))
15284    (use (match_operand:SF 1 "register_operand" ""))]
15285   "TARGET_USE_FANCY_MATH_387
15286    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15287    && flag_unsafe_math_optimizations"
15289   rtx copy = gen_reg_rtx (SFmode);
15290   emit_move_insn (copy, operands[1]);
15291   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15292   DONE;
15295 (define_expand "atansf2"
15296   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15297                    (unspec:SF [(match_dup 2)
15298                                (match_operand:SF 1 "register_operand" "")]
15299                     UNSPEC_FPATAN))
15300               (clobber (match_scratch:SF 3 ""))])]
15301   "TARGET_USE_FANCY_MATH_387
15302    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15303    && flag_unsafe_math_optimizations"
15305   operands[2] = gen_reg_rtx (SFmode);
15306   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15309 (define_insn "atan2xf3_1"
15310   [(set (match_operand:XF 0 "register_operand" "=f")
15311         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15312                     (match_operand:XF 1 "register_operand" "u")]
15313                    UNSPEC_FPATAN))
15314    (clobber (match_scratch:XF 3 "=1"))]
15315   "TARGET_USE_FANCY_MATH_387
15316    && flag_unsafe_math_optimizations"
15317   "fpatan"
15318   [(set_attr "type" "fpspc")
15319    (set_attr "mode" "XF")])
15321 (define_expand "atan2xf3"
15322   [(use (match_operand:XF 0 "register_operand" ""))
15323    (use (match_operand:XF 2 "register_operand" ""))
15324    (use (match_operand:XF 1 "register_operand" ""))]
15325   "TARGET_USE_FANCY_MATH_387
15326    && flag_unsafe_math_optimizations"
15328   rtx copy = gen_reg_rtx (XFmode);
15329   emit_move_insn (copy, operands[1]);
15330   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15331   DONE;
15334 (define_expand "atanxf2"
15335   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15336                    (unspec:XF [(match_dup 2)
15337                                (match_operand:XF 1 "register_operand" "")]
15338                     UNSPEC_FPATAN))
15339               (clobber (match_scratch:XF 3 ""))])]
15340   "TARGET_USE_FANCY_MATH_387
15341    && flag_unsafe_math_optimizations"
15343   operands[2] = gen_reg_rtx (XFmode);
15344   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15347 (define_expand "asindf2"
15348   [(set (match_dup 2)
15349         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15350    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15351    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15352    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15353    (parallel [(set (match_dup 7)
15354                    (unspec:XF [(match_dup 6) (match_dup 2)]
15355                               UNSPEC_FPATAN))
15356               (clobber (match_scratch:XF 8 ""))])
15357    (set (match_operand:DF 0 "register_operand" "")
15358         (float_truncate:DF (match_dup 7)))]
15359   "TARGET_USE_FANCY_MATH_387
15360    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15361    && flag_unsafe_math_optimizations"
15363   int i;
15365   for (i=2; i<8; i++)
15366     operands[i] = gen_reg_rtx (XFmode);
15368   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15371 (define_expand "asinsf2"
15372   [(set (match_dup 2)
15373         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15374    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15375    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15376    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15377    (parallel [(set (match_dup 7)
15378                    (unspec:XF [(match_dup 6) (match_dup 2)]
15379                               UNSPEC_FPATAN))
15380               (clobber (match_scratch:XF 8 ""))])
15381    (set (match_operand:SF 0 "register_operand" "")
15382         (float_truncate:SF (match_dup 7)))]
15383   "TARGET_USE_FANCY_MATH_387
15384    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15385    && flag_unsafe_math_optimizations"
15387   int i;
15389   for (i=2; i<8; i++)
15390     operands[i] = gen_reg_rtx (XFmode);
15392   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15395 (define_expand "asinxf2"
15396   [(set (match_dup 2)
15397         (mult:XF (match_operand:XF 1 "register_operand" "")
15398                  (match_dup 1)))
15399    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15400    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15401    (parallel [(set (match_operand:XF 0 "register_operand" "")
15402                    (unspec:XF [(match_dup 5) (match_dup 1)]
15403                               UNSPEC_FPATAN))
15404               (clobber (match_scratch:XF 6 ""))])]
15405   "TARGET_USE_FANCY_MATH_387
15406    && flag_unsafe_math_optimizations"
15408   int i;
15410   for (i=2; i<6; i++)
15411     operands[i] = gen_reg_rtx (XFmode);
15413   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15416 (define_expand "acosdf2"
15417   [(set (match_dup 2)
15418         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15419    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15420    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15421    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15422    (parallel [(set (match_dup 7)
15423                    (unspec:XF [(match_dup 2) (match_dup 6)]
15424                               UNSPEC_FPATAN))
15425               (clobber (match_scratch:XF 8 ""))])
15426    (set (match_operand:DF 0 "register_operand" "")
15427         (float_truncate:DF (match_dup 7)))]
15428   "TARGET_USE_FANCY_MATH_387
15429    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15430    && flag_unsafe_math_optimizations"
15432   int i;
15434   for (i=2; i<8; i++)
15435     operands[i] = gen_reg_rtx (XFmode);
15437   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15440 (define_expand "acossf2"
15441   [(set (match_dup 2)
15442         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15443    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15444    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15445    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15446    (parallel [(set (match_dup 7)
15447                    (unspec:XF [(match_dup 2) (match_dup 6)]
15448                               UNSPEC_FPATAN))
15449               (clobber (match_scratch:XF 8 ""))])
15450    (set (match_operand:SF 0 "register_operand" "")
15451         (float_truncate:SF (match_dup 7)))]
15452   "TARGET_USE_FANCY_MATH_387
15453    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15454    && flag_unsafe_math_optimizations"
15456   int i;
15458   for (i=2; i<8; i++)
15459     operands[i] = gen_reg_rtx (XFmode);
15461   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15464 (define_expand "acosxf2"
15465   [(set (match_dup 2)
15466         (mult:XF (match_operand:XF 1 "register_operand" "")
15467                  (match_dup 1)))
15468    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15469    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15470    (parallel [(set (match_operand:XF 0 "register_operand" "")
15471                    (unspec:XF [(match_dup 1) (match_dup 5)]
15472                               UNSPEC_FPATAN))
15473               (clobber (match_scratch:XF 6 ""))])]
15474   "TARGET_USE_FANCY_MATH_387
15475    && flag_unsafe_math_optimizations"
15477   int i;
15479   for (i=2; i<6; i++)
15480     operands[i] = gen_reg_rtx (XFmode);
15482   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15485 (define_insn "fyl2x_xf3"
15486   [(set (match_operand:XF 0 "register_operand" "=f")
15487         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15488                     (match_operand:XF 1 "register_operand" "u")]
15489                    UNSPEC_FYL2X))
15490    (clobber (match_scratch:XF 3 "=1"))]
15491   "TARGET_USE_FANCY_MATH_387
15492    && flag_unsafe_math_optimizations"
15493   "fyl2x"
15494   [(set_attr "type" "fpspc")
15495    (set_attr "mode" "XF")])
15497 (define_expand "logsf2"
15498   [(set (match_dup 2)
15499         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15500    (parallel [(set (match_dup 4)
15501                    (unspec:XF [(match_dup 2)
15502                                (match_dup 3)] UNSPEC_FYL2X))
15503               (clobber (match_scratch:XF 5 ""))])
15504    (set (match_operand:SF 0 "register_operand" "")
15505         (float_truncate:SF (match_dup 4)))]
15506   "TARGET_USE_FANCY_MATH_387
15507    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15508    && flag_unsafe_math_optimizations"
15510   rtx temp;
15512   operands[2] = gen_reg_rtx (XFmode);
15513   operands[3] = gen_reg_rtx (XFmode);
15514   operands[4] = gen_reg_rtx (XFmode);
15516   temp = standard_80387_constant_rtx (4); /* fldln2 */
15517   emit_move_insn (operands[3], temp);
15520 (define_expand "logdf2"
15521   [(set (match_dup 2)
15522         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15523    (parallel [(set (match_dup 4)
15524                    (unspec:XF [(match_dup 2)
15525                                (match_dup 3)] UNSPEC_FYL2X))
15526               (clobber (match_scratch:XF 5 ""))])
15527    (set (match_operand:DF 0 "register_operand" "")
15528         (float_truncate:DF (match_dup 4)))]
15529   "TARGET_USE_FANCY_MATH_387
15530    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15531    && flag_unsafe_math_optimizations"
15533   rtx temp;
15535   operands[2] = gen_reg_rtx (XFmode);
15536   operands[3] = gen_reg_rtx (XFmode);
15537   operands[4] = gen_reg_rtx (XFmode);
15539   temp = standard_80387_constant_rtx (4); /* fldln2 */
15540   emit_move_insn (operands[3], temp);
15543 (define_expand "logxf2"
15544   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15545                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15546                                (match_dup 2)] UNSPEC_FYL2X))
15547               (clobber (match_scratch:XF 3 ""))])]
15548   "TARGET_USE_FANCY_MATH_387
15549    && flag_unsafe_math_optimizations"
15551   rtx temp;
15553   operands[2] = gen_reg_rtx (XFmode);
15554   temp = standard_80387_constant_rtx (4); /* fldln2 */
15555   emit_move_insn (operands[2], temp);
15558 (define_expand "log10sf2"
15559   [(set (match_dup 2)
15560         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15561    (parallel [(set (match_dup 4)
15562                    (unspec:XF [(match_dup 2)
15563                                (match_dup 3)] UNSPEC_FYL2X))
15564               (clobber (match_scratch:XF 5 ""))])
15565    (set (match_operand:SF 0 "register_operand" "")
15566         (float_truncate:SF (match_dup 4)))]
15567   "TARGET_USE_FANCY_MATH_387
15568    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15569    && flag_unsafe_math_optimizations"
15571   rtx temp;
15573   operands[2] = gen_reg_rtx (XFmode);
15574   operands[3] = gen_reg_rtx (XFmode);
15575   operands[4] = gen_reg_rtx (XFmode);
15577   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15578   emit_move_insn (operands[3], temp);
15581 (define_expand "log10df2"
15582   [(set (match_dup 2)
15583         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15584    (parallel [(set (match_dup 4)
15585                    (unspec:XF [(match_dup 2)
15586                                (match_dup 3)] UNSPEC_FYL2X))
15587               (clobber (match_scratch:XF 5 ""))])
15588    (set (match_operand:DF 0 "register_operand" "")
15589         (float_truncate:DF (match_dup 4)))]
15590   "TARGET_USE_FANCY_MATH_387
15591    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15592    && flag_unsafe_math_optimizations"
15594   rtx temp;
15596   operands[2] = gen_reg_rtx (XFmode);
15597   operands[3] = gen_reg_rtx (XFmode);
15598   operands[4] = gen_reg_rtx (XFmode);
15600   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15601   emit_move_insn (operands[3], temp);
15604 (define_expand "log10xf2"
15605   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15606                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15607                                (match_dup 2)] UNSPEC_FYL2X))
15608               (clobber (match_scratch:XF 3 ""))])]
15609   "TARGET_USE_FANCY_MATH_387
15610    && flag_unsafe_math_optimizations"
15612   rtx temp;
15614   operands[2] = gen_reg_rtx (XFmode);
15615   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15616   emit_move_insn (operands[2], temp);
15619 (define_expand "log2sf2"
15620   [(set (match_dup 2)
15621         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15622    (parallel [(set (match_dup 4)
15623                    (unspec:XF [(match_dup 2)
15624                                (match_dup 3)] UNSPEC_FYL2X))
15625               (clobber (match_scratch:XF 5 ""))])
15626    (set (match_operand:SF 0 "register_operand" "")
15627         (float_truncate:SF (match_dup 4)))]
15628   "TARGET_USE_FANCY_MATH_387
15629    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15630    && flag_unsafe_math_optimizations"
15632   operands[2] = gen_reg_rtx (XFmode);
15633   operands[3] = gen_reg_rtx (XFmode);
15634   operands[4] = gen_reg_rtx (XFmode);
15636   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15639 (define_expand "log2df2"
15640   [(set (match_dup 2)
15641         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15642    (parallel [(set (match_dup 4)
15643                    (unspec:XF [(match_dup 2)
15644                                (match_dup 3)] UNSPEC_FYL2X))
15645               (clobber (match_scratch:XF 5 ""))])
15646    (set (match_operand:DF 0 "register_operand" "")
15647         (float_truncate:DF (match_dup 4)))]
15648   "TARGET_USE_FANCY_MATH_387
15649    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15650    && flag_unsafe_math_optimizations"
15652   operands[2] = gen_reg_rtx (XFmode);
15653   operands[3] = gen_reg_rtx (XFmode);
15654   operands[4] = gen_reg_rtx (XFmode);
15656   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15659 (define_expand "log2xf2"
15660   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15661                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15662                                (match_dup 2)] UNSPEC_FYL2X))
15663               (clobber (match_scratch:XF 3 ""))])]
15664   "TARGET_USE_FANCY_MATH_387
15665    && flag_unsafe_math_optimizations"
15667   operands[2] = gen_reg_rtx (XFmode);
15668   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15671 (define_insn "fyl2xp1_xf3"
15672   [(set (match_operand:XF 0 "register_operand" "=f")
15673         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15674                     (match_operand:XF 1 "register_operand" "u")]
15675                    UNSPEC_FYL2XP1))
15676    (clobber (match_scratch:XF 3 "=1"))]
15677   "TARGET_USE_FANCY_MATH_387
15678    && flag_unsafe_math_optimizations"
15679   "fyl2xp1"
15680   [(set_attr "type" "fpspc")
15681    (set_attr "mode" "XF")])
15683 (define_expand "log1psf2"
15684   [(use (match_operand:SF 0 "register_operand" ""))
15685    (use (match_operand:SF 1 "register_operand" ""))]
15686   "TARGET_USE_FANCY_MATH_387
15687    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15688    && flag_unsafe_math_optimizations"
15690   rtx op0 = gen_reg_rtx (XFmode);
15691   rtx op1 = gen_reg_rtx (XFmode);
15693   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15694   ix86_emit_i387_log1p (op0, op1);
15695   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15696   DONE;
15699 (define_expand "log1pdf2"
15700   [(use (match_operand:DF 0 "register_operand" ""))
15701    (use (match_operand:DF 1 "register_operand" ""))]
15702   "TARGET_USE_FANCY_MATH_387
15703    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15704    && flag_unsafe_math_optimizations"
15706   rtx op0 = gen_reg_rtx (XFmode);
15707   rtx op1 = gen_reg_rtx (XFmode);
15709   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15710   ix86_emit_i387_log1p (op0, op1);
15711   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15712   DONE;
15715 (define_expand "log1pxf2"
15716   [(use (match_operand:XF 0 "register_operand" ""))
15717    (use (match_operand:XF 1 "register_operand" ""))]
15718   "TARGET_USE_FANCY_MATH_387
15719    && flag_unsafe_math_optimizations"
15721   ix86_emit_i387_log1p (operands[0], operands[1]);
15722   DONE;
15725 (define_insn "*fxtractxf3"
15726   [(set (match_operand:XF 0 "register_operand" "=f")
15727         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15728                    UNSPEC_XTRACT_FRACT))
15729    (set (match_operand:XF 1 "register_operand" "=u")
15730         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15731   "TARGET_USE_FANCY_MATH_387
15732    && flag_unsafe_math_optimizations"
15733   "fxtract"
15734   [(set_attr "type" "fpspc")
15735    (set_attr "mode" "XF")])
15737 (define_expand "logbsf2"
15738   [(set (match_dup 2)
15739         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15740    (parallel [(set (match_dup 3)
15741                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15742               (set (match_dup 4)
15743                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15744    (set (match_operand:SF 0 "register_operand" "")
15745         (float_truncate:SF (match_dup 4)))]
15746   "TARGET_USE_FANCY_MATH_387
15747    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15748    && flag_unsafe_math_optimizations"
15750   operands[2] = gen_reg_rtx (XFmode);
15751   operands[3] = gen_reg_rtx (XFmode);
15752   operands[4] = gen_reg_rtx (XFmode);
15755 (define_expand "logbdf2"
15756   [(set (match_dup 2)
15757         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15758    (parallel [(set (match_dup 3)
15759                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15760               (set (match_dup 4)
15761                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15762    (set (match_operand:DF 0 "register_operand" "")
15763         (float_truncate:DF (match_dup 4)))]
15764   "TARGET_USE_FANCY_MATH_387
15765    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15766    && flag_unsafe_math_optimizations"
15768   operands[2] = gen_reg_rtx (XFmode);
15769   operands[3] = gen_reg_rtx (XFmode);
15770   operands[4] = gen_reg_rtx (XFmode);
15773 (define_expand "logbxf2"
15774   [(parallel [(set (match_dup 2)
15775                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15776                               UNSPEC_XTRACT_FRACT))
15777               (set (match_operand:XF 0 "register_operand" "")
15778                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15779   "TARGET_USE_FANCY_MATH_387
15780    && flag_unsafe_math_optimizations"
15782   operands[2] = gen_reg_rtx (XFmode);
15785 (define_expand "ilogbsi2"
15786   [(parallel [(set (match_dup 2)
15787                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15788                               UNSPEC_XTRACT_FRACT))
15789               (set (match_operand:XF 3 "register_operand" "")
15790                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15791    (parallel [(set (match_operand:SI 0 "register_operand" "")
15792                    (fix:SI (match_dup 3)))
15793               (clobber (reg:CC FLAGS_REG))])]
15794   "TARGET_USE_FANCY_MATH_387
15795    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15796    && flag_unsafe_math_optimizations"
15798   operands[2] = gen_reg_rtx (XFmode);
15799   operands[3] = gen_reg_rtx (XFmode);
15802 (define_insn "*f2xm1xf2"
15803   [(set (match_operand:XF 0 "register_operand" "=f")
15804         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15805          UNSPEC_F2XM1))]
15806   "TARGET_USE_FANCY_MATH_387
15807    && flag_unsafe_math_optimizations"
15808   "f2xm1"
15809   [(set_attr "type" "fpspc")
15810    (set_attr "mode" "XF")])
15812 (define_insn "*fscalexf4"
15813   [(set (match_operand:XF 0 "register_operand" "=f")
15814         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15815                     (match_operand:XF 3 "register_operand" "1")]
15816                    UNSPEC_FSCALE_FRACT))
15817    (set (match_operand:XF 1 "register_operand" "=u")
15818         (unspec:XF [(match_dup 2) (match_dup 3)]
15819                    UNSPEC_FSCALE_EXP))]
15820   "TARGET_USE_FANCY_MATH_387
15821    && flag_unsafe_math_optimizations"
15822   "fscale"
15823   [(set_attr "type" "fpspc")
15824    (set_attr "mode" "XF")])
15826 (define_expand "expsf2"
15827   [(set (match_dup 2)
15828         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15829    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15830    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15831    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15832    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15833    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15834    (parallel [(set (match_dup 10)
15835                    (unspec:XF [(match_dup 9) (match_dup 5)]
15836                               UNSPEC_FSCALE_FRACT))
15837               (set (match_dup 11)
15838                    (unspec:XF [(match_dup 9) (match_dup 5)]
15839                               UNSPEC_FSCALE_EXP))])
15840    (set (match_operand:SF 0 "register_operand" "")
15841         (float_truncate:SF (match_dup 10)))]
15842   "TARGET_USE_FANCY_MATH_387
15843    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15844    && flag_unsafe_math_optimizations"
15846   rtx temp;
15847   int i;
15849   for (i=2; i<12; i++)
15850     operands[i] = gen_reg_rtx (XFmode);
15851   temp = standard_80387_constant_rtx (5); /* fldl2e */
15852   emit_move_insn (operands[3], temp);
15853   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15856 (define_expand "expdf2"
15857   [(set (match_dup 2)
15858         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15859    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15860    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15861    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15862    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15863    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15864    (parallel [(set (match_dup 10)
15865                    (unspec:XF [(match_dup 9) (match_dup 5)]
15866                               UNSPEC_FSCALE_FRACT))
15867               (set (match_dup 11)
15868                    (unspec:XF [(match_dup 9) (match_dup 5)]
15869                               UNSPEC_FSCALE_EXP))])
15870    (set (match_operand:DF 0 "register_operand" "")
15871         (float_truncate:DF (match_dup 10)))]
15872   "TARGET_USE_FANCY_MATH_387
15873    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15874    && flag_unsafe_math_optimizations"
15876   rtx temp;
15877   int i;
15879   for (i=2; i<12; i++)
15880     operands[i] = gen_reg_rtx (XFmode);
15881   temp = standard_80387_constant_rtx (5); /* fldl2e */
15882   emit_move_insn (operands[3], temp);
15883   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15886 (define_expand "expxf2"
15887   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15888                                (match_dup 2)))
15889    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15890    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15891    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15892    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15893    (parallel [(set (match_operand:XF 0 "register_operand" "")
15894                    (unspec:XF [(match_dup 8) (match_dup 4)]
15895                               UNSPEC_FSCALE_FRACT))
15896               (set (match_dup 9)
15897                    (unspec:XF [(match_dup 8) (match_dup 4)]
15898                               UNSPEC_FSCALE_EXP))])]
15899   "TARGET_USE_FANCY_MATH_387
15900    && flag_unsafe_math_optimizations"
15902   rtx temp;
15903   int i;
15905   for (i=2; i<10; i++)
15906     operands[i] = gen_reg_rtx (XFmode);
15907   temp = standard_80387_constant_rtx (5); /* fldl2e */
15908   emit_move_insn (operands[2], temp);
15909   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15912 (define_expand "exp10sf2"
15913   [(set (match_dup 2)
15914         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15915    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15916    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15917    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15918    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15919    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15920    (parallel [(set (match_dup 10)
15921                    (unspec:XF [(match_dup 9) (match_dup 5)]
15922                               UNSPEC_FSCALE_FRACT))
15923               (set (match_dup 11)
15924                    (unspec:XF [(match_dup 9) (match_dup 5)]
15925                               UNSPEC_FSCALE_EXP))])
15926    (set (match_operand:SF 0 "register_operand" "")
15927         (float_truncate:SF (match_dup 10)))]
15928   "TARGET_USE_FANCY_MATH_387
15929    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15930    && flag_unsafe_math_optimizations"
15932   rtx temp;
15933   int i;
15935   for (i=2; i<12; i++)
15936     operands[i] = gen_reg_rtx (XFmode);
15937   temp = standard_80387_constant_rtx (6); /* fldl2t */
15938   emit_move_insn (operands[3], temp);
15939   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15942 (define_expand "exp10df2"
15943   [(set (match_dup 2)
15944         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15945    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15946    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15947    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15948    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15949    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15950    (parallel [(set (match_dup 10)
15951                    (unspec:XF [(match_dup 9) (match_dup 5)]
15952                               UNSPEC_FSCALE_FRACT))
15953               (set (match_dup 11)
15954                    (unspec:XF [(match_dup 9) (match_dup 5)]
15955                               UNSPEC_FSCALE_EXP))])
15956    (set (match_operand:DF 0 "register_operand" "")
15957         (float_truncate:DF (match_dup 10)))]
15958   "TARGET_USE_FANCY_MATH_387
15959    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15960    && flag_unsafe_math_optimizations"
15962   rtx temp;
15963   int i;
15965   for (i=2; i<12; i++)
15966     operands[i] = gen_reg_rtx (XFmode);
15967   temp = standard_80387_constant_rtx (6); /* fldl2t */
15968   emit_move_insn (operands[3], temp);
15969   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15972 (define_expand "exp10xf2"
15973   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15974                                (match_dup 2)))
15975    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15976    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15977    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15978    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15979    (parallel [(set (match_operand:XF 0 "register_operand" "")
15980                    (unspec:XF [(match_dup 8) (match_dup 4)]
15981                               UNSPEC_FSCALE_FRACT))
15982               (set (match_dup 9)
15983                    (unspec:XF [(match_dup 8) (match_dup 4)]
15984                               UNSPEC_FSCALE_EXP))])]
15985   "TARGET_USE_FANCY_MATH_387
15986    && flag_unsafe_math_optimizations"
15988   rtx temp;
15989   int i;
15991   for (i=2; i<10; i++)
15992     operands[i] = gen_reg_rtx (XFmode);
15993   temp = standard_80387_constant_rtx (6); /* fldl2t */
15994   emit_move_insn (operands[2], temp);
15995   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15998 (define_expand "exp2sf2"
15999   [(set (match_dup 2)
16000         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16001    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16002    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16003    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16004    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16005    (parallel [(set (match_dup 8)
16006                    (unspec:XF [(match_dup 7) (match_dup 3)]
16007                               UNSPEC_FSCALE_FRACT))
16008               (set (match_dup 9)
16009                    (unspec:XF [(match_dup 7) (match_dup 3)]
16010                               UNSPEC_FSCALE_EXP))])
16011    (set (match_operand:SF 0 "register_operand" "")
16012         (float_truncate:SF (match_dup 8)))]
16013   "TARGET_USE_FANCY_MATH_387
16014    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16015    && flag_unsafe_math_optimizations"
16017   int i;
16019   for (i=2; i<10; i++)
16020     operands[i] = gen_reg_rtx (XFmode);
16021   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16024 (define_expand "exp2df2"
16025   [(set (match_dup 2)
16026         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16027    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16028    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16029    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16030    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16031    (parallel [(set (match_dup 8)
16032                    (unspec:XF [(match_dup 7) (match_dup 3)]
16033                               UNSPEC_FSCALE_FRACT))
16034               (set (match_dup 9)
16035                    (unspec:XF [(match_dup 7) (match_dup 3)]
16036                               UNSPEC_FSCALE_EXP))])
16037    (set (match_operand:DF 0 "register_operand" "")
16038         (float_truncate:DF (match_dup 8)))]
16039   "TARGET_USE_FANCY_MATH_387
16040    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16041    && flag_unsafe_math_optimizations"
16043   int i;
16045   for (i=2; i<10; i++)
16046     operands[i] = gen_reg_rtx (XFmode);
16047   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16050 (define_expand "exp2xf2"
16051   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16052    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16053    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16054    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16055    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16056    (parallel [(set (match_operand:XF 0 "register_operand" "")
16057                    (unspec:XF [(match_dup 7) (match_dup 3)]
16058                               UNSPEC_FSCALE_FRACT))
16059               (set (match_dup 8)
16060                    (unspec:XF [(match_dup 7) (match_dup 3)]
16061                               UNSPEC_FSCALE_EXP))])]
16062   "TARGET_USE_FANCY_MATH_387
16063    && flag_unsafe_math_optimizations"
16065   int i;
16067   for (i=2; i<9; i++)
16068     operands[i] = gen_reg_rtx (XFmode);
16069   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16072 (define_expand "expm1df2"
16073   [(set (match_dup 2)
16074         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16075    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16076    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16077    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16078    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16079    (parallel [(set (match_dup 8)
16080                    (unspec:XF [(match_dup 7) (match_dup 5)]
16081                               UNSPEC_FSCALE_FRACT))
16082                    (set (match_dup 9)
16083                    (unspec:XF [(match_dup 7) (match_dup 5)]
16084                               UNSPEC_FSCALE_EXP))])
16085    (parallel [(set (match_dup 11)
16086                    (unspec:XF [(match_dup 10) (match_dup 9)]
16087                               UNSPEC_FSCALE_FRACT))
16088               (set (match_dup 12)
16089                    (unspec:XF [(match_dup 10) (match_dup 9)]
16090                               UNSPEC_FSCALE_EXP))])
16091    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16092    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16093    (set (match_operand:DF 0 "register_operand" "")
16094         (float_truncate:DF (match_dup 14)))]
16095   "TARGET_USE_FANCY_MATH_387
16096    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16097    && flag_unsafe_math_optimizations"
16099   rtx temp;
16100   int i;
16102   for (i=2; i<15; i++)
16103     operands[i] = gen_reg_rtx (XFmode);
16104   temp = standard_80387_constant_rtx (5); /* fldl2e */
16105   emit_move_insn (operands[3], temp);
16106   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16109 (define_expand "expm1sf2"
16110   [(set (match_dup 2)
16111         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16112    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16113    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16114    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16115    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16116    (parallel [(set (match_dup 8)
16117                    (unspec:XF [(match_dup 7) (match_dup 5)]
16118                               UNSPEC_FSCALE_FRACT))
16119                    (set (match_dup 9)
16120                    (unspec:XF [(match_dup 7) (match_dup 5)]
16121                               UNSPEC_FSCALE_EXP))])
16122    (parallel [(set (match_dup 11)
16123                    (unspec:XF [(match_dup 10) (match_dup 9)]
16124                               UNSPEC_FSCALE_FRACT))
16125               (set (match_dup 12)
16126                    (unspec:XF [(match_dup 10) (match_dup 9)]
16127                               UNSPEC_FSCALE_EXP))])
16128    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16129    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16130    (set (match_operand:SF 0 "register_operand" "")
16131         (float_truncate:SF (match_dup 14)))]
16132   "TARGET_USE_FANCY_MATH_387
16133    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16134    && flag_unsafe_math_optimizations"
16136   rtx temp;
16137   int i;
16139   for (i=2; i<15; i++)
16140     operands[i] = gen_reg_rtx (XFmode);
16141   temp = standard_80387_constant_rtx (5); /* fldl2e */
16142   emit_move_insn (operands[3], temp);
16143   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16146 (define_expand "expm1xf2"
16147   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16148                                (match_dup 2)))
16149    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16150    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16151    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16152    (parallel [(set (match_dup 7)
16153                    (unspec:XF [(match_dup 6) (match_dup 4)]
16154                               UNSPEC_FSCALE_FRACT))
16155                    (set (match_dup 8)
16156                    (unspec:XF [(match_dup 6) (match_dup 4)]
16157                               UNSPEC_FSCALE_EXP))])
16158    (parallel [(set (match_dup 10)
16159                    (unspec:XF [(match_dup 9) (match_dup 8)]
16160                               UNSPEC_FSCALE_FRACT))
16161               (set (match_dup 11)
16162                    (unspec:XF [(match_dup 9) (match_dup 8)]
16163                               UNSPEC_FSCALE_EXP))])
16164    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16165    (set (match_operand:XF 0 "register_operand" "")
16166         (plus:XF (match_dup 12) (match_dup 7)))]
16167   "TARGET_USE_FANCY_MATH_387
16168    && flag_unsafe_math_optimizations"
16170   rtx temp;
16171   int i;
16173   for (i=2; i<13; i++)
16174     operands[i] = gen_reg_rtx (XFmode);
16175   temp = standard_80387_constant_rtx (5); /* fldl2e */
16176   emit_move_insn (operands[2], temp);
16177   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16180 (define_expand "ldexpdf3"
16181   [(set (match_dup 3)
16182         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16183    (set (match_dup 4)
16184         (float:XF (match_operand:SI 2 "register_operand" "")))
16185    (parallel [(set (match_dup 5)
16186                    (unspec:XF [(match_dup 3) (match_dup 4)]
16187                               UNSPEC_FSCALE_FRACT))
16188               (set (match_dup 6)
16189                    (unspec:XF [(match_dup 3) (match_dup 4)]
16190                               UNSPEC_FSCALE_EXP))])
16191    (set (match_operand:DF 0 "register_operand" "")
16192         (float_truncate:DF (match_dup 5)))]
16193   "TARGET_USE_FANCY_MATH_387
16194    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16195    && flag_unsafe_math_optimizations"
16197   int i;
16199   for (i=3; i<7; i++)
16200     operands[i] = gen_reg_rtx (XFmode);
16203 (define_expand "ldexpsf3"
16204   [(set (match_dup 3)
16205         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16206    (set (match_dup 4)
16207         (float:XF (match_operand:SI 2 "register_operand" "")))
16208    (parallel [(set (match_dup 5)
16209                    (unspec:XF [(match_dup 3) (match_dup 4)]
16210                               UNSPEC_FSCALE_FRACT))
16211               (set (match_dup 6)
16212                    (unspec:XF [(match_dup 3) (match_dup 4)]
16213                               UNSPEC_FSCALE_EXP))])
16214    (set (match_operand:SF 0 "register_operand" "")
16215         (float_truncate:SF (match_dup 5)))]
16216   "TARGET_USE_FANCY_MATH_387
16217    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16218    && flag_unsafe_math_optimizations"
16220   int i;
16222   for (i=3; i<7; i++)
16223     operands[i] = gen_reg_rtx (XFmode);
16226 (define_expand "ldexpxf3"
16227   [(set (match_dup 3)
16228         (float:XF (match_operand:SI 2 "register_operand" "")))
16229    (parallel [(set (match_operand:XF 0 " register_operand" "")
16230                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16231                                (match_dup 3)]
16232                               UNSPEC_FSCALE_FRACT))
16233               (set (match_dup 4)
16234                    (unspec:XF [(match_dup 1) (match_dup 3)]
16235                               UNSPEC_FSCALE_EXP))])]
16236   "TARGET_USE_FANCY_MATH_387
16237    && flag_unsafe_math_optimizations"
16239   int i;
16241   for (i=3; i<5; i++)
16242     operands[i] = gen_reg_rtx (XFmode);
16246 (define_insn "frndintxf2"
16247   [(set (match_operand:XF 0 "register_operand" "=f")
16248         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16249          UNSPEC_FRNDINT))]
16250   "TARGET_USE_FANCY_MATH_387
16251    && flag_unsafe_math_optimizations"
16252   "frndint"
16253   [(set_attr "type" "fpspc")
16254    (set_attr "mode" "XF")])
16256 (define_expand "rintdf2"
16257   [(use (match_operand:DF 0 "register_operand" ""))
16258    (use (match_operand:DF 1 "register_operand" ""))]
16259   "TARGET_USE_FANCY_MATH_387
16260    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16261    && flag_unsafe_math_optimizations"
16263   rtx op0 = gen_reg_rtx (XFmode);
16264   rtx op1 = gen_reg_rtx (XFmode);
16266   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16267   emit_insn (gen_frndintxf2 (op0, op1));
16269   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16270   DONE;
16273 (define_expand "rintsf2"
16274   [(use (match_operand:SF 0 "register_operand" ""))
16275    (use (match_operand:SF 1 "register_operand" ""))]
16276   "TARGET_USE_FANCY_MATH_387
16277    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16278    && flag_unsafe_math_optimizations"
16280   rtx op0 = gen_reg_rtx (XFmode);
16281   rtx op1 = gen_reg_rtx (XFmode);
16283   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16284   emit_insn (gen_frndintxf2 (op0, op1));
16286   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16287   DONE;
16290 (define_expand "rintxf2"
16291   [(use (match_operand:XF 0 "register_operand" ""))
16292    (use (match_operand:XF 1 "register_operand" ""))]
16293   "TARGET_USE_FANCY_MATH_387
16294    && flag_unsafe_math_optimizations"
16296   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16297   DONE;
16300 (define_insn "frndintxf2_floor"
16301   [(set (match_operand:XF 0 "register_operand" "=f")
16302         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16303          UNSPEC_FRNDINT_FLOOR))
16304    (use (match_operand:HI 2 "memory_operand" "m"))
16305    (use (match_operand:HI 3 "memory_operand" "m"))]
16306   "TARGET_USE_FANCY_MATH_387
16307    && flag_unsafe_math_optimizations"
16308   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16309   [(set_attr "type" "frndint")
16310    (set_attr "i387_cw" "floor")
16311    (set_attr "mode" "XF")])
16313 (define_expand "floordf2"
16314   [(use (match_operand:DF 0 "register_operand" ""))
16315    (use (match_operand:DF 1 "register_operand" ""))]
16316   "TARGET_USE_FANCY_MATH_387
16317    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16318    && flag_unsafe_math_optimizations"
16320   rtx op0 = gen_reg_rtx (XFmode);
16321   rtx op1 = gen_reg_rtx (XFmode);
16322   rtx op2 = assign_386_stack_local (HImode, 1);
16323   rtx op3 = assign_386_stack_local (HImode, 2);
16324         
16325   ix86_optimize_mode_switching = 1;
16327   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16328   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16330   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16331   DONE;
16334 (define_expand "floorsf2"
16335   [(use (match_operand:SF 0 "register_operand" ""))
16336    (use (match_operand:SF 1 "register_operand" ""))]
16337   "TARGET_USE_FANCY_MATH_387
16338    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16339    && flag_unsafe_math_optimizations"
16341   rtx op0 = gen_reg_rtx (XFmode);
16342   rtx op1 = gen_reg_rtx (XFmode);
16343   rtx op2 = assign_386_stack_local (HImode, 1);
16344   rtx op3 = assign_386_stack_local (HImode, 2);
16345         
16346   ix86_optimize_mode_switching = 1;
16348   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16349   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16351   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16352   DONE;
16355 (define_expand "floorxf2"
16356   [(use (match_operand:XF 0 "register_operand" ""))
16357    (use (match_operand:XF 1 "register_operand" ""))]
16358   "TARGET_USE_FANCY_MATH_387
16359    && flag_unsafe_math_optimizations"
16361   rtx op2 = assign_386_stack_local (HImode, 1);
16362   rtx op3 = assign_386_stack_local (HImode, 2);
16363         
16364   ix86_optimize_mode_switching = 1;
16366   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16367   DONE;
16370 (define_insn "frndintxf2_ceil"
16371   [(set (match_operand:XF 0 "register_operand" "=f")
16372         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16373          UNSPEC_FRNDINT_CEIL))
16374    (use (match_operand:HI 2 "memory_operand" "m"))
16375    (use (match_operand:HI 3 "memory_operand" "m"))]
16376   "TARGET_USE_FANCY_MATH_387
16377    && flag_unsafe_math_optimizations"
16378   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16379   [(set_attr "type" "frndint")
16380    (set_attr "i387_cw" "ceil")
16381    (set_attr "mode" "XF")])
16383 (define_expand "ceildf2"
16384   [(use (match_operand:DF 0 "register_operand" ""))
16385    (use (match_operand:DF 1 "register_operand" ""))]
16386   "TARGET_USE_FANCY_MATH_387
16387    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16388    && flag_unsafe_math_optimizations"
16390   rtx op0 = gen_reg_rtx (XFmode);
16391   rtx op1 = gen_reg_rtx (XFmode);
16392   rtx op2 = assign_386_stack_local (HImode, 1);
16393   rtx op3 = assign_386_stack_local (HImode, 2);
16394         
16395   ix86_optimize_mode_switching = 1;
16397   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16398   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16400   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16401   DONE;
16404 (define_expand "ceilsf2"
16405   [(use (match_operand:SF 0 "register_operand" ""))
16406    (use (match_operand:SF 1 "register_operand" ""))]
16407   "TARGET_USE_FANCY_MATH_387
16408    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16409    && flag_unsafe_math_optimizations"
16411   rtx op0 = gen_reg_rtx (XFmode);
16412   rtx op1 = gen_reg_rtx (XFmode);
16413   rtx op2 = assign_386_stack_local (HImode, 1);
16414   rtx op3 = assign_386_stack_local (HImode, 2);
16415         
16416   ix86_optimize_mode_switching = 1;
16418   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16419   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16421   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16422   DONE;
16425 (define_expand "ceilxf2"
16426   [(use (match_operand:XF 0 "register_operand" ""))
16427    (use (match_operand:XF 1 "register_operand" ""))]
16428   "TARGET_USE_FANCY_MATH_387
16429    && flag_unsafe_math_optimizations"
16431   rtx op2 = assign_386_stack_local (HImode, 1);
16432   rtx op3 = assign_386_stack_local (HImode, 2);
16433         
16434   ix86_optimize_mode_switching = 1;
16436   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16437   DONE;
16440 (define_insn "frndintxf2_trunc"
16441   [(set (match_operand:XF 0 "register_operand" "=f")
16442         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16443          UNSPEC_FRNDINT_TRUNC))
16444    (use (match_operand:HI 2 "memory_operand" "m"))
16445    (use (match_operand:HI 3 "memory_operand" "m"))]
16446   "TARGET_USE_FANCY_MATH_387
16447    && flag_unsafe_math_optimizations"
16448   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16449   [(set_attr "type" "frndint")
16450    (set_attr "i387_cw" "trunc")
16451    (set_attr "mode" "XF")])
16453 (define_expand "btruncdf2"
16454   [(use (match_operand:DF 0 "register_operand" ""))
16455    (use (match_operand:DF 1 "register_operand" ""))]
16456   "TARGET_USE_FANCY_MATH_387
16457    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16458    && flag_unsafe_math_optimizations"
16460   rtx op0 = gen_reg_rtx (XFmode);
16461   rtx op1 = gen_reg_rtx (XFmode);
16462   rtx op2 = assign_386_stack_local (HImode, 1);
16463   rtx op3 = assign_386_stack_local (HImode, 2);
16464         
16465   ix86_optimize_mode_switching = 1;
16467   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16468   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16470   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16471   DONE;
16474 (define_expand "btruncsf2"
16475   [(use (match_operand:SF 0 "register_operand" ""))
16476    (use (match_operand:SF 1 "register_operand" ""))]
16477   "TARGET_USE_FANCY_MATH_387
16478    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16479    && flag_unsafe_math_optimizations"
16481   rtx op0 = gen_reg_rtx (XFmode);
16482   rtx op1 = gen_reg_rtx (XFmode);
16483   rtx op2 = assign_386_stack_local (HImode, 1);
16484   rtx op3 = assign_386_stack_local (HImode, 2);
16485         
16486   ix86_optimize_mode_switching = 1;
16488   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16489   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16491   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16492   DONE;
16495 (define_expand "btruncxf2"
16496   [(use (match_operand:XF 0 "register_operand" ""))
16497    (use (match_operand:XF 1 "register_operand" ""))]
16498   "TARGET_USE_FANCY_MATH_387
16499    && flag_unsafe_math_optimizations"
16501   rtx op2 = assign_386_stack_local (HImode, 1);
16502   rtx op3 = assign_386_stack_local (HImode, 2);
16503         
16504   ix86_optimize_mode_switching = 1;
16506   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16507   DONE;
16510 (define_insn "frndintxf2_mask_pm"
16511   [(set (match_operand:XF 0 "register_operand" "=f")
16512         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16513          UNSPEC_FRNDINT_MASK_PM))
16514    (use (match_operand:HI 2 "memory_operand" "m"))
16515    (use (match_operand:HI 3 "memory_operand" "m"))]
16516   "TARGET_USE_FANCY_MATH_387
16517    && flag_unsafe_math_optimizations"
16518   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16519   [(set_attr "type" "frndint")
16520    (set_attr "i387_cw" "mask_pm")
16521    (set_attr "mode" "XF")])
16523 (define_expand "nearbyintdf2"
16524   [(use (match_operand:DF 0 "register_operand" ""))
16525    (use (match_operand:DF 1 "register_operand" ""))]
16526   "TARGET_USE_FANCY_MATH_387
16527    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16528    && flag_unsafe_math_optimizations"
16530   rtx op0 = gen_reg_rtx (XFmode);
16531   rtx op1 = gen_reg_rtx (XFmode);
16532   rtx op2 = assign_386_stack_local (HImode, 1);
16533   rtx op3 = assign_386_stack_local (HImode, 2);
16534         
16535   ix86_optimize_mode_switching = 1;
16537   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16538   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16540   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16541   DONE;
16544 (define_expand "nearbyintsf2"
16545   [(use (match_operand:SF 0 "register_operand" ""))
16546    (use (match_operand:SF 1 "register_operand" ""))]
16547   "TARGET_USE_FANCY_MATH_387
16548    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16549    && flag_unsafe_math_optimizations"
16551   rtx op0 = gen_reg_rtx (XFmode);
16552   rtx op1 = gen_reg_rtx (XFmode);
16553   rtx op2 = assign_386_stack_local (HImode, 1);
16554   rtx op3 = assign_386_stack_local (HImode, 2);
16555         
16556   ix86_optimize_mode_switching = 1;
16558   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16559   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16561   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16562   DONE;
16565 (define_expand "nearbyintxf2"
16566   [(use (match_operand:XF 0 "register_operand" ""))
16567    (use (match_operand:XF 1 "register_operand" ""))]
16568   "TARGET_USE_FANCY_MATH_387
16569    && flag_unsafe_math_optimizations"
16571   rtx op2 = assign_386_stack_local (HImode, 1);
16572   rtx op3 = assign_386_stack_local (HImode, 2);
16573         
16574   ix86_optimize_mode_switching = 1;
16576   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16577                                      op2, op3));
16578   DONE;
16582 ;; Block operation instructions
16584 (define_insn "cld"
16585  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16586  ""
16587  "cld"
16588   [(set_attr "type" "cld")])
16590 (define_expand "movmemsi"
16591   [(use (match_operand:BLK 0 "memory_operand" ""))
16592    (use (match_operand:BLK 1 "memory_operand" ""))
16593    (use (match_operand:SI 2 "nonmemory_operand" ""))
16594    (use (match_operand:SI 3 "const_int_operand" ""))]
16595   "! optimize_size"
16597  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16598    DONE;
16599  else
16600    FAIL;
16603 (define_expand "movmemdi"
16604   [(use (match_operand:BLK 0 "memory_operand" ""))
16605    (use (match_operand:BLK 1 "memory_operand" ""))
16606    (use (match_operand:DI 2 "nonmemory_operand" ""))
16607    (use (match_operand:DI 3 "const_int_operand" ""))]
16608   "TARGET_64BIT"
16610  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16611    DONE;
16612  else
16613    FAIL;
16616 ;; Most CPUs don't like single string operations
16617 ;; Handle this case here to simplify previous expander.
16619 (define_expand "strmov"
16620   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16621    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16622    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16623               (clobber (reg:CC FLAGS_REG))])
16624    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16625               (clobber (reg:CC FLAGS_REG))])]
16626   ""
16628   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16630   /* If .md ever supports :P for Pmode, these can be directly
16631      in the pattern above.  */
16632   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16633   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16635   if (TARGET_SINGLE_STRINGOP || optimize_size)
16636     {
16637       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16638                                       operands[2], operands[3],
16639                                       operands[5], operands[6]));
16640       DONE;
16641     }
16643   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16646 (define_expand "strmov_singleop"
16647   [(parallel [(set (match_operand 1 "memory_operand" "")
16648                    (match_operand 3 "memory_operand" ""))
16649               (set (match_operand 0 "register_operand" "")
16650                    (match_operand 4 "" ""))
16651               (set (match_operand 2 "register_operand" "")
16652                    (match_operand 5 "" ""))
16653               (use (reg:SI DIRFLAG_REG))])]
16654   "TARGET_SINGLE_STRINGOP || optimize_size"
16655   "")
16657 (define_insn "*strmovdi_rex_1"
16658   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16659         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16660    (set (match_operand:DI 0 "register_operand" "=D")
16661         (plus:DI (match_dup 2)
16662                  (const_int 8)))
16663    (set (match_operand:DI 1 "register_operand" "=S")
16664         (plus:DI (match_dup 3)
16665                  (const_int 8)))
16666    (use (reg:SI DIRFLAG_REG))]
16667   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16668   "movsq"
16669   [(set_attr "type" "str")
16670    (set_attr "mode" "DI")
16671    (set_attr "memory" "both")])
16673 (define_insn "*strmovsi_1"
16674   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16675         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16676    (set (match_operand:SI 0 "register_operand" "=D")
16677         (plus:SI (match_dup 2)
16678                  (const_int 4)))
16679    (set (match_operand:SI 1 "register_operand" "=S")
16680         (plus:SI (match_dup 3)
16681                  (const_int 4)))
16682    (use (reg:SI DIRFLAG_REG))]
16683   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16684   "{movsl|movsd}"
16685   [(set_attr "type" "str")
16686    (set_attr "mode" "SI")
16687    (set_attr "memory" "both")])
16689 (define_insn "*strmovsi_rex_1"
16690   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16691         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16692    (set (match_operand:DI 0 "register_operand" "=D")
16693         (plus:DI (match_dup 2)
16694                  (const_int 4)))
16695    (set (match_operand:DI 1 "register_operand" "=S")
16696         (plus:DI (match_dup 3)
16697                  (const_int 4)))
16698    (use (reg:SI DIRFLAG_REG))]
16699   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16700   "{movsl|movsd}"
16701   [(set_attr "type" "str")
16702    (set_attr "mode" "SI")
16703    (set_attr "memory" "both")])
16705 (define_insn "*strmovhi_1"
16706   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16707         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16708    (set (match_operand:SI 0 "register_operand" "=D")
16709         (plus:SI (match_dup 2)
16710                  (const_int 2)))
16711    (set (match_operand:SI 1 "register_operand" "=S")
16712         (plus:SI (match_dup 3)
16713                  (const_int 2)))
16714    (use (reg:SI DIRFLAG_REG))]
16715   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16716   "movsw"
16717   [(set_attr "type" "str")
16718    (set_attr "memory" "both")
16719    (set_attr "mode" "HI")])
16721 (define_insn "*strmovhi_rex_1"
16722   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16723         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16724    (set (match_operand:DI 0 "register_operand" "=D")
16725         (plus:DI (match_dup 2)
16726                  (const_int 2)))
16727    (set (match_operand:DI 1 "register_operand" "=S")
16728         (plus:DI (match_dup 3)
16729                  (const_int 2)))
16730    (use (reg:SI DIRFLAG_REG))]
16731   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16732   "movsw"
16733   [(set_attr "type" "str")
16734    (set_attr "memory" "both")
16735    (set_attr "mode" "HI")])
16737 (define_insn "*strmovqi_1"
16738   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16739         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16740    (set (match_operand:SI 0 "register_operand" "=D")
16741         (plus:SI (match_dup 2)
16742                  (const_int 1)))
16743    (set (match_operand:SI 1 "register_operand" "=S")
16744         (plus:SI (match_dup 3)
16745                  (const_int 1)))
16746    (use (reg:SI DIRFLAG_REG))]
16747   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16748   "movsb"
16749   [(set_attr "type" "str")
16750    (set_attr "memory" "both")
16751    (set_attr "mode" "QI")])
16753 (define_insn "*strmovqi_rex_1"
16754   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16755         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16756    (set (match_operand:DI 0 "register_operand" "=D")
16757         (plus:DI (match_dup 2)
16758                  (const_int 1)))
16759    (set (match_operand:DI 1 "register_operand" "=S")
16760         (plus:DI (match_dup 3)
16761                  (const_int 1)))
16762    (use (reg:SI DIRFLAG_REG))]
16763   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16764   "movsb"
16765   [(set_attr "type" "str")
16766    (set_attr "memory" "both")
16767    (set_attr "mode" "QI")])
16769 (define_expand "rep_mov"
16770   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16771               (set (match_operand 0 "register_operand" "")
16772                    (match_operand 5 "" ""))
16773               (set (match_operand 2 "register_operand" "")
16774                    (match_operand 6 "" ""))
16775               (set (match_operand 1 "memory_operand" "")
16776                    (match_operand 3 "memory_operand" ""))
16777               (use (match_dup 4))
16778               (use (reg:SI DIRFLAG_REG))])]
16779   ""
16780   "")
16782 (define_insn "*rep_movdi_rex64"
16783   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16784    (set (match_operand:DI 0 "register_operand" "=D") 
16785         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16786                             (const_int 3))
16787                  (match_operand:DI 3 "register_operand" "0")))
16788    (set (match_operand:DI 1 "register_operand" "=S") 
16789         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16790                  (match_operand:DI 4 "register_operand" "1")))
16791    (set (mem:BLK (match_dup 3))
16792         (mem:BLK (match_dup 4)))
16793    (use (match_dup 5))
16794    (use (reg:SI DIRFLAG_REG))]
16795   "TARGET_64BIT"
16796   "{rep\;movsq|rep movsq}"
16797   [(set_attr "type" "str")
16798    (set_attr "prefix_rep" "1")
16799    (set_attr "memory" "both")
16800    (set_attr "mode" "DI")])
16802 (define_insn "*rep_movsi"
16803   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16804    (set (match_operand:SI 0 "register_operand" "=D") 
16805         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16806                             (const_int 2))
16807                  (match_operand:SI 3 "register_operand" "0")))
16808    (set (match_operand:SI 1 "register_operand" "=S") 
16809         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16810                  (match_operand:SI 4 "register_operand" "1")))
16811    (set (mem:BLK (match_dup 3))
16812         (mem:BLK (match_dup 4)))
16813    (use (match_dup 5))
16814    (use (reg:SI DIRFLAG_REG))]
16815   "!TARGET_64BIT"
16816   "{rep\;movsl|rep movsd}"
16817   [(set_attr "type" "str")
16818    (set_attr "prefix_rep" "1")
16819    (set_attr "memory" "both")
16820    (set_attr "mode" "SI")])
16822 (define_insn "*rep_movsi_rex64"
16823   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16824    (set (match_operand:DI 0 "register_operand" "=D") 
16825         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16826                             (const_int 2))
16827                  (match_operand:DI 3 "register_operand" "0")))
16828    (set (match_operand:DI 1 "register_operand" "=S") 
16829         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16830                  (match_operand:DI 4 "register_operand" "1")))
16831    (set (mem:BLK (match_dup 3))
16832         (mem:BLK (match_dup 4)))
16833    (use (match_dup 5))
16834    (use (reg:SI DIRFLAG_REG))]
16835   "TARGET_64BIT"
16836   "{rep\;movsl|rep movsd}"
16837   [(set_attr "type" "str")
16838    (set_attr "prefix_rep" "1")
16839    (set_attr "memory" "both")
16840    (set_attr "mode" "SI")])
16842 (define_insn "*rep_movqi"
16843   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16844    (set (match_operand:SI 0 "register_operand" "=D") 
16845         (plus:SI (match_operand:SI 3 "register_operand" "0")
16846                  (match_operand:SI 5 "register_operand" "2")))
16847    (set (match_operand:SI 1 "register_operand" "=S") 
16848         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16849    (set (mem:BLK (match_dup 3))
16850         (mem:BLK (match_dup 4)))
16851    (use (match_dup 5))
16852    (use (reg:SI DIRFLAG_REG))]
16853   "!TARGET_64BIT"
16854   "{rep\;movsb|rep movsb}"
16855   [(set_attr "type" "str")
16856    (set_attr "prefix_rep" "1")
16857    (set_attr "memory" "both")
16858    (set_attr "mode" "SI")])
16860 (define_insn "*rep_movqi_rex64"
16861   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16862    (set (match_operand:DI 0 "register_operand" "=D") 
16863         (plus:DI (match_operand:DI 3 "register_operand" "0")
16864                  (match_operand:DI 5 "register_operand" "2")))
16865    (set (match_operand:DI 1 "register_operand" "=S") 
16866         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16867    (set (mem:BLK (match_dup 3))
16868         (mem:BLK (match_dup 4)))
16869    (use (match_dup 5))
16870    (use (reg:SI DIRFLAG_REG))]
16871   "TARGET_64BIT"
16872   "{rep\;movsb|rep movsb}"
16873   [(set_attr "type" "str")
16874    (set_attr "prefix_rep" "1")
16875    (set_attr "memory" "both")
16876    (set_attr "mode" "SI")])
16878 (define_expand "clrmemsi"
16879    [(use (match_operand:BLK 0 "memory_operand" ""))
16880     (use (match_operand:SI 1 "nonmemory_operand" ""))
16881     (use (match_operand 2 "const_int_operand" ""))]
16882   ""
16884  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16885    DONE;
16886  else
16887    FAIL;
16890 (define_expand "clrmemdi"
16891    [(use (match_operand:BLK 0 "memory_operand" ""))
16892     (use (match_operand:DI 1 "nonmemory_operand" ""))
16893     (use (match_operand 2 "const_int_operand" ""))]
16894   "TARGET_64BIT"
16896  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16897    DONE;
16898  else
16899    FAIL;
16902 ;; Most CPUs don't like single string operations
16903 ;; Handle this case here to simplify previous expander.
16905 (define_expand "strset"
16906   [(set (match_operand 1 "memory_operand" "")
16907         (match_operand 2 "register_operand" ""))
16908    (parallel [(set (match_operand 0 "register_operand" "")
16909                    (match_dup 3))
16910               (clobber (reg:CC FLAGS_REG))])]
16911   ""
16913   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16914     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16916   /* If .md ever supports :P for Pmode, this can be directly
16917      in the pattern above.  */
16918   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16919                               GEN_INT (GET_MODE_SIZE (GET_MODE
16920                                                       (operands[2]))));
16921   if (TARGET_SINGLE_STRINGOP || optimize_size)
16922     {
16923       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16924                                       operands[3]));
16925       DONE;
16926     }
16929 (define_expand "strset_singleop"
16930   [(parallel [(set (match_operand 1 "memory_operand" "")
16931                    (match_operand 2 "register_operand" ""))
16932               (set (match_operand 0 "register_operand" "")
16933                    (match_operand 3 "" ""))
16934               (use (reg:SI DIRFLAG_REG))])]
16935   "TARGET_SINGLE_STRINGOP || optimize_size"
16936   "")
16938 (define_insn "*strsetdi_rex_1"
16939   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16940         (match_operand:DI 2 "register_operand" "a"))
16941    (set (match_operand:DI 0 "register_operand" "=D")
16942         (plus:DI (match_dup 1)
16943                  (const_int 8)))
16944    (use (reg:SI DIRFLAG_REG))]
16945   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16946   "stosq"
16947   [(set_attr "type" "str")
16948    (set_attr "memory" "store")
16949    (set_attr "mode" "DI")])
16951 (define_insn "*strsetsi_1"
16952   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16953         (match_operand:SI 2 "register_operand" "a"))
16954    (set (match_operand:SI 0 "register_operand" "=D")
16955         (plus:SI (match_dup 1)
16956                  (const_int 4)))
16957    (use (reg:SI DIRFLAG_REG))]
16958   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16959   "{stosl|stosd}"
16960   [(set_attr "type" "str")
16961    (set_attr "memory" "store")
16962    (set_attr "mode" "SI")])
16964 (define_insn "*strsetsi_rex_1"
16965   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16966         (match_operand:SI 2 "register_operand" "a"))
16967    (set (match_operand:DI 0 "register_operand" "=D")
16968         (plus:DI (match_dup 1)
16969                  (const_int 4)))
16970    (use (reg:SI DIRFLAG_REG))]
16971   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16972   "{stosl|stosd}"
16973   [(set_attr "type" "str")
16974    (set_attr "memory" "store")
16975    (set_attr "mode" "SI")])
16977 (define_insn "*strsethi_1"
16978   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16979         (match_operand:HI 2 "register_operand" "a"))
16980    (set (match_operand:SI 0 "register_operand" "=D")
16981         (plus:SI (match_dup 1)
16982                  (const_int 2)))
16983    (use (reg:SI DIRFLAG_REG))]
16984   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16985   "stosw"
16986   [(set_attr "type" "str")
16987    (set_attr "memory" "store")
16988    (set_attr "mode" "HI")])
16990 (define_insn "*strsethi_rex_1"
16991   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16992         (match_operand:HI 2 "register_operand" "a"))
16993    (set (match_operand:DI 0 "register_operand" "=D")
16994         (plus:DI (match_dup 1)
16995                  (const_int 2)))
16996    (use (reg:SI DIRFLAG_REG))]
16997   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16998   "stosw"
16999   [(set_attr "type" "str")
17000    (set_attr "memory" "store")
17001    (set_attr "mode" "HI")])
17003 (define_insn "*strsetqi_1"
17004   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17005         (match_operand:QI 2 "register_operand" "a"))
17006    (set (match_operand:SI 0 "register_operand" "=D")
17007         (plus:SI (match_dup 1)
17008                  (const_int 1)))
17009    (use (reg:SI DIRFLAG_REG))]
17010   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17011   "stosb"
17012   [(set_attr "type" "str")
17013    (set_attr "memory" "store")
17014    (set_attr "mode" "QI")])
17016 (define_insn "*strsetqi_rex_1"
17017   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17018         (match_operand:QI 2 "register_operand" "a"))
17019    (set (match_operand:DI 0 "register_operand" "=D")
17020         (plus:DI (match_dup 1)
17021                  (const_int 1)))
17022    (use (reg:SI DIRFLAG_REG))]
17023   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17024   "stosb"
17025   [(set_attr "type" "str")
17026    (set_attr "memory" "store")
17027    (set_attr "mode" "QI")])
17029 (define_expand "rep_stos"
17030   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17031               (set (match_operand 0 "register_operand" "")
17032                    (match_operand 4 "" ""))
17033               (set (match_operand 2 "memory_operand" "") (const_int 0))
17034               (use (match_operand 3 "register_operand" ""))
17035               (use (match_dup 1))
17036               (use (reg:SI DIRFLAG_REG))])]
17037   ""
17038   "")
17040 (define_insn "*rep_stosdi_rex64"
17041   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17042    (set (match_operand:DI 0 "register_operand" "=D") 
17043         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17044                             (const_int 3))
17045                  (match_operand:DI 3 "register_operand" "0")))
17046    (set (mem:BLK (match_dup 3))
17047         (const_int 0))
17048    (use (match_operand:DI 2 "register_operand" "a"))
17049    (use (match_dup 4))
17050    (use (reg:SI DIRFLAG_REG))]
17051   "TARGET_64BIT"
17052   "{rep\;stosq|rep stosq}"
17053   [(set_attr "type" "str")
17054    (set_attr "prefix_rep" "1")
17055    (set_attr "memory" "store")
17056    (set_attr "mode" "DI")])
17058 (define_insn "*rep_stossi"
17059   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17060    (set (match_operand:SI 0 "register_operand" "=D") 
17061         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17062                             (const_int 2))
17063                  (match_operand:SI 3 "register_operand" "0")))
17064    (set (mem:BLK (match_dup 3))
17065         (const_int 0))
17066    (use (match_operand:SI 2 "register_operand" "a"))
17067    (use (match_dup 4))
17068    (use (reg:SI DIRFLAG_REG))]
17069   "!TARGET_64BIT"
17070   "{rep\;stosl|rep stosd}"
17071   [(set_attr "type" "str")
17072    (set_attr "prefix_rep" "1")
17073    (set_attr "memory" "store")
17074    (set_attr "mode" "SI")])
17076 (define_insn "*rep_stossi_rex64"
17077   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17078    (set (match_operand:DI 0 "register_operand" "=D") 
17079         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17080                             (const_int 2))
17081                  (match_operand:DI 3 "register_operand" "0")))
17082    (set (mem:BLK (match_dup 3))
17083         (const_int 0))
17084    (use (match_operand:SI 2 "register_operand" "a"))
17085    (use (match_dup 4))
17086    (use (reg:SI DIRFLAG_REG))]
17087   "TARGET_64BIT"
17088   "{rep\;stosl|rep stosd}"
17089   [(set_attr "type" "str")
17090    (set_attr "prefix_rep" "1")
17091    (set_attr "memory" "store")
17092    (set_attr "mode" "SI")])
17094 (define_insn "*rep_stosqi"
17095   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17096    (set (match_operand:SI 0 "register_operand" "=D") 
17097         (plus:SI (match_operand:SI 3 "register_operand" "0")
17098                  (match_operand:SI 4 "register_operand" "1")))
17099    (set (mem:BLK (match_dup 3))
17100         (const_int 0))
17101    (use (match_operand:QI 2 "register_operand" "a"))
17102    (use (match_dup 4))
17103    (use (reg:SI DIRFLAG_REG))]
17104   "!TARGET_64BIT"
17105   "{rep\;stosb|rep stosb}"
17106   [(set_attr "type" "str")
17107    (set_attr "prefix_rep" "1")
17108    (set_attr "memory" "store")
17109    (set_attr "mode" "QI")])
17111 (define_insn "*rep_stosqi_rex64"
17112   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17113    (set (match_operand:DI 0 "register_operand" "=D") 
17114         (plus:DI (match_operand:DI 3 "register_operand" "0")
17115                  (match_operand:DI 4 "register_operand" "1")))
17116    (set (mem:BLK (match_dup 3))
17117         (const_int 0))
17118    (use (match_operand:QI 2 "register_operand" "a"))
17119    (use (match_dup 4))
17120    (use (reg:SI DIRFLAG_REG))]
17121   "TARGET_64BIT"
17122   "{rep\;stosb|rep stosb}"
17123   [(set_attr "type" "str")
17124    (set_attr "prefix_rep" "1")
17125    (set_attr "memory" "store")
17126    (set_attr "mode" "QI")])
17128 (define_expand "cmpstrsi"
17129   [(set (match_operand:SI 0 "register_operand" "")
17130         (compare:SI (match_operand:BLK 1 "general_operand" "")
17131                     (match_operand:BLK 2 "general_operand" "")))
17132    (use (match_operand 3 "general_operand" ""))
17133    (use (match_operand 4 "immediate_operand" ""))]
17134   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17136   rtx addr1, addr2, out, outlow, count, countreg, align;
17138   /* Can't use this if the user has appropriated esi or edi.  */
17139   if (global_regs[4] || global_regs[5])
17140     FAIL;
17142   out = operands[0];
17143   if (GET_CODE (out) != REG)
17144     out = gen_reg_rtx (SImode);
17146   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17147   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17148   if (addr1 != XEXP (operands[1], 0))
17149     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17150   if (addr2 != XEXP (operands[2], 0))
17151     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17153   count = operands[3];
17154   countreg = ix86_zero_extend_to_Pmode (count);
17156   /* %%% Iff we are testing strict equality, we can use known alignment
17157      to good advantage.  This may be possible with combine, particularly
17158      once cc0 is dead.  */
17159   align = operands[4];
17161   emit_insn (gen_cld ());
17162   if (GET_CODE (count) == CONST_INT)
17163     {
17164       if (INTVAL (count) == 0)
17165         {
17166           emit_move_insn (operands[0], const0_rtx);
17167           DONE;
17168         }
17169       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17170                                     operands[1], operands[2]));
17171     }
17172   else
17173     {
17174       if (TARGET_64BIT)
17175         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17176       else
17177         emit_insn (gen_cmpsi_1 (countreg, countreg));
17178       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17179                                  operands[1], operands[2]));
17180     }
17182   outlow = gen_lowpart (QImode, out);
17183   emit_insn (gen_cmpintqi (outlow));
17184   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17186   if (operands[0] != out)
17187     emit_move_insn (operands[0], out);
17189   DONE;
17192 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17194 (define_expand "cmpintqi"
17195   [(set (match_dup 1)
17196         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17197    (set (match_dup 2)
17198         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17199    (parallel [(set (match_operand:QI 0 "register_operand" "")
17200                    (minus:QI (match_dup 1)
17201                              (match_dup 2)))
17202               (clobber (reg:CC FLAGS_REG))])]
17203   ""
17204   "operands[1] = gen_reg_rtx (QImode);
17205    operands[2] = gen_reg_rtx (QImode);")
17207 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17208 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17210 (define_expand "cmpstrqi_nz_1"
17211   [(parallel [(set (reg:CC FLAGS_REG)
17212                    (compare:CC (match_operand 4 "memory_operand" "")
17213                                (match_operand 5 "memory_operand" "")))
17214               (use (match_operand 2 "register_operand" ""))
17215               (use (match_operand:SI 3 "immediate_operand" ""))
17216               (use (reg:SI DIRFLAG_REG))
17217               (clobber (match_operand 0 "register_operand" ""))
17218               (clobber (match_operand 1 "register_operand" ""))
17219               (clobber (match_dup 2))])]
17220   ""
17221   "")
17223 (define_insn "*cmpstrqi_nz_1"
17224   [(set (reg:CC FLAGS_REG)
17225         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17226                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17227    (use (match_operand:SI 6 "register_operand" "2"))
17228    (use (match_operand:SI 3 "immediate_operand" "i"))
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_nz_rex_1"
17240   [(set (reg:CC FLAGS_REG)
17241         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17242                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17243    (use (match_operand:DI 6 "register_operand" "2"))
17244    (use (match_operand:SI 3 "immediate_operand" "i"))
17245    (use (reg:SI DIRFLAG_REG))
17246    (clobber (match_operand:DI 0 "register_operand" "=S"))
17247    (clobber (match_operand:DI 1 "register_operand" "=D"))
17248    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17249   "TARGET_64BIT"
17250   "repz{\;| }cmpsb"
17251   [(set_attr "type" "str")
17252    (set_attr "mode" "QI")
17253    (set_attr "prefix_rep" "1")])
17255 ;; The same, but the count is not known to not be zero.
17257 (define_expand "cmpstrqi_1"
17258   [(parallel [(set (reg:CC FLAGS_REG)
17259                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17260                                      (const_int 0))
17261                   (compare:CC (match_operand 4 "memory_operand" "")
17262                               (match_operand 5 "memory_operand" ""))
17263                   (const_int 0)))
17264               (use (match_operand:SI 3 "immediate_operand" ""))
17265               (use (reg:CC FLAGS_REG))
17266               (use (reg:SI DIRFLAG_REG))
17267               (clobber (match_operand 0 "register_operand" ""))
17268               (clobber (match_operand 1 "register_operand" ""))
17269               (clobber (match_dup 2))])]
17270   ""
17271   "")
17273 (define_insn "*cmpstrqi_1"
17274   [(set (reg:CC FLAGS_REG)
17275         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17276                              (const_int 0))
17277           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17278                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17279           (const_int 0)))
17280    (use (match_operand:SI 3 "immediate_operand" "i"))
17281    (use (reg:CC FLAGS_REG))
17282    (use (reg:SI DIRFLAG_REG))
17283    (clobber (match_operand:SI 0 "register_operand" "=S"))
17284    (clobber (match_operand:SI 1 "register_operand" "=D"))
17285    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17286   "!TARGET_64BIT"
17287   "repz{\;| }cmpsb"
17288   [(set_attr "type" "str")
17289    (set_attr "mode" "QI")
17290    (set_attr "prefix_rep" "1")])
17292 (define_insn "*cmpstrqi_rex_1"
17293   [(set (reg:CC FLAGS_REG)
17294         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17295                              (const_int 0))
17296           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17297                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17298           (const_int 0)))
17299    (use (match_operand:SI 3 "immediate_operand" "i"))
17300    (use (reg:CC FLAGS_REG))
17301    (use (reg:SI DIRFLAG_REG))
17302    (clobber (match_operand:DI 0 "register_operand" "=S"))
17303    (clobber (match_operand:DI 1 "register_operand" "=D"))
17304    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17305   "TARGET_64BIT"
17306   "repz{\;| }cmpsb"
17307   [(set_attr "type" "str")
17308    (set_attr "mode" "QI")
17309    (set_attr "prefix_rep" "1")])
17311 (define_expand "strlensi"
17312   [(set (match_operand:SI 0 "register_operand" "")
17313         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17314                     (match_operand:QI 2 "immediate_operand" "")
17315                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17316   ""
17318  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17319    DONE;
17320  else
17321    FAIL;
17324 (define_expand "strlendi"
17325   [(set (match_operand:DI 0 "register_operand" "")
17326         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17327                     (match_operand:QI 2 "immediate_operand" "")
17328                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17329   ""
17331  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17332    DONE;
17333  else
17334    FAIL;
17337 (define_expand "strlenqi_1"
17338   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17339               (use (reg:SI DIRFLAG_REG))
17340               (clobber (match_operand 1 "register_operand" ""))
17341               (clobber (reg:CC FLAGS_REG))])]
17342   ""
17343   "")
17345 (define_insn "*strlenqi_1"
17346   [(set (match_operand:SI 0 "register_operand" "=&c")
17347         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17348                     (match_operand:QI 2 "register_operand" "a")
17349                     (match_operand:SI 3 "immediate_operand" "i")
17350                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17351    (use (reg:SI DIRFLAG_REG))
17352    (clobber (match_operand:SI 1 "register_operand" "=D"))
17353    (clobber (reg:CC FLAGS_REG))]
17354   "!TARGET_64BIT"
17355   "repnz{\;| }scasb"
17356   [(set_attr "type" "str")
17357    (set_attr "mode" "QI")
17358    (set_attr "prefix_rep" "1")])
17360 (define_insn "*strlenqi_rex_1"
17361   [(set (match_operand:DI 0 "register_operand" "=&c")
17362         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17363                     (match_operand:QI 2 "register_operand" "a")
17364                     (match_operand:DI 3 "immediate_operand" "i")
17365                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17366    (use (reg:SI DIRFLAG_REG))
17367    (clobber (match_operand:DI 1 "register_operand" "=D"))
17368    (clobber (reg:CC FLAGS_REG))]
17369   "TARGET_64BIT"
17370   "repnz{\;| }scasb"
17371   [(set_attr "type" "str")
17372    (set_attr "mode" "QI")
17373    (set_attr "prefix_rep" "1")])
17375 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17376 ;; handled in combine, but it is not currently up to the task.
17377 ;; When used for their truth value, the cmpstr* expanders generate
17378 ;; code like this:
17380 ;;   repz cmpsb
17381 ;;   seta       %al
17382 ;;   setb       %dl
17383 ;;   cmpb       %al, %dl
17384 ;;   jcc        label
17386 ;; The intermediate three instructions are unnecessary.
17388 ;; This one handles cmpstr*_nz_1...
17389 (define_peephole2
17390   [(parallel[
17391      (set (reg:CC FLAGS_REG)
17392           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17393                       (mem:BLK (match_operand 5 "register_operand" ""))))
17394      (use (match_operand 6 "register_operand" ""))
17395      (use (match_operand:SI 3 "immediate_operand" ""))
17396      (use (reg:SI DIRFLAG_REG))
17397      (clobber (match_operand 0 "register_operand" ""))
17398      (clobber (match_operand 1 "register_operand" ""))
17399      (clobber (match_operand 2 "register_operand" ""))])
17400    (set (match_operand:QI 7 "register_operand" "")
17401         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17402    (set (match_operand:QI 8 "register_operand" "")
17403         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17404    (set (reg FLAGS_REG)
17405         (compare (match_dup 7) (match_dup 8)))
17406   ]
17407   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17408   [(parallel[
17409      (set (reg:CC FLAGS_REG)
17410           (compare:CC (mem:BLK (match_dup 4))
17411                       (mem:BLK (match_dup 5))))
17412      (use (match_dup 6))
17413      (use (match_dup 3))
17414      (use (reg:SI DIRFLAG_REG))
17415      (clobber (match_dup 0))
17416      (clobber (match_dup 1))
17417      (clobber (match_dup 2))])]
17418   "")
17420 ;; ...and this one handles cmpstr*_1.
17421 (define_peephole2
17422   [(parallel[
17423      (set (reg:CC FLAGS_REG)
17424           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17425                                (const_int 0))
17426             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17427                         (mem:BLK (match_operand 5 "register_operand" "")))
17428             (const_int 0)))
17429      (use (match_operand:SI 3 "immediate_operand" ""))
17430      (use (reg:CC FLAGS_REG))
17431      (use (reg:SI DIRFLAG_REG))
17432      (clobber (match_operand 0 "register_operand" ""))
17433      (clobber (match_operand 1 "register_operand" ""))
17434      (clobber (match_operand 2 "register_operand" ""))])
17435    (set (match_operand:QI 7 "register_operand" "")
17436         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17437    (set (match_operand:QI 8 "register_operand" "")
17438         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17439    (set (reg FLAGS_REG)
17440         (compare (match_dup 7) (match_dup 8)))
17441   ]
17442   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17443   [(parallel[
17444      (set (reg:CC FLAGS_REG)
17445           (if_then_else:CC (ne (match_dup 6)
17446                                (const_int 0))
17447             (compare:CC (mem:BLK (match_dup 4))
17448                         (mem:BLK (match_dup 5)))
17449             (const_int 0)))
17450      (use (match_dup 3))
17451      (use (reg:CC FLAGS_REG))
17452      (use (reg:SI DIRFLAG_REG))
17453      (clobber (match_dup 0))
17454      (clobber (match_dup 1))
17455      (clobber (match_dup 2))])]
17456   "")
17460 ;; Conditional move instructions.
17462 (define_expand "movdicc"
17463   [(set (match_operand:DI 0 "register_operand" "")
17464         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17465                          (match_operand:DI 2 "general_operand" "")
17466                          (match_operand:DI 3 "general_operand" "")))]
17467   "TARGET_64BIT"
17468   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17470 (define_insn "x86_movdicc_0_m1_rex64"
17471   [(set (match_operand:DI 0 "register_operand" "=r")
17472         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17473           (const_int -1)
17474           (const_int 0)))
17475    (clobber (reg:CC FLAGS_REG))]
17476   "TARGET_64BIT"
17477   "sbb{q}\t%0, %0"
17478   ; Since we don't have the proper number of operands for an alu insn,
17479   ; fill in all the blanks.
17480   [(set_attr "type" "alu")
17481    (set_attr "pent_pair" "pu")
17482    (set_attr "memory" "none")
17483    (set_attr "imm_disp" "false")
17484    (set_attr "mode" "DI")
17485    (set_attr "length_immediate" "0")])
17487 (define_insn "*movdicc_c_rex64"
17488   [(set (match_operand:DI 0 "register_operand" "=r,r")
17489         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17490                                 [(reg FLAGS_REG) (const_int 0)])
17491                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17492                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17493   "TARGET_64BIT && TARGET_CMOVE
17494    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17495   "@
17496    cmov%O2%C1\t{%2, %0|%0, %2}
17497    cmov%O2%c1\t{%3, %0|%0, %3}"
17498   [(set_attr "type" "icmov")
17499    (set_attr "mode" "DI")])
17501 (define_expand "movsicc"
17502   [(set (match_operand:SI 0 "register_operand" "")
17503         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17504                          (match_operand:SI 2 "general_operand" "")
17505                          (match_operand:SI 3 "general_operand" "")))]
17506   ""
17507   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17509 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17510 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17511 ;; So just document what we're doing explicitly.
17513 (define_insn "x86_movsicc_0_m1"
17514   [(set (match_operand:SI 0 "register_operand" "=r")
17515         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17516           (const_int -1)
17517           (const_int 0)))
17518    (clobber (reg:CC FLAGS_REG))]
17519   ""
17520   "sbb{l}\t%0, %0"
17521   ; Since we don't have the proper number of operands for an alu insn,
17522   ; fill in all the blanks.
17523   [(set_attr "type" "alu")
17524    (set_attr "pent_pair" "pu")
17525    (set_attr "memory" "none")
17526    (set_attr "imm_disp" "false")
17527    (set_attr "mode" "SI")
17528    (set_attr "length_immediate" "0")])
17530 (define_insn "*movsicc_noc"
17531   [(set (match_operand:SI 0 "register_operand" "=r,r")
17532         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17533                                 [(reg FLAGS_REG) (const_int 0)])
17534                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17535                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17536   "TARGET_CMOVE
17537    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17538   "@
17539    cmov%O2%C1\t{%2, %0|%0, %2}
17540    cmov%O2%c1\t{%3, %0|%0, %3}"
17541   [(set_attr "type" "icmov")
17542    (set_attr "mode" "SI")])
17544 (define_expand "movhicc"
17545   [(set (match_operand:HI 0 "register_operand" "")
17546         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17547                          (match_operand:HI 2 "general_operand" "")
17548                          (match_operand:HI 3 "general_operand" "")))]
17549   "TARGET_HIMODE_MATH"
17550   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17552 (define_insn "*movhicc_noc"
17553   [(set (match_operand:HI 0 "register_operand" "=r,r")
17554         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17555                                 [(reg FLAGS_REG) (const_int 0)])
17556                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17557                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17558   "TARGET_CMOVE
17559    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17560   "@
17561    cmov%O2%C1\t{%2, %0|%0, %2}
17562    cmov%O2%c1\t{%3, %0|%0, %3}"
17563   [(set_attr "type" "icmov")
17564    (set_attr "mode" "HI")])
17566 (define_expand "movqicc"
17567   [(set (match_operand:QI 0 "register_operand" "")
17568         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17569                          (match_operand:QI 2 "general_operand" "")
17570                          (match_operand:QI 3 "general_operand" "")))]
17571   "TARGET_QIMODE_MATH"
17572   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17574 (define_insn_and_split "*movqicc_noc"
17575   [(set (match_operand:QI 0 "register_operand" "=r,r")
17576         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17577                                 [(match_operand 4 "flags_reg_operand" "")
17578                                  (const_int 0)])
17579                       (match_operand:QI 2 "register_operand" "r,0")
17580                       (match_operand:QI 3 "register_operand" "0,r")))]
17581   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17582   "#"
17583   "&& reload_completed"
17584   [(set (match_dup 0)
17585         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17586                       (match_dup 2)
17587                       (match_dup 3)))]
17588   "operands[0] = gen_lowpart (SImode, operands[0]);
17589    operands[2] = gen_lowpart (SImode, operands[2]);
17590    operands[3] = gen_lowpart (SImode, operands[3]);"
17591   [(set_attr "type" "icmov")
17592    (set_attr "mode" "SI")])
17594 (define_expand "movsfcc"
17595   [(set (match_operand:SF 0 "register_operand" "")
17596         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17597                          (match_operand:SF 2 "register_operand" "")
17598                          (match_operand:SF 3 "register_operand" "")))]
17599   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17600   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17602 ;; These versions of min/max are aware of the instruction's behavior
17603 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17604 ;; should have used the smin/smax expanders in the first place.
17605 (define_insn "*movsfcc_1_sse_min"
17606   [(set (match_operand:SF 0 "register_operand" "=x")
17607         (if_then_else:SF
17608           (lt:SF (match_operand:SF 1 "register_operand" "0")
17609                  (match_operand:SF 2 "nonimmediate_operand" "xm"))
17610           (match_dup 1)
17611           (match_dup 2)))]
17612   "TARGET_SSE_MATH"
17613   "minss\t{%2, %0|%0, %2}"
17614   [(set_attr "type" "sseadd")
17615    (set_attr "mode" "SF")])
17617 (define_insn "*movsfcc_1_sse_max"
17618   [(set (match_operand:SF 0 "register_operand" "=x")
17619         (if_then_else:SF
17620           (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
17621                  (match_operand:SF 1 "nonimmediate_operand" "0"))
17622           (match_dup 1)
17623           (match_dup 2)))]
17624   "TARGET_SSE_MATH"
17625   "maxss\t{%2, %0|%0, %2}"
17626   [(set_attr "type" "sseadd")
17627    (set_attr "mode" "SF")])
17629 (define_insn_and_split "*movsfcc_1_sse"
17630   [(set (match_operand:SF 0 "register_operand" "=x,x,x")
17631         (if_then_else:SF
17632           (match_operator:SF 4 "sse_comparison_operator"
17633             [(match_operand:SF 5 "register_operand" "0,0,0")
17634              (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
17635           (match_operand:SF 2 "reg_or_0_operand" "C,x,x")
17636           (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
17637    (clobber (match_scratch:V4SF 1 "=&x,&x,&x"))]
17638   "TARGET_SSE_MATH"
17639   "#"
17640   "&& reload_completed"
17641   [(const_int 0)]
17643   ix86_split_sse_movcc (operands);
17644   DONE;
17647 (define_insn "*movsfcc_1_387"
17648   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17649         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17650                                 [(reg FLAGS_REG) (const_int 0)])
17651                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17652                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17653   "TARGET_80387 && TARGET_CMOVE
17654    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17655   "@
17656    fcmov%F1\t{%2, %0|%0, %2}
17657    fcmov%f1\t{%3, %0|%0, %3}
17658    cmov%O2%C1\t{%2, %0|%0, %2}
17659    cmov%O2%c1\t{%3, %0|%0, %3}"
17660   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17661    (set_attr "mode" "SF,SF,SI,SI")])
17663 (define_expand "movdfcc"
17664   [(set (match_operand:DF 0 "register_operand" "")
17665         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17666                          (match_operand:DF 2 "register_operand" "")
17667                          (match_operand:DF 3 "register_operand" "")))]
17668   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17669   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17671 ;; These versions of min/max are aware of the instruction's behavior
17672 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17673 ;; should have used the smin/smax expanders in the first place.
17674 (define_insn "*movdfcc_1_sse_min"
17675   [(set (match_operand:DF 0 "register_operand" "=x")
17676         (if_then_else:DF
17677           (lt:DF (match_operand:DF 1 "register_operand" "0")
17678                  (match_operand:DF 2 "nonimmediate_operand" "xm"))
17679           (match_dup 1)
17680           (match_dup 2)))]
17681   "TARGET_SSE2 && TARGET_SSE_MATH"
17682   "minsd\t{%2, %0|%0, %2}"
17683   [(set_attr "type" "sseadd")
17684    (set_attr "mode" "DF")])
17686 (define_insn "*movdfcc_1_sse_max"
17687   [(set (match_operand:DF 0 "register_operand" "=x")
17688         (if_then_else:DF
17689           (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
17690                  (match_operand:DF 1 "nonimmediate_operand" "0"))
17691           (match_dup 1)
17692           (match_dup 2)))]
17693   "TARGET_SSE2 && TARGET_SSE_MATH"
17694   "maxsd\t{%2, %0|%0, %2}"
17695   [(set_attr "type" "sseadd")
17696    (set_attr "mode" "DF")])
17698 (define_insn_and_split "*movdfcc_1_sse"
17699   [(set (match_operand:DF 0 "register_operand" "=x,x,x")
17700         (if_then_else:DF
17701           (match_operator:DF 4 "sse_comparison_operator"
17702             [(match_operand:DF 5 "register_operand" "0,0,0")
17703              (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
17704           (match_operand:DF 2 "reg_or_0_operand" "C,x,x")
17705           (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
17706    (clobber (match_scratch:V2DF 1 "=&x,&x,&x"))]
17707   "TARGET_SSE2 && TARGET_SSE_MATH"
17708   "#"
17709   "&& reload_completed"
17710   [(const_int 0)]
17712   ix86_split_sse_movcc (operands);
17713   DONE;
17716 (define_insn "*movdfcc_1"
17717   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17718         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17719                                 [(reg FLAGS_REG) (const_int 0)])
17720                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17721                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17722   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17723    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17724   "@
17725    fcmov%F1\t{%2, %0|%0, %2}
17726    fcmov%f1\t{%3, %0|%0, %3}
17727    #
17728    #"
17729   [(set_attr "type" "fcmov,fcmov,multi,multi")
17730    (set_attr "mode" "DF")])
17732 (define_insn "*movdfcc_1_rex64"
17733   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17734         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17735                                 [(reg FLAGS_REG) (const_int 0)])
17736                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17737                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17738   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17739    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17740   "@
17741    fcmov%F1\t{%2, %0|%0, %2}
17742    fcmov%f1\t{%3, %0|%0, %3}
17743    cmov%O2%C1\t{%2, %0|%0, %2}
17744    cmov%O2%c1\t{%3, %0|%0, %3}"
17745   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17746    (set_attr "mode" "DF")])
17748 (define_split
17749   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17750         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17751                                 [(match_operand 4 "flags_reg_operand" "")
17752                                  (const_int 0)])
17753                       (match_operand:DF 2 "nonimmediate_operand" "")
17754                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17755   "!TARGET_64BIT && reload_completed"
17756   [(set (match_dup 2)
17757         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17758                       (match_dup 5)
17759                       (match_dup 7)))
17760    (set (match_dup 3)
17761         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17762                       (match_dup 6)
17763                       (match_dup 8)))]
17764   "split_di (operands+2, 1, operands+5, operands+6);
17765    split_di (operands+3, 1, operands+7, operands+8);
17766    split_di (operands, 1, operands+2, operands+3);")
17768 (define_expand "movxfcc"
17769   [(set (match_operand:XF 0 "register_operand" "")
17770         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17771                          (match_operand:XF 2 "register_operand" "")
17772                          (match_operand:XF 3 "register_operand" "")))]
17773   "TARGET_80387 && TARGET_CMOVE"
17774   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17776 (define_insn "*movxfcc_1"
17777   [(set (match_operand:XF 0 "register_operand" "=f,f")
17778         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17779                                 [(reg FLAGS_REG) (const_int 0)])
17780                       (match_operand:XF 2 "register_operand" "f,0")
17781                       (match_operand:XF 3 "register_operand" "0,f")))]
17782   "TARGET_80387 && TARGET_CMOVE"
17783   "@
17784    fcmov%F1\t{%2, %0|%0, %2}
17785    fcmov%f1\t{%3, %0|%0, %3}"
17786   [(set_attr "type" "fcmov")
17787    (set_attr "mode" "XF")])
17789 ;; These versions of the min/max patterns are intentionally ignorant of
17790 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17791 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17792 ;; are undefined in this condition, we're certain this is correct.
17794 (define_insn "sminsf3"
17795   [(set (match_operand:SF 0 "register_operand" "=x")
17796         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17797                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17798   "TARGET_SSE_MATH"
17799   "minss\t{%2, %0|%0, %2}"
17800   [(set_attr "type" "sseadd")
17801    (set_attr "mode" "SF")])
17803 (define_insn "smaxsf3"
17804   [(set (match_operand:SF 0 "register_operand" "=x")
17805         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17806                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17807   "TARGET_SSE_MATH"
17808   "maxss\t{%2, %0|%0, %2}"
17809   [(set_attr "type" "sseadd")
17810    (set_attr "mode" "SF")])
17812 (define_insn "smindf3"
17813   [(set (match_operand:DF 0 "register_operand" "=x")
17814         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17815                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17816   "TARGET_SSE2 && TARGET_SSE_MATH"
17817   "minsd\t{%2, %0|%0, %2}"
17818   [(set_attr "type" "sseadd")
17819    (set_attr "mode" "DF")])
17821 (define_insn "smaxdf3"
17822   [(set (match_operand:DF 0 "register_operand" "=x")
17823         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17824                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17825   "TARGET_SSE2 && TARGET_SSE_MATH"
17826   "maxsd\t{%2, %0|%0, %2}"
17827   [(set_attr "type" "sseadd")
17828    (set_attr "mode" "DF")])
17830 ;; Conditional addition patterns
17831 (define_expand "addqicc"
17832   [(match_operand:QI 0 "register_operand" "")
17833    (match_operand 1 "comparison_operator" "")
17834    (match_operand:QI 2 "register_operand" "")
17835    (match_operand:QI 3 "const_int_operand" "")]
17836   ""
17837   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17839 (define_expand "addhicc"
17840   [(match_operand:HI 0 "register_operand" "")
17841    (match_operand 1 "comparison_operator" "")
17842    (match_operand:HI 2 "register_operand" "")
17843    (match_operand:HI 3 "const_int_operand" "")]
17844   ""
17845   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17847 (define_expand "addsicc"
17848   [(match_operand:SI 0 "register_operand" "")
17849    (match_operand 1 "comparison_operator" "")
17850    (match_operand:SI 2 "register_operand" "")
17851    (match_operand:SI 3 "const_int_operand" "")]
17852   ""
17853   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17855 (define_expand "adddicc"
17856   [(match_operand:DI 0 "register_operand" "")
17857    (match_operand 1 "comparison_operator" "")
17858    (match_operand:DI 2 "register_operand" "")
17859    (match_operand:DI 3 "const_int_operand" "")]
17860   "TARGET_64BIT"
17861   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17864 ;; Misc patterns (?)
17866 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17867 ;; Otherwise there will be nothing to keep
17868 ;; 
17869 ;; [(set (reg ebp) (reg esp))]
17870 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17871 ;;  (clobber (eflags)]
17872 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17874 ;; in proper program order.
17875 (define_insn "pro_epilogue_adjust_stack_1"
17876   [(set (match_operand:SI 0 "register_operand" "=r,r")
17877         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17878                  (match_operand:SI 2 "immediate_operand" "i,i")))
17879    (clobber (reg:CC FLAGS_REG))
17880    (clobber (mem:BLK (scratch)))]
17881   "!TARGET_64BIT"
17883   switch (get_attr_type (insn))
17884     {
17885     case TYPE_IMOV:
17886       return "mov{l}\t{%1, %0|%0, %1}";
17888     case TYPE_ALU:
17889       if (GET_CODE (operands[2]) == CONST_INT
17890           && (INTVAL (operands[2]) == 128
17891               || (INTVAL (operands[2]) < 0
17892                   && INTVAL (operands[2]) != -128)))
17893         {
17894           operands[2] = GEN_INT (-INTVAL (operands[2]));
17895           return "sub{l}\t{%2, %0|%0, %2}";
17896         }
17897       return "add{l}\t{%2, %0|%0, %2}";
17899     case TYPE_LEA:
17900       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17901       return "lea{l}\t{%a2, %0|%0, %a2}";
17903     default:
17904       abort ();
17905     }
17907   [(set (attr "type")
17908         (cond [(eq_attr "alternative" "0")
17909                  (const_string "alu")
17910                (match_operand:SI 2 "const0_operand" "")
17911                  (const_string "imov")
17912               ]
17913               (const_string "lea")))
17914    (set_attr "mode" "SI")])
17916 (define_insn "pro_epilogue_adjust_stack_rex64"
17917   [(set (match_operand:DI 0 "register_operand" "=r,r")
17918         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17919                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17920    (clobber (reg:CC FLAGS_REG))
17921    (clobber (mem:BLK (scratch)))]
17922   "TARGET_64BIT"
17924   switch (get_attr_type (insn))
17925     {
17926     case TYPE_IMOV:
17927       return "mov{q}\t{%1, %0|%0, %1}";
17929     case TYPE_ALU:
17930       if (GET_CODE (operands[2]) == CONST_INT
17931           /* Avoid overflows.  */
17932           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17933           && (INTVAL (operands[2]) == 128
17934               || (INTVAL (operands[2]) < 0
17935                   && INTVAL (operands[2]) != -128)))
17936         {
17937           operands[2] = GEN_INT (-INTVAL (operands[2]));
17938           return "sub{q}\t{%2, %0|%0, %2}";
17939         }
17940       return "add{q}\t{%2, %0|%0, %2}";
17942     case TYPE_LEA:
17943       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17944       return "lea{q}\t{%a2, %0|%0, %a2}";
17946     default:
17947       abort ();
17948     }
17950   [(set (attr "type")
17951         (cond [(eq_attr "alternative" "0")
17952                  (const_string "alu")
17953                (match_operand:DI 2 "const0_operand" "")
17954                  (const_string "imov")
17955               ]
17956               (const_string "lea")))
17957    (set_attr "mode" "DI")])
17959 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17960   [(set (match_operand:DI 0 "register_operand" "=r,r")
17961         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17962                  (match_operand:DI 3 "immediate_operand" "i,i")))
17963    (use (match_operand:DI 2 "register_operand" "r,r"))
17964    (clobber (reg:CC FLAGS_REG))
17965    (clobber (mem:BLK (scratch)))]
17966   "TARGET_64BIT"
17968   switch (get_attr_type (insn))
17969     {
17970     case TYPE_ALU:
17971       return "add{q}\t{%2, %0|%0, %2}";
17973     case TYPE_LEA:
17974       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17975       return "lea{q}\t{%a2, %0|%0, %a2}";
17977     default:
17978       abort ();
17979     }
17981   [(set_attr "type" "alu,lea")
17982    (set_attr "mode" "DI")])
17984 (define_expand "allocate_stack_worker"
17985   [(match_operand:SI 0 "register_operand" "")]
17986   "TARGET_STACK_PROBE"
17988   if (reload_completed)
17989     {
17990       if (TARGET_64BIT)
17991         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17992       else
17993         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17994     }
17995   else
17996     {
17997       if (TARGET_64BIT)
17998         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17999       else
18000         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18001     }
18002   DONE;
18005 (define_insn "allocate_stack_worker_1"
18006   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18007     UNSPECV_STACK_PROBE)
18008    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18009    (clobber (match_scratch:SI 1 "=0"))
18010    (clobber (reg:CC FLAGS_REG))]
18011   "!TARGET_64BIT && TARGET_STACK_PROBE"
18012   "call\t__alloca"
18013   [(set_attr "type" "multi")
18014    (set_attr "length" "5")])
18016 (define_expand "allocate_stack_worker_postreload"
18017   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18018                                     UNSPECV_STACK_PROBE)
18019               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18020               (clobber (match_dup 0))
18021               (clobber (reg:CC FLAGS_REG))])]
18022   ""
18023   "")
18025 (define_insn "allocate_stack_worker_rex64"
18026   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18027     UNSPECV_STACK_PROBE)
18028    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18029    (clobber (match_scratch:DI 1 "=0"))
18030    (clobber (reg:CC FLAGS_REG))]
18031   "TARGET_64BIT && TARGET_STACK_PROBE"
18032   "call\t__alloca"
18033   [(set_attr "type" "multi")
18034    (set_attr "length" "5")])
18036 (define_expand "allocate_stack_worker_rex64_postreload"
18037   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18038                                     UNSPECV_STACK_PROBE)
18039               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18040               (clobber (match_dup 0))
18041               (clobber (reg:CC FLAGS_REG))])]
18042   ""
18043   "")
18045 (define_expand "allocate_stack"
18046   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18047                    (minus:SI (reg:SI SP_REG)
18048                              (match_operand:SI 1 "general_operand" "")))
18049               (clobber (reg:CC FLAGS_REG))])
18050    (parallel [(set (reg:SI SP_REG)
18051                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18052               (clobber (reg:CC FLAGS_REG))])]
18053   "TARGET_STACK_PROBE"
18055 #ifdef CHECK_STACK_LIMIT
18056   if (GET_CODE (operands[1]) == CONST_INT
18057       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18058     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18059                            operands[1]));
18060   else 
18061 #endif
18062     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18063                                                             operands[1])));
18065   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18066   DONE;
18069 (define_expand "builtin_setjmp_receiver"
18070   [(label_ref (match_operand 0 "" ""))]
18071   "!TARGET_64BIT && flag_pic"
18073   emit_insn (gen_set_got (pic_offset_table_rtx));
18074   DONE;
18077 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18079 (define_split
18080   [(set (match_operand 0 "register_operand" "")
18081         (match_operator 3 "promotable_binary_operator"
18082            [(match_operand 1 "register_operand" "")
18083             (match_operand 2 "aligned_operand" "")]))
18084    (clobber (reg:CC FLAGS_REG))]
18085   "! TARGET_PARTIAL_REG_STALL && reload_completed
18086    && ((GET_MODE (operands[0]) == HImode 
18087         && ((!optimize_size && !TARGET_FAST_PREFIX)
18088             || GET_CODE (operands[2]) != CONST_INT
18089             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18090        || (GET_MODE (operands[0]) == QImode 
18091            && (TARGET_PROMOTE_QImode || optimize_size)))"
18092   [(parallel [(set (match_dup 0)
18093                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18094               (clobber (reg:CC FLAGS_REG))])]
18095   "operands[0] = gen_lowpart (SImode, operands[0]);
18096    operands[1] = gen_lowpart (SImode, operands[1]);
18097    if (GET_CODE (operands[3]) != ASHIFT)
18098      operands[2] = gen_lowpart (SImode, operands[2]);
18099    PUT_MODE (operands[3], SImode);")
18101 ; Promote the QImode tests, as i386 has encoding of the AND
18102 ; instruction with 32-bit sign-extended immediate and thus the
18103 ; instruction size is unchanged, except in the %eax case for
18104 ; which it is increased by one byte, hence the ! optimize_size.
18105 (define_split
18106   [(set (match_operand 0 "flags_reg_operand" "")
18107         (match_operator 2 "compare_operator"
18108           [(and (match_operand 3 "aligned_operand" "")
18109                 (match_operand 4 "const_int_operand" ""))
18110            (const_int 0)]))
18111    (set (match_operand 1 "register_operand" "")
18112         (and (match_dup 3) (match_dup 4)))]
18113   "! TARGET_PARTIAL_REG_STALL && reload_completed
18114    /* Ensure that the operand will remain sign-extended immediate.  */
18115    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18116    && ! optimize_size
18117    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18118        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18119   [(parallel [(set (match_dup 0)
18120                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18121                                     (const_int 0)]))
18122               (set (match_dup 1)
18123                    (and:SI (match_dup 3) (match_dup 4)))])]
18125   operands[4]
18126     = gen_int_mode (INTVAL (operands[4])
18127                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18128   operands[1] = gen_lowpart (SImode, operands[1]);
18129   operands[3] = gen_lowpart (SImode, operands[3]);
18132 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18133 ; the TEST instruction with 32-bit sign-extended immediate and thus
18134 ; the instruction size would at least double, which is not what we
18135 ; want even with ! optimize_size.
18136 (define_split
18137   [(set (match_operand 0 "flags_reg_operand" "")
18138         (match_operator 1 "compare_operator"
18139           [(and (match_operand:HI 2 "aligned_operand" "")
18140                 (match_operand:HI 3 "const_int_operand" ""))
18141            (const_int 0)]))]
18142   "! TARGET_PARTIAL_REG_STALL && reload_completed
18143    /* Ensure that the operand will remain sign-extended immediate.  */
18144    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18145    && ! TARGET_FAST_PREFIX
18146    && ! optimize_size"
18147   [(set (match_dup 0)
18148         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18149                          (const_int 0)]))]
18151   operands[3]
18152     = gen_int_mode (INTVAL (operands[3])
18153                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18154   operands[2] = gen_lowpart (SImode, operands[2]);
18157 (define_split
18158   [(set (match_operand 0 "register_operand" "")
18159         (neg (match_operand 1 "register_operand" "")))
18160    (clobber (reg:CC FLAGS_REG))]
18161   "! TARGET_PARTIAL_REG_STALL && reload_completed
18162    && (GET_MODE (operands[0]) == HImode
18163        || (GET_MODE (operands[0]) == QImode 
18164            && (TARGET_PROMOTE_QImode || optimize_size)))"
18165   [(parallel [(set (match_dup 0)
18166                    (neg:SI (match_dup 1)))
18167               (clobber (reg:CC FLAGS_REG))])]
18168   "operands[0] = gen_lowpart (SImode, operands[0]);
18169    operands[1] = gen_lowpart (SImode, operands[1]);")
18171 (define_split
18172   [(set (match_operand 0 "register_operand" "")
18173         (not (match_operand 1 "register_operand" "")))]
18174   "! TARGET_PARTIAL_REG_STALL && reload_completed
18175    && (GET_MODE (operands[0]) == HImode
18176        || (GET_MODE (operands[0]) == QImode 
18177            && (TARGET_PROMOTE_QImode || optimize_size)))"
18178   [(set (match_dup 0)
18179         (not:SI (match_dup 1)))]
18180   "operands[0] = gen_lowpart (SImode, operands[0]);
18181    operands[1] = gen_lowpart (SImode, operands[1]);")
18183 (define_split 
18184   [(set (match_operand 0 "register_operand" "")
18185         (if_then_else (match_operator 1 "comparison_operator" 
18186                                 [(reg FLAGS_REG) (const_int 0)])
18187                       (match_operand 2 "register_operand" "")
18188                       (match_operand 3 "register_operand" "")))]
18189   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18190    && (GET_MODE (operands[0]) == HImode
18191        || (GET_MODE (operands[0]) == QImode 
18192            && (TARGET_PROMOTE_QImode || optimize_size)))"
18193   [(set (match_dup 0)
18194         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18195   "operands[0] = gen_lowpart (SImode, operands[0]);
18196    operands[2] = gen_lowpart (SImode, operands[2]);
18197    operands[3] = gen_lowpart (SImode, operands[3]);")
18198                         
18200 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18201 ;; transform a complex memory operation into two memory to register operations.
18203 ;; Don't push memory operands
18204 (define_peephole2
18205   [(set (match_operand:SI 0 "push_operand" "")
18206         (match_operand:SI 1 "memory_operand" ""))
18207    (match_scratch:SI 2 "r")]
18208   "! optimize_size && ! TARGET_PUSH_MEMORY"
18209   [(set (match_dup 2) (match_dup 1))
18210    (set (match_dup 0) (match_dup 2))]
18211   "")
18213 (define_peephole2
18214   [(set (match_operand:DI 0 "push_operand" "")
18215         (match_operand:DI 1 "memory_operand" ""))
18216    (match_scratch:DI 2 "r")]
18217   "! optimize_size && ! TARGET_PUSH_MEMORY"
18218   [(set (match_dup 2) (match_dup 1))
18219    (set (match_dup 0) (match_dup 2))]
18220   "")
18222 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18223 ;; SImode pushes.
18224 (define_peephole2
18225   [(set (match_operand:SF 0 "push_operand" "")
18226         (match_operand:SF 1 "memory_operand" ""))
18227    (match_scratch:SF 2 "r")]
18228   "! optimize_size && ! TARGET_PUSH_MEMORY"
18229   [(set (match_dup 2) (match_dup 1))
18230    (set (match_dup 0) (match_dup 2))]
18231   "")
18233 (define_peephole2
18234   [(set (match_operand:HI 0 "push_operand" "")
18235         (match_operand:HI 1 "memory_operand" ""))
18236    (match_scratch:HI 2 "r")]
18237   "! optimize_size && ! TARGET_PUSH_MEMORY"
18238   [(set (match_dup 2) (match_dup 1))
18239    (set (match_dup 0) (match_dup 2))]
18240   "")
18242 (define_peephole2
18243   [(set (match_operand:QI 0 "push_operand" "")
18244         (match_operand:QI 1 "memory_operand" ""))
18245    (match_scratch:QI 2 "q")]
18246   "! optimize_size && ! TARGET_PUSH_MEMORY"
18247   [(set (match_dup 2) (match_dup 1))
18248    (set (match_dup 0) (match_dup 2))]
18249   "")
18251 ;; Don't move an immediate directly to memory when the instruction
18252 ;; gets too big.
18253 (define_peephole2
18254   [(match_scratch:SI 1 "r")
18255    (set (match_operand:SI 0 "memory_operand" "")
18256         (const_int 0))]
18257   "! optimize_size
18258    && ! TARGET_USE_MOV0
18259    && TARGET_SPLIT_LONG_MOVES
18260    && get_attr_length (insn) >= ix86_cost->large_insn
18261    && peep2_regno_dead_p (0, FLAGS_REG)"
18262   [(parallel [(set (match_dup 1) (const_int 0))
18263               (clobber (reg:CC FLAGS_REG))])
18264    (set (match_dup 0) (match_dup 1))]
18265   "")
18267 (define_peephole2
18268   [(match_scratch:HI 1 "r")
18269    (set (match_operand:HI 0 "memory_operand" "")
18270         (const_int 0))]
18271   "! optimize_size
18272    && ! TARGET_USE_MOV0
18273    && TARGET_SPLIT_LONG_MOVES
18274    && get_attr_length (insn) >= ix86_cost->large_insn
18275    && peep2_regno_dead_p (0, FLAGS_REG)"
18276   [(parallel [(set (match_dup 2) (const_int 0))
18277               (clobber (reg:CC FLAGS_REG))])
18278    (set (match_dup 0) (match_dup 1))]
18279   "operands[2] = gen_lowpart (SImode, operands[1]);")
18281 (define_peephole2
18282   [(match_scratch:QI 1 "q")
18283    (set (match_operand:QI 0 "memory_operand" "")
18284         (const_int 0))]
18285   "! optimize_size
18286    && ! TARGET_USE_MOV0
18287    && TARGET_SPLIT_LONG_MOVES
18288    && get_attr_length (insn) >= ix86_cost->large_insn
18289    && peep2_regno_dead_p (0, FLAGS_REG)"
18290   [(parallel [(set (match_dup 2) (const_int 0))
18291               (clobber (reg:CC FLAGS_REG))])
18292    (set (match_dup 0) (match_dup 1))]
18293   "operands[2] = gen_lowpart (SImode, operands[1]);")
18295 (define_peephole2
18296   [(match_scratch:SI 2 "r")
18297    (set (match_operand:SI 0 "memory_operand" "")
18298         (match_operand:SI 1 "immediate_operand" ""))]
18299   "! optimize_size
18300    && get_attr_length (insn) >= ix86_cost->large_insn
18301    && TARGET_SPLIT_LONG_MOVES"
18302   [(set (match_dup 2) (match_dup 1))
18303    (set (match_dup 0) (match_dup 2))]
18304   "")
18306 (define_peephole2
18307   [(match_scratch:HI 2 "r")
18308    (set (match_operand:HI 0 "memory_operand" "")
18309         (match_operand:HI 1 "immediate_operand" ""))]
18310   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18311   && TARGET_SPLIT_LONG_MOVES"
18312   [(set (match_dup 2) (match_dup 1))
18313    (set (match_dup 0) (match_dup 2))]
18314   "")
18316 (define_peephole2
18317   [(match_scratch:QI 2 "q")
18318    (set (match_operand:QI 0 "memory_operand" "")
18319         (match_operand:QI 1 "immediate_operand" ""))]
18320   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18321   && TARGET_SPLIT_LONG_MOVES"
18322   [(set (match_dup 2) (match_dup 1))
18323    (set (match_dup 0) (match_dup 2))]
18324   "")
18326 ;; Don't compare memory with zero, load and use a test instead.
18327 (define_peephole2
18328   [(set (match_operand 0 "flags_reg_operand" "")
18329         (match_operator 1 "compare_operator"
18330           [(match_operand:SI 2 "memory_operand" "")
18331            (const_int 0)]))
18332    (match_scratch:SI 3 "r")]
18333   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18334   [(set (match_dup 3) (match_dup 2))
18335    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18336   "")
18338 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18339 ;; Don't split NOTs with a displacement operand, because resulting XOR
18340 ;; will not be pairable anyway.
18342 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18343 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18344 ;; so this split helps here as well.
18346 ;; Note: Can't do this as a regular split because we can't get proper
18347 ;; lifetime information then.
18349 (define_peephole2
18350   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18351         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18352   "!optimize_size
18353    && peep2_regno_dead_p (0, FLAGS_REG)
18354    && ((TARGET_PENTIUM 
18355         && (GET_CODE (operands[0]) != MEM
18356             || !memory_displacement_operand (operands[0], SImode)))
18357        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18358   [(parallel [(set (match_dup 0)
18359                    (xor:SI (match_dup 1) (const_int -1)))
18360               (clobber (reg:CC FLAGS_REG))])]
18361   "")
18363 (define_peephole2
18364   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18365         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18366   "!optimize_size
18367    && peep2_regno_dead_p (0, FLAGS_REG)
18368    && ((TARGET_PENTIUM 
18369         && (GET_CODE (operands[0]) != MEM
18370             || !memory_displacement_operand (operands[0], HImode)))
18371        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18372   [(parallel [(set (match_dup 0)
18373                    (xor:HI (match_dup 1) (const_int -1)))
18374               (clobber (reg:CC FLAGS_REG))])]
18375   "")
18377 (define_peephole2
18378   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18379         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18380   "!optimize_size
18381    && peep2_regno_dead_p (0, FLAGS_REG)
18382    && ((TARGET_PENTIUM 
18383         && (GET_CODE (operands[0]) != MEM
18384             || !memory_displacement_operand (operands[0], QImode)))
18385        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18386   [(parallel [(set (match_dup 0)
18387                    (xor:QI (match_dup 1) (const_int -1)))
18388               (clobber (reg:CC FLAGS_REG))])]
18389   "")
18391 ;; Non pairable "test imm, reg" instructions can be translated to
18392 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18393 ;; byte opcode instead of two, have a short form for byte operands),
18394 ;; so do it for other CPUs as well.  Given that the value was dead,
18395 ;; this should not create any new dependencies.  Pass on the sub-word
18396 ;; versions if we're concerned about partial register stalls.
18398 (define_peephole2
18399   [(set (match_operand 0 "flags_reg_operand" "")
18400         (match_operator 1 "compare_operator"
18401           [(and:SI (match_operand:SI 2 "register_operand" "")
18402                    (match_operand:SI 3 "immediate_operand" ""))
18403            (const_int 0)]))]
18404   "ix86_match_ccmode (insn, CCNOmode)
18405    && (true_regnum (operands[2]) != 0
18406        || (GET_CODE (operands[3]) == CONST_INT
18407            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18408    && peep2_reg_dead_p (1, operands[2])"
18409   [(parallel
18410      [(set (match_dup 0)
18411            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18412                             (const_int 0)]))
18413       (set (match_dup 2)
18414            (and:SI (match_dup 2) (match_dup 3)))])]
18415   "")
18417 ;; We don't need to handle HImode case, because it will be promoted to SImode
18418 ;; on ! TARGET_PARTIAL_REG_STALL
18420 (define_peephole2
18421   [(set (match_operand 0 "flags_reg_operand" "")
18422         (match_operator 1 "compare_operator"
18423           [(and:QI (match_operand:QI 2 "register_operand" "")
18424                    (match_operand:QI 3 "immediate_operand" ""))
18425            (const_int 0)]))]
18426   "! TARGET_PARTIAL_REG_STALL
18427    && ix86_match_ccmode (insn, CCNOmode)
18428    && true_regnum (operands[2]) != 0
18429    && peep2_reg_dead_p (1, operands[2])"
18430   [(parallel
18431      [(set (match_dup 0)
18432            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18433                             (const_int 0)]))
18434       (set (match_dup 2)
18435            (and:QI (match_dup 2) (match_dup 3)))])]
18436   "")
18438 (define_peephole2
18439   [(set (match_operand 0 "flags_reg_operand" "")
18440         (match_operator 1 "compare_operator"
18441           [(and:SI
18442              (zero_extract:SI
18443                (match_operand 2 "ext_register_operand" "")
18444                (const_int 8)
18445                (const_int 8))
18446              (match_operand 3 "const_int_operand" ""))
18447            (const_int 0)]))]
18448   "! TARGET_PARTIAL_REG_STALL
18449    && ix86_match_ccmode (insn, CCNOmode)
18450    && true_regnum (operands[2]) != 0
18451    && peep2_reg_dead_p (1, operands[2])"
18452   [(parallel [(set (match_dup 0)
18453                    (match_op_dup 1
18454                      [(and:SI
18455                         (zero_extract:SI
18456                           (match_dup 2)
18457                           (const_int 8)
18458                           (const_int 8))
18459                         (match_dup 3))
18460                       (const_int 0)]))
18461               (set (zero_extract:SI (match_dup 2)
18462                                     (const_int 8)
18463                                     (const_int 8))
18464                    (and:SI 
18465                      (zero_extract:SI
18466                        (match_dup 2)
18467                        (const_int 8)
18468                        (const_int 8))
18469                      (match_dup 3)))])]
18470   "")
18472 ;; Don't do logical operations with memory inputs.
18473 (define_peephole2
18474   [(match_scratch:SI 2 "r")
18475    (parallel [(set (match_operand:SI 0 "register_operand" "")
18476                    (match_operator:SI 3 "arith_or_logical_operator"
18477                      [(match_dup 0)
18478                       (match_operand:SI 1 "memory_operand" "")]))
18479               (clobber (reg:CC FLAGS_REG))])]
18480   "! optimize_size && ! TARGET_READ_MODIFY"
18481   [(set (match_dup 2) (match_dup 1))
18482    (parallel [(set (match_dup 0)
18483                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18484               (clobber (reg:CC FLAGS_REG))])]
18485   "")
18487 (define_peephole2
18488   [(match_scratch:SI 2 "r")
18489    (parallel [(set (match_operand:SI 0 "register_operand" "")
18490                    (match_operator:SI 3 "arith_or_logical_operator"
18491                      [(match_operand:SI 1 "memory_operand" "")
18492                       (match_dup 0)]))
18493               (clobber (reg:CC FLAGS_REG))])]
18494   "! optimize_size && ! TARGET_READ_MODIFY"
18495   [(set (match_dup 2) (match_dup 1))
18496    (parallel [(set (match_dup 0)
18497                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18498               (clobber (reg:CC FLAGS_REG))])]
18499   "")
18501 ; Don't do logical operations with memory outputs
18503 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18504 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18505 ; the same decoder scheduling characteristics as the original.
18507 (define_peephole2
18508   [(match_scratch:SI 2 "r")
18509    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18510                    (match_operator:SI 3 "arith_or_logical_operator"
18511                      [(match_dup 0)
18512                       (match_operand:SI 1 "nonmemory_operand" "")]))
18513               (clobber (reg:CC FLAGS_REG))])]
18514   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18515   [(set (match_dup 2) (match_dup 0))
18516    (parallel [(set (match_dup 2)
18517                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18518               (clobber (reg:CC FLAGS_REG))])
18519    (set (match_dup 0) (match_dup 2))]
18520   "")
18522 (define_peephole2
18523   [(match_scratch:SI 2 "r")
18524    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18525                    (match_operator:SI 3 "arith_or_logical_operator"
18526                      [(match_operand:SI 1 "nonmemory_operand" "")
18527                       (match_dup 0)]))
18528               (clobber (reg:CC FLAGS_REG))])]
18529   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18530   [(set (match_dup 2) (match_dup 0))
18531    (parallel [(set (match_dup 2)
18532                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18533               (clobber (reg:CC FLAGS_REG))])
18534    (set (match_dup 0) (match_dup 2))]
18535   "")
18537 ;; Attempt to always use XOR for zeroing registers.
18538 (define_peephole2
18539   [(set (match_operand 0 "register_operand" "")
18540         (const_int 0))]
18541   "(GET_MODE (operands[0]) == QImode
18542     || GET_MODE (operands[0]) == HImode
18543     || GET_MODE (operands[0]) == SImode
18544     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18545    && (! TARGET_USE_MOV0 || optimize_size)
18546    && GENERAL_REG_P (operands[0])
18547    && peep2_regno_dead_p (0, FLAGS_REG)"
18548   [(parallel [(set (match_dup 0) (const_int 0))
18549               (clobber (reg:CC FLAGS_REG))])]
18550   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18551                               operands[0]);")
18553 (define_peephole2
18554   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18555         (const_int 0))]
18556   "(GET_MODE (operands[0]) == QImode
18557     || GET_MODE (operands[0]) == HImode)
18558    && (! TARGET_USE_MOV0 || optimize_size)
18559    && peep2_regno_dead_p (0, FLAGS_REG)"
18560   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18561               (clobber (reg:CC FLAGS_REG))])])
18563 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18564 (define_peephole2
18565   [(set (match_operand 0 "register_operand" "")
18566         (const_int -1))]
18567   "(GET_MODE (operands[0]) == HImode
18568     || GET_MODE (operands[0]) == SImode 
18569     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18570    && (optimize_size || TARGET_PENTIUM)
18571    && peep2_regno_dead_p (0, FLAGS_REG)"
18572   [(parallel [(set (match_dup 0) (const_int -1))
18573               (clobber (reg:CC FLAGS_REG))])]
18574   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18575                               operands[0]);")
18577 ;; Attempt to convert simple leas to adds. These can be created by
18578 ;; move expanders.
18579 (define_peephole2
18580   [(set (match_operand:SI 0 "register_operand" "")
18581         (plus:SI (match_dup 0)
18582                  (match_operand:SI 1 "nonmemory_operand" "")))]
18583   "peep2_regno_dead_p (0, FLAGS_REG)"
18584   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18585               (clobber (reg:CC FLAGS_REG))])]
18586   "")
18588 (define_peephole2
18589   [(set (match_operand:SI 0 "register_operand" "")
18590         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18591                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18592   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18593   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18594               (clobber (reg:CC FLAGS_REG))])]
18595   "operands[2] = gen_lowpart (SImode, operands[2]);")
18597 (define_peephole2
18598   [(set (match_operand:DI 0 "register_operand" "")
18599         (plus:DI (match_dup 0)
18600                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18601   "peep2_regno_dead_p (0, FLAGS_REG)"
18602   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18603               (clobber (reg:CC FLAGS_REG))])]
18604   "")
18606 (define_peephole2
18607   [(set (match_operand:SI 0 "register_operand" "")
18608         (mult:SI (match_dup 0)
18609                  (match_operand:SI 1 "const_int_operand" "")))]
18610   "exact_log2 (INTVAL (operands[1])) >= 0
18611    && peep2_regno_dead_p (0, FLAGS_REG)"
18612   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18613               (clobber (reg:CC FLAGS_REG))])]
18614   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18616 (define_peephole2
18617   [(set (match_operand:DI 0 "register_operand" "")
18618         (mult:DI (match_dup 0)
18619                  (match_operand:DI 1 "const_int_operand" "")))]
18620   "exact_log2 (INTVAL (operands[1])) >= 0
18621    && peep2_regno_dead_p (0, FLAGS_REG)"
18622   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18623               (clobber (reg:CC FLAGS_REG))])]
18624   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18626 (define_peephole2
18627   [(set (match_operand:SI 0 "register_operand" "")
18628         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18629                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18630   "exact_log2 (INTVAL (operands[2])) >= 0
18631    && REGNO (operands[0]) == REGNO (operands[1])
18632    && peep2_regno_dead_p (0, FLAGS_REG)"
18633   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18634               (clobber (reg:CC FLAGS_REG))])]
18635   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18637 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18638 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18639 ;; many CPUs it is also faster, since special hardware to avoid esp
18640 ;; dependencies is present.
18642 ;; While some of these conversions may be done using splitters, we use peepholes
18643 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18645 ;; Convert prologue esp subtractions to push.
18646 ;; We need register to push.  In order to keep verify_flow_info happy we have
18647 ;; two choices
18648 ;; - use scratch and clobber it in order to avoid dependencies
18649 ;; - use already live register
18650 ;; We can't use the second way right now, since there is no reliable way how to
18651 ;; verify that given register is live.  First choice will also most likely in
18652 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18653 ;; call clobbered registers are dead.  We may want to use base pointer as an
18654 ;; alternative when no register is available later.
18656 (define_peephole2
18657   [(match_scratch:SI 0 "r")
18658    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18659               (clobber (reg:CC FLAGS_REG))
18660               (clobber (mem:BLK (scratch)))])]
18661   "optimize_size || !TARGET_SUB_ESP_4"
18662   [(clobber (match_dup 0))
18663    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18664               (clobber (mem:BLK (scratch)))])])
18666 (define_peephole2
18667   [(match_scratch:SI 0 "r")
18668    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18669               (clobber (reg:CC FLAGS_REG))
18670               (clobber (mem:BLK (scratch)))])]
18671   "optimize_size || !TARGET_SUB_ESP_8"
18672   [(clobber (match_dup 0))
18673    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18674    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18675               (clobber (mem:BLK (scratch)))])])
18677 ;; Convert esp subtractions to push.
18678 (define_peephole2
18679   [(match_scratch:SI 0 "r")
18680    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18681               (clobber (reg:CC FLAGS_REG))])]
18682   "optimize_size || !TARGET_SUB_ESP_4"
18683   [(clobber (match_dup 0))
18684    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18686 (define_peephole2
18687   [(match_scratch:SI 0 "r")
18688    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18689               (clobber (reg:CC FLAGS_REG))])]
18690   "optimize_size || !TARGET_SUB_ESP_8"
18691   [(clobber (match_dup 0))
18692    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18693    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18695 ;; Convert epilogue deallocator to pop.
18696 (define_peephole2
18697   [(match_scratch:SI 0 "r")
18698    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18699               (clobber (reg:CC FLAGS_REG))
18700               (clobber (mem:BLK (scratch)))])]
18701   "optimize_size || !TARGET_ADD_ESP_4"
18702   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18703               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18704               (clobber (mem:BLK (scratch)))])]
18705   "")
18707 ;; Two pops case is tricky, since pop causes dependency on destination register.
18708 ;; We use two registers if available.
18709 (define_peephole2
18710   [(match_scratch:SI 0 "r")
18711    (match_scratch:SI 1 "r")
18712    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18713               (clobber (reg:CC FLAGS_REG))
18714               (clobber (mem:BLK (scratch)))])]
18715   "optimize_size || !TARGET_ADD_ESP_8"
18716   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18717               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18718               (clobber (mem:BLK (scratch)))])
18719    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18720               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18721   "")
18723 (define_peephole2
18724   [(match_scratch:SI 0 "r")
18725    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18726               (clobber (reg:CC FLAGS_REG))
18727               (clobber (mem:BLK (scratch)))])]
18728   "optimize_size"
18729   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18730               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18731               (clobber (mem:BLK (scratch)))])
18732    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18733               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18734   "")
18736 ;; Convert esp additions to pop.
18737 (define_peephole2
18738   [(match_scratch:SI 0 "r")
18739    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18740               (clobber (reg:CC FLAGS_REG))])]
18741   ""
18742   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18743               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18744   "")
18746 ;; Two pops case is tricky, since pop causes dependency on destination register.
18747 ;; We use two registers if available.
18748 (define_peephole2
18749   [(match_scratch:SI 0 "r")
18750    (match_scratch:SI 1 "r")
18751    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18752               (clobber (reg:CC FLAGS_REG))])]
18753   ""
18754   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18755               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18756    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18757               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18758   "")
18760 (define_peephole2
18761   [(match_scratch:SI 0 "r")
18762    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18763               (clobber (reg:CC FLAGS_REG))])]
18764   "optimize_size"
18765   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18766               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18767    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18768               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18769   "")
18771 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18772 ;; required and register dies.  Similarly for 128 to plus -128.
18773 (define_peephole2
18774   [(set (match_operand 0 "flags_reg_operand" "")
18775         (match_operator 1 "compare_operator"
18776           [(match_operand 2 "register_operand" "")
18777            (match_operand 3 "const_int_operand" "")]))]
18778   "(INTVAL (operands[3]) == -1
18779     || INTVAL (operands[3]) == 1
18780     || INTVAL (operands[3]) == 128)
18781    && ix86_match_ccmode (insn, CCGCmode)
18782    && peep2_reg_dead_p (1, operands[2])"
18783   [(parallel [(set (match_dup 0)
18784                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18785               (clobber (match_dup 2))])]
18786   "")
18788 (define_peephole2
18789   [(match_scratch:DI 0 "r")
18790    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18791               (clobber (reg:CC FLAGS_REG))
18792               (clobber (mem:BLK (scratch)))])]
18793   "optimize_size || !TARGET_SUB_ESP_4"
18794   [(clobber (match_dup 0))
18795    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18796               (clobber (mem:BLK (scratch)))])])
18798 (define_peephole2
18799   [(match_scratch:DI 0 "r")
18800    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18801               (clobber (reg:CC FLAGS_REG))
18802               (clobber (mem:BLK (scratch)))])]
18803   "optimize_size || !TARGET_SUB_ESP_8"
18804   [(clobber (match_dup 0))
18805    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18806    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18807               (clobber (mem:BLK (scratch)))])])
18809 ;; Convert esp subtractions to push.
18810 (define_peephole2
18811   [(match_scratch:DI 0 "r")
18812    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18813               (clobber (reg:CC FLAGS_REG))])]
18814   "optimize_size || !TARGET_SUB_ESP_4"
18815   [(clobber (match_dup 0))
18816    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18818 (define_peephole2
18819   [(match_scratch:DI 0 "r")
18820    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18821               (clobber (reg:CC FLAGS_REG))])]
18822   "optimize_size || !TARGET_SUB_ESP_8"
18823   [(clobber (match_dup 0))
18824    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18825    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18827 ;; Convert epilogue deallocator to pop.
18828 (define_peephole2
18829   [(match_scratch:DI 0 "r")
18830    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18831               (clobber (reg:CC FLAGS_REG))
18832               (clobber (mem:BLK (scratch)))])]
18833   "optimize_size || !TARGET_ADD_ESP_4"
18834   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18835               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18836               (clobber (mem:BLK (scratch)))])]
18837   "")
18839 ;; Two pops case is tricky, since pop causes dependency on destination register.
18840 ;; We use two registers if available.
18841 (define_peephole2
18842   [(match_scratch:DI 0 "r")
18843    (match_scratch:DI 1 "r")
18844    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18845               (clobber (reg:CC FLAGS_REG))
18846               (clobber (mem:BLK (scratch)))])]
18847   "optimize_size || !TARGET_ADD_ESP_8"
18848   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18849               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18850               (clobber (mem:BLK (scratch)))])
18851    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18852               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18853   "")
18855 (define_peephole2
18856   [(match_scratch:DI 0 "r")
18857    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18858               (clobber (reg:CC FLAGS_REG))
18859               (clobber (mem:BLK (scratch)))])]
18860   "optimize_size"
18861   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18862               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18863               (clobber (mem:BLK (scratch)))])
18864    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18865               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18866   "")
18868 ;; Convert esp additions to pop.
18869 (define_peephole2
18870   [(match_scratch:DI 0 "r")
18871    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18872               (clobber (reg:CC FLAGS_REG))])]
18873   ""
18874   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18875               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18876   "")
18878 ;; Two pops case is tricky, since pop causes dependency on destination register.
18879 ;; We use two registers if available.
18880 (define_peephole2
18881   [(match_scratch:DI 0 "r")
18882    (match_scratch:DI 1 "r")
18883    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18884               (clobber (reg:CC FLAGS_REG))])]
18885   ""
18886   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18887               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18888    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18889               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18890   "")
18892 (define_peephole2
18893   [(match_scratch:DI 0 "r")
18894    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18895               (clobber (reg:CC FLAGS_REG))])]
18896   "optimize_size"
18897   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18898               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18899    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18900               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18901   "")
18903 ;; Convert imul by three, five and nine into lea
18904 (define_peephole2
18905   [(parallel
18906     [(set (match_operand:SI 0 "register_operand" "")
18907           (mult:SI (match_operand:SI 1 "register_operand" "")
18908                    (match_operand:SI 2 "const_int_operand" "")))
18909      (clobber (reg:CC FLAGS_REG))])]
18910   "INTVAL (operands[2]) == 3
18911    || INTVAL (operands[2]) == 5
18912    || INTVAL (operands[2]) == 9"
18913   [(set (match_dup 0)
18914         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18915                  (match_dup 1)))]
18916   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18918 (define_peephole2
18919   [(parallel
18920     [(set (match_operand:SI 0 "register_operand" "")
18921           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18922                    (match_operand:SI 2 "const_int_operand" "")))
18923      (clobber (reg:CC FLAGS_REG))])]
18924   "!optimize_size 
18925    && (INTVAL (operands[2]) == 3
18926        || INTVAL (operands[2]) == 5
18927        || INTVAL (operands[2]) == 9)"
18928   [(set (match_dup 0) (match_dup 1))
18929    (set (match_dup 0)
18930         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18931                  (match_dup 0)))]
18932   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18934 (define_peephole2
18935   [(parallel
18936     [(set (match_operand:DI 0 "register_operand" "")
18937           (mult:DI (match_operand:DI 1 "register_operand" "")
18938                    (match_operand:DI 2 "const_int_operand" "")))
18939      (clobber (reg:CC FLAGS_REG))])]
18940   "TARGET_64BIT
18941    && (INTVAL (operands[2]) == 3
18942        || INTVAL (operands[2]) == 5
18943        || INTVAL (operands[2]) == 9)"
18944   [(set (match_dup 0)
18945         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18946                  (match_dup 1)))]
18947   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18949 (define_peephole2
18950   [(parallel
18951     [(set (match_operand:DI 0 "register_operand" "")
18952           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18953                    (match_operand:DI 2 "const_int_operand" "")))
18954      (clobber (reg:CC FLAGS_REG))])]
18955   "TARGET_64BIT
18956    && !optimize_size 
18957    && (INTVAL (operands[2]) == 3
18958        || INTVAL (operands[2]) == 5
18959        || INTVAL (operands[2]) == 9)"
18960   [(set (match_dup 0) (match_dup 1))
18961    (set (match_dup 0)
18962         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18963                  (match_dup 0)))]
18964   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18966 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18967 ;; imul $32bit_imm, reg, reg is direct decoded.
18968 (define_peephole2
18969   [(match_scratch:DI 3 "r")
18970    (parallel [(set (match_operand:DI 0 "register_operand" "")
18971                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18972                             (match_operand:DI 2 "immediate_operand" "")))
18973               (clobber (reg:CC FLAGS_REG))])]
18974   "TARGET_K8 && !optimize_size
18975    && (GET_CODE (operands[2]) != CONST_INT
18976        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18977   [(set (match_dup 3) (match_dup 1))
18978    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18979               (clobber (reg:CC FLAGS_REG))])]
18982 (define_peephole2
18983   [(match_scratch:SI 3 "r")
18984    (parallel [(set (match_operand:SI 0 "register_operand" "")
18985                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18986                             (match_operand:SI 2 "immediate_operand" "")))
18987               (clobber (reg:CC FLAGS_REG))])]
18988   "TARGET_K8 && !optimize_size
18989    && (GET_CODE (operands[2]) != CONST_INT
18990        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18991   [(set (match_dup 3) (match_dup 1))
18992    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18993               (clobber (reg:CC FLAGS_REG))])]
18996 (define_peephole2
18997   [(match_scratch:SI 3 "r")
18998    (parallel [(set (match_operand:DI 0 "register_operand" "")
18999                    (zero_extend:DI
19000                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19001                               (match_operand:SI 2 "immediate_operand" ""))))
19002               (clobber (reg:CC FLAGS_REG))])]
19003   "TARGET_K8 && !optimize_size
19004    && (GET_CODE (operands[2]) != CONST_INT
19005        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19006   [(set (match_dup 3) (match_dup 1))
19007    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19008               (clobber (reg:CC FLAGS_REG))])]
19011 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19012 ;; Convert it into imul reg, reg
19013 ;; It would be better to force assembler to encode instruction using long
19014 ;; immediate, but there is apparently no way to do so.
19015 (define_peephole2
19016   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19017                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19018                             (match_operand:DI 2 "const_int_operand" "")))
19019               (clobber (reg:CC FLAGS_REG))])
19020    (match_scratch:DI 3 "r")]
19021   "TARGET_K8 && !optimize_size
19022    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19023   [(set (match_dup 3) (match_dup 2))
19024    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19025               (clobber (reg:CC FLAGS_REG))])]
19027   if (!rtx_equal_p (operands[0], operands[1]))
19028     emit_move_insn (operands[0], operands[1]);
19031 (define_peephole2
19032   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19033                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19034                             (match_operand:SI 2 "const_int_operand" "")))
19035               (clobber (reg:CC FLAGS_REG))])
19036    (match_scratch:SI 3 "r")]
19037   "TARGET_K8 && !optimize_size
19038    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19039   [(set (match_dup 3) (match_dup 2))
19040    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19041               (clobber (reg:CC FLAGS_REG))])]
19043   if (!rtx_equal_p (operands[0], operands[1]))
19044     emit_move_insn (operands[0], operands[1]);
19047 (define_peephole2
19048   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19049                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19050                             (match_operand:HI 2 "immediate_operand" "")))
19051               (clobber (reg:CC FLAGS_REG))])
19052    (match_scratch:HI 3 "r")]
19053   "TARGET_K8 && !optimize_size"
19054   [(set (match_dup 3) (match_dup 2))
19055    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19056               (clobber (reg:CC FLAGS_REG))])]
19058   if (!rtx_equal_p (operands[0], operands[1]))
19059     emit_move_insn (operands[0], operands[1]);
19062 ;; Call-value patterns last so that the wildcard operand does not
19063 ;; disrupt insn-recog's switch tables.
19065 (define_insn "*call_value_pop_0"
19066   [(set (match_operand 0 "" "")
19067         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19068               (match_operand:SI 2 "" "")))
19069    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19070                             (match_operand:SI 3 "immediate_operand" "")))]
19071   "!TARGET_64BIT"
19073   if (SIBLING_CALL_P (insn))
19074     return "jmp\t%P1";
19075   else
19076     return "call\t%P1";
19078   [(set_attr "type" "callv")])
19080 (define_insn "*call_value_pop_1"
19081   [(set (match_operand 0 "" "")
19082         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19083               (match_operand:SI 2 "" "")))
19084    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19085                             (match_operand:SI 3 "immediate_operand" "i")))]
19086   "!TARGET_64BIT"
19088   if (constant_call_address_operand (operands[1], Pmode))
19089     {
19090       if (SIBLING_CALL_P (insn))
19091         return "jmp\t%P1";
19092       else
19093         return "call\t%P1";
19094     }
19095   if (SIBLING_CALL_P (insn))
19096     return "jmp\t%A1";
19097   else
19098     return "call\t%A1";
19100   [(set_attr "type" "callv")])
19102 (define_insn "*call_value_0"
19103   [(set (match_operand 0 "" "")
19104         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19105               (match_operand:SI 2 "" "")))]
19106   "!TARGET_64BIT"
19108   if (SIBLING_CALL_P (insn))
19109     return "jmp\t%P1";
19110   else
19111     return "call\t%P1";
19113   [(set_attr "type" "callv")])
19115 (define_insn "*call_value_0_rex64"
19116   [(set (match_operand 0 "" "")
19117         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19118               (match_operand:DI 2 "const_int_operand" "")))]
19119   "TARGET_64BIT"
19121   if (SIBLING_CALL_P (insn))
19122     return "jmp\t%P1";
19123   else
19124     return "call\t%P1";
19126   [(set_attr "type" "callv")])
19128 (define_insn "*call_value_1"
19129   [(set (match_operand 0 "" "")
19130         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19131               (match_operand:SI 2 "" "")))]
19132   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19134   if (constant_call_address_operand (operands[1], Pmode))
19135     return "call\t%P1";
19136   return "call\t%A1";
19138   [(set_attr "type" "callv")])
19140 (define_insn "*sibcall_value_1"
19141   [(set (match_operand 0 "" "")
19142         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19143               (match_operand:SI 2 "" "")))]
19144   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19146   if (constant_call_address_operand (operands[1], Pmode))
19147     return "jmp\t%P1";
19148   return "jmp\t%A1";
19150   [(set_attr "type" "callv")])
19152 (define_insn "*call_value_1_rex64"
19153   [(set (match_operand 0 "" "")
19154         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19155               (match_operand:DI 2 "" "")))]
19156   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19158   if (constant_call_address_operand (operands[1], Pmode))
19159     return "call\t%P1";
19160   return "call\t%A1";
19162   [(set_attr "type" "callv")])
19164 (define_insn "*sibcall_value_1_rex64"
19165   [(set (match_operand 0 "" "")
19166         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19167               (match_operand:DI 2 "" "")))]
19168   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19169   "jmp\t%P1"
19170   [(set_attr "type" "callv")])
19172 (define_insn "*sibcall_value_1_rex64_v"
19173   [(set (match_operand 0 "" "")
19174         (call (mem:QI (reg:DI 40))
19175               (match_operand:DI 1 "" "")))]
19176   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19177   "jmp\t*%%r11"
19178   [(set_attr "type" "callv")])
19180 (define_insn "trap"
19181   [(trap_if (const_int 1) (const_int 5))]
19182   ""
19183   "int\t$5")
19185 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19186 ;;; for the sake of bounds checking.  By emitting bounds checks as
19187 ;;; conditional traps rather than as conditional jumps around
19188 ;;; unconditional traps we avoid introducing spurious basic-block
19189 ;;; boundaries and facilitate elimination of redundant checks.  In
19190 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19191 ;;; interrupt 5.
19192 ;;; 
19193 ;;; FIXME: Static branch prediction rules for ix86 are such that
19194 ;;; forward conditional branches predict as untaken.  As implemented
19195 ;;; below, pseudo conditional traps violate that rule.  We should use
19196 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19197 ;;; section loaded at the end of the text segment and branch forward
19198 ;;; there on bounds-failure, and then jump back immediately (in case
19199 ;;; the system chooses to ignore bounds violations, or to report
19200 ;;; violations and continue execution).
19202 (define_expand "conditional_trap"
19203   [(trap_if (match_operator 0 "comparison_operator"
19204              [(match_dup 2) (const_int 0)])
19205             (match_operand 1 "const_int_operand" ""))]
19206   ""
19208   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19209                               ix86_expand_compare (GET_CODE (operands[0]),
19210                                                    NULL, NULL),
19211                               operands[1]));
19212   DONE;
19215 (define_insn "*conditional_trap_1"
19216   [(trap_if (match_operator 0 "comparison_operator"
19217              [(reg FLAGS_REG) (const_int 0)])
19218             (match_operand 1 "const_int_operand" ""))]
19219   ""
19221   operands[2] = gen_label_rtx ();
19222   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19223   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19224                              CODE_LABEL_NUMBER (operands[2]));
19225   RET;
19228 (define_expand "sse_prologue_save"
19229   [(parallel [(set (match_operand:BLK 0 "" "")
19230                    (unspec:BLK [(reg:DI 21)
19231                                 (reg:DI 22)
19232                                 (reg:DI 23)
19233                                 (reg:DI 24)
19234                                 (reg:DI 25)
19235                                 (reg:DI 26)
19236                                 (reg:DI 27)
19237                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19238               (use (match_operand:DI 1 "register_operand" ""))
19239               (use (match_operand:DI 2 "immediate_operand" ""))
19240               (use (label_ref:DI (match_operand 3 "" "")))])]
19241   "TARGET_64BIT"
19242   "")
19244 (define_insn "*sse_prologue_save_insn"
19245   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19246                           (match_operand:DI 4 "const_int_operand" "n")))
19247         (unspec:BLK [(reg:DI 21)
19248                      (reg:DI 22)
19249                      (reg:DI 23)
19250                      (reg:DI 24)
19251                      (reg:DI 25)
19252                      (reg:DI 26)
19253                      (reg:DI 27)
19254                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19255    (use (match_operand:DI 1 "register_operand" "r"))
19256    (use (match_operand:DI 2 "const_int_operand" "i"))
19257    (use (label_ref:DI (match_operand 3 "" "X")))]
19258   "TARGET_64BIT
19259    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19260    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19261   "*
19263   int i;
19264   operands[0] = gen_rtx_MEM (Pmode,
19265                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19266   output_asm_insn (\"jmp\\t%A1\", operands);
19267   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19268     {
19269       operands[4] = adjust_address (operands[0], DImode, i*16);
19270       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19271       PUT_MODE (operands[4], TImode);
19272       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19273         output_asm_insn (\"rex\", operands);
19274       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19275     }
19276   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19277                              CODE_LABEL_NUMBER (operands[3]));
19278   RET;
19280   "
19281   [(set_attr "type" "other")
19282    (set_attr "length_immediate" "0")
19283    (set_attr "length_address" "0")
19284    (set_attr "length" "135")
19285    (set_attr "memory" "store")
19286    (set_attr "modrm" "0")
19287    (set_attr "mode" "DI")])
19289 (define_expand "prefetch"
19290   [(prefetch (match_operand 0 "address_operand" "")
19291              (match_operand:SI 1 "const_int_operand" "")
19292              (match_operand:SI 2 "const_int_operand" ""))]
19293   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19295   int rw = INTVAL (operands[1]);
19296   int locality = INTVAL (operands[2]);
19298   if (rw != 0 && rw != 1)
19299     abort ();
19300   if (locality < 0 || locality > 3)
19301     abort ();
19302   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19303     abort ();
19305   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19306      suported by SSE counterpart or the SSE prefetch is not available
19307      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19308      of locality.  */
19309   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19310     operands[2] = GEN_INT (3);
19311   else
19312     operands[1] = const0_rtx;
19315 (define_insn "*prefetch_sse"
19316   [(prefetch (match_operand:SI 0 "address_operand" "p")
19317              (const_int 0)
19318              (match_operand:SI 1 "const_int_operand" ""))]
19319   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19321   static const char * const patterns[4] = {
19322    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19323   };
19325   int locality = INTVAL (operands[1]);
19326   if (locality < 0 || locality > 3)
19327     abort ();
19329   return patterns[locality];  
19331   [(set_attr "type" "sse")
19332    (set_attr "memory" "none")])
19334 (define_insn "*prefetch_sse_rex"
19335   [(prefetch (match_operand:DI 0 "address_operand" "p")
19336              (const_int 0)
19337              (match_operand:SI 1 "const_int_operand" ""))]
19338   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19340   static const char * const patterns[4] = {
19341    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19342   };
19344   int locality = INTVAL (operands[1]);
19345   if (locality < 0 || locality > 3)
19346     abort ();
19348   return patterns[locality];  
19350   [(set_attr "type" "sse")
19351    (set_attr "memory" "none")])
19353 (define_insn "*prefetch_3dnow"
19354   [(prefetch (match_operand:SI 0 "address_operand" "p")
19355              (match_operand:SI 1 "const_int_operand" "n")
19356              (const_int 3))]
19357   "TARGET_3DNOW && !TARGET_64BIT"
19359   if (INTVAL (operands[1]) == 0)
19360     return "prefetch\t%a0";
19361   else
19362     return "prefetchw\t%a0";
19364   [(set_attr "type" "mmx")
19365    (set_attr "memory" "none")])
19367 (define_insn "*prefetch_3dnow_rex"
19368   [(prefetch (match_operand:DI 0 "address_operand" "p")
19369              (match_operand:SI 1 "const_int_operand" "n")
19370              (const_int 3))]
19371   "TARGET_3DNOW && TARGET_64BIT"
19373   if (INTVAL (operands[1]) == 0)
19374     return "prefetch\t%a0";
19375   else
19376     return "prefetchw\t%a0";
19378   [(set_attr "type" "mmx")
19379    (set_attr "memory" "none")])
19381 (include "sse.md")
19382 (include "mmx.md")