PR target/19236
[official-gcc.git] / gcc / config / i386 / i386.md
blob923bdf90660bc5aa441bf7ec1d5a65bddf58109b
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
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_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
143    ; REP instruction
144    (UNSPEC_REP                  75)
146    (UNSPEC_EH_RETURN            76)
147   ])
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
203   (const_string "unknown"))
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
411 ;; Indicates if an instruction has both an immediate and a displacement.
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
427 ;; Indicates if an FP operation has an integer source.
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
432 ;; Defines rounding mode of an FP operation.
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435   (const_string "any"))
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
442 ;; Scheduling descriptions
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
450 ;; Operand and operator predicates
452 (include "predicates.md")
455 ;; Compare instructions.
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg FLAGS_REG)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg FLAGS_REG)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg FLAGS_REG)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg FLAGS_REG)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
603 (define_insn "*cmphi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
613 (define_insn "*cmphi_1"
614   [(set (reg FLAGS_REG)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
635 (define_insn "*cmpqi_1"
636   [(set (reg FLAGS_REG)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg FLAGS_REG)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg FLAGS_REG)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg FLAGS_REG)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg FLAGS_REG)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg FLAGS_REG)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
803 (define_insn "*cmpfp_0_sf"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "const0_operand" "X"))]
809         UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 0, 0);"
812   [(set_attr "type" "multi")
813    (set_attr "mode" "SF")])
815 (define_insn "*cmpfp_0_df"
816   [(set (match_operand:HI 0 "register_operand" "=a")
817         (unspec:HI
818           [(compare:CCFP
819              (match_operand:DF 1 "register_operand" "f")
820              (match_operand:DF 2 "const0_operand" "X"))]
821         UNSPEC_FNSTSW))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "multi")
825    (set_attr "mode" "DF")])
827 (define_insn "*cmpfp_0_xf"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:XF 1 "register_operand" "f")
832              (match_operand:XF 2 "const0_operand" "X"))]
833         UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 0, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "XF")])
839 (define_insn "*cmpfp_sf"
840   [(set (match_operand:HI 0 "register_operand" "=a")
841         (unspec:HI
842           [(compare:CCFP
843              (match_operand:SF 1 "register_operand" "f")
844              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845           UNSPEC_FNSTSW))]
846   "TARGET_80387"
847   "* return output_fp_compare (insn, operands, 0, 0);"
848   [(set_attr "type" "multi")
849    (set_attr "mode" "SF")])
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "mode" "DF")])
863 (define_insn "*cmpfp_xf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:XF 1 "register_operand" "f")
868              (match_operand:XF 2 "register_operand" "f"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "mode" "XF")])
875 (define_insn "*cmpfp_u"
876   [(set (match_operand:HI 0 "register_operand" "=a")
877         (unspec:HI
878           [(compare:CCFPU
879              (match_operand 1 "register_operand" "f")
880              (match_operand 2 "register_operand" "f"))]
881           UNSPEC_FNSTSW))]
882   "TARGET_80387
883    && FLOAT_MODE_P (GET_MODE (operands[1]))
884    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885   "* return output_fp_compare (insn, operands, 0, 1);"
886   [(set_attr "type" "multi")
887    (set (attr "mode")
888      (cond [(match_operand:SF 1 "" "")
889               (const_string "SF")
890             (match_operand:DF 1 "" "")
891               (const_string "DF")
892            ]
893            (const_string "XF")))])
895 (define_insn "*cmpfp_si"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand 1 "register_operand" "f")
900              (match_operator 3 "float_operator"
901                [(match_operand:SI 2 "memory_operand" "m")]))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387 && TARGET_USE_FIOP
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "fp_int_src" "true")
909    (set_attr "mode" "SI")])
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
914 (define_insn "x86_fnstsw_1"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "fnstsw\t%0"
919   [(set_attr "length" "2")
920    (set_attr "mode" "SI")
921    (set_attr "unit" "i387")])
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
926 (define_insn "x86_sahf_1"
927   [(set (reg:CC FLAGS_REG)
928         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929   "!TARGET_64BIT"
930   "sahf"
931   [(set_attr "length" "1")
932    (set_attr "athlon_decode" "vector")
933    (set_attr "mode" "SI")])
935 ;; Pentium Pro can do steps 1 through 3 in one go.
937 (define_insn "*cmpfp_i"
938   [(set (reg:CCFP FLAGS_REG)
939         (compare:CCFP (match_operand 0 "register_operand" "f")
940                       (match_operand 1 "register_operand" "f")))]
941   "TARGET_80387 && TARGET_CMOVE
942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943    && FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp")
947    (set (attr "mode")
948      (cond [(match_operand:SF 1 "" "")
949               (const_string "SF")
950             (match_operand:DF 1 "" "")
951               (const_string "DF")
952            ]
953            (const_string "XF")))
954    (set_attr "athlon_decode" "vector")])
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_80387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
971 (define_insn "*cmpfp_i_sse_only"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977   "* return output_fp_compare (insn, operands, 1, 0);"
978   [(set_attr "type" "ssecomi")
979    (set (attr "mode")
980      (if_then_else (match_operand:SF 1 "" "")
981         (const_string "SF")
982         (const_string "DF")))
983    (set_attr "athlon_decode" "vector")])
985 (define_insn "*cmpfp_iu"
986   [(set (reg:CCFPU FLAGS_REG)
987         (compare:CCFPU (match_operand 0 "register_operand" "f")
988                        (match_operand 1 "register_operand" "f")))]
989   "TARGET_80387 && TARGET_CMOVE
990    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && FLOAT_MODE_P (GET_MODE (operands[0]))
992    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993   "* return output_fp_compare (insn, operands, 1, 1);"
994   [(set_attr "type" "fcmp")
995    (set (attr "mode")
996      (cond [(match_operand:SF 1 "" "")
997               (const_string "SF")
998             (match_operand:DF 1 "" "")
999               (const_string "DF")
1000            ]
1001            (const_string "XF")))
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" "f#x,x#f")
1007                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008   "TARGET_80387
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" "fcmp,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_sse_only"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "x")
1022                        (match_operand 1 "nonimmediate_operand" "xm")))]
1023   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1033 ;; Move instructions.
1035 ;; General case of fullword move.
1037 (define_expand "movsi"
1038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039         (match_operand:SI 1 "general_operand" ""))]
1040   ""
1041   "ix86_expand_move (SImode, operands); DONE;")
1043 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1044 ;; general_operand.
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1052 (define_insn "*pushsi2"
1053   [(set (match_operand:SI 0 "push_operand" "=<")
1054         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055   "!TARGET_64BIT"
1056   "push{l}\t%1"
1057   [(set_attr "type" "push")
1058    (set_attr "mode" "SI")])
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062   [(set (match_operand:SI 0 "push_operand" "=X")
1063         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064   "TARGET_64BIT"
1065   "push{q}\t%q1"
1066   [(set_attr "type" "push")
1067    (set_attr "mode" "SI")])
1069 (define_insn "*pushsi2_prologue"
1070   [(set (match_operand:SI 0 "push_operand" "=<")
1071         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072    (clobber (mem:BLK (scratch)))]
1073   "!TARGET_64BIT"
1074   "push{l}\t%1"
1075   [(set_attr "type" "push")
1076    (set_attr "mode" "SI")])
1078 (define_insn "*popsi1_epilogue"
1079   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080         (mem:SI (reg:SI SP_REG)))
1081    (set (reg:SI SP_REG)
1082         (plus:SI (reg:SI SP_REG) (const_int 4)))
1083    (clobber (mem:BLK (scratch)))]
1084   "!TARGET_64BIT"
1085   "pop{l}\t%0"
1086   [(set_attr "type" "pop")
1087    (set_attr "mode" "SI")])
1089 (define_insn "popsi1"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091         (mem:SI (reg:SI SP_REG)))
1092    (set (reg:SI SP_REG)
1093         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094   "!TARGET_64BIT"
1095   "pop{l}\t%0"
1096   [(set_attr "type" "pop")
1097    (set_attr "mode" "SI")])
1099 (define_insn "*movsi_xor"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (match_operand:SI 1 "const0_operand" "i"))
1102    (clobber (reg:CC FLAGS_REG))]
1103   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104   "xor{l}\t{%0, %0|%0, %0}"
1105   [(set_attr "type" "alu1")
1106    (set_attr "mode" "SI")
1107    (set_attr "length_immediate" "0")])
1109 (define_insn "*movsi_or"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (match_operand:SI 1 "immediate_operand" "i"))
1112    (clobber (reg:CC FLAGS_REG))]
1113   "reload_completed
1114    && operands[1] == constm1_rtx
1115    && (TARGET_PENTIUM || optimize_size)"
1117   operands[1] = constm1_rtx;
1118   return "or{l}\t{%1, %0|%0, %1}";
1120   [(set_attr "type" "alu1")
1121    (set_attr "mode" "SI")
1122    (set_attr "length_immediate" "1")])
1124 (define_insn "*movsi_1"
1125   [(set (match_operand:SI 0 "nonimmediate_operand"
1126                         "=r  ,m  ,!*y,!rm,!*y,!*x,!rm,!*x")
1127         (match_operand:SI 1 "general_operand"
1128                         "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
1129   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1132   switch (get_attr_type (insn))
1133     {
1134     case TYPE_SSEMOV:
1135       if (get_attr_mode (insn) == MODE_TI)
1136         return "movdqa\t{%1, %0|%0, %1}";
1137       return "movd\t{%1, %0|%0, %1}";
1139     case TYPE_MMXMOV:
1140       if (get_attr_mode (insn) == MODE_DI)
1141         return "movq\t{%1, %0|%0, %1}";
1142       return "movd\t{%1, %0|%0, %1}";
1144     case TYPE_LEA:
1145       return "lea{l}\t{%1, %0|%0, %1}";
1147     default:
1148       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1149         abort();
1150       return "mov{l}\t{%1, %0|%0, %1}";
1151     }
1153   [(set (attr "type")
1154      (cond [(eq_attr "alternative" "2,3,4")
1155               (const_string "mmxmov")
1156             (eq_attr "alternative" "5,6,7")
1157               (const_string "ssemov")
1158             (and (ne (symbol_ref "flag_pic") (const_int 0))
1159                  (match_operand:SI 1 "symbolic_operand" ""))
1160               (const_string "lea")
1161            ]
1162            (const_string "imov")))
1163    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1165 (define_insn "*movsi_1_nointernunit"
1166   [(set (match_operand:SI 0 "nonimmediate_operand"
1167                         "=r  ,m  ,!*y,!m,!*y,!*x,!m,!*x")
1168         (match_operand:SI 1 "general_operand"
1169                         "rinm,rin,*y ,*y,m  ,*x ,*x,m"))]
1170   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1171    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1173   switch (get_attr_type (insn))
1174     {
1175     case TYPE_SSEMOV:
1176       if (get_attr_mode (insn) == MODE_TI)
1177         return "movdqa\t{%1, %0|%0, %1}";
1178       return "movd\t{%1, %0|%0, %1}";
1180     case TYPE_MMXMOV:
1181       if (get_attr_mode (insn) == MODE_DI)
1182         return "movq\t{%1, %0|%0, %1}";
1183       return "movd\t{%1, %0|%0, %1}";
1185     case TYPE_LEA:
1186       return "lea{l}\t{%1, %0|%0, %1}";
1188     default:
1189       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1190         abort();
1191       return "mov{l}\t{%1, %0|%0, %1}";
1192     }
1194   [(set (attr "type")
1195      (cond [(eq_attr "alternative" "2,3,4")
1196               (const_string "mmxmov")
1197             (eq_attr "alternative" "5,6,7")
1198               (const_string "ssemov")
1199             (and (ne (symbol_ref "flag_pic") (const_int 0))
1200                  (match_operand:SI 1 "symbolic_operand" ""))
1201               (const_string "lea")
1202            ]
1203            (const_string "imov")))
1204    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1206 ;; Stores and loads of ax to arbitrary constant address.
1207 ;; We fake an second form of instruction to force reload to load address
1208 ;; into register when rax is not available
1209 (define_insn "*movabssi_1_rex64"
1210   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1211         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1212   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1213   "@
1214    movabs{l}\t{%1, %P0|%P0, %1}
1215    mov{l}\t{%1, %a0|%a0, %1}"
1216   [(set_attr "type" "imov")
1217    (set_attr "modrm" "0,*")
1218    (set_attr "length_address" "8,0")
1219    (set_attr "length_immediate" "0,*")
1220    (set_attr "memory" "store")
1221    (set_attr "mode" "SI")])
1223 (define_insn "*movabssi_2_rex64"
1224   [(set (match_operand:SI 0 "register_operand" "=a,r")
1225         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1226   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1227   "@
1228    movabs{l}\t{%P1, %0|%0, %P1}
1229    mov{l}\t{%a1, %0|%0, %a1}"
1230   [(set_attr "type" "imov")
1231    (set_attr "modrm" "0,*")
1232    (set_attr "length_address" "8,0")
1233    (set_attr "length_immediate" "0")
1234    (set_attr "memory" "load")
1235    (set_attr "mode" "SI")])
1237 (define_insn "*swapsi"
1238   [(set (match_operand:SI 0 "register_operand" "+r")
1239         (match_operand:SI 1 "register_operand" "+r"))
1240    (set (match_dup 1)
1241         (match_dup 0))]
1242   ""
1243   "xchg{l}\t%1, %0"
1244   [(set_attr "type" "imov")
1245    (set_attr "mode" "SI")
1246    (set_attr "pent_pair" "np")
1247    (set_attr "athlon_decode" "vector")])
1249 (define_expand "movhi"
1250   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1251         (match_operand:HI 1 "general_operand" ""))]
1252   ""
1253   "ix86_expand_move (HImode, operands); DONE;")
1255 (define_insn "*pushhi2"
1256   [(set (match_operand:HI 0 "push_operand" "=<,<")
1257         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1258   "!TARGET_64BIT"
1259   "@
1260    push{w}\t{|WORD PTR }%1
1261    push{w}\t%1"
1262   [(set_attr "type" "push")
1263    (set_attr "mode" "HI")])
1265 ;; For 64BIT abi we always round up to 8 bytes.
1266 (define_insn "*pushhi2_rex64"
1267   [(set (match_operand:HI 0 "push_operand" "=X")
1268         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1269   "TARGET_64BIT"
1270   "push{q}\t%q1"
1271   [(set_attr "type" "push")
1272    (set_attr "mode" "QI")])
1274 (define_insn "*movhi_1"
1275   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1276         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1277   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1279   switch (get_attr_type (insn))
1280     {
1281     case TYPE_IMOVX:
1282       /* movzwl is faster than movw on p2 due to partial word stalls,
1283          though not as fast as an aligned movl.  */
1284       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1285     default:
1286       if (get_attr_mode (insn) == MODE_SI)
1287         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1288       else
1289         return "mov{w}\t{%1, %0|%0, %1}";
1290     }
1292   [(set (attr "type")
1293      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1294               (const_string "imov")
1295             (and (eq_attr "alternative" "0")
1296                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1297                           (const_int 0))
1298                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1299                           (const_int 0))))
1300               (const_string "imov")
1301             (and (eq_attr "alternative" "1,2")
1302                  (match_operand:HI 1 "aligned_operand" ""))
1303               (const_string "imov")
1304             (and (ne (symbol_ref "TARGET_MOVX")
1305                      (const_int 0))
1306                  (eq_attr "alternative" "0,2"))
1307               (const_string "imovx")
1308            ]
1309            (const_string "imov")))
1310     (set (attr "mode")
1311       (cond [(eq_attr "type" "imovx")
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "1,2")
1314                   (match_operand:HI 1 "aligned_operand" ""))
1315                (const_string "SI")
1316              (and (eq_attr "alternative" "0")
1317                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                            (const_int 0))
1319                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                            (const_int 0))))
1321                (const_string "SI")
1322             ]
1323             (const_string "HI")))])
1325 ;; Stores and loads of ax to arbitrary constant address.
1326 ;; We fake an second form of instruction to force reload to load address
1327 ;; into register when rax is not available
1328 (define_insn "*movabshi_1_rex64"
1329   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1330         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1331   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1332   "@
1333    movabs{w}\t{%1, %P0|%P0, %1}
1334    mov{w}\t{%1, %a0|%a0, %1}"
1335   [(set_attr "type" "imov")
1336    (set_attr "modrm" "0,*")
1337    (set_attr "length_address" "8,0")
1338    (set_attr "length_immediate" "0,*")
1339    (set_attr "memory" "store")
1340    (set_attr "mode" "HI")])
1342 (define_insn "*movabshi_2_rex64"
1343   [(set (match_operand:HI 0 "register_operand" "=a,r")
1344         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1345   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1346   "@
1347    movabs{w}\t{%P1, %0|%0, %P1}
1348    mov{w}\t{%a1, %0|%0, %a1}"
1349   [(set_attr "type" "imov")
1350    (set_attr "modrm" "0,*")
1351    (set_attr "length_address" "8,0")
1352    (set_attr "length_immediate" "0")
1353    (set_attr "memory" "load")
1354    (set_attr "mode" "HI")])
1356 (define_insn "*swaphi_1"
1357   [(set (match_operand:HI 0 "register_operand" "+r")
1358         (match_operand:HI 1 "register_operand" "+r"))
1359    (set (match_dup 1)
1360         (match_dup 0))]
1361   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1362   "xchg{l}\t%k1, %k0"
1363   [(set_attr "type" "imov")
1364    (set_attr "mode" "SI")
1365    (set_attr "pent_pair" "np")
1366    (set_attr "athlon_decode" "vector")])
1368 (define_insn "*swaphi_2"
1369   [(set (match_operand:HI 0 "register_operand" "+r")
1370         (match_operand:HI 1 "register_operand" "+r"))
1371    (set (match_dup 1)
1372         (match_dup 0))]
1373   "TARGET_PARTIAL_REG_STALL"
1374   "xchg{w}\t%1, %0"
1375   [(set_attr "type" "imov")
1376    (set_attr "mode" "HI")
1377    (set_attr "pent_pair" "np")
1378    (set_attr "athlon_decode" "vector")])
1380 (define_expand "movstricthi"
1381   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1382         (match_operand:HI 1 "general_operand" ""))]
1383   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1385   /* Don't generate memory->memory moves, go through a register */
1386   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1387     operands[1] = force_reg (HImode, operands[1]);
1390 (define_insn "*movstricthi_1"
1391   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1392         (match_operand:HI 1 "general_operand" "rn,m"))]
1393   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1394    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1395   "mov{w}\t{%1, %0|%0, %1}"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")])
1399 (define_insn "*movstricthi_xor"
1400   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1401         (match_operand:HI 1 "const0_operand" "i"))
1402    (clobber (reg:CC FLAGS_REG))]
1403   "reload_completed
1404    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1405   "xor{w}\t{%0, %0|%0, %0}"
1406   [(set_attr "type" "alu1")
1407    (set_attr "mode" "HI")
1408    (set_attr "length_immediate" "0")])
1410 (define_expand "movqi"
1411   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1412         (match_operand:QI 1 "general_operand" ""))]
1413   ""
1414   "ix86_expand_move (QImode, operands); DONE;")
1416 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1417 ;; "push a byte".  But actually we use pushw, which has the effect
1418 ;; of rounding the amount pushed up to a halfword.
1420 (define_insn "*pushqi2"
1421   [(set (match_operand:QI 0 "push_operand" "=X,X")
1422         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1423   "!TARGET_64BIT"
1424   "@
1425    push{w}\t{|word ptr }%1
1426    push{w}\t%w1"
1427   [(set_attr "type" "push")
1428    (set_attr "mode" "HI")])
1430 ;; For 64BIT abi we always round up to 8 bytes.
1431 (define_insn "*pushqi2_rex64"
1432   [(set (match_operand:QI 0 "push_operand" "=X")
1433         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1434   "TARGET_64BIT"
1435   "push{q}\t%q1"
1436   [(set_attr "type" "push")
1437    (set_attr "mode" "QI")])
1439 ;; Situation is quite tricky about when to choose full sized (SImode) move
1440 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1441 ;; partial register dependency machines (such as AMD Athlon), where QImode
1442 ;; moves issue extra dependency and for partial register stalls machines
1443 ;; that don't use QImode patterns (and QImode move cause stall on the next
1444 ;; instruction).
1446 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1447 ;; register stall machines with, where we use QImode instructions, since
1448 ;; partial register stall can be caused there.  Then we use movzx.
1449 (define_insn "*movqi_1"
1450   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1451         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1452   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1454   switch (get_attr_type (insn))
1455     {
1456     case TYPE_IMOVX:
1457       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1458         abort ();
1459       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1460     default:
1461       if (get_attr_mode (insn) == MODE_SI)
1462         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1463       else
1464         return "mov{b}\t{%1, %0|%0, %1}";
1465     }
1467   [(set (attr "type")
1468      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1469               (const_string "imov")
1470             (and (eq_attr "alternative" "3")
1471                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1472                           (const_int 0))
1473                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1474                           (const_int 0))))
1475               (const_string "imov")
1476             (eq_attr "alternative" "3,5")
1477               (const_string "imovx")
1478             (and (ne (symbol_ref "TARGET_MOVX")
1479                      (const_int 0))
1480                  (eq_attr "alternative" "2"))
1481               (const_string "imovx")
1482            ]
1483            (const_string "imov")))
1484    (set (attr "mode")
1485       (cond [(eq_attr "alternative" "3,4,5")
1486                (const_string "SI")
1487              (eq_attr "alternative" "6")
1488                (const_string "QI")
1489              (eq_attr "type" "imovx")
1490                (const_string "SI")
1491              (and (eq_attr "type" "imov")
1492                   (and (eq_attr "alternative" "0,1")
1493                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1494                            (const_int 0))))
1495                (const_string "SI")
1496              ;; Avoid partial register stalls when not using QImode arithmetic
1497              (and (eq_attr "type" "imov")
1498                   (and (eq_attr "alternative" "0,1")
1499                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1500                                 (const_int 0))
1501                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1502                                 (const_int 0)))))
1503                (const_string "SI")
1504            ]
1505            (const_string "QI")))])
1507 (define_expand "reload_outqi"
1508   [(parallel [(match_operand:QI 0 "" "=m")
1509               (match_operand:QI 1 "register_operand" "r")
1510               (match_operand:QI 2 "register_operand" "=&q")])]
1511   ""
1513   rtx op0, op1, op2;
1514   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1516   if (reg_overlap_mentioned_p (op2, op0))
1517     abort ();
1518   if (! q_regs_operand (op1, QImode))
1519     {
1520       emit_insn (gen_movqi (op2, op1));
1521       op1 = op2;
1522     }
1523   emit_insn (gen_movqi (op0, op1));
1524   DONE;
1527 (define_insn "*swapqi_1"
1528   [(set (match_operand:QI 0 "register_operand" "+r")
1529         (match_operand:QI 1 "register_operand" "+r"))
1530    (set (match_dup 1)
1531         (match_dup 0))]
1532   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1533   "xchg{l}\t%k1, %k0"
1534   [(set_attr "type" "imov")
1535    (set_attr "mode" "SI")
1536    (set_attr "pent_pair" "np")
1537    (set_attr "athlon_decode" "vector")])
1539 (define_insn "*swapqi_2"
1540   [(set (match_operand:QI 0 "register_operand" "+q")
1541         (match_operand:QI 1 "register_operand" "+q"))
1542    (set (match_dup 1)
1543         (match_dup 0))]
1544   "TARGET_PARTIAL_REG_STALL"
1545   "xchg{b}\t%1, %0"
1546   [(set_attr "type" "imov")
1547    (set_attr "mode" "QI")
1548    (set_attr "pent_pair" "np")
1549    (set_attr "athlon_decode" "vector")])
1551 (define_expand "movstrictqi"
1552   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1553         (match_operand:QI 1 "general_operand" ""))]
1554   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1556   /* Don't generate memory->memory moves, go through a register.  */
1557   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1558     operands[1] = force_reg (QImode, operands[1]);
1561 (define_insn "*movstrictqi_1"
1562   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1563         (match_operand:QI 1 "general_operand" "*qn,m"))]
1564   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1566   "mov{b}\t{%1, %0|%0, %1}"
1567   [(set_attr "type" "imov")
1568    (set_attr "mode" "QI")])
1570 (define_insn "*movstrictqi_xor"
1571   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1572         (match_operand:QI 1 "const0_operand" "i"))
1573    (clobber (reg:CC FLAGS_REG))]
1574   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1575   "xor{b}\t{%0, %0|%0, %0}"
1576   [(set_attr "type" "alu1")
1577    (set_attr "mode" "QI")
1578    (set_attr "length_immediate" "0")])
1580 (define_insn "*movsi_extv_1"
1581   [(set (match_operand:SI 0 "register_operand" "=R")
1582         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1583                          (const_int 8)
1584                          (const_int 8)))]
1585   ""
1586   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1587   [(set_attr "type" "imovx")
1588    (set_attr "mode" "SI")])
1590 (define_insn "*movhi_extv_1"
1591   [(set (match_operand:HI 0 "register_operand" "=R")
1592         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1593                          (const_int 8)
1594                          (const_int 8)))]
1595   ""
1596   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1597   [(set_attr "type" "imovx")
1598    (set_attr "mode" "SI")])
1600 (define_insn "*movqi_extv_1"
1601   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1602         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1603                          (const_int 8)
1604                          (const_int 8)))]
1605   "!TARGET_64BIT"
1607   switch (get_attr_type (insn))
1608     {
1609     case TYPE_IMOVX:
1610       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1611     default:
1612       return "mov{b}\t{%h1, %0|%0, %h1}";
1613     }
1615   [(set (attr "type")
1616      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1617                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1618                              (ne (symbol_ref "TARGET_MOVX")
1619                                  (const_int 0))))
1620         (const_string "imovx")
1621         (const_string "imov")))
1622    (set (attr "mode")
1623      (if_then_else (eq_attr "type" "imovx")
1624         (const_string "SI")
1625         (const_string "QI")))])
1627 (define_insn "*movqi_extv_1_rex64"
1628   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1629         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1630                          (const_int 8)
1631                          (const_int 8)))]
1632   "TARGET_64BIT"
1634   switch (get_attr_type (insn))
1635     {
1636     case TYPE_IMOVX:
1637       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1638     default:
1639       return "mov{b}\t{%h1, %0|%0, %h1}";
1640     }
1642   [(set (attr "type")
1643      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1644                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1645                              (ne (symbol_ref "TARGET_MOVX")
1646                                  (const_int 0))))
1647         (const_string "imovx")
1648         (const_string "imov")))
1649    (set (attr "mode")
1650      (if_then_else (eq_attr "type" "imovx")
1651         (const_string "SI")
1652         (const_string "QI")))])
1654 ;; Stores and loads of ax to arbitrary constant address.
1655 ;; We fake an second form of instruction to force reload to load address
1656 ;; into register when rax is not available
1657 (define_insn "*movabsqi_1_rex64"
1658   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1659         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1660   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1661   "@
1662    movabs{b}\t{%1, %P0|%P0, %1}
1663    mov{b}\t{%1, %a0|%a0, %1}"
1664   [(set_attr "type" "imov")
1665    (set_attr "modrm" "0,*")
1666    (set_attr "length_address" "8,0")
1667    (set_attr "length_immediate" "0,*")
1668    (set_attr "memory" "store")
1669    (set_attr "mode" "QI")])
1671 (define_insn "*movabsqi_2_rex64"
1672   [(set (match_operand:QI 0 "register_operand" "=a,r")
1673         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1674   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1675   "@
1676    movabs{b}\t{%P1, %0|%0, %P1}
1677    mov{b}\t{%a1, %0|%0, %a1}"
1678   [(set_attr "type" "imov")
1679    (set_attr "modrm" "0,*")
1680    (set_attr "length_address" "8,0")
1681    (set_attr "length_immediate" "0")
1682    (set_attr "memory" "load")
1683    (set_attr "mode" "QI")])
1685 (define_insn "*movsi_extzv_1"
1686   [(set (match_operand:SI 0 "register_operand" "=R")
1687         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1688                          (const_int 8)
1689                          (const_int 8)))]
1690   ""
1691   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1692   [(set_attr "type" "imovx")
1693    (set_attr "mode" "SI")])
1695 (define_insn "*movqi_extzv_2"
1696   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1697         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1698                                     (const_int 8)
1699                                     (const_int 8)) 0))]
1700   "!TARGET_64BIT"
1702   switch (get_attr_type (insn))
1703     {
1704     case TYPE_IMOVX:
1705       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1706     default:
1707       return "mov{b}\t{%h1, %0|%0, %h1}";
1708     }
1710   [(set (attr "type")
1711      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1712                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1713                              (ne (symbol_ref "TARGET_MOVX")
1714                                  (const_int 0))))
1715         (const_string "imovx")
1716         (const_string "imov")))
1717    (set (attr "mode")
1718      (if_then_else (eq_attr "type" "imovx")
1719         (const_string "SI")
1720         (const_string "QI")))])
1722 (define_insn "*movqi_extzv_2_rex64"
1723   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1724         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1725                                     (const_int 8)
1726                                     (const_int 8)) 0))]
1727   "TARGET_64BIT"
1729   switch (get_attr_type (insn))
1730     {
1731     case TYPE_IMOVX:
1732       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1733     default:
1734       return "mov{b}\t{%h1, %0|%0, %h1}";
1735     }
1737   [(set (attr "type")
1738      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1739                         (ne (symbol_ref "TARGET_MOVX")
1740                             (const_int 0)))
1741         (const_string "imovx")
1742         (const_string "imov")))
1743    (set (attr "mode")
1744      (if_then_else (eq_attr "type" "imovx")
1745         (const_string "SI")
1746         (const_string "QI")))])
1748 (define_insn "movsi_insv_1"
1749   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1750                          (const_int 8)
1751                          (const_int 8))
1752         (match_operand:SI 1 "general_operand" "Qmn"))]
1753   "!TARGET_64BIT"
1754   "mov{b}\t{%b1, %h0|%h0, %b1}"
1755   [(set_attr "type" "imov")
1756    (set_attr "mode" "QI")])
1758 (define_insn "movdi_insv_1_rex64"
1759   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1760                          (const_int 8)
1761                          (const_int 8))
1762         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1763   "TARGET_64BIT"
1764   "mov{b}\t{%b1, %h0|%h0, %b1}"
1765   [(set_attr "type" "imov")
1766    (set_attr "mode" "QI")])
1768 (define_insn "*movqi_insv_2"
1769   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1770                          (const_int 8)
1771                          (const_int 8))
1772         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1773                      (const_int 8)))]
1774   ""
1775   "mov{b}\t{%h1, %h0|%h0, %h1}"
1776   [(set_attr "type" "imov")
1777    (set_attr "mode" "QI")])
1779 (define_expand "movdi"
1780   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1781         (match_operand:DI 1 "general_operand" ""))]
1782   ""
1783   "ix86_expand_move (DImode, operands); DONE;")
1785 (define_insn "*pushdi"
1786   [(set (match_operand:DI 0 "push_operand" "=<")
1787         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1788   "!TARGET_64BIT"
1789   "#")
1791 (define_insn "*pushdi2_rex64"
1792   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1793         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1794   "TARGET_64BIT"
1795   "@
1796    push{q}\t%1
1797    #"
1798   [(set_attr "type" "push,multi")
1799    (set_attr "mode" "DI")])
1801 ;; Convert impossible pushes of immediate to existing instructions.
1802 ;; First try to get scratch register and go through it.  In case this
1803 ;; fails, push sign extended lower part first and then overwrite
1804 ;; upper part by 32bit move.
1805 (define_peephole2
1806   [(match_scratch:DI 2 "r")
1807    (set (match_operand:DI 0 "push_operand" "")
1808         (match_operand:DI 1 "immediate_operand" ""))]
1809   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1810    && !x86_64_immediate_operand (operands[1], DImode)"
1811   [(set (match_dup 2) (match_dup 1))
1812    (set (match_dup 0) (match_dup 2))]
1813   "")
1815 ;; We need to define this as both peepholer and splitter for case
1816 ;; peephole2 pass is not run.
1817 ;; "&& 1" is needed to keep it from matching the previous pattern.
1818 (define_peephole2
1819   [(set (match_operand:DI 0 "push_operand" "")
1820         (match_operand:DI 1 "immediate_operand" ""))]
1821   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1822    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1823   [(set (match_dup 0) (match_dup 1))
1824    (set (match_dup 2) (match_dup 3))]
1825   "split_di (operands + 1, 1, operands + 2, operands + 3);
1826    operands[1] = gen_lowpart (DImode, operands[2]);
1827    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1828                                                     GEN_INT (4)));
1829   ")
1831 (define_split
1832   [(set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1835    && !symbolic_operand (operands[1], DImode)
1836    && !x86_64_immediate_operand (operands[1], DImode)"
1837   [(set (match_dup 0) (match_dup 1))
1838    (set (match_dup 2) (match_dup 3))]
1839   "split_di (operands + 1, 1, operands + 2, operands + 3);
1840    operands[1] = gen_lowpart (DImode, operands[2]);
1841    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842                                                     GEN_INT (4)));
1843   ")
1845 (define_insn "*pushdi2_prologue_rex64"
1846   [(set (match_operand:DI 0 "push_operand" "=<")
1847         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1848    (clobber (mem:BLK (scratch)))]
1849   "TARGET_64BIT"
1850   "push{q}\t%1"
1851   [(set_attr "type" "push")
1852    (set_attr "mode" "DI")])
1854 (define_insn "*popdi1_epilogue_rex64"
1855   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1856         (mem:DI (reg:DI SP_REG)))
1857    (set (reg:DI SP_REG)
1858         (plus:DI (reg:DI SP_REG) (const_int 8)))
1859    (clobber (mem:BLK (scratch)))]
1860   "TARGET_64BIT"
1861   "pop{q}\t%0"
1862   [(set_attr "type" "pop")
1863    (set_attr "mode" "DI")])
1865 (define_insn "popdi1"
1866   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1867         (mem:DI (reg:DI SP_REG)))
1868    (set (reg:DI SP_REG)
1869         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1870   "TARGET_64BIT"
1871   "pop{q}\t%0"
1872   [(set_attr "type" "pop")
1873    (set_attr "mode" "DI")])
1875 (define_insn "*movdi_xor_rex64"
1876   [(set (match_operand:DI 0 "register_operand" "=r")
1877         (match_operand:DI 1 "const0_operand" "i"))
1878    (clobber (reg:CC FLAGS_REG))]
1879   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1880    && reload_completed"
1881   "xor{l}\t{%k0, %k0|%k0, %k0}"
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "SI")
1884    (set_attr "length_immediate" "0")])
1886 (define_insn "*movdi_or_rex64"
1887   [(set (match_operand:DI 0 "register_operand" "=r")
1888         (match_operand:DI 1 "const_int_operand" "i"))
1889    (clobber (reg:CC FLAGS_REG))]
1890   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1891    && reload_completed
1892    && operands[1] == constm1_rtx"
1894   operands[1] = constm1_rtx;
1895   return "or{q}\t{%1, %0|%0, %1}";
1897   [(set_attr "type" "alu1")
1898    (set_attr "mode" "DI")
1899    (set_attr "length_immediate" "1")])
1901 (define_insn "*movdi_2"
1902   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*x,!*x")
1903         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*x,*x,m"))]
1904   "!TARGET_64BIT
1905    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1906   "@
1907    #
1908    #
1909    movq\t{%1, %0|%0, %1}
1910    movq\t{%1, %0|%0, %1}
1911    movq\t{%1, %0|%0, %1}
1912    movdqa\t{%1, %0|%0, %1}
1913    movq\t{%1, %0|%0, %1}"
1914   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1915    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1917 (define_split
1918   [(set (match_operand:DI 0 "push_operand" "")
1919         (match_operand:DI 1 "general_operand" ""))]
1920   "!TARGET_64BIT && reload_completed
1921    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1922   [(const_int 0)]
1923   "ix86_split_long_move (operands); DONE;")
1925 ;; %%% This multiword shite has got to go.
1926 (define_split
1927   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1928         (match_operand:DI 1 "general_operand" ""))]
1929   "!TARGET_64BIT && reload_completed
1930    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1931    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1932   [(const_int 0)]
1933   "ix86_split_long_move (operands); DONE;")
1935 (define_insn "*movdi_1_rex64"
1936   [(set (match_operand:DI 0 "nonimmediate_operand"
1937                 "=r,r  ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
1938         (match_operand:DI 1 "general_operand"
1939                 "Z ,rem,i,re,n  ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
1940   "TARGET_64BIT
1941    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1942    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1944   switch (get_attr_type (insn))
1945     {
1946     case TYPE_SSECVT:
1947       if (which_alternative == 11)
1948         return "movq2dq\t{%1, %0|%0, %1}";
1949       else
1950         return "movdq2q\t{%1, %0|%0, %1}";
1951     case TYPE_SSEMOV:
1952       if (get_attr_mode (insn) == MODE_TI)
1953           return "movdqa\t{%1, %0|%0, %1}";
1954       /* FALLTHRU */
1955     case TYPE_MMXMOV:
1956       /* Moves from and into integer register is done using movd opcode with
1957          REX prefix.  */
1958       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1959           return "movd\t{%1, %0|%0, %1}";
1960       return "movq\t{%1, %0|%0, %1}";
1961     case TYPE_MULTI:
1962       return "#";
1963     case TYPE_LEA:
1964       return "lea{q}\t{%a1, %0|%0, %a1}";
1965     default:
1966       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1967         abort ();
1968       if (get_attr_mode (insn) == MODE_SI)
1969         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1970       else if (which_alternative == 2)
1971         return "movabs{q}\t{%1, %0|%0, %1}";
1972       else
1973         return "mov{q}\t{%1, %0|%0, %1}";
1974     }
1976   [(set (attr "type")
1977      (cond [(eq_attr "alternative" "5,6,7")
1978               (const_string "mmxmov")
1979             (eq_attr "alternative" "8,9,10")
1980               (const_string "ssemov")
1981             (eq_attr "alternative" "11,12")
1982               (const_string "ssecvt")
1983             (eq_attr "alternative" "4")
1984               (const_string "multi")
1985             (and (ne (symbol_ref "flag_pic") (const_int 0))
1986                  (match_operand:DI 1 "symbolic_operand" ""))
1987               (const_string "lea")
1988            ]
1989            (const_string "imov")))
1990    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1991    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1992    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1994 (define_insn "*movdi_1_rex64_nointerunit"
1995   [(set (match_operand:DI 0 "nonimmediate_operand"
1996                 "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1997         (match_operand:DI 1 "general_operand"
1998                 "Z,rem,i,re,n  ,*y ,*y,m  ,*Y ,*Y,m"))]
1999   "TARGET_64BIT
2000    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2001    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2003   switch (get_attr_type (insn))
2004     {
2005     case TYPE_SSEMOV:
2006       if (get_attr_mode (insn) == MODE_TI)
2007           return "movdqa\t{%1, %0|%0, %1}";
2008       /* FALLTHRU */
2009     case TYPE_MMXMOV:
2010       return "movq\t{%1, %0|%0, %1}";
2011     case TYPE_MULTI:
2012       return "#";
2013     case TYPE_LEA:
2014       return "lea{q}\t{%a1, %0|%0, %a1}";
2015     default:
2016       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2017         abort ();
2018       if (get_attr_mode (insn) == MODE_SI)
2019         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2020       else if (which_alternative == 2)
2021         return "movabs{q}\t{%1, %0|%0, %1}";
2022       else
2023         return "mov{q}\t{%1, %0|%0, %1}";
2024     }
2026   [(set (attr "type")
2027      (cond [(eq_attr "alternative" "5,6,7")
2028               (const_string "mmxmov")
2029             (eq_attr "alternative" "8,9,10")
2030               (const_string "ssemov")
2031             (eq_attr "alternative" "4")
2032               (const_string "multi")
2033             (and (ne (symbol_ref "flag_pic") (const_int 0))
2034                  (match_operand:DI 1 "symbolic_operand" ""))
2035               (const_string "lea")
2036            ]
2037            (const_string "imov")))
2038    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2039    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2040    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsdi_1_rex64"
2046   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2048   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2049   "@
2050    movabs{q}\t{%1, %P0|%P0, %1}
2051    mov{q}\t{%1, %a0|%a0, %1}"
2052   [(set_attr "type" "imov")
2053    (set_attr "modrm" "0,*")
2054    (set_attr "length_address" "8,0")
2055    (set_attr "length_immediate" "0,*")
2056    (set_attr "memory" "store")
2057    (set_attr "mode" "DI")])
2059 (define_insn "*movabsdi_2_rex64"
2060   [(set (match_operand:DI 0 "register_operand" "=a,r")
2061         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2063   "@
2064    movabs{q}\t{%P1, %0|%0, %P1}
2065    mov{q}\t{%a1, %0|%0, %a1}"
2066   [(set_attr "type" "imov")
2067    (set_attr "modrm" "0,*")
2068    (set_attr "length_address" "8,0")
2069    (set_attr "length_immediate" "0")
2070    (set_attr "memory" "load")
2071    (set_attr "mode" "DI")])
2073 ;; Convert impossible stores of immediate to existing instructions.
2074 ;; First try to get scratch register and go through it.  In case this
2075 ;; fails, move by 32bit parts.
2076 (define_peephole2
2077   [(match_scratch:DI 2 "r")
2078    (set (match_operand:DI 0 "memory_operand" "")
2079         (match_operand:DI 1 "immediate_operand" ""))]
2080   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2081    && !x86_64_immediate_operand (operands[1], DImode)"
2082   [(set (match_dup 2) (match_dup 1))
2083    (set (match_dup 0) (match_dup 2))]
2084   "")
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 ;; "&& 1" is needed to keep it from matching the previous pattern.
2089 (define_peephole2
2090   [(set (match_operand:DI 0 "memory_operand" "")
2091         (match_operand:DI 1 "immediate_operand" ""))]
2092   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2093    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2094   [(set (match_dup 2) (match_dup 3))
2095    (set (match_dup 4) (match_dup 5))]
2096   "split_di (operands, 2, operands + 2, operands + 4);")
2098 (define_split
2099   [(set (match_operand:DI 0 "memory_operand" "")
2100         (match_operand:DI 1 "immediate_operand" ""))]
2101   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2102    && !symbolic_operand (operands[1], DImode)
2103    && !x86_64_immediate_operand (operands[1], DImode)"
2104   [(set (match_dup 2) (match_dup 3))
2105    (set (match_dup 4) (match_dup 5))]
2106   "split_di (operands, 2, operands + 2, operands + 4);")
2108 (define_insn "*swapdi_rex64"
2109   [(set (match_operand:DI 0 "register_operand" "+r")
2110         (match_operand:DI 1 "register_operand" "+r"))
2111    (set (match_dup 1)
2112         (match_dup 0))]
2113   "TARGET_64BIT"
2114   "xchg{q}\t%1, %0"
2115   [(set_attr "type" "imov")
2116    (set_attr "mode" "DI")
2117    (set_attr "pent_pair" "np")
2118    (set_attr "athlon_decode" "vector")])
2120 (define_expand "movsf"
2121   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2122         (match_operand:SF 1 "general_operand" ""))]
2123   ""
2124   "ix86_expand_move (SFmode, operands); DONE;")
2126 (define_insn "*pushsf"
2127   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2128         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2129   "!TARGET_64BIT"
2131   switch (which_alternative)
2132     {
2133     case 1:
2134       return "push{l}\t%1";
2136     default:
2137       /* This insn should be already split before reg-stack.  */
2138       abort ();
2139     }
2141   [(set_attr "type" "multi,push,multi")
2142    (set_attr "mode" "SF,SI,SF")])
2144 (define_insn "*pushsf_rex64"
2145   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2146         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2147   "TARGET_64BIT"
2149   switch (which_alternative)
2150     {
2151     case 1:
2152       return "push{q}\t%q1";
2154     default:
2155       /* This insn should be already split before reg-stack.  */
2156       abort ();
2157     }
2159   [(set_attr "type" "multi,push,multi")
2160    (set_attr "mode" "SF,DI,SF")])
2162 (define_split
2163   [(set (match_operand:SF 0 "push_operand" "")
2164         (match_operand:SF 1 "memory_operand" ""))]
2165   "reload_completed
2166    && GET_CODE (operands[1]) == MEM
2167    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2168    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2169   [(set (match_dup 0)
2170         (match_dup 1))]
2171   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2174 ;; %%% Kill this when call knows how to work this out.
2175 (define_split
2176   [(set (match_operand:SF 0 "push_operand" "")
2177         (match_operand:SF 1 "any_fp_register_operand" ""))]
2178   "!TARGET_64BIT"
2179   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2180    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2182 (define_split
2183   [(set (match_operand:SF 0 "push_operand" "")
2184         (match_operand:SF 1 "any_fp_register_operand" ""))]
2185   "TARGET_64BIT"
2186   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2187    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2189 (define_insn "*movsf_1"
2190   [(set (match_operand:SF 0 "nonimmediate_operand"
2191           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2192         (match_operand:SF 1 "general_operand"
2193           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2194   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2195    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2196    && (reload_in_progress || reload_completed
2197        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2198        || GET_CODE (operands[1]) != CONST_DOUBLE
2199        || memory_operand (operands[0], SFmode))" 
2201   switch (which_alternative)
2202     {
2203     case 0:
2204       return output_387_reg_move (insn, operands);
2206     case 1:
2207       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2208         return "fstp%z0\t%y0";
2209       else
2210         return "fst%z0\t%y0";
2212     case 2:
2213       return standard_80387_constant_opcode (operands[1]);
2215     case 3:
2216     case 4:
2217       return "mov{l}\t{%1, %0|%0, %1}";
2218     case 5:
2219       if (get_attr_mode (insn) == MODE_TI)
2220         return "pxor\t%0, %0";
2221       else
2222         return "xorps\t%0, %0";
2223     case 6:
2224       if (get_attr_mode (insn) == MODE_V4SF)
2225         return "movaps\t{%1, %0|%0, %1}";
2226       else
2227         return "movss\t{%1, %0|%0, %1}";
2228     case 7:
2229     case 8:
2230       return "movss\t{%1, %0|%0, %1}";
2232     case 9:
2233     case 10:
2234       return "movd\t{%1, %0|%0, %1}";
2236     case 11:
2237       return "movq\t{%1, %0|%0, %1}";
2239     default:
2240       abort();
2241     }
2243   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2244    (set (attr "mode")
2245         (cond [(eq_attr "alternative" "3,4,9,10")
2246                  (const_string "SI")
2247                (eq_attr "alternative" "5")
2248                  (if_then_else
2249                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2250                                  (const_int 0))
2251                              (ne (symbol_ref "TARGET_SSE2")
2252                                  (const_int 0)))
2253                         (eq (symbol_ref "optimize_size")
2254                             (const_int 0)))
2255                    (const_string "TI")
2256                    (const_string "V4SF"))
2257                /* For architectures resolving dependencies on
2258                   whole SSE registers use APS move to break dependency
2259                   chains, otherwise use short move to avoid extra work. 
2261                   Do the same for architectures resolving dependencies on
2262                   the parts.  While in DF mode it is better to always handle
2263                   just register parts, the SF mode is different due to lack
2264                   of instructions to load just part of the register.  It is
2265                   better to maintain the whole registers in single format
2266                   to avoid problems on using packed logical operations.  */
2267                (eq_attr "alternative" "6")
2268                  (if_then_else
2269                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2270                             (const_int 0))
2271                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2272                             (const_int 0)))
2273                    (const_string "V4SF")
2274                    (const_string "SF"))
2275                (eq_attr "alternative" "11")
2276                  (const_string "DI")]
2277                (const_string "SF")))])
2279 (define_insn "*movsf_1_nointerunit"
2280   [(set (match_operand:SF 0 "nonimmediate_operand"
2281           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!m,!*y")
2282         (match_operand:SF 1 "general_operand"
2283           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,m  ,*y,*y"))]
2284   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2285    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2286    && (reload_in_progress || reload_completed
2287        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288        || GET_CODE (operands[1]) != CONST_DOUBLE
2289        || memory_operand (operands[0], SFmode))" 
2291   switch (which_alternative)
2292     {
2293     case 0:
2294       return output_387_reg_move (insn, operands);
2296     case 1:
2297       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298         return "fstp%z0\t%y0";
2299       else
2300         return "fst%z0\t%y0";
2302     case 2:
2303       return standard_80387_constant_opcode (operands[1]);
2305     case 3:
2306     case 4:
2307       return "mov{l}\t{%1, %0|%0, %1}";
2308     case 5:
2309       if (get_attr_mode (insn) == MODE_TI)
2310         return "pxor\t%0, %0";
2311       else
2312         return "xorps\t%0, %0";
2313     case 6:
2314       if (get_attr_mode (insn) == MODE_V4SF)
2315         return "movaps\t{%1, %0|%0, %1}";
2316       else
2317         return "movss\t{%1, %0|%0, %1}";
2318     case 7:
2319     case 8:
2320       return "movss\t{%1, %0|%0, %1}";
2322     case 9:
2323     case 10:
2324       return "movd\t{%1, %0|%0, %1}";
2326     case 11:
2327       return "movq\t{%1, %0|%0, %1}";
2329     default:
2330       abort();
2331     }
2333   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334    (set (attr "mode")
2335         (cond [(eq_attr "alternative" "3,4,9,10")
2336                  (const_string "SI")
2337                (eq_attr "alternative" "5")
2338                  (if_then_else
2339                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340                                  (const_int 0))
2341                              (ne (symbol_ref "TARGET_SSE2")
2342                                  (const_int 0)))
2343                         (eq (symbol_ref "optimize_size")
2344                             (const_int 0)))
2345                    (const_string "TI")
2346                    (const_string "V4SF"))
2347                /* For architectures resolving dependencies on
2348                   whole SSE registers use APS move to break dependency
2349                   chains, otherwise use short move to avoid extra work. 
2351                   Do the same for architectures resolving dependencies on
2352                   the parts.  While in DF mode it is better to always handle
2353                   just register parts, the SF mode is different due to lack
2354                   of instructions to load just part of the register.  It is
2355                   better to maintain the whole registers in single format
2356                   to avoid problems on using packed logical operations.  */
2357                (eq_attr "alternative" "6")
2358                  (if_then_else
2359                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360                             (const_int 0))
2361                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2362                             (const_int 0)))
2363                    (const_string "V4SF")
2364                    (const_string "SF"))
2365                (eq_attr "alternative" "11")
2366                  (const_string "DI")]
2367                (const_string "SF")))])
2369 (define_insn "*swapsf"
2370   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2371         (match_operand:SF 1 "fp_register_operand" "+f"))
2372    (set (match_dup 1)
2373         (match_dup 0))]
2374   "reload_completed || TARGET_80387"
2376   if (STACK_TOP_P (operands[0]))
2377     return "fxch\t%1";
2378   else
2379     return "fxch\t%0";
2381   [(set_attr "type" "fxch")
2382    (set_attr "mode" "SF")])
2384 (define_expand "movdf"
2385   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386         (match_operand:DF 1 "general_operand" ""))]
2387   ""
2388   "ix86_expand_move (DFmode, operands); DONE;")
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter.  Allow this
2393 ;; pattern for optimize_size too.
2395 (define_insn "*pushdf_nointeger"
2396   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2398   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2400   /* This insn should be already split before reg-stack.  */
2401   abort ();
2403   [(set_attr "type" "multi")
2404    (set_attr "mode" "DF,SI,SI,DF")])
2406 (define_insn "*pushdf_integer"
2407   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2408         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2409   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2411   /* This insn should be already split before reg-stack.  */
2412   abort ();
2414   [(set_attr "type" "multi")
2415    (set_attr "mode" "DF,SI,DF")])
2417 ;; %%% Kill this when call knows how to work this out.
2418 (define_split
2419   [(set (match_operand:DF 0 "push_operand" "")
2420         (match_operand:DF 1 "any_fp_register_operand" ""))]
2421   "!TARGET_64BIT && reload_completed"
2422   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2423    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2424   "")
2426 (define_split
2427   [(set (match_operand:DF 0 "push_operand" "")
2428         (match_operand:DF 1 "any_fp_register_operand" ""))]
2429   "TARGET_64BIT && reload_completed"
2430   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2431    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2432   "")
2434 (define_split
2435   [(set (match_operand:DF 0 "push_operand" "")
2436         (match_operand:DF 1 "general_operand" ""))]
2437   "reload_completed"
2438   [(const_int 0)]
2439   "ix86_split_long_move (operands); DONE;")
2441 ;; Moving is usually shorter when only FP registers are used. This separate
2442 ;; movdf pattern avoids the use of integer registers for FP operations
2443 ;; when optimizing for size.
2445 (define_insn "*movdf_nointeger"
2446   [(set (match_operand:DF 0 "nonimmediate_operand"
2447                                 "=f#x,m  ,f#x,*r  ,o  ,x#f,x#f,x#f  ,m")
2448         (match_operand:DF 1 "general_operand"
2449                                 "fm#x,f#x,G  ,*roF,F*r,C  ,x#f,xHm#f,x#f"))]
2450   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2451    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2452    && (reload_in_progress || reload_completed
2453        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2454        || GET_CODE (operands[1]) != CONST_DOUBLE
2455        || memory_operand (operands[0], DFmode))" 
2457   switch (which_alternative)
2458     {
2459     case 0:
2460       return output_387_reg_move (insn, operands);
2462     case 1:
2463       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2464         return "fstp%z0\t%y0";
2465       else
2466         return "fst%z0\t%y0";
2468     case 2:
2469       return standard_80387_constant_opcode (operands[1]);
2471     case 3:
2472     case 4:
2473       return "#";
2474     case 5:
2475       switch (get_attr_mode (insn))
2476         {
2477         case MODE_V4SF:
2478           return "xorps\t%0, %0";
2479         case MODE_V2DF:
2480           return "xorpd\t%0, %0";
2481         case MODE_TI:
2482           return "pxor\t%0, %0";
2483         default:
2484           abort ();
2485         }
2486     case 6:
2487     case 7:
2488     case 8:
2489       switch (get_attr_mode (insn))
2490         {
2491         case MODE_V4SF:
2492           return "movaps\t{%1, %0|%0, %1}";
2493         case MODE_V2DF:
2494           return "movapd\t{%1, %0|%0, %1}";
2495         case MODE_TI:
2496           return "movdqa\t{%1, %0|%0, %1}";
2497         case MODE_DI:
2498           return "movq\t{%1, %0|%0, %1}";
2499         case MODE_DF:
2500           return "movsd\t{%1, %0|%0, %1}";
2501         case MODE_V1DF:
2502           return "movlpd\t{%1, %0|%0, %1}";
2503         default:
2504           abort ();
2505         }
2507     default:
2508       abort();
2509     }
2511   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2512    (set (attr "mode")
2513         (cond [(eq_attr "alternative" "3,4")
2514                  (const_string "SI")
2516                /* For SSE1, we have many fewer alternatives.  */
2517                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518                  (cond [(eq_attr "alternative" "5,6")
2519                           (if_then_else
2520                             (ne (symbol_ref "optimize_size") (const_int 0))
2521                             (const_string "V4SF")
2522                             (const_string "TI"))
2523                        ]
2524                    (const_string "DI"))
2526                /* xorps is one byte shorter.  */
2527                (eq_attr "alternative" "5")
2528                  (cond [(ne (symbol_ref "optimize_size")
2529                             (const_int 0))
2530                           (const_string "V4SF")
2531                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2532                             (const_int 0))
2533                           (const_string "TI")
2534                        ]
2535                        (const_string "V2DF"))
2537                /* For architectures resolving dependencies on
2538                   whole SSE registers use APD move to break dependency
2539                   chains, otherwise use short move to avoid extra work.
2541                   movaps encodes one byte shorter.  */
2542                (eq_attr "alternative" "6")
2543                  (cond
2544                    [(ne (symbol_ref "optimize_size")
2545                         (const_int 0))
2546                       (const_string "V4SF")
2547                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2548                         (const_int 0))
2549                       (const_string "V2DF")
2550                    ]
2551                    (const_string "DF"))
2552                /* For architectures resolving dependencies on register
2553                   parts we may avoid extra work to zero out upper part
2554                   of register.  */
2555                (eq_attr "alternative" "7")
2556                  (if_then_else
2557                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2558                        (const_int 0))
2559                    (const_string "V1DF")
2560                    (const_string "DF"))
2561               ]
2562               (const_string "DF")))])
2564 (define_insn "*movdf_integer"
2565   [(set (match_operand:DF 0 "nonimmediate_operand"
2566                         "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y#rf,Y#rf,Y#rf ,m")
2567         (match_operand:DF 1 "general_operand"
2568                         "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C   ,Y#rf,Ym#rf,Y#rf"))]
2569   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2570    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2571    && (reload_in_progress || reload_completed
2572        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2573        || GET_CODE (operands[1]) != CONST_DOUBLE
2574        || memory_operand (operands[0], DFmode))" 
2576   switch (which_alternative)
2577     {
2578     case 0:
2579       return output_387_reg_move (insn, operands);
2581     case 1:
2582       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2583         return "fstp%z0\t%y0";
2584       else
2585         return "fst%z0\t%y0";
2587     case 2:
2588       return standard_80387_constant_opcode (operands[1]);
2590     case 3:
2591     case 4:
2592       return "#";
2594     case 5:
2595       switch (get_attr_mode (insn))
2596         {
2597         case MODE_V4SF:
2598           return "xorps\t%0, %0";
2599         case MODE_V2DF:
2600           return "xorpd\t%0, %0";
2601         case MODE_TI:
2602           return "pxor\t%0, %0";
2603         default:
2604           abort ();
2605         }
2606     case 6:
2607     case 7:
2608     case 8:
2609       switch (get_attr_mode (insn))
2610         {
2611         case MODE_V4SF:
2612           return "movaps\t{%1, %0|%0, %1}";
2613         case MODE_V2DF:
2614           return "movapd\t{%1, %0|%0, %1}";
2615         case MODE_TI:
2616           return "movdqa\t{%1, %0|%0, %1}";
2617         case MODE_DI:
2618           return "movq\t{%1, %0|%0, %1}";
2619         case MODE_DF:
2620           return "movsd\t{%1, %0|%0, %1}";
2621         case MODE_V1DF:
2622           return "movlpd\t{%1, %0|%0, %1}";
2623         default:
2624           abort ();
2625         }
2627     default:
2628       abort();
2629     }
2631   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "3,4")
2634                  (const_string "SI")
2636                /* For SSE1, we have many fewer alternatives.  */
2637                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2638                  (cond [(eq_attr "alternative" "5,6")
2639                           (if_then_else
2640                             (ne (symbol_ref "optimize_size") (const_int 0))
2641                             (const_string "V4SF")
2642                             (const_string "TI"))
2643                        ]
2644                    (const_string "DI"))
2646                /* xorps is one byte shorter.  */
2647                (eq_attr "alternative" "5")
2648                  (cond [(ne (symbol_ref "optimize_size")
2649                             (const_int 0))
2650                           (const_string "V4SF")
2651                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2652                             (const_int 0))
2653                           (const_string "TI")
2654                        ]
2655                        (const_string "V2DF"))
2657                /* For architectures resolving dependencies on
2658                   whole SSE registers use APD move to break dependency
2659                   chains, otherwise use short move to avoid extra work.
2661                   movaps encodes one byte shorter.  */
2662                (eq_attr "alternative" "6")
2663                  (cond
2664                    [(ne (symbol_ref "optimize_size")
2665                         (const_int 0))
2666                       (const_string "V4SF")
2667                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668                         (const_int 0))
2669                       (const_string "V2DF")
2670                    ]
2671                    (const_string "DF"))
2672                /* For architectures resolving dependencies on register
2673                   parts we may avoid extra work to zero out upper part
2674                   of register.  */
2675                (eq_attr "alternative" "7")
2676                  (if_then_else
2677                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2678                        (const_int 0))
2679                    (const_string "V1DF")
2680                    (const_string "DF"))
2681               ]
2682               (const_string "DF")))])
2684 (define_split
2685   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2686         (match_operand:DF 1 "general_operand" ""))]
2687   "reload_completed
2688    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2689    && ! (ANY_FP_REG_P (operands[0]) || 
2690          (GET_CODE (operands[0]) == SUBREG
2691           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2692    && ! (ANY_FP_REG_P (operands[1]) || 
2693          (GET_CODE (operands[1]) == SUBREG
2694           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2695   [(const_int 0)]
2696   "ix86_split_long_move (operands); DONE;")
2698 (define_insn "*swapdf"
2699   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2700         (match_operand:DF 1 "fp_register_operand" "+f"))
2701    (set (match_dup 1)
2702         (match_dup 0))]
2703   "reload_completed || TARGET_80387"
2705   if (STACK_TOP_P (operands[0]))
2706     return "fxch\t%1";
2707   else
2708     return "fxch\t%0";
2710   [(set_attr "type" "fxch")
2711    (set_attr "mode" "DF")])
2713 (define_expand "movxf"
2714   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2715         (match_operand:XF 1 "general_operand" ""))]
2716   ""
2717   "ix86_expand_move (XFmode, operands); DONE;")
2719 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2720 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2721 ;; Pushing using integer instructions is longer except for constants
2722 ;; and direct memory references.
2723 ;; (assuming that any given constant is pushed only once, but this ought to be
2724 ;;  handled elsewhere).
2726 (define_insn "*pushxf_nointeger"
2727   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2728         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2729   "optimize_size"
2731   /* This insn should be already split before reg-stack.  */
2732   abort ();
2734   [(set_attr "type" "multi")
2735    (set_attr "mode" "XF,SI,SI")])
2737 (define_insn "*pushxf_integer"
2738   [(set (match_operand:XF 0 "push_operand" "=<,<")
2739         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2740   "!optimize_size"
2742   /* This insn should be already split before reg-stack.  */
2743   abort ();
2745   [(set_attr "type" "multi")
2746    (set_attr "mode" "XF,SI")])
2748 (define_split
2749   [(set (match_operand 0 "push_operand" "")
2750         (match_operand 1 "general_operand" ""))]
2751   "reload_completed
2752    && (GET_MODE (operands[0]) == XFmode
2753        || GET_MODE (operands[0]) == DFmode)
2754    && !ANY_FP_REG_P (operands[1])"
2755   [(const_int 0)]
2756   "ix86_split_long_move (operands); DONE;")
2758 (define_split
2759   [(set (match_operand:XF 0 "push_operand" "")
2760         (match_operand:XF 1 "any_fp_register_operand" ""))]
2761   "!TARGET_64BIT"
2762   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2766 (define_split
2767   [(set (match_operand:XF 0 "push_operand" "")
2768         (match_operand:XF 1 "any_fp_register_operand" ""))]
2769   "TARGET_64BIT"
2770   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2778   "optimize_size
2779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780    && (reload_in_progress || reload_completed
2781        || GET_CODE (operands[1]) != CONST_DOUBLE
2782        || memory_operand (operands[0], XFmode))" 
2784   switch (which_alternative)
2785     {
2786     case 0:
2787       return output_387_reg_move (insn, operands);
2789     case 1:
2790       /* There is no non-popping store to memory for XFmode.  So if
2791          we need one, follow the store with a load.  */
2792       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793         return "fstp%z0\t%y0\;fld%z0\t%y0";
2794       else
2795         return "fstp%z0\t%y0";
2797     case 2:
2798       return standard_80387_constant_opcode (operands[1]);
2800     case 3: case 4:
2801       return "#";
2802     }
2803   abort();
2805   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2806    (set_attr "mode" "XF,XF,XF,SI,SI")])
2808 (define_insn "*movxf_integer"
2809   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2810         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2811   "!optimize_size
2812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2813    && (reload_in_progress || reload_completed
2814        || GET_CODE (operands[1]) != CONST_DOUBLE
2815        || memory_operand (operands[0], XFmode))" 
2817   switch (which_alternative)
2818     {
2819     case 0:
2820       return output_387_reg_move (insn, operands);
2822     case 1:
2823       /* There is no non-popping store to memory for XFmode.  So if
2824          we need one, follow the store with a load.  */
2825       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2826         return "fstp%z0\t%y0\;fld%z0\t%y0";
2827       else
2828         return "fstp%z0\t%y0";
2830     case 2:
2831       return standard_80387_constant_opcode (operands[1]);
2833     case 3: case 4:
2834       return "#";
2835     }
2836   abort();
2838   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839    (set_attr "mode" "XF,XF,XF,SI,SI")])
2841 (define_split
2842   [(set (match_operand 0 "nonimmediate_operand" "")
2843         (match_operand 1 "general_operand" ""))]
2844   "reload_completed
2845    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2846    && GET_MODE (operands[0]) == XFmode
2847    && ! (ANY_FP_REG_P (operands[0]) || 
2848          (GET_CODE (operands[0]) == SUBREG
2849           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2850    && ! (ANY_FP_REG_P (operands[1]) || 
2851          (GET_CODE (operands[1]) == SUBREG
2852           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2853   [(const_int 0)]
2854   "ix86_split_long_move (operands); DONE;")
2856 (define_split
2857   [(set (match_operand 0 "register_operand" "")
2858         (match_operand 1 "memory_operand" ""))]
2859   "reload_completed
2860    && GET_CODE (operands[1]) == MEM
2861    && (GET_MODE (operands[0]) == XFmode
2862        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2863    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2864    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2865   [(set (match_dup 0) (match_dup 1))]
2867   rtx c = get_pool_constant (XEXP (operands[1], 0));
2868   rtx r = operands[0];
2870   if (GET_CODE (r) == SUBREG)
2871     r = SUBREG_REG (r);
2873   if (SSE_REG_P (r))
2874     {
2875       if (!standard_sse_constant_p (c))
2876         FAIL;
2877     }
2878   else if (FP_REG_P (r))
2879     {
2880       if (!standard_80387_constant_p (c))
2881         FAIL;
2882     }
2883   else if (MMX_REG_P (r))
2884     FAIL;
2886   operands[1] = c;
2889 (define_insn "swapxf"
2890   [(set (match_operand:XF 0 "register_operand" "+f")
2891         (match_operand:XF 1 "register_operand" "+f"))
2892    (set (match_dup 1)
2893         (match_dup 0))]
2894   "TARGET_80387"
2896   if (STACK_TOP_P (operands[0]))
2897     return "fxch\t%1";
2898   else
2899     return "fxch\t%0";
2901   [(set_attr "type" "fxch")
2902    (set_attr "mode" "XF")])
2904 ;; Zero extension instructions
2906 (define_expand "zero_extendhisi2"
2907   [(set (match_operand:SI 0 "register_operand" "")
2908      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2909   ""
2911   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2912     {
2913       operands[1] = force_reg (HImode, operands[1]);
2914       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2915       DONE;
2916     }
2919 (define_insn "zero_extendhisi2_and"
2920   [(set (match_operand:SI 0 "register_operand" "=r")
2921      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2922    (clobber (reg:CC FLAGS_REG))]
2923   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2924   "#"
2925   [(set_attr "type" "alu1")
2926    (set_attr "mode" "SI")])
2928 (define_split
2929   [(set (match_operand:SI 0 "register_operand" "")
2930         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2931    (clobber (reg:CC FLAGS_REG))]
2932   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2933   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2934               (clobber (reg:CC FLAGS_REG))])]
2935   "")
2937 (define_insn "*zero_extendhisi2_movzwl"
2938   [(set (match_operand:SI 0 "register_operand" "=r")
2939      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2940   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2941   "movz{wl|x}\t{%1, %0|%0, %1}"
2942   [(set_attr "type" "imovx")
2943    (set_attr "mode" "SI")])
2945 (define_expand "zero_extendqihi2"
2946   [(parallel
2947     [(set (match_operand:HI 0 "register_operand" "")
2948        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2949      (clobber (reg:CC FLAGS_REG))])]
2950   ""
2951   "")
2953 (define_insn "*zero_extendqihi2_and"
2954   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2955      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2956    (clobber (reg:CC FLAGS_REG))]
2957   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2958   "#"
2959   [(set_attr "type" "alu1")
2960    (set_attr "mode" "HI")])
2962 (define_insn "*zero_extendqihi2_movzbw_and"
2963   [(set (match_operand:HI 0 "register_operand" "=r,r")
2964      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2965    (clobber (reg:CC FLAGS_REG))]
2966   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2967   "#"
2968   [(set_attr "type" "imovx,alu1")
2969    (set_attr "mode" "HI")])
2971 (define_insn "*zero_extendqihi2_movzbw"
2972   [(set (match_operand:HI 0 "register_operand" "=r")
2973      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2974   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2975   "movz{bw|x}\t{%1, %0|%0, %1}"
2976   [(set_attr "type" "imovx")
2977    (set_attr "mode" "HI")])
2979 ;; For the movzbw case strip only the clobber
2980 (define_split
2981   [(set (match_operand:HI 0 "register_operand" "")
2982         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2983    (clobber (reg:CC FLAGS_REG))]
2984   "reload_completed 
2985    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2986    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2987   [(set (match_operand:HI 0 "register_operand" "")
2988         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2990 ;; When source and destination does not overlap, clear destination
2991 ;; first and then do the movb
2992 (define_split
2993   [(set (match_operand:HI 0 "register_operand" "")
2994         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed
2997    && ANY_QI_REG_P (operands[0])
2998    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2999    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3000   [(set (match_dup 0) (const_int 0))
3001    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3002   "operands[2] = gen_lowpart (QImode, operands[0]);")
3004 ;; Rest is handled by single and.
3005 (define_split
3006   [(set (match_operand:HI 0 "register_operand" "")
3007         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3008    (clobber (reg:CC FLAGS_REG))]
3009   "reload_completed
3010    && true_regnum (operands[0]) == true_regnum (operands[1])"
3011   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3012               (clobber (reg:CC FLAGS_REG))])]
3013   "")
3015 (define_expand "zero_extendqisi2"
3016   [(parallel
3017     [(set (match_operand:SI 0 "register_operand" "")
3018        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3019      (clobber (reg:CC FLAGS_REG))])]
3020   ""
3021   "")
3023 (define_insn "*zero_extendqisi2_and"
3024   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3025      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3026    (clobber (reg:CC FLAGS_REG))]
3027   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3028   "#"
3029   [(set_attr "type" "alu1")
3030    (set_attr "mode" "SI")])
3032 (define_insn "*zero_extendqisi2_movzbw_and"
3033   [(set (match_operand:SI 0 "register_operand" "=r,r")
3034      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3035    (clobber (reg:CC FLAGS_REG))]
3036   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3037   "#"
3038   [(set_attr "type" "imovx,alu1")
3039    (set_attr "mode" "SI")])
3041 (define_insn "*zero_extendqisi2_movzbw"
3042   [(set (match_operand:SI 0 "register_operand" "=r")
3043      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3044   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3045   "movz{bl|x}\t{%1, %0|%0, %1}"
3046   [(set_attr "type" "imovx")
3047    (set_attr "mode" "SI")])
3049 ;; For the movzbl case strip only the clobber
3050 (define_split
3051   [(set (match_operand:SI 0 "register_operand" "")
3052         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3053    (clobber (reg:CC FLAGS_REG))]
3054   "reload_completed 
3055    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3056    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3057   [(set (match_dup 0)
3058         (zero_extend:SI (match_dup 1)))])
3060 ;; When source and destination does not overlap, clear destination
3061 ;; first and then do the movb
3062 (define_split
3063   [(set (match_operand:SI 0 "register_operand" "")
3064         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3065    (clobber (reg:CC FLAGS_REG))]
3066   "reload_completed
3067    && ANY_QI_REG_P (operands[0])
3068    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3069    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3070    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3071   [(set (match_dup 0) (const_int 0))
3072    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3073   "operands[2] = gen_lowpart (QImode, operands[0]);")
3075 ;; Rest is handled by single and.
3076 (define_split
3077   [(set (match_operand:SI 0 "register_operand" "")
3078         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3079    (clobber (reg:CC FLAGS_REG))]
3080   "reload_completed
3081    && true_regnum (operands[0]) == true_regnum (operands[1])"
3082   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3083               (clobber (reg:CC FLAGS_REG))])]
3084   "")
3086 ;; %%% Kill me once multi-word ops are sane.
3087 (define_expand "zero_extendsidi2"
3088   [(set (match_operand:DI 0 "register_operand" "=r")
3089      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3090   ""
3091   "if (!TARGET_64BIT)
3092      {
3093        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3094        DONE;
3095      }
3096   ")
3098 (define_insn "zero_extendsidi2_32"
3099   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3100         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3101    (clobber (reg:CC FLAGS_REG))]
3102   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3103   "@
3104    #
3105    #
3106    #
3107    movd\t{%1, %0|%0, %1}
3108    movd\t{%1, %0|%0, %1}"
3109   [(set_attr "mode" "SI,SI,SI,DI,TI")
3110    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3112 (define_insn "*zero_extendsidi2_32_1"
3113   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3114         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3115    (clobber (reg:CC FLAGS_REG))]
3116   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3117   "@
3118    #
3119    #
3120    #
3121    movd\t{%1, %0|%0, %1}
3122    movd\t{%1, %0|%0, %1}"
3123   [(set_attr "mode" "SI,SI,SI,DI,TI")
3124    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3126 (define_insn "zero_extendsidi2_rex64"
3127   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3128      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3129   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3130   "@
3131    mov\t{%k1, %k0|%k0, %k1}
3132    #
3133    movd\t{%1, %0|%0, %1}
3134    movd\t{%1, %0|%0, %1}"
3135   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3136    (set_attr "mode" "SI,DI,DI,TI")])
3138 (define_insn "*zero_extendsidi2_rex64_1"
3139   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3140      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3141   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3142   "@
3143    mov\t{%k1, %k0|%k0, %k1}
3144    #
3145    movd\t{%1, %0|%0, %1}
3146    movd\t{%1, %0|%0, %1}"
3147   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3148    (set_attr "mode" "SI,DI,SI,SI")])
3150 (define_split
3151   [(set (match_operand:DI 0 "memory_operand" "")
3152      (zero_extend:DI (match_dup 0)))]
3153   "TARGET_64BIT"
3154   [(set (match_dup 4) (const_int 0))]
3155   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3157 (define_split 
3158   [(set (match_operand:DI 0 "register_operand" "")
3159         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3160    (clobber (reg:CC FLAGS_REG))]
3161   "!TARGET_64BIT && reload_completed
3162    && true_regnum (operands[0]) == true_regnum (operands[1])"
3163   [(set (match_dup 4) (const_int 0))]
3164   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3166 (define_split 
3167   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3168         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3169    (clobber (reg:CC FLAGS_REG))]
3170   "!TARGET_64BIT && reload_completed
3171    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3172   [(set (match_dup 3) (match_dup 1))
3173    (set (match_dup 4) (const_int 0))]
3174   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3176 (define_insn "zero_extendhidi2"
3177   [(set (match_operand:DI 0 "register_operand" "=r,r")
3178      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3179   "TARGET_64BIT"
3180   "@
3181    movz{wl|x}\t{%1, %k0|%k0, %1}
3182    movz{wq|x}\t{%1, %0|%0, %1}"
3183   [(set_attr "type" "imovx")
3184    (set_attr "mode" "SI,DI")])
3186 (define_insn "zero_extendqidi2"
3187   [(set (match_operand:DI 0 "register_operand" "=r,r")
3188      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3189   "TARGET_64BIT"
3190   "@
3191    movz{bl|x}\t{%1, %k0|%k0, %1}
3192    movz{bq|x}\t{%1, %0|%0, %1}"
3193   [(set_attr "type" "imovx")
3194    (set_attr "mode" "SI,DI")])
3196 ;; Sign extension instructions
3198 (define_expand "extendsidi2"
3199   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3200                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3201               (clobber (reg:CC FLAGS_REG))
3202               (clobber (match_scratch:SI 2 ""))])]
3203   ""
3205   if (TARGET_64BIT)
3206     {
3207       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3208       DONE;
3209     }
3212 (define_insn "*extendsidi2_1"
3213   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3214         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3215    (clobber (reg:CC FLAGS_REG))
3216    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3217   "!TARGET_64BIT"
3218   "#")
3220 (define_insn "extendsidi2_rex64"
3221   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3222         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3223   "TARGET_64BIT"
3224   "@
3225    {cltq|cdqe}
3226    movs{lq|x}\t{%1,%0|%0, %1}"
3227   [(set_attr "type" "imovx")
3228    (set_attr "mode" "DI")
3229    (set_attr "prefix_0f" "0")
3230    (set_attr "modrm" "0,1")])
3232 (define_insn "extendhidi2"
3233   [(set (match_operand:DI 0 "register_operand" "=r")
3234         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3235   "TARGET_64BIT"
3236   "movs{wq|x}\t{%1,%0|%0, %1}"
3237   [(set_attr "type" "imovx")
3238    (set_attr "mode" "DI")])
3240 (define_insn "extendqidi2"
3241   [(set (match_operand:DI 0 "register_operand" "=r")
3242         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3243   "TARGET_64BIT"
3244   "movs{bq|x}\t{%1,%0|%0, %1}"
3245    [(set_attr "type" "imovx")
3246     (set_attr "mode" "DI")])
3248 ;; Extend to memory case when source register does die.
3249 (define_split 
3250   [(set (match_operand:DI 0 "memory_operand" "")
3251         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3252    (clobber (reg:CC FLAGS_REG))
3253    (clobber (match_operand:SI 2 "register_operand" ""))]
3254   "(reload_completed
3255     && dead_or_set_p (insn, operands[1])
3256     && !reg_mentioned_p (operands[1], operands[0]))"
3257   [(set (match_dup 3) (match_dup 1))
3258    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3259               (clobber (reg:CC FLAGS_REG))])
3260    (set (match_dup 4) (match_dup 1))]
3261   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3263 ;; Extend to memory case when source register does not die.
3264 (define_split 
3265   [(set (match_operand:DI 0 "memory_operand" "")
3266         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3267    (clobber (reg:CC FLAGS_REG))
3268    (clobber (match_operand:SI 2 "register_operand" ""))]
3269   "reload_completed"
3270   [(const_int 0)]
3272   split_di (&operands[0], 1, &operands[3], &operands[4]);
3274   emit_move_insn (operands[3], operands[1]);
3276   /* Generate a cltd if possible and doing so it profitable.  */
3277   if (true_regnum (operands[1]) == 0
3278       && true_regnum (operands[2]) == 1
3279       && (optimize_size || TARGET_USE_CLTD))
3280     {
3281       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3282     }
3283   else
3284     {
3285       emit_move_insn (operands[2], operands[1]);
3286       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3287     }
3288   emit_move_insn (operands[4], operands[2]);
3289   DONE;
3292 ;; Extend to register case.  Optimize case where source and destination
3293 ;; registers match and cases where we can use cltd.
3294 (define_split 
3295   [(set (match_operand:DI 0 "register_operand" "")
3296         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3297    (clobber (reg:CC FLAGS_REG))
3298    (clobber (match_scratch:SI 2 ""))]
3299   "reload_completed"
3300   [(const_int 0)]
3302   split_di (&operands[0], 1, &operands[3], &operands[4]);
3304   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3305     emit_move_insn (operands[3], operands[1]);
3307   /* Generate a cltd if possible and doing so it profitable.  */
3308   if (true_regnum (operands[3]) == 0
3309       && (optimize_size || TARGET_USE_CLTD))
3310     {
3311       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3312       DONE;
3313     }
3315   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3316     emit_move_insn (operands[4], operands[1]);
3318   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3319   DONE;
3322 (define_insn "extendhisi2"
3323   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3324         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3325   ""
3327   switch (get_attr_prefix_0f (insn))
3328     {
3329     case 0:
3330       return "{cwtl|cwde}";
3331     default:
3332       return "movs{wl|x}\t{%1,%0|%0, %1}";
3333     }
3335   [(set_attr "type" "imovx")
3336    (set_attr "mode" "SI")
3337    (set (attr "prefix_0f")
3338      ;; movsx is short decodable while cwtl is vector decoded.
3339      (if_then_else (and (eq_attr "cpu" "!k6")
3340                         (eq_attr "alternative" "0"))
3341         (const_string "0")
3342         (const_string "1")))
3343    (set (attr "modrm")
3344      (if_then_else (eq_attr "prefix_0f" "0")
3345         (const_string "0")
3346         (const_string "1")))])
3348 (define_insn "*extendhisi2_zext"
3349   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3350         (zero_extend:DI
3351           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3352   "TARGET_64BIT"
3354   switch (get_attr_prefix_0f (insn))
3355     {
3356     case 0:
3357       return "{cwtl|cwde}";
3358     default:
3359       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3360     }
3362   [(set_attr "type" "imovx")
3363    (set_attr "mode" "SI")
3364    (set (attr "prefix_0f")
3365      ;; movsx is short decodable while cwtl is vector decoded.
3366      (if_then_else (and (eq_attr "cpu" "!k6")
3367                         (eq_attr "alternative" "0"))
3368         (const_string "0")
3369         (const_string "1")))
3370    (set (attr "modrm")
3371      (if_then_else (eq_attr "prefix_0f" "0")
3372         (const_string "0")
3373         (const_string "1")))])
3375 (define_insn "extendqihi2"
3376   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3377         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3378   ""
3380   switch (get_attr_prefix_0f (insn))
3381     {
3382     case 0:
3383       return "{cbtw|cbw}";
3384     default:
3385       return "movs{bw|x}\t{%1,%0|%0, %1}";
3386     }
3388   [(set_attr "type" "imovx")
3389    (set_attr "mode" "HI")
3390    (set (attr "prefix_0f")
3391      ;; movsx is short decodable while cwtl is vector decoded.
3392      (if_then_else (and (eq_attr "cpu" "!k6")
3393                         (eq_attr "alternative" "0"))
3394         (const_string "0")
3395         (const_string "1")))
3396    (set (attr "modrm")
3397      (if_then_else (eq_attr "prefix_0f" "0")
3398         (const_string "0")
3399         (const_string "1")))])
3401 (define_insn "extendqisi2"
3402   [(set (match_operand:SI 0 "register_operand" "=r")
3403         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3404   ""
3405   "movs{bl|x}\t{%1,%0|%0, %1}"
3406    [(set_attr "type" "imovx")
3407     (set_attr "mode" "SI")])
3409 (define_insn "*extendqisi2_zext"
3410   [(set (match_operand:DI 0 "register_operand" "=r")
3411         (zero_extend:DI
3412           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3413   "TARGET_64BIT"
3414   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3415    [(set_attr "type" "imovx")
3416     (set_attr "mode" "SI")])
3418 ;; Conversions between float and double.
3420 ;; These are all no-ops in the model used for the 80387.  So just
3421 ;; emit moves.
3423 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3424 (define_insn "*dummy_extendsfdf2"
3425   [(set (match_operand:DF 0 "push_operand" "=<")
3426         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3427   "0"
3428   "#")
3430 (define_split
3431   [(set (match_operand:DF 0 "push_operand" "")
3432         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3433   "!TARGET_64BIT"
3434   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3435    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3437 (define_split
3438   [(set (match_operand:DF 0 "push_operand" "")
3439         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3440   "TARGET_64BIT"
3441   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3442    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3444 (define_insn "*dummy_extendsfxf2"
3445   [(set (match_operand:XF 0 "push_operand" "=<")
3446         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3447   "0"
3448   "#")
3450 (define_split
3451   [(set (match_operand:XF 0 "push_operand" "")
3452         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3453   ""
3454   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3455    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3456   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3458 (define_split
3459   [(set (match_operand:XF 0 "push_operand" "")
3460         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3461   "TARGET_64BIT"
3462   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3463    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3464   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3466 (define_split
3467   [(set (match_operand:XF 0 "push_operand" "")
3468         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3469   ""
3470   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3471    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3472   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3474 (define_split
3475   [(set (match_operand:XF 0 "push_operand" "")
3476         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3477   "TARGET_64BIT"
3478   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3479    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3480   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3482 (define_expand "extendsfdf2"
3483   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3484         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3485   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3487   /* ??? Needed for compress_float_constant since all fp constants
3488      are LEGITIMATE_CONSTANT_P.  */
3489   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3490     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3491   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3492     operands[1] = force_reg (SFmode, operands[1]);
3495 (define_insn "*extendsfdf2_mixed"
3496   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3497         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3498   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3499    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3501   switch (which_alternative)
3502     {
3503     case 0:
3504       return output_387_reg_move (insn, operands);
3506     case 1:
3507       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3508         return "fstp%z0\t%y0";
3509       else
3510         return "fst%z0\t%y0";
3512     case 2:
3513       return "cvtss2sd\t{%1, %0|%0, %1}";
3515     default:
3516       abort ();
3517     }
3519   [(set_attr "type" "fmov,fmov,ssecvt")
3520    (set_attr "mode" "SF,XF,DF")])
3522 (define_insn "*extendsfdf2_sse"
3523   [(set (match_operand:DF 0 "register_operand" "=Y")
3524         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3525   "TARGET_SSE2 && TARGET_SSE_MATH
3526    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3527   "cvtss2sd\t{%1, %0|%0, %1}"
3528   [(set_attr "type" "ssecvt")
3529    (set_attr "mode" "DF")])
3531 (define_insn "*extendsfdf2_i387"
3532   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3533         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3534   "TARGET_80387
3535    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3537   switch (which_alternative)
3538     {
3539     case 0:
3540       return output_387_reg_move (insn, operands);
3542     case 1:
3543       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3544         return "fstp%z0\t%y0";
3545       else
3546         return "fst%z0\t%y0";
3548     default:
3549       abort ();
3550     }
3552   [(set_attr "type" "fmov")
3553    (set_attr "mode" "SF,XF")])
3555 (define_expand "extendsfxf2"
3556   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3557         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3558   "TARGET_80387"
3560   /* ??? Needed for compress_float_constant since all fp constants
3561      are LEGITIMATE_CONSTANT_P.  */
3562   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3563     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3564   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3565     operands[1] = force_reg (SFmode, operands[1]);
3568 (define_insn "*extendsfxf2_i387"
3569   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3570         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3571   "TARGET_80387
3572    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3574   switch (which_alternative)
3575     {
3576     case 0:
3577       return output_387_reg_move (insn, operands);
3579     case 1:
3580       /* There is no non-popping store to memory for XFmode.  So if
3581          we need one, follow the store with a load.  */
3582       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3583         return "fstp%z0\t%y0";
3584       else
3585         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3587     default:
3588       abort ();
3589     }
3591   [(set_attr "type" "fmov")
3592    (set_attr "mode" "SF,XF")])
3594 (define_expand "extenddfxf2"
3595   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3596         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3597   "TARGET_80387"
3599   /* ??? Needed for compress_float_constant since all fp constants
3600      are LEGITIMATE_CONSTANT_P.  */
3601   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3602     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3603   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3604     operands[1] = force_reg (DFmode, operands[1]);
3607 (define_insn "*extenddfxf2_i387"
3608   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3609         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3610   "TARGET_80387
3611    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3613   switch (which_alternative)
3614     {
3615     case 0:
3616       return output_387_reg_move (insn, operands);
3618     case 1:
3619       /* There is no non-popping store to memory for XFmode.  So if
3620          we need one, follow the store with a load.  */
3621       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3622         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3623       else
3624         return "fstp%z0\t%y0";
3626     default:
3627       abort ();
3628     }
3630   [(set_attr "type" "fmov")
3631    (set_attr "mode" "DF,XF")])
3633 ;; %%% This seems bad bad news.
3634 ;; This cannot output into an f-reg because there is no way to be sure
3635 ;; of truncating in that case.  Otherwise this is just like a simple move
3636 ;; insn.  So we pretend we can output to a reg in order to get better
3637 ;; register preferencing, but we really use a stack slot.
3639 ;; Conversion from DFmode to SFmode.
3641 (define_expand "truncdfsf2"
3642   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3643         (float_truncate:SF
3644           (match_operand:DF 1 "nonimmediate_operand" "")))]
3645   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3647   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3648     operands[1] = force_reg (DFmode, operands[1]);
3650   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3651     ;
3652   else if (flag_unsafe_math_optimizations)
3653     ;
3654   else
3655     {
3656       rtx temp = assign_386_stack_local (SFmode, 0);
3657       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3658       DONE;
3659     }
3662 (define_expand "truncdfsf2_with_temp"
3663   [(parallel [(set (match_operand:SF 0 "" "")
3664                    (float_truncate:SF (match_operand:DF 1 "" "")))
3665               (clobber (match_operand:SF 2 "" ""))])]
3666   "")
3668 (define_insn "*truncdfsf_fast_mixed"
3669   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3670         (float_truncate:SF
3671           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3672   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3674   switch (which_alternative)
3675     {
3676     case 0:
3677       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3678         return "fstp%z0\t%y0";
3679       else
3680         return "fst%z0\t%y0";
3681     case 1:
3682       return output_387_reg_move (insn, operands);
3683     case 2:
3684       return "cvtsd2ss\t{%1, %0|%0, %1}";
3685     default:
3686       abort ();
3687     }
3689   [(set_attr "type" "fmov,fmov,ssecvt")
3690    (set_attr "mode" "SF")])
3692 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3693 ;; because nothing we do here is unsafe.
3694 (define_insn "*truncdfsf_fast_sse"
3695   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3696         (float_truncate:SF
3697           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3698   "TARGET_SSE2 && TARGET_SSE_MATH"
3699   "cvtsd2ss\t{%1, %0|%0, %1}"
3700   [(set_attr "type" "ssecvt")
3701    (set_attr "mode" "SF")])
3703 (define_insn "*truncdfsf_fast_i387"
3704   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3705         (float_truncate:SF
3706           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3707   "TARGET_80387 && flag_unsafe_math_optimizations"
3708   "* return output_387_reg_move (insn, operands);"
3709   [(set_attr "type" "fmov")
3710    (set_attr "mode" "SF")])
3712 (define_insn "*truncdfsf_mixed"
3713   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3714         (float_truncate:SF
3715           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3716    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3717   "TARGET_MIX_SSE_I387"
3719   switch (which_alternative)
3720     {
3721     case 0:
3722       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3723         return "fstp%z0\t%y0";
3724       else
3725         return "fst%z0\t%y0";
3726     case 1:
3727       return "#";
3728     case 2:
3729       return "cvtsd2ss\t{%1, %0|%0, %1}";
3730     default:
3731       abort ();
3732     }
3734   [(set_attr "type" "fmov,multi,ssecvt")
3735    (set_attr "mode" "SF")])
3737 (define_insn "*truncdfsf_i387"
3738   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3739         (float_truncate:SF
3740           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3741    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3742   "TARGET_80387"
3744   switch (which_alternative)
3745     {
3746     case 0:
3747       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3748         return "fstp%z0\t%y0";
3749       else
3750         return "fst%z0\t%y0";
3751     case 1:
3752       return "#";
3753     default:
3754       abort ();
3755     }
3757   [(set_attr "type" "fmov,multi")
3758    (set_attr "mode" "SF")])
3760 (define_split
3761   [(set (match_operand:SF 0 "register_operand" "")
3762         (float_truncate:SF
3763          (match_operand:DF 1 "fp_register_operand" "")))
3764    (clobber (match_operand 2 "" ""))]
3765   "reload_completed"
3766   [(set (match_dup 2) (match_dup 1))
3767    (set (match_dup 0) (match_dup 2))]
3769   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3772 ;; Conversion from XFmode to SFmode.
3774 (define_expand "truncxfsf2"
3775   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3776                    (float_truncate:SF
3777                     (match_operand:XF 1 "register_operand" "")))
3778               (clobber (match_dup 2))])]
3779   "TARGET_80387"
3781   if (flag_unsafe_math_optimizations)
3782     {
3783       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3784       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3785       if (reg != operands[0])
3786         emit_move_insn (operands[0], reg);
3787       DONE;
3788     }
3789   else
3790     operands[2] = assign_386_stack_local (SFmode, 0);
3793 (define_insn "*truncxfsf2_mixed"
3794   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3795         (float_truncate:SF
3796          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3797    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3798   "TARGET_MIX_SSE_I387"
3800   switch (which_alternative)
3801     {
3802     case 0:
3803       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3804         return "fstp%z0\t%y0";
3805       else
3806         return "fst%z0\t%y0";
3807     default:
3808       abort();
3809     }
3811   [(set_attr "type" "fmov,multi,multi,multi")
3812    (set_attr "mode" "SF")])
3814 (define_insn "truncxfsf2_i387_noop"
3815   [(set (match_operand:SF 0 "register_operand" "=f")
3816         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3817   "TARGET_80387 && flag_unsafe_math_optimizations"
3819   return output_387_reg_move (insn, operands);
3821   [(set_attr "type" "fmov")
3822    (set_attr "mode" "SF")])
3824 (define_insn "*truncxfsf2_i387"
3825   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3826         (float_truncate:SF
3827          (match_operand:XF 1 "register_operand" "f,f,f")))
3828    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3829   "TARGET_80387"
3831   switch (which_alternative)
3832     {
3833     case 0:
3834       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3835         return "fstp%z0\t%y0";
3836       else
3837         return "fst%z0\t%y0";
3838     default:
3839       abort ();
3840     }
3842   [(set_attr "type" "fmov,multi,multi")
3843    (set_attr "mode" "SF")])
3845 (define_insn "*truncxfsf2_i387_1"
3846   [(set (match_operand:SF 0 "memory_operand" "=m")
3847         (float_truncate:SF
3848          (match_operand:XF 1 "register_operand" "f")))]
3849   "TARGET_80387"
3851   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3852     return "fstp%z0\t%y0";
3853   else
3854     return "fst%z0\t%y0";
3856   [(set_attr "type" "fmov")
3857    (set_attr "mode" "SF")])
3859 (define_split
3860   [(set (match_operand:SF 0 "register_operand" "")
3861         (float_truncate:SF
3862          (match_operand:XF 1 "register_operand" "")))
3863    (clobber (match_operand:SF 2 "memory_operand" ""))]
3864   "TARGET_80387 && reload_completed"
3865   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3866    (set (match_dup 0) (match_dup 2))]
3867   "")
3869 (define_split
3870   [(set (match_operand:SF 0 "memory_operand" "")
3871         (float_truncate:SF
3872          (match_operand:XF 1 "register_operand" "")))
3873    (clobber (match_operand:SF 2 "memory_operand" ""))]
3874   "TARGET_80387"
3875   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3876   "")
3878 ;; Conversion from XFmode to DFmode.
3880 (define_expand "truncxfdf2"
3881   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3882                    (float_truncate:DF
3883                     (match_operand:XF 1 "register_operand" "")))
3884               (clobber (match_dup 2))])]
3885   "TARGET_80387"
3887   if (flag_unsafe_math_optimizations)
3888     {
3889       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3890       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3891       if (reg != operands[0])
3892         emit_move_insn (operands[0], reg);
3893       DONE;
3894     }
3895   else
3896     operands[2] = assign_386_stack_local (DFmode, 0);
3899 (define_insn "*truncxfdf2_mixed"
3900   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3901         (float_truncate:DF
3902          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3903    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3904   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3906   switch (which_alternative)
3907     {
3908     case 0:
3909       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910         return "fstp%z0\t%y0";
3911       else
3912         return "fst%z0\t%y0";
3913     default:
3914       abort();
3915     }
3916   abort ();
3918   [(set_attr "type" "fmov,multi,multi,multi")
3919    (set_attr "mode" "DF")])
3921 (define_insn "truncxfdf2_i387_noop"
3922   [(set (match_operand:DF 0 "register_operand" "=f")
3923         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3924   "TARGET_80387 && flag_unsafe_math_optimizations"
3926   return output_387_reg_move (insn, operands);
3928   [(set_attr "type" "fmov")
3929    (set_attr "mode" "DF")])
3931 (define_insn "*truncxfdf2_i387"
3932   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3933         (float_truncate:DF
3934          (match_operand:XF 1 "register_operand" "f,f,f")))
3935    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3936   "TARGET_80387"
3938   switch (which_alternative)
3939     {
3940     case 0:
3941       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3942         return "fstp%z0\t%y0";
3943       else
3944         return "fst%z0\t%y0";
3945     default:
3946       abort ();
3947     }
3949   [(set_attr "type" "fmov,multi,multi")
3950    (set_attr "mode" "DF")])
3952 (define_insn "*truncxfdf2_i387_1"
3953   [(set (match_operand:DF 0 "memory_operand" "=m")
3954         (float_truncate:DF
3955           (match_operand:XF 1 "register_operand" "f")))]
3956   "TARGET_80387"
3958   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3959     return "fstp%z0\t%y0";
3960   else
3961     return "fst%z0\t%y0";
3963   [(set_attr "type" "fmov")
3964    (set_attr "mode" "DF")])
3966 (define_split
3967   [(set (match_operand:DF 0 "register_operand" "")
3968         (float_truncate:DF
3969          (match_operand:XF 1 "register_operand" "")))
3970    (clobber (match_operand:DF 2 "memory_operand" ""))]
3971   "TARGET_80387 && reload_completed"
3972   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3973    (set (match_dup 0) (match_dup 2))]
3974   "")
3976 (define_split
3977   [(set (match_operand:DF 0 "memory_operand" "")
3978         (float_truncate:DF
3979          (match_operand:XF 1 "register_operand" "")))
3980    (clobber (match_operand:DF 2 "memory_operand" ""))]
3981   "TARGET_80387"
3982   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3983   "")
3985 ;; %%% Break up all these bad boys.
3987 ;; Signed conversion to DImode.
3989 (define_expand "fix_truncxfdi2"
3990   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3991                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3992               (clobber (reg:CC FLAGS_REG))])]
3993   "TARGET_80387"
3994   "")
3996 (define_expand "fix_truncdfdi2"
3997   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3998                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3999               (clobber (reg:CC FLAGS_REG))])]
4000   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
4002   if (TARGET_64BIT && TARGET_SSE2)
4003    {
4004      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4005      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4006      if (out != operands[0])
4007         emit_move_insn (operands[0], out);
4008      DONE;
4009    }
4012 (define_expand "fix_truncsfdi2"
4013   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4014                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4015               (clobber (reg:CC FLAGS_REG))])] 
4016   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
4018   if (TARGET_64BIT && TARGET_SSE)
4019    {
4020      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4021      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4022      if (out != operands[0])
4023         emit_move_insn (operands[0], out);
4024      DONE;
4025    }
4028 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4029 ;; of the machinery.
4030 (define_insn_and_split "*fix_truncdi_i387"
4031   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4032         (fix:DI (match_operand 1 "register_operand" "f,f")))
4033    (clobber (reg:CC FLAGS_REG))]
4034   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4035    && !reload_completed && !reload_in_progress
4036    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4037   "#"
4038   "&& 1"
4039   [(const_int 0)]
4041   ix86_optimize_mode_switching = 1;
4042   operands[2] = assign_386_stack_local (HImode, 1);
4043   operands[3] = assign_386_stack_local (HImode, 2);
4044   if (memory_operand (operands[0], VOIDmode))
4045     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4046                                        operands[2], operands[3]));
4047   else
4048     {
4049       operands[4] = assign_386_stack_local (DImode, 0);
4050       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4051                                            operands[2], operands[3],
4052                                            operands[4]));
4053     }
4054   DONE;
4056   [(set_attr "type" "fistp")
4057    (set_attr "i387_cw" "trunc")
4058    (set_attr "mode" "DI")])
4060 (define_insn "fix_truncdi_nomemory"
4061   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4062         (fix:DI (match_operand 1 "register_operand" "f,f")))
4063    (use (match_operand:HI 2 "memory_operand" "m,m"))
4064    (use (match_operand:HI 3 "memory_operand" "m,m"))
4065    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4066    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4067   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4068    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4069   "#"
4070   [(set_attr "type" "fistp")
4071    (set_attr "i387_cw" "trunc")
4072    (set_attr "mode" "DI")])
4074 (define_insn "fix_truncdi_memory"
4075   [(set (match_operand:DI 0 "memory_operand" "=m")
4076         (fix:DI (match_operand 1 "register_operand" "f")))
4077    (use (match_operand:HI 2 "memory_operand" "m"))
4078    (use (match_operand:HI 3 "memory_operand" "m"))
4079    (clobber (match_scratch:DF 4 "=&1f"))]
4080   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4081    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4082   "* return output_fix_trunc (insn, operands);"
4083   [(set_attr "type" "fistp")
4084    (set_attr "i387_cw" "trunc")
4085    (set_attr "mode" "DI")])
4087 (define_split 
4088   [(set (match_operand:DI 0 "register_operand" "")
4089         (fix:DI (match_operand 1 "register_operand" "")))
4090    (use (match_operand:HI 2 "memory_operand" ""))
4091    (use (match_operand:HI 3 "memory_operand" ""))
4092    (clobber (match_operand:DI 4 "memory_operand" ""))
4093    (clobber (match_scratch 5 ""))]
4094   "reload_completed"
4095   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4096               (use (match_dup 2))
4097               (use (match_dup 3))
4098               (clobber (match_dup 5))])
4099    (set (match_dup 0) (match_dup 4))]
4100   "")
4102 (define_split 
4103   [(set (match_operand:DI 0 "memory_operand" "")
4104         (fix:DI (match_operand 1 "register_operand" "")))
4105    (use (match_operand:HI 2 "memory_operand" ""))
4106    (use (match_operand:HI 3 "memory_operand" ""))
4107    (clobber (match_operand:DI 4 "memory_operand" ""))
4108    (clobber (match_scratch 5 ""))]
4109   "reload_completed"
4110   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4111               (use (match_dup 2))
4112               (use (match_dup 3))
4113               (clobber (match_dup 5))])]
4114   "")
4116 ;; When SSE available, it is always faster to use it!
4117 (define_insn "fix_truncsfdi_sse"
4118   [(set (match_operand:DI 0 "register_operand" "=r,r")
4119         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4120   "TARGET_64BIT && TARGET_SSE"
4121   "cvttss2si{q}\t{%1, %0|%0, %1}"
4122   [(set_attr "type" "sseicvt")
4123    (set_attr "mode" "SF")
4124    (set_attr "athlon_decode" "double,vector")])
4126 ;; Avoid vector decoded form of the instruction.
4127 (define_peephole2
4128   [(match_scratch:SF 2 "x")
4129    (set (match_operand:DI 0 "register_operand" "")
4130         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4131   "TARGET_K8 && !optimize_size"
4132   [(set (match_dup 2) (match_dup 1))
4133    (set (match_dup 0) (fix:DI (match_dup 2)))]
4134   "")
4136 (define_insn "fix_truncdfdi_sse"
4137   [(set (match_operand:DI 0 "register_operand" "=r,r")
4138         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4139   "TARGET_64BIT && TARGET_SSE2"
4140   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4141   [(set_attr "type" "sseicvt,sseicvt")
4142    (set_attr "mode" "DF")
4143    (set_attr "athlon_decode" "double,vector")])
4145 ;; Avoid vector decoded form of the instruction.
4146 (define_peephole2
4147   [(match_scratch:DF 2 "Y")
4148    (set (match_operand:DI 0 "register_operand" "")
4149         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4150   "TARGET_K8 && !optimize_size"
4151   [(set (match_dup 2) (match_dup 1))
4152    (set (match_dup 0) (fix:DI (match_dup 2)))]
4153   "")
4155 ;; Signed conversion to SImode.
4157 (define_expand "fix_truncxfsi2"
4158   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4160               (clobber (reg:CC FLAGS_REG))])]
4161   "TARGET_80387"
4162   "")
4164 (define_expand "fix_truncdfsi2"
4165   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4166                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4167               (clobber (reg:CC FLAGS_REG))])]
4168   "TARGET_80387 || TARGET_SSE2"
4170   if (TARGET_SSE2)
4171    {
4172      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4173      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4174      if (out != operands[0])
4175         emit_move_insn (operands[0], out);
4176      DONE;
4177    }
4180 (define_expand "fix_truncsfsi2"
4181   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4182                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4183               (clobber (reg:CC FLAGS_REG))])] 
4184   "TARGET_80387 || TARGET_SSE"
4186   if (TARGET_SSE)
4187    {
4188      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4189      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4190      if (out != operands[0])
4191         emit_move_insn (operands[0], out);
4192      DONE;
4193    }
4196 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4197 ;; of the machinery.
4198 (define_insn_and_split "*fix_truncsi_i387"
4199   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4200         (fix:SI (match_operand 1 "register_operand" "f,f")))
4201    (clobber (reg:CC FLAGS_REG))]
4202   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4203    && !reload_completed && !reload_in_progress
4204    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4205   "#"
4206   "&& 1"
4207   [(const_int 0)]
4209   ix86_optimize_mode_switching = 1;
4210   operands[2] = assign_386_stack_local (HImode, 1);
4211   operands[3] = assign_386_stack_local (HImode, 2);
4212   if (memory_operand (operands[0], VOIDmode))
4213     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4214                                        operands[2], operands[3]));
4215   else
4216     {
4217       operands[4] = assign_386_stack_local (SImode, 0);
4218       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4219                                            operands[2], operands[3],
4220                                            operands[4]));
4221     }
4222   DONE;
4224   [(set_attr "type" "fistp")
4225    (set_attr "i387_cw" "trunc")
4226    (set_attr "mode" "SI")])
4228 (define_insn "fix_truncsi_nomemory"
4229   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4230         (fix:SI (match_operand 1 "register_operand" "f,f")))
4231    (use (match_operand:HI 2 "memory_operand" "m,m"))
4232    (use (match_operand:HI 3 "memory_operand" "m,m"))
4233    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4234   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4235    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4236   "#"
4237   [(set_attr "type" "fistp")
4238    (set_attr "i387_cw" "trunc")
4239    (set_attr "mode" "SI")])
4241 (define_insn "fix_truncsi_memory"
4242   [(set (match_operand:SI 0 "memory_operand" "=m")
4243         (fix:SI (match_operand 1 "register_operand" "f")))
4244    (use (match_operand:HI 2 "memory_operand" "m"))
4245    (use (match_operand:HI 3 "memory_operand" "m"))]
4246   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4247    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4248   "* return output_fix_trunc (insn, operands);"
4249   [(set_attr "type" "fistp")
4250    (set_attr "i387_cw" "trunc")
4251    (set_attr "mode" "SI")])
4253 ;; When SSE available, it is always faster to use it!
4254 (define_insn "fix_truncsfsi_sse"
4255   [(set (match_operand:SI 0 "register_operand" "=r,r")
4256         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4257   "TARGET_SSE"
4258   "cvttss2si\t{%1, %0|%0, %1}"
4259   [(set_attr "type" "sseicvt")
4260    (set_attr "mode" "DF")
4261    (set_attr "athlon_decode" "double,vector")])
4263 ;; Avoid vector decoded form of the instruction.
4264 (define_peephole2
4265   [(match_scratch:SF 2 "x")
4266    (set (match_operand:SI 0 "register_operand" "")
4267         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4268   "TARGET_K8 && !optimize_size"
4269   [(set (match_dup 2) (match_dup 1))
4270    (set (match_dup 0) (fix:SI (match_dup 2)))]
4271   "")
4273 (define_insn "fix_truncdfsi_sse"
4274   [(set (match_operand:SI 0 "register_operand" "=r,r")
4275         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4276   "TARGET_SSE2"
4277   "cvttsd2si\t{%1, %0|%0, %1}"
4278   [(set_attr "type" "sseicvt")
4279    (set_attr "mode" "DF")
4280    (set_attr "athlon_decode" "double,vector")])
4282 ;; Avoid vector decoded form of the instruction.
4283 (define_peephole2
4284   [(match_scratch:DF 2 "Y")
4285    (set (match_operand:SI 0 "register_operand" "")
4286         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4287   "TARGET_K8 && !optimize_size"
4288   [(set (match_dup 2) (match_dup 1))
4289    (set (match_dup 0) (fix:SI (match_dup 2)))]
4290   "")
4292 (define_split 
4293   [(set (match_operand:SI 0 "register_operand" "")
4294         (fix:SI (match_operand 1 "register_operand" "")))
4295    (use (match_operand:HI 2 "memory_operand" ""))
4296    (use (match_operand:HI 3 "memory_operand" ""))
4297    (clobber (match_operand:SI 4 "memory_operand" ""))]
4298   "reload_completed"
4299   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4300               (use (match_dup 2))
4301               (use (match_dup 3))])
4302    (set (match_dup 0) (match_dup 4))]
4303   "")
4305 (define_split 
4306   [(set (match_operand:SI 0 "memory_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 0) (fix:SI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))])]
4315   "")
4317 ;; Signed conversion to HImode.
4319 (define_expand "fix_truncxfhi2"
4320   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4321                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4322               (clobber (reg:CC FLAGS_REG))])] 
4323   "TARGET_80387"
4324   "")
4326 (define_expand "fix_truncdfhi2"
4327   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4329               (clobber (reg:CC FLAGS_REG))])]
4330   "TARGET_80387 && !TARGET_SSE2"
4331   "")
4333 (define_expand "fix_truncsfhi2"
4334   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4335                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4336                (clobber (reg:CC FLAGS_REG))])]
4337   "TARGET_80387 && !TARGET_SSE"
4338   "")
4340 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4341 ;; of the machinery.
4342 (define_insn_and_split "*fix_trunchi_i387"
4343   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4344         (fix:HI (match_operand 1 "register_operand" "f,f")))
4345    (clobber (reg:CC FLAGS_REG))]
4346   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4347    && !reload_completed && !reload_in_progress
4348    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4349   "#"
4350   "&& 1"
4351   [(const_int 0)]
4353   ix86_optimize_mode_switching = 1;
4354   operands[2] = assign_386_stack_local (HImode, 1);
4355   operands[3] = assign_386_stack_local (HImode, 2);
4356   if (memory_operand (operands[0], VOIDmode))
4357     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4358                                        operands[2], operands[3]));
4359   else
4360     {
4361       operands[4] = assign_386_stack_local (HImode, 0);
4362       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4363                                            operands[2], operands[3],
4364                                            operands[4]));
4365     }
4366   DONE;
4368   [(set_attr "type" "fistp")
4369    (set_attr "i387_cw" "trunc")
4370    (set_attr "mode" "HI")])
4372 (define_insn "fix_trunchi_nomemory"
4373   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4374         (fix:HI (match_operand 1 "register_operand" "f,f")))
4375    (use (match_operand:HI 2 "memory_operand" "m,m"))
4376    (use (match_operand:HI 3 "memory_operand" "m,m"))
4377    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4378   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4379    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4380   "#"
4381   [(set_attr "type" "fistp")
4382    (set_attr "i387_cw" "trunc")
4383    (set_attr "mode" "HI")])
4385 (define_insn "fix_trunchi_memory"
4386   [(set (match_operand:HI 0 "memory_operand" "=m")
4387         (fix:HI (match_operand 1 "register_operand" "f")))
4388    (use (match_operand:HI 2 "memory_operand" "m"))
4389    (use (match_operand:HI 3 "memory_operand" "m"))]
4390   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4391    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4392   "* return output_fix_trunc (insn, operands);"
4393   [(set_attr "type" "fistp")
4394    (set_attr "i387_cw" "trunc")
4395    (set_attr "mode" "HI")])
4397 (define_split 
4398   [(set (match_operand:HI 0 "memory_operand" "")
4399         (fix:HI (match_operand 1 "register_operand" "")))
4400    (use (match_operand:HI 2 "memory_operand" ""))
4401    (use (match_operand:HI 3 "memory_operand" ""))
4402    (clobber (match_operand:HI 4 "memory_operand" ""))]
4403   "reload_completed"
4404   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4405               (use (match_dup 2))
4406               (use (match_dup 3))])]
4407   "")
4409 (define_split 
4410   [(set (match_operand:HI 0 "register_operand" "")
4411         (fix:HI (match_operand 1 "register_operand" "")))
4412    (use (match_operand:HI 2 "memory_operand" ""))
4413    (use (match_operand:HI 3 "memory_operand" ""))
4414    (clobber (match_operand:HI 4 "memory_operand" ""))]
4415   "reload_completed"
4416   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4417               (use (match_dup 2))
4418               (use (match_dup 3))
4419               (clobber (match_dup 4))])
4420    (set (match_dup 0) (match_dup 4))]
4421   "")
4423 (define_insn "x86_fnstcw_1"
4424   [(set (match_operand:HI 0 "memory_operand" "=m")
4425         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4426   "TARGET_80387"
4427   "fnstcw\t%0"
4428   [(set_attr "length" "2")
4429    (set_attr "mode" "HI")
4430    (set_attr "unit" "i387")])
4432 (define_insn "x86_fldcw_1"
4433   [(set (reg:HI FPSR_REG)
4434         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4435   "TARGET_80387"
4436   "fldcw\t%0"
4437   [(set_attr "length" "2")
4438    (set_attr "mode" "HI")
4439    (set_attr "unit" "i387")
4440    (set_attr "athlon_decode" "vector")])
4442 ;; Conversion between fixed point and floating point.
4444 ;; Even though we only accept memory inputs, the backend _really_
4445 ;; wants to be able to do this between registers.
4447 (define_expand "floathisf2"
4448   [(set (match_operand:SF 0 "register_operand" "")
4449         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4450   "TARGET_80387 || TARGET_SSE_MATH"
4452   if (TARGET_SSE_MATH)
4453     {
4454       emit_insn (gen_floatsisf2 (operands[0],
4455                                  convert_to_mode (SImode, operands[1], 0)));
4456       DONE;
4457     }
4460 (define_insn "*floathisf2_i387"
4461   [(set (match_operand:SF 0 "register_operand" "=f,f")
4462         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4463   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4464   "@
4465    fild%z1\t%1
4466    #"
4467   [(set_attr "type" "fmov,multi")
4468    (set_attr "mode" "SF")
4469    (set_attr "fp_int_src" "true")])
4471 (define_expand "floatsisf2"
4472   [(set (match_operand:SF 0 "register_operand" "")
4473         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4474   "TARGET_80387 || TARGET_SSE_MATH"
4475   "")
4477 (define_insn "*floatsisf2_mixed"
4478   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4479         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4480   "TARGET_MIX_SSE_I387"
4481   "@
4482    fild%z1\t%1
4483    #
4484    cvtsi2ss\t{%1, %0|%0, %1}
4485    cvtsi2ss\t{%1, %0|%0, %1}"
4486   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4487    (set_attr "mode" "SF")
4488    (set_attr "athlon_decode" "*,*,vector,double")
4489    (set_attr "fp_int_src" "true")])
4491 (define_insn "*floatsisf2_sse"
4492   [(set (match_operand:SF 0 "register_operand" "=x,x")
4493         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4494   "TARGET_SSE_MATH"
4495   "cvtsi2ss\t{%1, %0|%0, %1}"
4496   [(set_attr "type" "sseicvt")
4497    (set_attr "mode" "SF")
4498    (set_attr "athlon_decode" "vector,double")
4499    (set_attr "fp_int_src" "true")])
4501 (define_insn "*floatsisf2_i387"
4502   [(set (match_operand:SF 0 "register_operand" "=f,f")
4503         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4504   "TARGET_80387"
4505   "@
4506    fild%z1\t%1
4507    #"
4508   [(set_attr "type" "fmov,multi")
4509    (set_attr "mode" "SF")
4510    (set_attr "fp_int_src" "true")])
4512 (define_expand "floatdisf2"
4513   [(set (match_operand:SF 0 "register_operand" "")
4514         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4515   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4516   "")
4518 (define_insn "*floatdisf2_mixed"
4519   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4520         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4521   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4522   "@
4523    fild%z1\t%1
4524    #
4525    cvtsi2ss{q}\t{%1, %0|%0, %1}
4526    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4527   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4528    (set_attr "mode" "SF")
4529    (set_attr "athlon_decode" "*,*,vector,double")
4530    (set_attr "fp_int_src" "true")])
4532 (define_insn "*floatdisf2_sse"
4533   [(set (match_operand:SF 0 "register_operand" "=x,x")
4534         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4535   "TARGET_64BIT && TARGET_SSE_MATH"
4536   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4537   [(set_attr "type" "sseicvt")
4538    (set_attr "mode" "SF")
4539    (set_attr "athlon_decode" "vector,double")
4540    (set_attr "fp_int_src" "true")])
4542 (define_insn "*floatdisf2_i387"
4543   [(set (match_operand:SF 0 "register_operand" "=f,f")
4544         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4545   "TARGET_80387"
4546   "@
4547    fild%z1\t%1
4548    #"
4549   [(set_attr "type" "fmov,multi")
4550    (set_attr "mode" "SF")
4551    (set_attr "fp_int_src" "true")])
4553 (define_expand "floathidf2"
4554   [(set (match_operand:DF 0 "register_operand" "")
4555         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4556   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4558   if (TARGET_SSE2 && TARGET_SSE_MATH)
4559     {
4560       emit_insn (gen_floatsidf2 (operands[0],
4561                                  convert_to_mode (SImode, operands[1], 0)));
4562       DONE;
4563     }
4566 (define_insn "*floathidf2_i387"
4567   [(set (match_operand:DF 0 "register_operand" "=f,f")
4568         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4569   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4570   "@
4571    fild%z1\t%1
4572    #"
4573   [(set_attr "type" "fmov,multi")
4574    (set_attr "mode" "DF")
4575    (set_attr "fp_int_src" "true")])
4577 (define_expand "floatsidf2"
4578   [(set (match_operand:DF 0 "register_operand" "")
4579         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4580   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4581   "")
4583 (define_insn "*floatsidf2_mixed"
4584   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4585         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4586   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4587   "@
4588    fild%z1\t%1
4589    #
4590    cvtsi2sd\t{%1, %0|%0, %1}
4591    cvtsi2sd\t{%1, %0|%0, %1}"
4592   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4593    (set_attr "mode" "DF")
4594    (set_attr "athlon_decode" "*,*,double,direct")
4595    (set_attr "fp_int_src" "true")])
4597 (define_insn "*floatsidf2_sse"
4598   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4599         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4600   "TARGET_SSE2 && TARGET_SSE_MATH"
4601   "cvtsi2sd\t{%1, %0|%0, %1}"
4602   [(set_attr "type" "sseicvt")
4603    (set_attr "mode" "DF")
4604    (set_attr "athlon_decode" "double,direct")
4605    (set_attr "fp_int_src" "true")])
4607 (define_insn "*floatsidf2_i387"
4608   [(set (match_operand:DF 0 "register_operand" "=f,f")
4609         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4610   "TARGET_80387"
4611   "@
4612    fild%z1\t%1
4613    #"
4614   [(set_attr "type" "fmov,multi")
4615    (set_attr "mode" "DF")
4616    (set_attr "fp_int_src" "true")])
4618 (define_expand "floatdidf2"
4619   [(set (match_operand:DF 0 "register_operand" "")
4620         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4621   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4622   "")
4624 (define_insn "*floatdidf2_mixed"
4625   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4626         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4627   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4628   "@
4629    fild%z1\t%1
4630    #
4631    cvtsi2sd{q}\t{%1, %0|%0, %1}
4632    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4633   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4634    (set_attr "mode" "DF")
4635    (set_attr "athlon_decode" "*,*,double,direct")
4636    (set_attr "fp_int_src" "true")])
4638 (define_insn "*floatdidf2_sse"
4639   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4640         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4641   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4642   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4643   [(set_attr "type" "sseicvt")
4644    (set_attr "mode" "DF")
4645    (set_attr "athlon_decode" "double,direct")
4646    (set_attr "fp_int_src" "true")])
4648 (define_insn "*floatdidf2_i387"
4649   [(set (match_operand:DF 0 "register_operand" "=f,f")
4650         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4651   "TARGET_80387"
4652   "@
4653    fild%z1\t%1
4654    #"
4655   [(set_attr "type" "fmov,multi")
4656    (set_attr "mode" "DF")
4657    (set_attr "fp_int_src" "true")])
4659 (define_insn "floathixf2"
4660   [(set (match_operand:XF 0 "register_operand" "=f,f")
4661         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4662   "TARGET_80387"
4663   "@
4664    fild%z1\t%1
4665    #"
4666   [(set_attr "type" "fmov,multi")
4667    (set_attr "mode" "XF")
4668    (set_attr "fp_int_src" "true")])
4670 (define_insn "floatsixf2"
4671   [(set (match_operand:XF 0 "register_operand" "=f,f")
4672         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4673   "TARGET_80387"
4674   "@
4675    fild%z1\t%1
4676    #"
4677   [(set_attr "type" "fmov,multi")
4678    (set_attr "mode" "XF")
4679    (set_attr "fp_int_src" "true")])
4681 (define_insn "floatdixf2"
4682   [(set (match_operand:XF 0 "register_operand" "=f,f")
4683         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4684   "TARGET_80387"
4685   "@
4686    fild%z1\t%1
4687    #"
4688   [(set_attr "type" "fmov,multi")
4689    (set_attr "mode" "XF")
4690    (set_attr "fp_int_src" "true")])
4692 ;; %%% Kill these when reload knows how to do it.
4693 (define_split
4694   [(set (match_operand 0 "fp_register_operand" "")
4695         (float (match_operand 1 "register_operand" "")))]
4696   "reload_completed
4697    && TARGET_80387
4698    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4699   [(const_int 0)]
4701   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4702   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4703   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4704   ix86_free_from_memory (GET_MODE (operands[1]));
4705   DONE;
4708 (define_expand "floatunssisf2"
4709   [(use (match_operand:SF 0 "register_operand" ""))
4710    (use (match_operand:SI 1 "register_operand" ""))]
4711   "!TARGET_64BIT && TARGET_SSE_MATH"
4712   "x86_emit_floatuns (operands); DONE;")
4714 (define_expand "floatunsdisf2"
4715   [(use (match_operand:SF 0 "register_operand" ""))
4716    (use (match_operand:DI 1 "register_operand" ""))]
4717   "TARGET_64BIT && TARGET_SSE_MATH"
4718   "x86_emit_floatuns (operands); DONE;")
4720 (define_expand "floatunsdidf2"
4721   [(use (match_operand:DF 0 "register_operand" ""))
4722    (use (match_operand:DI 1 "register_operand" ""))]
4723   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4724   "x86_emit_floatuns (operands); DONE;")
4726 ;; SSE extract/set expanders
4728 (define_expand "vec_setv2df"
4729   [(match_operand:V2DF 0 "register_operand" "")
4730    (match_operand:DF 1 "register_operand" "")
4731    (match_operand 2 "const_int_operand" "")]
4732   "TARGET_SSE2"
4734   switch (INTVAL (operands[2]))
4735     {
4736     case 0:
4737       emit_insn (gen_sse2_loadlpd (operands[0], operands[0], operands[1]));
4738       break;
4739     case 1:
4740       emit_insn (gen_sse2_loadhpd (operands[0], operands[0], operands[1]));
4741       break;
4742     default:
4743       abort ();
4744     }
4745   DONE;
4748 (define_expand "vec_extractv2df"
4749   [(match_operand:DF 0 "register_operand" "")
4750    (match_operand:V2DF 1 "register_operand" "")
4751    (match_operand 2 "const_int_operand" "")]
4752   "TARGET_SSE2"
4754   switch (INTVAL (operands[2]))
4755     {
4756     case 0:
4757       emit_insn (gen_sse2_storelpd (operands[0], operands[1]));
4758       break;
4759     case 1:
4760       emit_insn (gen_sse2_storehpd (operands[0], operands[1]));
4761       break;
4762     default:
4763       abort ();
4764     }
4765   DONE;
4768 (define_expand "vec_initv2df"
4769   [(match_operand:V2DF 0 "register_operand" "")
4770    (match_operand 1 "" "")]
4771   "TARGET_SSE2"
4773   ix86_expand_vector_init (operands[0], operands[1]);
4774   DONE;
4777 (define_expand "vec_setv4sf"
4778   [(match_operand:V4SF 0 "register_operand" "")
4779    (match_operand:SF 1 "register_operand" "")
4780    (match_operand 2 "const_int_operand" "")]
4781   "TARGET_SSE"
4783   switch (INTVAL (operands[2]))
4784     {
4785     case 0:
4786       emit_insn (gen_sse_movss (operands[0], operands[0],
4787                                 simplify_gen_subreg (V4SFmode, operands[1],
4788                                                      SFmode, 0)));
4789       break;
4790     case 1:
4791       {
4792         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4793         rtx tmp = gen_reg_rtx (V4SFmode);
4795         emit_move_insn (tmp, operands[0]);
4796         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4797         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4798         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4799                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4800       }
4801       break;
4802     case 2:
4803       {
4804         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4805         rtx tmp = gen_reg_rtx (V4SFmode);
4807         emit_move_insn (tmp, operands[0]);
4808         emit_insn (gen_sse_movss (tmp, tmp, op1));
4809         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4810                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4811       }
4812       break;
4813     case 3:
4814       {
4815         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4816         rtx tmp = gen_reg_rtx (V4SFmode);
4818         emit_move_insn (tmp, operands[0]);
4819         emit_insn (gen_sse_movss (tmp, tmp, op1));
4820         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4821                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4822       }
4823       break;
4824     default:
4825       abort ();
4826     }
4827   DONE;
4830 (define_expand "vec_extractv4sf"
4831   [(match_operand:SF 0 "register_operand" "")
4832    (match_operand:V4SF 1 "register_operand" "")
4833    (match_operand 2 "const_int_operand" "")]
4834   "TARGET_SSE"
4836   switch (INTVAL (operands[2]))
4837     {
4838     case 0:
4839       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4840       break;
4841     case 1:
4842       {
4843         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4844         rtx tmp = gen_reg_rtx (V4SFmode);
4846         emit_move_insn (tmp, operands[1]);
4847         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4848                                    const1_rtx));
4849       }
4850       break;
4851     case 2:
4852       {
4853         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4854         rtx tmp = gen_reg_rtx (V4SFmode);
4856         emit_move_insn (tmp, operands[1]);
4857         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4858       }
4859       break;
4860     case 3:
4861       {
4862         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4863         rtx tmp = gen_reg_rtx (V4SFmode);
4865         emit_move_insn (tmp, operands[1]);
4866         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4867                                    GEN_INT (3)));
4868       }
4869       break;
4870     default:
4871       abort ();
4872     }
4873   DONE;
4876 (define_expand "vec_initv4sf"
4877   [(match_operand:V4SF 0 "register_operand" "")
4878    (match_operand 1 "" "")]
4879   "TARGET_SSE"
4881   ix86_expand_vector_init (operands[0], operands[1]);
4882   DONE;
4885 ;; Add instructions
4887 ;; %%% splits for addsidi3
4888 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4889 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4890 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4892 (define_expand "adddi3"
4893   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4894         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4895                  (match_operand:DI 2 "x86_64_general_operand" "")))
4896    (clobber (reg:CC FLAGS_REG))]
4897   ""
4898   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4900 (define_insn "*adddi3_1"
4901   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4902         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4903                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4904    (clobber (reg:CC FLAGS_REG))]
4905   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4906   "#")
4908 (define_split
4909   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4910         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4911                  (match_operand:DI 2 "general_operand" "")))
4912    (clobber (reg:CC FLAGS_REG))]
4913   "!TARGET_64BIT && reload_completed"
4914   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4915                                           UNSPEC_ADD_CARRY))
4916               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4917    (parallel [(set (match_dup 3)
4918                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4919                                      (match_dup 4))
4920                             (match_dup 5)))
4921               (clobber (reg:CC FLAGS_REG))])]
4922   "split_di (operands+0, 1, operands+0, operands+3);
4923    split_di (operands+1, 1, operands+1, operands+4);
4924    split_di (operands+2, 1, operands+2, operands+5);")
4926 (define_insn "adddi3_carry_rex64"
4927   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4928           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4929                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4930                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4931    (clobber (reg:CC FLAGS_REG))]
4932   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4933   "adc{q}\t{%2, %0|%0, %2}"
4934   [(set_attr "type" "alu")
4935    (set_attr "pent_pair" "pu")
4936    (set_attr "mode" "DI")])
4938 (define_insn "*adddi3_cc_rex64"
4939   [(set (reg:CC FLAGS_REG)
4940         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4941                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4942                    UNSPEC_ADD_CARRY))
4943    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4944         (plus:DI (match_dup 1) (match_dup 2)))]
4945   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4946   "add{q}\t{%2, %0|%0, %2}"
4947   [(set_attr "type" "alu")
4948    (set_attr "mode" "DI")])
4950 (define_insn "addqi3_carry"
4951   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4952           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4953                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4954                    (match_operand:QI 2 "general_operand" "qi,qm")))
4955    (clobber (reg:CC FLAGS_REG))]
4956   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4957   "adc{b}\t{%2, %0|%0, %2}"
4958   [(set_attr "type" "alu")
4959    (set_attr "pent_pair" "pu")
4960    (set_attr "mode" "QI")])
4962 (define_insn "addhi3_carry"
4963   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4964           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4965                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4966                    (match_operand:HI 2 "general_operand" "ri,rm")))
4967    (clobber (reg:CC FLAGS_REG))]
4968   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4969   "adc{w}\t{%2, %0|%0, %2}"
4970   [(set_attr "type" "alu")
4971    (set_attr "pent_pair" "pu")
4972    (set_attr "mode" "HI")])
4974 (define_insn "addsi3_carry"
4975   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4976           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4977                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4978                    (match_operand:SI 2 "general_operand" "ri,rm")))
4979    (clobber (reg:CC FLAGS_REG))]
4980   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4981   "adc{l}\t{%2, %0|%0, %2}"
4982   [(set_attr "type" "alu")
4983    (set_attr "pent_pair" "pu")
4984    (set_attr "mode" "SI")])
4986 (define_insn "*addsi3_carry_zext"
4987   [(set (match_operand:DI 0 "register_operand" "=r")
4988           (zero_extend:DI 
4989             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4990                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4991                      (match_operand:SI 2 "general_operand" "rim"))))
4992    (clobber (reg:CC FLAGS_REG))]
4993   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4994   "adc{l}\t{%2, %k0|%k0, %2}"
4995   [(set_attr "type" "alu")
4996    (set_attr "pent_pair" "pu")
4997    (set_attr "mode" "SI")])
4999 (define_insn "*addsi3_cc"
5000   [(set (reg:CC FLAGS_REG)
5001         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5002                     (match_operand:SI 2 "general_operand" "ri,rm")]
5003                    UNSPEC_ADD_CARRY))
5004    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5005         (plus:SI (match_dup 1) (match_dup 2)))]
5006   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5007   "add{l}\t{%2, %0|%0, %2}"
5008   [(set_attr "type" "alu")
5009    (set_attr "mode" "SI")])
5011 (define_insn "addqi3_cc"
5012   [(set (reg:CC FLAGS_REG)
5013         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5014                     (match_operand:QI 2 "general_operand" "qi,qm")]
5015                    UNSPEC_ADD_CARRY))
5016    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5017         (plus:QI (match_dup 1) (match_dup 2)))]
5018   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5019   "add{b}\t{%2, %0|%0, %2}"
5020   [(set_attr "type" "alu")
5021    (set_attr "mode" "QI")])
5023 (define_expand "addsi3"
5024   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5025                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5026                             (match_operand:SI 2 "general_operand" "")))
5027               (clobber (reg:CC FLAGS_REG))])]
5028   ""
5029   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5031 (define_insn "*lea_1"
5032   [(set (match_operand:SI 0 "register_operand" "=r")
5033         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5034   "!TARGET_64BIT"
5035   "lea{l}\t{%a1, %0|%0, %a1}"
5036   [(set_attr "type" "lea")
5037    (set_attr "mode" "SI")])
5039 (define_insn "*lea_1_rex64"
5040   [(set (match_operand:SI 0 "register_operand" "=r")
5041         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5042   "TARGET_64BIT"
5043   "lea{l}\t{%a1, %0|%0, %a1}"
5044   [(set_attr "type" "lea")
5045    (set_attr "mode" "SI")])
5047 (define_insn "*lea_1_zext"
5048   [(set (match_operand:DI 0 "register_operand" "=r")
5049         (zero_extend:DI
5050          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5051   "TARGET_64BIT"
5052   "lea{l}\t{%a1, %k0|%k0, %a1}"
5053   [(set_attr "type" "lea")
5054    (set_attr "mode" "SI")])
5056 (define_insn "*lea_2_rex64"
5057   [(set (match_operand:DI 0 "register_operand" "=r")
5058         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5059   "TARGET_64BIT"
5060   "lea{q}\t{%a1, %0|%0, %a1}"
5061   [(set_attr "type" "lea")
5062    (set_attr "mode" "DI")])
5064 ;; The lea patterns for non-Pmodes needs to be matched by several
5065 ;; insns converted to real lea by splitters.
5067 (define_insn_and_split "*lea_general_1"
5068   [(set (match_operand 0 "register_operand" "=r")
5069         (plus (plus (match_operand 1 "index_register_operand" "l")
5070                     (match_operand 2 "register_operand" "r"))
5071               (match_operand 3 "immediate_operand" "i")))]
5072   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5073     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5074    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5075    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5076    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5077    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5078        || GET_MODE (operands[3]) == VOIDmode)"
5079   "#"
5080   "&& reload_completed"
5081   [(const_int 0)]
5083   rtx pat;
5084   operands[0] = gen_lowpart (SImode, operands[0]);
5085   operands[1] = gen_lowpart (Pmode, operands[1]);
5086   operands[2] = gen_lowpart (Pmode, operands[2]);
5087   operands[3] = gen_lowpart (Pmode, operands[3]);
5088   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5089                       operands[3]);
5090   if (Pmode != SImode)
5091     pat = gen_rtx_SUBREG (SImode, pat, 0);
5092   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5093   DONE;
5095   [(set_attr "type" "lea")
5096    (set_attr "mode" "SI")])
5098 (define_insn_and_split "*lea_general_1_zext"
5099   [(set (match_operand:DI 0 "register_operand" "=r")
5100         (zero_extend:DI
5101           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5102                             (match_operand:SI 2 "register_operand" "r"))
5103                    (match_operand:SI 3 "immediate_operand" "i"))))]
5104   "TARGET_64BIT"
5105   "#"
5106   "&& reload_completed"
5107   [(set (match_dup 0)
5108         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5109                                                      (match_dup 2))
5110                                             (match_dup 3)) 0)))]
5112   operands[1] = gen_lowpart (Pmode, operands[1]);
5113   operands[2] = gen_lowpart (Pmode, operands[2]);
5114   operands[3] = gen_lowpart (Pmode, operands[3]);
5116   [(set_attr "type" "lea")
5117    (set_attr "mode" "SI")])
5119 (define_insn_and_split "*lea_general_2"
5120   [(set (match_operand 0 "register_operand" "=r")
5121         (plus (mult (match_operand 1 "index_register_operand" "l")
5122                     (match_operand 2 "const248_operand" "i"))
5123               (match_operand 3 "nonmemory_operand" "ri")))]
5124   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5125     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5126    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5127    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5128    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5129        || GET_MODE (operands[3]) == VOIDmode)"
5130   "#"
5131   "&& reload_completed"
5132   [(const_int 0)]
5134   rtx pat;
5135   operands[0] = gen_lowpart (SImode, operands[0]);
5136   operands[1] = gen_lowpart (Pmode, operands[1]);
5137   operands[3] = gen_lowpart (Pmode, operands[3]);
5138   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5139                       operands[3]);
5140   if (Pmode != SImode)
5141     pat = gen_rtx_SUBREG (SImode, pat, 0);
5142   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5143   DONE;
5145   [(set_attr "type" "lea")
5146    (set_attr "mode" "SI")])
5148 (define_insn_and_split "*lea_general_2_zext"
5149   [(set (match_operand:DI 0 "register_operand" "=r")
5150         (zero_extend:DI
5151           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5152                             (match_operand:SI 2 "const248_operand" "n"))
5153                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5154   "TARGET_64BIT"
5155   "#"
5156   "&& reload_completed"
5157   [(set (match_dup 0)
5158         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5159                                                      (match_dup 2))
5160                                             (match_dup 3)) 0)))]
5162   operands[1] = gen_lowpart (Pmode, operands[1]);
5163   operands[3] = gen_lowpart (Pmode, operands[3]);
5165   [(set_attr "type" "lea")
5166    (set_attr "mode" "SI")])
5168 (define_insn_and_split "*lea_general_3"
5169   [(set (match_operand 0 "register_operand" "=r")
5170         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5171                           (match_operand 2 "const248_operand" "i"))
5172                     (match_operand 3 "register_operand" "r"))
5173               (match_operand 4 "immediate_operand" "i")))]
5174   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5175     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5176    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5177    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5178    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5179   "#"
5180   "&& reload_completed"
5181   [(const_int 0)]
5183   rtx pat;
5184   operands[0] = gen_lowpart (SImode, operands[0]);
5185   operands[1] = gen_lowpart (Pmode, operands[1]);
5186   operands[3] = gen_lowpart (Pmode, operands[3]);
5187   operands[4] = gen_lowpart (Pmode, operands[4]);
5188   pat = gen_rtx_PLUS (Pmode,
5189                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5190                                                          operands[2]),
5191                                     operands[3]),
5192                       operands[4]);
5193   if (Pmode != SImode)
5194     pat = gen_rtx_SUBREG (SImode, pat, 0);
5195   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5196   DONE;
5198   [(set_attr "type" "lea")
5199    (set_attr "mode" "SI")])
5201 (define_insn_and_split "*lea_general_3_zext"
5202   [(set (match_operand:DI 0 "register_operand" "=r")
5203         (zero_extend:DI
5204           (plus:SI (plus:SI (mult:SI
5205                               (match_operand:SI 1 "index_register_operand" "l")
5206                               (match_operand:SI 2 "const248_operand" "n"))
5207                             (match_operand:SI 3 "register_operand" "r"))
5208                    (match_operand:SI 4 "immediate_operand" "i"))))]
5209   "TARGET_64BIT"
5210   "#"
5211   "&& reload_completed"
5212   [(set (match_dup 0)
5213         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5214                                                               (match_dup 2))
5215                                                      (match_dup 3))
5216                                             (match_dup 4)) 0)))]
5218   operands[1] = gen_lowpart (Pmode, operands[1]);
5219   operands[3] = gen_lowpart (Pmode, operands[3]);
5220   operands[4] = gen_lowpart (Pmode, operands[4]);
5222   [(set_attr "type" "lea")
5223    (set_attr "mode" "SI")])
5225 (define_insn "*adddi_1_rex64"
5226   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5227         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5228                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5229    (clobber (reg:CC FLAGS_REG))]
5230   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5232   switch (get_attr_type (insn))
5233     {
5234     case TYPE_LEA:
5235       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5236       return "lea{q}\t{%a2, %0|%0, %a2}";
5238     case TYPE_INCDEC:
5239       if (! rtx_equal_p (operands[0], operands[1]))
5240         abort ();
5241       if (operands[2] == const1_rtx)
5242         return "inc{q}\t%0";
5243       else if (operands[2] == constm1_rtx)
5244         return "dec{q}\t%0";
5245       else
5246         abort ();
5248     default:
5249       if (! rtx_equal_p (operands[0], operands[1]))
5250         abort ();
5252       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5253          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5254       if (GET_CODE (operands[2]) == CONST_INT
5255           /* Avoid overflows.  */
5256           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5257           && (INTVAL (operands[2]) == 128
5258               || (INTVAL (operands[2]) < 0
5259                   && INTVAL (operands[2]) != -128)))
5260         {
5261           operands[2] = GEN_INT (-INTVAL (operands[2]));
5262           return "sub{q}\t{%2, %0|%0, %2}";
5263         }
5264       return "add{q}\t{%2, %0|%0, %2}";
5265     }
5267   [(set (attr "type")
5268      (cond [(eq_attr "alternative" "2")
5269               (const_string "lea")
5270             ; Current assemblers are broken and do not allow @GOTOFF in
5271             ; ought but a memory context.
5272             (match_operand:DI 2 "pic_symbolic_operand" "")
5273               (const_string "lea")
5274             (match_operand:DI 2 "incdec_operand" "")
5275               (const_string "incdec")
5276            ]
5277            (const_string "alu")))
5278    (set_attr "mode" "DI")])
5280 ;; Convert lea to the lea pattern to avoid flags dependency.
5281 (define_split
5282   [(set (match_operand:DI 0 "register_operand" "")
5283         (plus:DI (match_operand:DI 1 "register_operand" "")
5284                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5285    (clobber (reg:CC FLAGS_REG))]
5286   "TARGET_64BIT && reload_completed
5287    && true_regnum (operands[0]) != true_regnum (operands[1])"
5288   [(set (match_dup 0)
5289         (plus:DI (match_dup 1)
5290                  (match_dup 2)))]
5291   "")
5293 (define_insn "*adddi_2_rex64"
5294   [(set (reg FLAGS_REG)
5295         (compare
5296           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5297                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5298           (const_int 0)))                       
5299    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5300         (plus:DI (match_dup 1) (match_dup 2)))]
5301   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5302    && ix86_binary_operator_ok (PLUS, DImode, operands)
5303    /* Current assemblers are broken and do not allow @GOTOFF in
5304       ought but a memory context.  */
5305    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5307   switch (get_attr_type (insn))
5308     {
5309     case TYPE_INCDEC:
5310       if (! rtx_equal_p (operands[0], operands[1]))
5311         abort ();
5312       if (operands[2] == const1_rtx)
5313         return "inc{q}\t%0";
5314       else if (operands[2] == constm1_rtx)
5315         return "dec{q}\t%0";
5316       else
5317         abort ();
5319     default:
5320       if (! rtx_equal_p (operands[0], operands[1]))
5321         abort ();
5322       /* ???? We ought to handle there the 32bit case too
5323          - do we need new constraint?  */
5324       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5325          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5326       if (GET_CODE (operands[2]) == CONST_INT
5327           /* Avoid overflows.  */
5328           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5329           && (INTVAL (operands[2]) == 128
5330               || (INTVAL (operands[2]) < 0
5331                   && INTVAL (operands[2]) != -128)))
5332         {
5333           operands[2] = GEN_INT (-INTVAL (operands[2]));
5334           return "sub{q}\t{%2, %0|%0, %2}";
5335         }
5336       return "add{q}\t{%2, %0|%0, %2}";
5337     }
5339   [(set (attr "type")
5340      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5341         (const_string "incdec")
5342         (const_string "alu")))
5343    (set_attr "mode" "DI")])
5345 (define_insn "*adddi_3_rex64"
5346   [(set (reg FLAGS_REG)
5347         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5348                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5349    (clobber (match_scratch:DI 0 "=r"))]
5350   "TARGET_64BIT
5351    && ix86_match_ccmode (insn, CCZmode)
5352    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5353    /* Current assemblers are broken and do not allow @GOTOFF in
5354       ought but a memory context.  */
5355    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5357   switch (get_attr_type (insn))
5358     {
5359     case TYPE_INCDEC:
5360       if (! rtx_equal_p (operands[0], operands[1]))
5361         abort ();
5362       if (operands[2] == const1_rtx)
5363         return "inc{q}\t%0";
5364       else if (operands[2] == constm1_rtx)
5365         return "dec{q}\t%0";
5366       else
5367         abort ();
5369     default:
5370       if (! rtx_equal_p (operands[0], operands[1]))
5371         abort ();
5372       /* ???? We ought to handle there the 32bit case too
5373          - do we need new constraint?  */
5374       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5376       if (GET_CODE (operands[2]) == CONST_INT
5377           /* Avoid overflows.  */
5378           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5379           && (INTVAL (operands[2]) == 128
5380               || (INTVAL (operands[2]) < 0
5381                   && INTVAL (operands[2]) != -128)))
5382         {
5383           operands[2] = GEN_INT (-INTVAL (operands[2]));
5384           return "sub{q}\t{%2, %0|%0, %2}";
5385         }
5386       return "add{q}\t{%2, %0|%0, %2}";
5387     }
5389   [(set (attr "type")
5390      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5391         (const_string "incdec")
5392         (const_string "alu")))
5393    (set_attr "mode" "DI")])
5395 ; For comparisons against 1, -1 and 128, we may generate better code
5396 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5397 ; is matched then.  We can't accept general immediate, because for
5398 ; case of overflows,  the result is messed up.
5399 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5400 ; when negated.
5401 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5402 ; only for comparisons not depending on it.
5403 (define_insn "*adddi_4_rex64"
5404   [(set (reg FLAGS_REG)
5405         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5406                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5407    (clobber (match_scratch:DI 0 "=rm"))]
5408   "TARGET_64BIT
5409    &&  ix86_match_ccmode (insn, CCGCmode)"
5411   switch (get_attr_type (insn))
5412     {
5413     case TYPE_INCDEC:
5414       if (operands[2] == constm1_rtx)
5415         return "inc{q}\t%0";
5416       else if (operands[2] == const1_rtx)
5417         return "dec{q}\t%0";
5418       else
5419         abort();
5421     default:
5422       if (! rtx_equal_p (operands[0], operands[1]))
5423         abort ();
5424       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5425          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5426       if ((INTVAL (operands[2]) == -128
5427            || (INTVAL (operands[2]) > 0
5428                && INTVAL (operands[2]) != 128))
5429           /* Avoid overflows.  */
5430           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5431         return "sub{q}\t{%2, %0|%0, %2}";
5432       operands[2] = GEN_INT (-INTVAL (operands[2]));
5433       return "add{q}\t{%2, %0|%0, %2}";
5434     }
5436   [(set (attr "type")
5437      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5438         (const_string "incdec")
5439         (const_string "alu")))
5440    (set_attr "mode" "DI")])
5442 (define_insn "*adddi_5_rex64"
5443   [(set (reg FLAGS_REG)
5444         (compare
5445           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5446                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5447           (const_int 0)))                       
5448    (clobber (match_scratch:DI 0 "=r"))]
5449   "TARGET_64BIT
5450    && ix86_match_ccmode (insn, CCGOCmode)
5451    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5452    /* Current assemblers are broken and do not allow @GOTOFF in
5453       ought but a memory context.  */
5454    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5456   switch (get_attr_type (insn))
5457     {
5458     case TYPE_INCDEC:
5459       if (! rtx_equal_p (operands[0], operands[1]))
5460         abort ();
5461       if (operands[2] == const1_rtx)
5462         return "inc{q}\t%0";
5463       else if (operands[2] == constm1_rtx)
5464         return "dec{q}\t%0";
5465       else
5466         abort();
5468     default:
5469       if (! rtx_equal_p (operands[0], operands[1]))
5470         abort ();
5471       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5472          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5473       if (GET_CODE (operands[2]) == CONST_INT
5474           /* Avoid overflows.  */
5475           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5476           && (INTVAL (operands[2]) == 128
5477               || (INTVAL (operands[2]) < 0
5478                   && INTVAL (operands[2]) != -128)))
5479         {
5480           operands[2] = GEN_INT (-INTVAL (operands[2]));
5481           return "sub{q}\t{%2, %0|%0, %2}";
5482         }
5483       return "add{q}\t{%2, %0|%0, %2}";
5484     }
5486   [(set (attr "type")
5487      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5488         (const_string "incdec")
5489         (const_string "alu")))
5490    (set_attr "mode" "DI")])
5493 (define_insn "*addsi_1"
5494   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5495         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5496                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5497    (clobber (reg:CC FLAGS_REG))]
5498   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5500   switch (get_attr_type (insn))
5501     {
5502     case TYPE_LEA:
5503       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5504       return "lea{l}\t{%a2, %0|%0, %a2}";
5506     case TYPE_INCDEC:
5507       if (! rtx_equal_p (operands[0], operands[1]))
5508         abort ();
5509       if (operands[2] == const1_rtx)
5510         return "inc{l}\t%0";
5511       else if (operands[2] == constm1_rtx)
5512         return "dec{l}\t%0";
5513       else
5514         abort();
5516     default:
5517       if (! rtx_equal_p (operands[0], operands[1]))
5518         abort ();
5520       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5521          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5522       if (GET_CODE (operands[2]) == CONST_INT
5523           && (INTVAL (operands[2]) == 128
5524               || (INTVAL (operands[2]) < 0
5525                   && INTVAL (operands[2]) != -128)))
5526         {
5527           operands[2] = GEN_INT (-INTVAL (operands[2]));
5528           return "sub{l}\t{%2, %0|%0, %2}";
5529         }
5530       return "add{l}\t{%2, %0|%0, %2}";
5531     }
5533   [(set (attr "type")
5534      (cond [(eq_attr "alternative" "2")
5535               (const_string "lea")
5536             ; Current assemblers are broken and do not allow @GOTOFF in
5537             ; ought but a memory context.
5538             (match_operand:SI 2 "pic_symbolic_operand" "")
5539               (const_string "lea")
5540             (match_operand:SI 2 "incdec_operand" "")
5541               (const_string "incdec")
5542            ]
5543            (const_string "alu")))
5544    (set_attr "mode" "SI")])
5546 ;; Convert lea to the lea pattern to avoid flags dependency.
5547 (define_split
5548   [(set (match_operand 0 "register_operand" "")
5549         (plus (match_operand 1 "register_operand" "")
5550               (match_operand 2 "nonmemory_operand" "")))
5551    (clobber (reg:CC FLAGS_REG))]
5552   "reload_completed
5553    && true_regnum (operands[0]) != true_regnum (operands[1])"
5554   [(const_int 0)]
5556   rtx pat;
5557   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5558      may confuse gen_lowpart.  */
5559   if (GET_MODE (operands[0]) != Pmode)
5560     {
5561       operands[1] = gen_lowpart (Pmode, operands[1]);
5562       operands[2] = gen_lowpart (Pmode, operands[2]);
5563     }
5564   operands[0] = gen_lowpart (SImode, operands[0]);
5565   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5566   if (Pmode != SImode)
5567     pat = gen_rtx_SUBREG (SImode, pat, 0);
5568   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5569   DONE;
5572 ;; It may seem that nonimmediate operand is proper one for operand 1.
5573 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5574 ;; we take care in ix86_binary_operator_ok to not allow two memory
5575 ;; operands so proper swapping will be done in reload.  This allow
5576 ;; patterns constructed from addsi_1 to match.
5577 (define_insn "addsi_1_zext"
5578   [(set (match_operand:DI 0 "register_operand" "=r,r")
5579         (zero_extend:DI
5580           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5581                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5582    (clobber (reg:CC FLAGS_REG))]
5583   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5585   switch (get_attr_type (insn))
5586     {
5587     case TYPE_LEA:
5588       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5589       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5591     case TYPE_INCDEC:
5592       if (operands[2] == const1_rtx)
5593         return "inc{l}\t%k0";
5594       else if (operands[2] == constm1_rtx)
5595         return "dec{l}\t%k0";
5596       else
5597         abort();
5599     default:
5600       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5601          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5602       if (GET_CODE (operands[2]) == CONST_INT
5603           && (INTVAL (operands[2]) == 128
5604               || (INTVAL (operands[2]) < 0
5605                   && INTVAL (operands[2]) != -128)))
5606         {
5607           operands[2] = GEN_INT (-INTVAL (operands[2]));
5608           return "sub{l}\t{%2, %k0|%k0, %2}";
5609         }
5610       return "add{l}\t{%2, %k0|%k0, %2}";
5611     }
5613   [(set (attr "type")
5614      (cond [(eq_attr "alternative" "1")
5615               (const_string "lea")
5616             ; Current assemblers are broken and do not allow @GOTOFF in
5617             ; ought but a memory context.
5618             (match_operand:SI 2 "pic_symbolic_operand" "")
5619               (const_string "lea")
5620             (match_operand:SI 2 "incdec_operand" "")
5621               (const_string "incdec")
5622            ]
5623            (const_string "alu")))
5624    (set_attr "mode" "SI")])
5626 ;; Convert lea to the lea pattern to avoid flags dependency.
5627 (define_split
5628   [(set (match_operand:DI 0 "register_operand" "")
5629         (zero_extend:DI
5630           (plus:SI (match_operand:SI 1 "register_operand" "")
5631                    (match_operand:SI 2 "nonmemory_operand" ""))))
5632    (clobber (reg:CC FLAGS_REG))]
5633   "TARGET_64BIT && reload_completed
5634    && true_regnum (operands[0]) != true_regnum (operands[1])"
5635   [(set (match_dup 0)
5636         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5638   operands[1] = gen_lowpart (Pmode, operands[1]);
5639   operands[2] = gen_lowpart (Pmode, operands[2]);
5642 (define_insn "*addsi_2"
5643   [(set (reg FLAGS_REG)
5644         (compare
5645           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5646                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5647           (const_int 0)))                       
5648    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5649         (plus:SI (match_dup 1) (match_dup 2)))]
5650   "ix86_match_ccmode (insn, CCGOCmode)
5651    && ix86_binary_operator_ok (PLUS, SImode, operands)
5652    /* Current assemblers are broken and do not allow @GOTOFF in
5653       ought but a memory context.  */
5654    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5656   switch (get_attr_type (insn))
5657     {
5658     case TYPE_INCDEC:
5659       if (! rtx_equal_p (operands[0], operands[1]))
5660         abort ();
5661       if (operands[2] == const1_rtx)
5662         return "inc{l}\t%0";
5663       else if (operands[2] == constm1_rtx)
5664         return "dec{l}\t%0";
5665       else
5666         abort();
5668     default:
5669       if (! rtx_equal_p (operands[0], operands[1]))
5670         abort ();
5671       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5672          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5673       if (GET_CODE (operands[2]) == CONST_INT
5674           && (INTVAL (operands[2]) == 128
5675               || (INTVAL (operands[2]) < 0
5676                   && INTVAL (operands[2]) != -128)))
5677         {
5678           operands[2] = GEN_INT (-INTVAL (operands[2]));
5679           return "sub{l}\t{%2, %0|%0, %2}";
5680         }
5681       return "add{l}\t{%2, %0|%0, %2}";
5682     }
5684   [(set (attr "type")
5685      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5686         (const_string "incdec")
5687         (const_string "alu")))
5688    (set_attr "mode" "SI")])
5690 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5691 (define_insn "*addsi_2_zext"
5692   [(set (reg FLAGS_REG)
5693         (compare
5694           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5695                    (match_operand:SI 2 "general_operand" "rmni"))
5696           (const_int 0)))                       
5697    (set (match_operand:DI 0 "register_operand" "=r")
5698         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5699   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5700    && ix86_binary_operator_ok (PLUS, SImode, operands)
5701    /* Current assemblers are broken and do not allow @GOTOFF in
5702       ought but a memory context.  */
5703    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5705   switch (get_attr_type (insn))
5706     {
5707     case TYPE_INCDEC:
5708       if (operands[2] == const1_rtx)
5709         return "inc{l}\t%k0";
5710       else if (operands[2] == constm1_rtx)
5711         return "dec{l}\t%k0";
5712       else
5713         abort();
5715     default:
5716       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5717          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5718       if (GET_CODE (operands[2]) == CONST_INT
5719           && (INTVAL (operands[2]) == 128
5720               || (INTVAL (operands[2]) < 0
5721                   && INTVAL (operands[2]) != -128)))
5722         {
5723           operands[2] = GEN_INT (-INTVAL (operands[2]));
5724           return "sub{l}\t{%2, %k0|%k0, %2}";
5725         }
5726       return "add{l}\t{%2, %k0|%k0, %2}";
5727     }
5729   [(set (attr "type")
5730      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5731         (const_string "incdec")
5732         (const_string "alu")))
5733    (set_attr "mode" "SI")])
5735 (define_insn "*addsi_3"
5736   [(set (reg FLAGS_REG)
5737         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5738                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5739    (clobber (match_scratch:SI 0 "=r"))]
5740   "ix86_match_ccmode (insn, CCZmode)
5741    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5742    /* Current assemblers are broken and do not allow @GOTOFF in
5743       ought but a memory context.  */
5744    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5746   switch (get_attr_type (insn))
5747     {
5748     case TYPE_INCDEC:
5749       if (! rtx_equal_p (operands[0], operands[1]))
5750         abort ();
5751       if (operands[2] == const1_rtx)
5752         return "inc{l}\t%0";
5753       else if (operands[2] == constm1_rtx)
5754         return "dec{l}\t%0";
5755       else
5756         abort();
5758     default:
5759       if (! rtx_equal_p (operands[0], operands[1]))
5760         abort ();
5761       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5762          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5763       if (GET_CODE (operands[2]) == CONST_INT
5764           && (INTVAL (operands[2]) == 128
5765               || (INTVAL (operands[2]) < 0
5766                   && INTVAL (operands[2]) != -128)))
5767         {
5768           operands[2] = GEN_INT (-INTVAL (operands[2]));
5769           return "sub{l}\t{%2, %0|%0, %2}";
5770         }
5771       return "add{l}\t{%2, %0|%0, %2}";
5772     }
5774   [(set (attr "type")
5775      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5776         (const_string "incdec")
5777         (const_string "alu")))
5778    (set_attr "mode" "SI")])
5780 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5781 (define_insn "*addsi_3_zext"
5782   [(set (reg FLAGS_REG)
5783         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5784                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5785    (set (match_operand:DI 0 "register_operand" "=r")
5786         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5787   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5788    && ix86_binary_operator_ok (PLUS, SImode, operands)
5789    /* Current assemblers are broken and do not allow @GOTOFF in
5790       ought but a memory context.  */
5791    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5793   switch (get_attr_type (insn))
5794     {
5795     case TYPE_INCDEC:
5796       if (operands[2] == const1_rtx)
5797         return "inc{l}\t%k0";
5798       else if (operands[2] == constm1_rtx)
5799         return "dec{l}\t%k0";
5800       else
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{l}\t{%2, %k0|%k0, %2}";
5813         }
5814       return "add{l}\t{%2, %k0|%k0, %2}";
5815     }
5817   [(set (attr "type")
5818      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5819         (const_string "incdec")
5820         (const_string "alu")))
5821    (set_attr "mode" "SI")])
5823 ; For comparisons against 1, -1 and 128, we may generate better code
5824 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5825 ; is matched then.  We can't accept general immediate, because for
5826 ; case of overflows,  the result is messed up.
5827 ; This pattern also don't hold of 0x80000000, since the value overflows
5828 ; when negated.
5829 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5830 ; only for comparisons not depending on it.
5831 (define_insn "*addsi_4"
5832   [(set (reg FLAGS_REG)
5833         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5834                  (match_operand:SI 2 "const_int_operand" "n")))
5835    (clobber (match_scratch:SI 0 "=rm"))]
5836   "ix86_match_ccmode (insn, CCGCmode)
5837    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5839   switch (get_attr_type (insn))
5840     {
5841     case TYPE_INCDEC:
5842       if (operands[2] == constm1_rtx)
5843         return "inc{l}\t%0";
5844       else if (operands[2] == const1_rtx)
5845         return "dec{l}\t%0";
5846       else
5847         abort();
5849     default:
5850       if (! rtx_equal_p (operands[0], operands[1]))
5851         abort ();
5852       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5853          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5854       if ((INTVAL (operands[2]) == -128
5855            || (INTVAL (operands[2]) > 0
5856                && INTVAL (operands[2]) != 128)))
5857         return "sub{l}\t{%2, %0|%0, %2}";
5858       operands[2] = GEN_INT (-INTVAL (operands[2]));
5859       return "add{l}\t{%2, %0|%0, %2}";
5860     }
5862   [(set (attr "type")
5863      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5864         (const_string "incdec")
5865         (const_string "alu")))
5866    (set_attr "mode" "SI")])
5868 (define_insn "*addsi_5"
5869   [(set (reg FLAGS_REG)
5870         (compare
5871           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5872                    (match_operand:SI 2 "general_operand" "rmni"))
5873           (const_int 0)))                       
5874    (clobber (match_scratch:SI 0 "=r"))]
5875   "ix86_match_ccmode (insn, CCGOCmode)
5876    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5877    /* Current assemblers are broken and do not allow @GOTOFF in
5878       ought but a memory context.  */
5879    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5881   switch (get_attr_type (insn))
5882     {
5883     case TYPE_INCDEC:
5884       if (! rtx_equal_p (operands[0], operands[1]))
5885         abort ();
5886       if (operands[2] == const1_rtx)
5887         return "inc{l}\t%0";
5888       else if (operands[2] == constm1_rtx)
5889         return "dec{l}\t%0";
5890       else
5891         abort();
5893     default:
5894       if (! rtx_equal_p (operands[0], operands[1]))
5895         abort ();
5896       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5897          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5898       if (GET_CODE (operands[2]) == CONST_INT
5899           && (INTVAL (operands[2]) == 128
5900               || (INTVAL (operands[2]) < 0
5901                   && INTVAL (operands[2]) != -128)))
5902         {
5903           operands[2] = GEN_INT (-INTVAL (operands[2]));
5904           return "sub{l}\t{%2, %0|%0, %2}";
5905         }
5906       return "add{l}\t{%2, %0|%0, %2}";
5907     }
5909   [(set (attr "type")
5910      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5911         (const_string "incdec")
5912         (const_string "alu")))
5913    (set_attr "mode" "SI")])
5915 (define_expand "addhi3"
5916   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5917                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5918                             (match_operand:HI 2 "general_operand" "")))
5919               (clobber (reg:CC FLAGS_REG))])]
5920   "TARGET_HIMODE_MATH"
5921   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5923 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5924 ;; type optimizations enabled by define-splits.  This is not important
5925 ;; for PII, and in fact harmful because of partial register stalls.
5927 (define_insn "*addhi_1_lea"
5928   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5929         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5930                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5931    (clobber (reg:CC FLAGS_REG))]
5932   "!TARGET_PARTIAL_REG_STALL
5933    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5935   switch (get_attr_type (insn))
5936     {
5937     case TYPE_LEA:
5938       return "#";
5939     case TYPE_INCDEC:
5940       if (operands[2] == const1_rtx)
5941         return "inc{w}\t%0";
5942       else if (operands[2] == constm1_rtx)
5943         return "dec{w}\t%0";
5944       abort();
5946     default:
5947       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5948          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5949       if (GET_CODE (operands[2]) == CONST_INT
5950           && (INTVAL (operands[2]) == 128
5951               || (INTVAL (operands[2]) < 0
5952                   && INTVAL (operands[2]) != -128)))
5953         {
5954           operands[2] = GEN_INT (-INTVAL (operands[2]));
5955           return "sub{w}\t{%2, %0|%0, %2}";
5956         }
5957       return "add{w}\t{%2, %0|%0, %2}";
5958     }
5960   [(set (attr "type")
5961      (if_then_else (eq_attr "alternative" "2")
5962         (const_string "lea")
5963         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5964            (const_string "incdec")
5965            (const_string "alu"))))
5966    (set_attr "mode" "HI,HI,SI")])
5968 (define_insn "*addhi_1"
5969   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5970         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5971                  (match_operand:HI 2 "general_operand" "ri,rm")))
5972    (clobber (reg:CC FLAGS_REG))]
5973   "TARGET_PARTIAL_REG_STALL
5974    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5976   switch (get_attr_type (insn))
5977     {
5978     case TYPE_INCDEC:
5979       if (operands[2] == const1_rtx)
5980         return "inc{w}\t%0";
5981       else if (operands[2] == constm1_rtx)
5982         return "dec{w}\t%0";
5983       abort();
5985     default:
5986       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5987          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5988       if (GET_CODE (operands[2]) == CONST_INT
5989           && (INTVAL (operands[2]) == 128
5990               || (INTVAL (operands[2]) < 0
5991                   && INTVAL (operands[2]) != -128)))
5992         {
5993           operands[2] = GEN_INT (-INTVAL (operands[2]));
5994           return "sub{w}\t{%2, %0|%0, %2}";
5995         }
5996       return "add{w}\t{%2, %0|%0, %2}";
5997     }
5999   [(set (attr "type")
6000      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6001         (const_string "incdec")
6002         (const_string "alu")))
6003    (set_attr "mode" "HI")])
6005 (define_insn "*addhi_2"
6006   [(set (reg FLAGS_REG)
6007         (compare
6008           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6009                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6010           (const_int 0)))                       
6011    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6012         (plus:HI (match_dup 1) (match_dup 2)))]
6013   "ix86_match_ccmode (insn, CCGOCmode)
6014    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6016   switch (get_attr_type (insn))
6017     {
6018     case TYPE_INCDEC:
6019       if (operands[2] == const1_rtx)
6020         return "inc{w}\t%0";
6021       else if (operands[2] == constm1_rtx)
6022         return "dec{w}\t%0";
6023       abort();
6025     default:
6026       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6027          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6028       if (GET_CODE (operands[2]) == CONST_INT
6029           && (INTVAL (operands[2]) == 128
6030               || (INTVAL (operands[2]) < 0
6031                   && INTVAL (operands[2]) != -128)))
6032         {
6033           operands[2] = GEN_INT (-INTVAL (operands[2]));
6034           return "sub{w}\t{%2, %0|%0, %2}";
6035         }
6036       return "add{w}\t{%2, %0|%0, %2}";
6037     }
6039   [(set (attr "type")
6040      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6041         (const_string "incdec")
6042         (const_string "alu")))
6043    (set_attr "mode" "HI")])
6045 (define_insn "*addhi_3"
6046   [(set (reg FLAGS_REG)
6047         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6048                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6049    (clobber (match_scratch:HI 0 "=r"))]
6050   "ix86_match_ccmode (insn, CCZmode)
6051    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6053   switch (get_attr_type (insn))
6054     {
6055     case TYPE_INCDEC:
6056       if (operands[2] == const1_rtx)
6057         return "inc{w}\t%0";
6058       else if (operands[2] == constm1_rtx)
6059         return "dec{w}\t%0";
6060       abort();
6062     default:
6063       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6065       if (GET_CODE (operands[2]) == CONST_INT
6066           && (INTVAL (operands[2]) == 128
6067               || (INTVAL (operands[2]) < 0
6068                   && INTVAL (operands[2]) != -128)))
6069         {
6070           operands[2] = GEN_INT (-INTVAL (operands[2]));
6071           return "sub{w}\t{%2, %0|%0, %2}";
6072         }
6073       return "add{w}\t{%2, %0|%0, %2}";
6074     }
6076   [(set (attr "type")
6077      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078         (const_string "incdec")
6079         (const_string "alu")))
6080    (set_attr "mode" "HI")])
6082 ; See comments above addsi_3_imm for details.
6083 (define_insn "*addhi_4"
6084   [(set (reg FLAGS_REG)
6085         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6086                  (match_operand:HI 2 "const_int_operand" "n")))
6087    (clobber (match_scratch:HI 0 "=rm"))]
6088   "ix86_match_ccmode (insn, CCGCmode)
6089    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6091   switch (get_attr_type (insn))
6092     {
6093     case TYPE_INCDEC:
6094       if (operands[2] == constm1_rtx)
6095         return "inc{w}\t%0";
6096       else if (operands[2] == const1_rtx)
6097         return "dec{w}\t%0";
6098       else
6099         abort();
6101     default:
6102       if (! rtx_equal_p (operands[0], operands[1]))
6103         abort ();
6104       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6106       if ((INTVAL (operands[2]) == -128
6107            || (INTVAL (operands[2]) > 0
6108                && INTVAL (operands[2]) != 128)))
6109         return "sub{w}\t{%2, %0|%0, %2}";
6110       operands[2] = GEN_INT (-INTVAL (operands[2]));
6111       return "add{w}\t{%2, %0|%0, %2}";
6112     }
6114   [(set (attr "type")
6115      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6116         (const_string "incdec")
6117         (const_string "alu")))
6118    (set_attr "mode" "SI")])
6121 (define_insn "*addhi_5"
6122   [(set (reg FLAGS_REG)
6123         (compare
6124           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6125                    (match_operand:HI 2 "general_operand" "rmni"))
6126           (const_int 0)))                       
6127    (clobber (match_scratch:HI 0 "=r"))]
6128   "ix86_match_ccmode (insn, CCGOCmode)
6129    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6131   switch (get_attr_type (insn))
6132     {
6133     case TYPE_INCDEC:
6134       if (operands[2] == const1_rtx)
6135         return "inc{w}\t%0";
6136       else if (operands[2] == constm1_rtx)
6137         return "dec{w}\t%0";
6138       abort();
6140     default:
6141       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6143       if (GET_CODE (operands[2]) == CONST_INT
6144           && (INTVAL (operands[2]) == 128
6145               || (INTVAL (operands[2]) < 0
6146                   && INTVAL (operands[2]) != -128)))
6147         {
6148           operands[2] = GEN_INT (-INTVAL (operands[2]));
6149           return "sub{w}\t{%2, %0|%0, %2}";
6150         }
6151       return "add{w}\t{%2, %0|%0, %2}";
6152     }
6154   [(set (attr "type")
6155      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6156         (const_string "incdec")
6157         (const_string "alu")))
6158    (set_attr "mode" "HI")])
6160 (define_expand "addqi3"
6161   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6162                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6163                             (match_operand:QI 2 "general_operand" "")))
6164               (clobber (reg:CC FLAGS_REG))])]
6165   "TARGET_QIMODE_MATH"
6166   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6168 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6169 (define_insn "*addqi_1_lea"
6170   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6171         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6172                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6173    (clobber (reg:CC FLAGS_REG))]
6174   "!TARGET_PARTIAL_REG_STALL
6175    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6177   int widen = (which_alternative == 2);
6178   switch (get_attr_type (insn))
6179     {
6180     case TYPE_LEA:
6181       return "#";
6182     case TYPE_INCDEC:
6183       if (operands[2] == const1_rtx)
6184         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6185       else if (operands[2] == constm1_rtx)
6186         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6187       abort();
6189     default:
6190       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6191          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6192       if (GET_CODE (operands[2]) == CONST_INT
6193           && (INTVAL (operands[2]) == 128
6194               || (INTVAL (operands[2]) < 0
6195                   && INTVAL (operands[2]) != -128)))
6196         {
6197           operands[2] = GEN_INT (-INTVAL (operands[2]));
6198           if (widen)
6199             return "sub{l}\t{%2, %k0|%k0, %2}";
6200           else
6201             return "sub{b}\t{%2, %0|%0, %2}";
6202         }
6203       if (widen)
6204         return "add{l}\t{%k2, %k0|%k0, %k2}";
6205       else
6206         return "add{b}\t{%2, %0|%0, %2}";
6207     }
6209   [(set (attr "type")
6210      (if_then_else (eq_attr "alternative" "3")
6211         (const_string "lea")
6212         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6213            (const_string "incdec")
6214            (const_string "alu"))))
6215    (set_attr "mode" "QI,QI,SI,SI")])
6217 (define_insn "*addqi_1"
6218   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6219         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6220                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6221    (clobber (reg:CC FLAGS_REG))]
6222   "TARGET_PARTIAL_REG_STALL
6223    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6225   int widen = (which_alternative == 2);
6226   switch (get_attr_type (insn))
6227     {
6228     case TYPE_INCDEC:
6229       if (operands[2] == const1_rtx)
6230         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6231       else if (operands[2] == constm1_rtx)
6232         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6233       abort();
6235     default:
6236       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6237          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6238       if (GET_CODE (operands[2]) == CONST_INT
6239           && (INTVAL (operands[2]) == 128
6240               || (INTVAL (operands[2]) < 0
6241                   && INTVAL (operands[2]) != -128)))
6242         {
6243           operands[2] = GEN_INT (-INTVAL (operands[2]));
6244           if (widen)
6245             return "sub{l}\t{%2, %k0|%k0, %2}";
6246           else
6247             return "sub{b}\t{%2, %0|%0, %2}";
6248         }
6249       if (widen)
6250         return "add{l}\t{%k2, %k0|%k0, %k2}";
6251       else
6252         return "add{b}\t{%2, %0|%0, %2}";
6253     }
6255   [(set (attr "type")
6256      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6257         (const_string "incdec")
6258         (const_string "alu")))
6259    (set_attr "mode" "QI,QI,SI")])
6261 (define_insn "*addqi_1_slp"
6262   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6263         (plus:QI (match_dup 0)
6264                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6265    (clobber (reg:CC FLAGS_REG))]
6266   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6267    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6269   switch (get_attr_type (insn))
6270     {
6271     case TYPE_INCDEC:
6272       if (operands[1] == const1_rtx)
6273         return "inc{b}\t%0";
6274       else if (operands[1] == constm1_rtx)
6275         return "dec{b}\t%0";
6276       abort();
6278     default:
6279       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6280       if (GET_CODE (operands[1]) == CONST_INT
6281           && INTVAL (operands[1]) < 0)
6282         {
6283           operands[1] = GEN_INT (-INTVAL (operands[1]));
6284           return "sub{b}\t{%1, %0|%0, %1}";
6285         }
6286       return "add{b}\t{%1, %0|%0, %1}";
6287     }
6289   [(set (attr "type")
6290      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6291         (const_string "incdec")
6292         (const_string "alu1")))
6293    (set_attr "mode" "QI")])
6295 (define_insn "*addqi_2"
6296   [(set (reg FLAGS_REG)
6297         (compare
6298           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6299                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6300           (const_int 0)))
6301    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6302         (plus:QI (match_dup 1) (match_dup 2)))]
6303   "ix86_match_ccmode (insn, CCGOCmode)
6304    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6306   switch (get_attr_type (insn))
6307     {
6308     case TYPE_INCDEC:
6309       if (operands[2] == const1_rtx)
6310         return "inc{b}\t%0";
6311       else if (operands[2] == constm1_rtx
6312                || (GET_CODE (operands[2]) == CONST_INT
6313                    && INTVAL (operands[2]) == 255))
6314         return "dec{b}\t%0";
6315       abort();
6317     default:
6318       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6319       if (GET_CODE (operands[2]) == CONST_INT
6320           && INTVAL (operands[2]) < 0)
6321         {
6322           operands[2] = GEN_INT (-INTVAL (operands[2]));
6323           return "sub{b}\t{%2, %0|%0, %2}";
6324         }
6325       return "add{b}\t{%2, %0|%0, %2}";
6326     }
6328   [(set (attr "type")
6329      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6330         (const_string "incdec")
6331         (const_string "alu")))
6332    (set_attr "mode" "QI")])
6334 (define_insn "*addqi_3"
6335   [(set (reg FLAGS_REG)
6336         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6337                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6338    (clobber (match_scratch:QI 0 "=q"))]
6339   "ix86_match_ccmode (insn, CCZmode)
6340    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6342   switch (get_attr_type (insn))
6343     {
6344     case TYPE_INCDEC:
6345       if (operands[2] == const1_rtx)
6346         return "inc{b}\t%0";
6347       else if (operands[2] == constm1_rtx
6348                || (GET_CODE (operands[2]) == CONST_INT
6349                    && INTVAL (operands[2]) == 255))
6350         return "dec{b}\t%0";
6351       abort();
6353     default:
6354       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6355       if (GET_CODE (operands[2]) == CONST_INT
6356           && INTVAL (operands[2]) < 0)
6357         {
6358           operands[2] = GEN_INT (-INTVAL (operands[2]));
6359           return "sub{b}\t{%2, %0|%0, %2}";
6360         }
6361       return "add{b}\t{%2, %0|%0, %2}";
6362     }
6364   [(set (attr "type")
6365      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6366         (const_string "incdec")
6367         (const_string "alu")))
6368    (set_attr "mode" "QI")])
6370 ; See comments above addsi_3_imm for details.
6371 (define_insn "*addqi_4"
6372   [(set (reg FLAGS_REG)
6373         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6374                  (match_operand:QI 2 "const_int_operand" "n")))
6375    (clobber (match_scratch:QI 0 "=qm"))]
6376   "ix86_match_ccmode (insn, CCGCmode)
6377    && (INTVAL (operands[2]) & 0xff) != 0x80"
6379   switch (get_attr_type (insn))
6380     {
6381     case TYPE_INCDEC:
6382       if (operands[2] == constm1_rtx
6383           || (GET_CODE (operands[2]) == CONST_INT
6384               && INTVAL (operands[2]) == 255))
6385         return "inc{b}\t%0";
6386       else if (operands[2] == const1_rtx)
6387         return "dec{b}\t%0";
6388       else
6389         abort();
6391     default:
6392       if (! rtx_equal_p (operands[0], operands[1]))
6393         abort ();
6394       if (INTVAL (operands[2]) < 0)
6395         {
6396           operands[2] = GEN_INT (-INTVAL (operands[2]));
6397           return "add{b}\t{%2, %0|%0, %2}";
6398         }
6399       return "sub{b}\t{%2, %0|%0, %2}";
6400     }
6402   [(set (attr "type")
6403      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6404         (const_string "incdec")
6405         (const_string "alu")))
6406    (set_attr "mode" "QI")])
6409 (define_insn "*addqi_5"
6410   [(set (reg FLAGS_REG)
6411         (compare
6412           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6413                    (match_operand:QI 2 "general_operand" "qmni"))
6414           (const_int 0)))
6415    (clobber (match_scratch:QI 0 "=q"))]
6416   "ix86_match_ccmode (insn, CCGOCmode)
6417    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6419   switch (get_attr_type (insn))
6420     {
6421     case TYPE_INCDEC:
6422       if (operands[2] == const1_rtx)
6423         return "inc{b}\t%0";
6424       else if (operands[2] == constm1_rtx
6425                || (GET_CODE (operands[2]) == CONST_INT
6426                    && INTVAL (operands[2]) == 255))
6427         return "dec{b}\t%0";
6428       abort();
6430     default:
6431       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6432       if (GET_CODE (operands[2]) == CONST_INT
6433           && INTVAL (operands[2]) < 0)
6434         {
6435           operands[2] = GEN_INT (-INTVAL (operands[2]));
6436           return "sub{b}\t{%2, %0|%0, %2}";
6437         }
6438       return "add{b}\t{%2, %0|%0, %2}";
6439     }
6441   [(set (attr "type")
6442      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6443         (const_string "incdec")
6444         (const_string "alu")))
6445    (set_attr "mode" "QI")])
6448 (define_insn "addqi_ext_1"
6449   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6450                          (const_int 8)
6451                          (const_int 8))
6452         (plus:SI
6453           (zero_extract:SI
6454             (match_operand 1 "ext_register_operand" "0")
6455             (const_int 8)
6456             (const_int 8))
6457           (match_operand:QI 2 "general_operand" "Qmn")))
6458    (clobber (reg:CC FLAGS_REG))]
6459   "!TARGET_64BIT"
6461   switch (get_attr_type (insn))
6462     {
6463     case TYPE_INCDEC:
6464       if (operands[2] == const1_rtx)
6465         return "inc{b}\t%h0";
6466       else if (operands[2] == constm1_rtx
6467                || (GET_CODE (operands[2]) == CONST_INT
6468                    && INTVAL (operands[2]) == 255))
6469         return "dec{b}\t%h0";
6470       abort();
6472     default:
6473       return "add{b}\t{%2, %h0|%h0, %2}";
6474     }
6476   [(set (attr "type")
6477      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6478         (const_string "incdec")
6479         (const_string "alu")))
6480    (set_attr "mode" "QI")])
6482 (define_insn "*addqi_ext_1_rex64"
6483   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6484                          (const_int 8)
6485                          (const_int 8))
6486         (plus:SI
6487           (zero_extract:SI
6488             (match_operand 1 "ext_register_operand" "0")
6489             (const_int 8)
6490             (const_int 8))
6491           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6492    (clobber (reg:CC FLAGS_REG))]
6493   "TARGET_64BIT"
6495   switch (get_attr_type (insn))
6496     {
6497     case TYPE_INCDEC:
6498       if (operands[2] == const1_rtx)
6499         return "inc{b}\t%h0";
6500       else if (operands[2] == constm1_rtx
6501                || (GET_CODE (operands[2]) == CONST_INT
6502                    && INTVAL (operands[2]) == 255))
6503         return "dec{b}\t%h0";
6504       abort();
6506     default:
6507       return "add{b}\t{%2, %h0|%h0, %2}";
6508     }
6510   [(set (attr "type")
6511      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6512         (const_string "incdec")
6513         (const_string "alu")))
6514    (set_attr "mode" "QI")])
6516 (define_insn "*addqi_ext_2"
6517   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6518                          (const_int 8)
6519                          (const_int 8))
6520         (plus:SI
6521           (zero_extract:SI
6522             (match_operand 1 "ext_register_operand" "%0")
6523             (const_int 8)
6524             (const_int 8))
6525           (zero_extract:SI
6526             (match_operand 2 "ext_register_operand" "Q")
6527             (const_int 8)
6528             (const_int 8))))
6529    (clobber (reg:CC FLAGS_REG))]
6530   ""
6531   "add{b}\t{%h2, %h0|%h0, %h2}"
6532   [(set_attr "type" "alu")
6533    (set_attr "mode" "QI")])
6535 ;; The patterns that match these are at the end of this file.
6537 (define_expand "addxf3"
6538   [(set (match_operand:XF 0 "register_operand" "")
6539         (plus:XF (match_operand:XF 1 "register_operand" "")
6540                  (match_operand:XF 2 "register_operand" "")))]
6541   "TARGET_80387"
6542   "")
6544 (define_expand "adddf3"
6545   [(set (match_operand:DF 0 "register_operand" "")
6546         (plus:DF (match_operand:DF 1 "register_operand" "")
6547                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6548   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6549   "")
6551 (define_expand "addsf3"
6552   [(set (match_operand:SF 0 "register_operand" "")
6553         (plus:SF (match_operand:SF 1 "register_operand" "")
6554                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6555   "TARGET_80387 || TARGET_SSE_MATH"
6556   "")
6558 ;; Subtract instructions
6560 ;; %%% splits for subsidi3
6562 (define_expand "subdi3"
6563   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6564                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6565                              (match_operand:DI 2 "x86_64_general_operand" "")))
6566               (clobber (reg:CC FLAGS_REG))])]
6567   ""
6568   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6570 (define_insn "*subdi3_1"
6571   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6572         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6573                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6574    (clobber (reg:CC FLAGS_REG))]
6575   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6576   "#")
6578 (define_split
6579   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6580         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6581                   (match_operand:DI 2 "general_operand" "")))
6582    (clobber (reg:CC FLAGS_REG))]
6583   "!TARGET_64BIT && reload_completed"
6584   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6585               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6586    (parallel [(set (match_dup 3)
6587                    (minus:SI (match_dup 4)
6588                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6589                                       (match_dup 5))))
6590               (clobber (reg:CC FLAGS_REG))])]
6591   "split_di (operands+0, 1, operands+0, operands+3);
6592    split_di (operands+1, 1, operands+1, operands+4);
6593    split_di (operands+2, 1, operands+2, operands+5);")
6595 (define_insn "subdi3_carry_rex64"
6596   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6597           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6598             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6599                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6600    (clobber (reg:CC FLAGS_REG))]
6601   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6602   "sbb{q}\t{%2, %0|%0, %2}"
6603   [(set_attr "type" "alu")
6604    (set_attr "pent_pair" "pu")
6605    (set_attr "mode" "DI")])
6607 (define_insn "*subdi_1_rex64"
6608   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6609         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6610                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6613   "sub{q}\t{%2, %0|%0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "mode" "DI")])
6617 (define_insn "*subdi_2_rex64"
6618   [(set (reg FLAGS_REG)
6619         (compare
6620           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6621                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6622           (const_int 0)))
6623    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6624         (minus:DI (match_dup 1) (match_dup 2)))]
6625   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6626    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6627   "sub{q}\t{%2, %0|%0, %2}"
6628   [(set_attr "type" "alu")
6629    (set_attr "mode" "DI")])
6631 (define_insn "*subdi_3_rex63"
6632   [(set (reg FLAGS_REG)
6633         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6634                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6635    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6636         (minus:DI (match_dup 1) (match_dup 2)))]
6637   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6638    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6639   "sub{q}\t{%2, %0|%0, %2}"
6640   [(set_attr "type" "alu")
6641    (set_attr "mode" "DI")])
6643 (define_insn "subqi3_carry"
6644   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6645           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6646             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6647                (match_operand:QI 2 "general_operand" "qi,qm"))))
6648    (clobber (reg:CC FLAGS_REG))]
6649   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6650   "sbb{b}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "pent_pair" "pu")
6653    (set_attr "mode" "QI")])
6655 (define_insn "subhi3_carry"
6656   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6657           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6658             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6659                (match_operand:HI 2 "general_operand" "ri,rm"))))
6660    (clobber (reg:CC FLAGS_REG))]
6661   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6662   "sbb{w}\t{%2, %0|%0, %2}"
6663   [(set_attr "type" "alu")
6664    (set_attr "pent_pair" "pu")
6665    (set_attr "mode" "HI")])
6667 (define_insn "subsi3_carry"
6668   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6669           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6670             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6671                (match_operand:SI 2 "general_operand" "ri,rm"))))
6672    (clobber (reg:CC FLAGS_REG))]
6673   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6674   "sbb{l}\t{%2, %0|%0, %2}"
6675   [(set_attr "type" "alu")
6676    (set_attr "pent_pair" "pu")
6677    (set_attr "mode" "SI")])
6679 (define_insn "subsi3_carry_zext"
6680   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6681           (zero_extend:DI
6682             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6683               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6684                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6685    (clobber (reg:CC FLAGS_REG))]
6686   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6687   "sbb{l}\t{%2, %k0|%k0, %2}"
6688   [(set_attr "type" "alu")
6689    (set_attr "pent_pair" "pu")
6690    (set_attr "mode" "SI")])
6692 (define_expand "subsi3"
6693   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6694                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6695                              (match_operand:SI 2 "general_operand" "")))
6696               (clobber (reg:CC FLAGS_REG))])]
6697   ""
6698   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6700 (define_insn "*subsi_1"
6701   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6702         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6703                   (match_operand:SI 2 "general_operand" "ri,rm")))
6704    (clobber (reg:CC FLAGS_REG))]
6705   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6706   "sub{l}\t{%2, %0|%0, %2}"
6707   [(set_attr "type" "alu")
6708    (set_attr "mode" "SI")])
6710 (define_insn "*subsi_1_zext"
6711   [(set (match_operand:DI 0 "register_operand" "=r")
6712         (zero_extend:DI
6713           (minus:SI (match_operand:SI 1 "register_operand" "0")
6714                     (match_operand:SI 2 "general_operand" "rim"))))
6715    (clobber (reg:CC FLAGS_REG))]
6716   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6717   "sub{l}\t{%2, %k0|%k0, %2}"
6718   [(set_attr "type" "alu")
6719    (set_attr "mode" "SI")])
6721 (define_insn "*subsi_2"
6722   [(set (reg FLAGS_REG)
6723         (compare
6724           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6725                     (match_operand:SI 2 "general_operand" "ri,rm"))
6726           (const_int 0)))
6727    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6728         (minus:SI (match_dup 1) (match_dup 2)))]
6729   "ix86_match_ccmode (insn, CCGOCmode)
6730    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6731   "sub{l}\t{%2, %0|%0, %2}"
6732   [(set_attr "type" "alu")
6733    (set_attr "mode" "SI")])
6735 (define_insn "*subsi_2_zext"
6736   [(set (reg FLAGS_REG)
6737         (compare
6738           (minus:SI (match_operand:SI 1 "register_operand" "0")
6739                     (match_operand:SI 2 "general_operand" "rim"))
6740           (const_int 0)))
6741    (set (match_operand:DI 0 "register_operand" "=r")
6742         (zero_extend:DI
6743           (minus:SI (match_dup 1)
6744                     (match_dup 2))))]
6745   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6746    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6747   "sub{l}\t{%2, %k0|%k0, %2}"
6748   [(set_attr "type" "alu")
6749    (set_attr "mode" "SI")])
6751 (define_insn "*subsi_3"
6752   [(set (reg FLAGS_REG)
6753         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6754                  (match_operand:SI 2 "general_operand" "ri,rm")))
6755    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6756         (minus:SI (match_dup 1) (match_dup 2)))]
6757   "ix86_match_ccmode (insn, CCmode)
6758    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6759   "sub{l}\t{%2, %0|%0, %2}"
6760   [(set_attr "type" "alu")
6761    (set_attr "mode" "SI")])
6763 (define_insn "*subsi_3_zext"
6764   [(set (reg FLAGS_REG)
6765         (compare (match_operand:SI 1 "register_operand" "0")
6766                  (match_operand:SI 2 "general_operand" "rim")))
6767    (set (match_operand:DI 0 "register_operand" "=r")
6768         (zero_extend:DI
6769           (minus:SI (match_dup 1)
6770                     (match_dup 2))))]
6771   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6772    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6773   "sub{q}\t{%2, %0|%0, %2}"
6774   [(set_attr "type" "alu")
6775    (set_attr "mode" "DI")])
6777 (define_expand "subhi3"
6778   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6779                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6780                              (match_operand:HI 2 "general_operand" "")))
6781               (clobber (reg:CC FLAGS_REG))])]
6782   "TARGET_HIMODE_MATH"
6783   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6785 (define_insn "*subhi_1"
6786   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6787         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6788                   (match_operand:HI 2 "general_operand" "ri,rm")))
6789    (clobber (reg:CC FLAGS_REG))]
6790   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6791   "sub{w}\t{%2, %0|%0, %2}"
6792   [(set_attr "type" "alu")
6793    (set_attr "mode" "HI")])
6795 (define_insn "*subhi_2"
6796   [(set (reg FLAGS_REG)
6797         (compare
6798           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6799                     (match_operand:HI 2 "general_operand" "ri,rm"))
6800           (const_int 0)))
6801    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6802         (minus:HI (match_dup 1) (match_dup 2)))]
6803   "ix86_match_ccmode (insn, CCGOCmode)
6804    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6805   "sub{w}\t{%2, %0|%0, %2}"
6806   [(set_attr "type" "alu")
6807    (set_attr "mode" "HI")])
6809 (define_insn "*subhi_3"
6810   [(set (reg FLAGS_REG)
6811         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6812                  (match_operand:HI 2 "general_operand" "ri,rm")))
6813    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6814         (minus:HI (match_dup 1) (match_dup 2)))]
6815   "ix86_match_ccmode (insn, CCmode)
6816    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6817   "sub{w}\t{%2, %0|%0, %2}"
6818   [(set_attr "type" "alu")
6819    (set_attr "mode" "HI")])
6821 (define_expand "subqi3"
6822   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6823                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6824                              (match_operand:QI 2 "general_operand" "")))
6825               (clobber (reg:CC FLAGS_REG))])]
6826   "TARGET_QIMODE_MATH"
6827   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6829 (define_insn "*subqi_1"
6830   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6831         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6832                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6833    (clobber (reg:CC FLAGS_REG))]
6834   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6835   "sub{b}\t{%2, %0|%0, %2}"
6836   [(set_attr "type" "alu")
6837    (set_attr "mode" "QI")])
6839 (define_insn "*subqi_1_slp"
6840   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6841         (minus:QI (match_dup 0)
6842                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6843    (clobber (reg:CC FLAGS_REG))]
6844   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6845    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6846   "sub{b}\t{%1, %0|%0, %1}"
6847   [(set_attr "type" "alu1")
6848    (set_attr "mode" "QI")])
6850 (define_insn "*subqi_2"
6851   [(set (reg FLAGS_REG)
6852         (compare
6853           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6854                     (match_operand:QI 2 "general_operand" "qi,qm"))
6855           (const_int 0)))
6856    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6857         (minus:HI (match_dup 1) (match_dup 2)))]
6858   "ix86_match_ccmode (insn, CCGOCmode)
6859    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6860   "sub{b}\t{%2, %0|%0, %2}"
6861   [(set_attr "type" "alu")
6862    (set_attr "mode" "QI")])
6864 (define_insn "*subqi_3"
6865   [(set (reg FLAGS_REG)
6866         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6867                  (match_operand:QI 2 "general_operand" "qi,qm")))
6868    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6869         (minus:HI (match_dup 1) (match_dup 2)))]
6870   "ix86_match_ccmode (insn, CCmode)
6871    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6872   "sub{b}\t{%2, %0|%0, %2}"
6873   [(set_attr "type" "alu")
6874    (set_attr "mode" "QI")])
6876 ;; The patterns that match these are at the end of this file.
6878 (define_expand "subxf3"
6879   [(set (match_operand:XF 0 "register_operand" "")
6880         (minus:XF (match_operand:XF 1 "register_operand" "")
6881                   (match_operand:XF 2 "register_operand" "")))]
6882   "TARGET_80387"
6883   "")
6885 (define_expand "subdf3"
6886   [(set (match_operand:DF 0 "register_operand" "")
6887         (minus:DF (match_operand:DF 1 "register_operand" "")
6888                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6889   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6890   "")
6892 (define_expand "subsf3"
6893   [(set (match_operand:SF 0 "register_operand" "")
6894         (minus:SF (match_operand:SF 1 "register_operand" "")
6895                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6896   "TARGET_80387 || TARGET_SSE_MATH"
6897   "")
6899 ;; Multiply instructions
6901 (define_expand "muldi3"
6902   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6903                    (mult:DI (match_operand:DI 1 "register_operand" "")
6904                             (match_operand:DI 2 "x86_64_general_operand" "")))
6905               (clobber (reg:CC FLAGS_REG))])]
6906   "TARGET_64BIT"
6907   "")
6909 (define_insn "*muldi3_1_rex64"
6910   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6911         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6912                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6913    (clobber (reg:CC FLAGS_REG))]
6914   "TARGET_64BIT
6915    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6916   "@
6917    imul{q}\t{%2, %1, %0|%0, %1, %2}
6918    imul{q}\t{%2, %1, %0|%0, %1, %2}
6919    imul{q}\t{%2, %0|%0, %2}"
6920   [(set_attr "type" "imul")
6921    (set_attr "prefix_0f" "0,0,1")
6922    (set (attr "athlon_decode")
6923         (cond [(eq_attr "cpu" "athlon")
6924                   (const_string "vector")
6925                (eq_attr "alternative" "1")
6926                   (const_string "vector")
6927                (and (eq_attr "alternative" "2")
6928                     (match_operand 1 "memory_operand" ""))
6929                   (const_string "vector")]
6930               (const_string "direct")))
6931    (set_attr "mode" "DI")])
6933 (define_expand "mulsi3"
6934   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6935                    (mult:SI (match_operand:SI 1 "register_operand" "")
6936                             (match_operand:SI 2 "general_operand" "")))
6937               (clobber (reg:CC FLAGS_REG))])]
6938   ""
6939   "")
6941 (define_insn "*mulsi3_1"
6942   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6943         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6944                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6945    (clobber (reg:CC FLAGS_REG))]
6946   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6947   "@
6948    imul{l}\t{%2, %1, %0|%0, %1, %2}
6949    imul{l}\t{%2, %1, %0|%0, %1, %2}
6950    imul{l}\t{%2, %0|%0, %2}"
6951   [(set_attr "type" "imul")
6952    (set_attr "prefix_0f" "0,0,1")
6953    (set (attr "athlon_decode")
6954         (cond [(eq_attr "cpu" "athlon")
6955                   (const_string "vector")
6956                (eq_attr "alternative" "1")
6957                   (const_string "vector")
6958                (and (eq_attr "alternative" "2")
6959                     (match_operand 1 "memory_operand" ""))
6960                   (const_string "vector")]
6961               (const_string "direct")))
6962    (set_attr "mode" "SI")])
6964 (define_insn "*mulsi3_1_zext"
6965   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6966         (zero_extend:DI
6967           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6968                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6969    (clobber (reg:CC FLAGS_REG))]
6970   "TARGET_64BIT
6971    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6972   "@
6973    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6974    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6975    imul{l}\t{%2, %k0|%k0, %2}"
6976   [(set_attr "type" "imul")
6977    (set_attr "prefix_0f" "0,0,1")
6978    (set (attr "athlon_decode")
6979         (cond [(eq_attr "cpu" "athlon")
6980                   (const_string "vector")
6981                (eq_attr "alternative" "1")
6982                   (const_string "vector")
6983                (and (eq_attr "alternative" "2")
6984                     (match_operand 1 "memory_operand" ""))
6985                   (const_string "vector")]
6986               (const_string "direct")))
6987    (set_attr "mode" "SI")])
6989 (define_expand "mulhi3"
6990   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6991                    (mult:HI (match_operand:HI 1 "register_operand" "")
6992                             (match_operand:HI 2 "general_operand" "")))
6993               (clobber (reg:CC FLAGS_REG))])]
6994   "TARGET_HIMODE_MATH"
6995   "")
6997 (define_insn "*mulhi3_1"
6998   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6999         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7000                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7001    (clobber (reg:CC FLAGS_REG))]
7002   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7003   "@
7004    imul{w}\t{%2, %1, %0|%0, %1, %2}
7005    imul{w}\t{%2, %1, %0|%0, %1, %2}
7006    imul{w}\t{%2, %0|%0, %2}"
7007   [(set_attr "type" "imul")
7008    (set_attr "prefix_0f" "0,0,1")
7009    (set (attr "athlon_decode")
7010         (cond [(eq_attr "cpu" "athlon")
7011                   (const_string "vector")
7012                (eq_attr "alternative" "1,2")
7013                   (const_string "vector")]
7014               (const_string "direct")))
7015    (set_attr "mode" "HI")])
7017 (define_expand "mulqi3"
7018   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7019                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7020                             (match_operand:QI 2 "register_operand" "")))
7021               (clobber (reg:CC FLAGS_REG))])]
7022   "TARGET_QIMODE_MATH"
7023   "")
7025 (define_insn "*mulqi3_1"
7026   [(set (match_operand:QI 0 "register_operand" "=a")
7027         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7028                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7029    (clobber (reg:CC FLAGS_REG))]
7030   "TARGET_QIMODE_MATH
7031    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7032   "mul{b}\t%2"
7033   [(set_attr "type" "imul")
7034    (set_attr "length_immediate" "0")
7035    (set (attr "athlon_decode")
7036      (if_then_else (eq_attr "cpu" "athlon")
7037         (const_string "vector")
7038         (const_string "direct")))
7039    (set_attr "mode" "QI")])
7041 (define_expand "umulqihi3"
7042   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7043                    (mult:HI (zero_extend:HI
7044                               (match_operand:QI 1 "nonimmediate_operand" ""))
7045                             (zero_extend:HI
7046                               (match_operand:QI 2 "register_operand" ""))))
7047               (clobber (reg:CC FLAGS_REG))])]
7048   "TARGET_QIMODE_MATH"
7049   "")
7051 (define_insn "*umulqihi3_1"
7052   [(set (match_operand:HI 0 "register_operand" "=a")
7053         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7054                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7055    (clobber (reg:CC FLAGS_REG))]
7056   "TARGET_QIMODE_MATH
7057    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7058   "mul{b}\t%2"
7059   [(set_attr "type" "imul")
7060    (set_attr "length_immediate" "0")
7061    (set (attr "athlon_decode")
7062      (if_then_else (eq_attr "cpu" "athlon")
7063         (const_string "vector")
7064         (const_string "direct")))
7065    (set_attr "mode" "QI")])
7067 (define_expand "mulqihi3"
7068   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7069                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7070                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7071               (clobber (reg:CC FLAGS_REG))])]
7072   "TARGET_QIMODE_MATH"
7073   "")
7075 (define_insn "*mulqihi3_insn"
7076   [(set (match_operand:HI 0 "register_operand" "=a")
7077         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7078                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7079    (clobber (reg:CC FLAGS_REG))]
7080   "TARGET_QIMODE_MATH
7081    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7082   "imul{b}\t%2"
7083   [(set_attr "type" "imul")
7084    (set_attr "length_immediate" "0")
7085    (set (attr "athlon_decode")
7086      (if_then_else (eq_attr "cpu" "athlon")
7087         (const_string "vector")
7088         (const_string "direct")))
7089    (set_attr "mode" "QI")])
7091 (define_expand "umulditi3"
7092   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7093                    (mult:TI (zero_extend:TI
7094                               (match_operand:DI 1 "nonimmediate_operand" ""))
7095                             (zero_extend:TI
7096                               (match_operand:DI 2 "register_operand" ""))))
7097               (clobber (reg:CC FLAGS_REG))])]
7098   "TARGET_64BIT"
7099   "")
7101 (define_insn "*umulditi3_insn"
7102   [(set (match_operand:TI 0 "register_operand" "=A")
7103         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7104                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7105    (clobber (reg:CC FLAGS_REG))]
7106   "TARGET_64BIT
7107    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7108   "mul{q}\t%2"
7109   [(set_attr "type" "imul")
7110    (set_attr "length_immediate" "0")
7111    (set (attr "athlon_decode")
7112      (if_then_else (eq_attr "cpu" "athlon")
7113         (const_string "vector")
7114         (const_string "double")))
7115    (set_attr "mode" "DI")])
7117 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7118 (define_expand "umulsidi3"
7119   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7120                    (mult:DI (zero_extend:DI
7121                               (match_operand:SI 1 "nonimmediate_operand" ""))
7122                             (zero_extend:DI
7123                               (match_operand:SI 2 "register_operand" ""))))
7124               (clobber (reg:CC FLAGS_REG))])]
7125   "!TARGET_64BIT"
7126   "")
7128 (define_insn "*umulsidi3_insn"
7129   [(set (match_operand:DI 0 "register_operand" "=A")
7130         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7131                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7132    (clobber (reg:CC FLAGS_REG))]
7133   "!TARGET_64BIT
7134    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7135   "mul{l}\t%2"
7136   [(set_attr "type" "imul")
7137    (set_attr "length_immediate" "0")
7138    (set (attr "athlon_decode")
7139      (if_then_else (eq_attr "cpu" "athlon")
7140         (const_string "vector")
7141         (const_string "double")))
7142    (set_attr "mode" "SI")])
7144 (define_expand "mulditi3"
7145   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7146                    (mult:TI (sign_extend:TI
7147                               (match_operand:DI 1 "nonimmediate_operand" ""))
7148                             (sign_extend:TI
7149                               (match_operand:DI 2 "register_operand" ""))))
7150               (clobber (reg:CC FLAGS_REG))])]
7151   "TARGET_64BIT"
7152   "")
7154 (define_insn "*mulditi3_insn"
7155   [(set (match_operand:TI 0 "register_operand" "=A")
7156         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7157                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7158    (clobber (reg:CC FLAGS_REG))]
7159   "TARGET_64BIT
7160    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7161   "imul{q}\t%2"
7162   [(set_attr "type" "imul")
7163    (set_attr "length_immediate" "0")
7164    (set (attr "athlon_decode")
7165      (if_then_else (eq_attr "cpu" "athlon")
7166         (const_string "vector")
7167         (const_string "double")))
7168    (set_attr "mode" "DI")])
7170 (define_expand "mulsidi3"
7171   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7172                    (mult:DI (sign_extend:DI
7173                               (match_operand:SI 1 "nonimmediate_operand" ""))
7174                             (sign_extend:DI
7175                               (match_operand:SI 2 "register_operand" ""))))
7176               (clobber (reg:CC FLAGS_REG))])]
7177   "!TARGET_64BIT"
7178   "")
7180 (define_insn "*mulsidi3_insn"
7181   [(set (match_operand:DI 0 "register_operand" "=A")
7182         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7183                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7184    (clobber (reg:CC FLAGS_REG))]
7185   "!TARGET_64BIT
7186    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7187   "imul{l}\t%2"
7188   [(set_attr "type" "imul")
7189    (set_attr "length_immediate" "0")
7190    (set (attr "athlon_decode")
7191      (if_then_else (eq_attr "cpu" "athlon")
7192         (const_string "vector")
7193         (const_string "double")))
7194    (set_attr "mode" "SI")])
7196 (define_expand "umuldi3_highpart"
7197   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7198                    (truncate:DI
7199                      (lshiftrt:TI
7200                        (mult:TI (zero_extend:TI
7201                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7202                                 (zero_extend:TI
7203                                   (match_operand:DI 2 "register_operand" "")))
7204                        (const_int 64))))
7205               (clobber (match_scratch:DI 3 ""))
7206               (clobber (reg:CC FLAGS_REG))])]
7207   "TARGET_64BIT"
7208   "")
7210 (define_insn "*umuldi3_highpart_rex64"
7211   [(set (match_operand:DI 0 "register_operand" "=d")
7212         (truncate:DI
7213           (lshiftrt:TI
7214             (mult:TI (zero_extend:TI
7215                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7216                      (zero_extend:TI
7217                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7218             (const_int 64))))
7219    (clobber (match_scratch:DI 3 "=1"))
7220    (clobber (reg:CC FLAGS_REG))]
7221   "TARGET_64BIT
7222    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7223   "mul{q}\t%2"
7224   [(set_attr "type" "imul")
7225    (set_attr "length_immediate" "0")
7226    (set (attr "athlon_decode")
7227      (if_then_else (eq_attr "cpu" "athlon")
7228         (const_string "vector")
7229         (const_string "double")))
7230    (set_attr "mode" "DI")])
7232 (define_expand "umulsi3_highpart"
7233   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7234                    (truncate:SI
7235                      (lshiftrt:DI
7236                        (mult:DI (zero_extend:DI
7237                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7238                                 (zero_extend:DI
7239                                   (match_operand:SI 2 "register_operand" "")))
7240                        (const_int 32))))
7241               (clobber (match_scratch:SI 3 ""))
7242               (clobber (reg:CC FLAGS_REG))])]
7243   ""
7244   "")
7246 (define_insn "*umulsi3_highpart_insn"
7247   [(set (match_operand:SI 0 "register_operand" "=d")
7248         (truncate:SI
7249           (lshiftrt:DI
7250             (mult:DI (zero_extend:DI
7251                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7252                      (zero_extend:DI
7253                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7254             (const_int 32))))
7255    (clobber (match_scratch:SI 3 "=1"))
7256    (clobber (reg:CC FLAGS_REG))]
7257   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7258   "mul{l}\t%2"
7259   [(set_attr "type" "imul")
7260    (set_attr "length_immediate" "0")
7261    (set (attr "athlon_decode")
7262      (if_then_else (eq_attr "cpu" "athlon")
7263         (const_string "vector")
7264         (const_string "double")))
7265    (set_attr "mode" "SI")])
7267 (define_insn "*umulsi3_highpart_zext"
7268   [(set (match_operand:DI 0 "register_operand" "=d")
7269         (zero_extend:DI (truncate:SI
7270           (lshiftrt:DI
7271             (mult:DI (zero_extend:DI
7272                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7273                      (zero_extend:DI
7274                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7275             (const_int 32)))))
7276    (clobber (match_scratch:SI 3 "=1"))
7277    (clobber (reg:CC FLAGS_REG))]
7278   "TARGET_64BIT
7279    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7280   "mul{l}\t%2"
7281   [(set_attr "type" "imul")
7282    (set_attr "length_immediate" "0")
7283    (set (attr "athlon_decode")
7284      (if_then_else (eq_attr "cpu" "athlon")
7285         (const_string "vector")
7286         (const_string "double")))
7287    (set_attr "mode" "SI")])
7289 (define_expand "smuldi3_highpart"
7290   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7291                    (truncate:DI
7292                      (lshiftrt:TI
7293                        (mult:TI (sign_extend:TI
7294                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7295                                 (sign_extend:TI
7296                                   (match_operand:DI 2 "register_operand" "")))
7297                        (const_int 64))))
7298               (clobber (match_scratch:DI 3 ""))
7299               (clobber (reg:CC FLAGS_REG))])]
7300   "TARGET_64BIT"
7301   "")
7303 (define_insn "*smuldi3_highpart_rex64"
7304   [(set (match_operand:DI 0 "register_operand" "=d")
7305         (truncate:DI
7306           (lshiftrt:TI
7307             (mult:TI (sign_extend:TI
7308                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7309                      (sign_extend:TI
7310                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7311             (const_int 64))))
7312    (clobber (match_scratch:DI 3 "=1"))
7313    (clobber (reg:CC FLAGS_REG))]
7314   "TARGET_64BIT
7315    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7316   "imul{q}\t%2"
7317   [(set_attr "type" "imul")
7318    (set (attr "athlon_decode")
7319      (if_then_else (eq_attr "cpu" "athlon")
7320         (const_string "vector")
7321         (const_string "double")))
7322    (set_attr "mode" "DI")])
7324 (define_expand "smulsi3_highpart"
7325   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7326                    (truncate:SI
7327                      (lshiftrt:DI
7328                        (mult:DI (sign_extend:DI
7329                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7330                                 (sign_extend:DI
7331                                   (match_operand:SI 2 "register_operand" "")))
7332                        (const_int 32))))
7333               (clobber (match_scratch:SI 3 ""))
7334               (clobber (reg:CC FLAGS_REG))])]
7335   ""
7336   "")
7338 (define_insn "*smulsi3_highpart_insn"
7339   [(set (match_operand:SI 0 "register_operand" "=d")
7340         (truncate:SI
7341           (lshiftrt:DI
7342             (mult:DI (sign_extend:DI
7343                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7344                      (sign_extend:DI
7345                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7346             (const_int 32))))
7347    (clobber (match_scratch:SI 3 "=1"))
7348    (clobber (reg:CC FLAGS_REG))]
7349   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7350   "imul{l}\t%2"
7351   [(set_attr "type" "imul")
7352    (set (attr "athlon_decode")
7353      (if_then_else (eq_attr "cpu" "athlon")
7354         (const_string "vector")
7355         (const_string "double")))
7356    (set_attr "mode" "SI")])
7358 (define_insn "*smulsi3_highpart_zext"
7359   [(set (match_operand:DI 0 "register_operand" "=d")
7360         (zero_extend:DI (truncate:SI
7361           (lshiftrt:DI
7362             (mult:DI (sign_extend:DI
7363                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7364                      (sign_extend:DI
7365                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7366             (const_int 32)))))
7367    (clobber (match_scratch:SI 3 "=1"))
7368    (clobber (reg:CC FLAGS_REG))]
7369   "TARGET_64BIT
7370    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7371   "imul{l}\t%2"
7372   [(set_attr "type" "imul")
7373    (set (attr "athlon_decode")
7374      (if_then_else (eq_attr "cpu" "athlon")
7375         (const_string "vector")
7376         (const_string "double")))
7377    (set_attr "mode" "SI")])
7379 ;; The patterns that match these are at the end of this file.
7381 (define_expand "mulxf3"
7382   [(set (match_operand:XF 0 "register_operand" "")
7383         (mult:XF (match_operand:XF 1 "register_operand" "")
7384                  (match_operand:XF 2 "register_operand" "")))]
7385   "TARGET_80387"
7386   "")
7388 (define_expand "muldf3"
7389   [(set (match_operand:DF 0 "register_operand" "")
7390         (mult:DF (match_operand:DF 1 "register_operand" "")
7391                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7392   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7393   "")
7395 (define_expand "mulsf3"
7396   [(set (match_operand:SF 0 "register_operand" "")
7397         (mult:SF (match_operand:SF 1 "register_operand" "")
7398                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7399   "TARGET_80387 || TARGET_SSE_MATH"
7400   "")
7402 ;; Divide instructions
7404 (define_insn "divqi3"
7405   [(set (match_operand:QI 0 "register_operand" "=a")
7406         (div:QI (match_operand:HI 1 "register_operand" "0")
7407                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7408    (clobber (reg:CC FLAGS_REG))]
7409   "TARGET_QIMODE_MATH"
7410   "idiv{b}\t%2"
7411   [(set_attr "type" "idiv")
7412    (set_attr "mode" "QI")])
7414 (define_insn "udivqi3"
7415   [(set (match_operand:QI 0 "register_operand" "=a")
7416         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7417                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7418    (clobber (reg:CC FLAGS_REG))]
7419   "TARGET_QIMODE_MATH"
7420   "div{b}\t%2"
7421   [(set_attr "type" "idiv")
7422    (set_attr "mode" "QI")])
7424 ;; The patterns that match these are at the end of this file.
7426 (define_expand "divxf3"
7427   [(set (match_operand:XF 0 "register_operand" "")
7428         (div:XF (match_operand:XF 1 "register_operand" "")
7429                 (match_operand:XF 2 "register_operand" "")))]
7430   "TARGET_80387"
7431   "")
7433 (define_expand "divdf3"
7434   [(set (match_operand:DF 0 "register_operand" "")
7435         (div:DF (match_operand:DF 1 "register_operand" "")
7436                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7437    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7438    "")
7440 (define_expand "divsf3"
7441   [(set (match_operand:SF 0 "register_operand" "")
7442         (div:SF (match_operand:SF 1 "register_operand" "")
7443                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7444   "TARGET_80387 || TARGET_SSE_MATH"
7445   "")
7447 ;; Remainder instructions.
7449 (define_expand "divmoddi4"
7450   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7451                    (div:DI (match_operand:DI 1 "register_operand" "")
7452                            (match_operand:DI 2 "nonimmediate_operand" "")))
7453               (set (match_operand:DI 3 "register_operand" "")
7454                    (mod:DI (match_dup 1) (match_dup 2)))
7455               (clobber (reg:CC FLAGS_REG))])]
7456   "TARGET_64BIT"
7457   "")
7459 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7460 ;; Penalize eax case slightly because it results in worse scheduling
7461 ;; of code.
7462 (define_insn "*divmoddi4_nocltd_rex64"
7463   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7464         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7465                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7466    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7467         (mod:DI (match_dup 2) (match_dup 3)))
7468    (clobber (reg:CC FLAGS_REG))]
7469   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7470   "#"
7471   [(set_attr "type" "multi")])
7473 (define_insn "*divmoddi4_cltd_rex64"
7474   [(set (match_operand:DI 0 "register_operand" "=a")
7475         (div:DI (match_operand:DI 2 "register_operand" "a")
7476                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7477    (set (match_operand:DI 1 "register_operand" "=&d")
7478         (mod:DI (match_dup 2) (match_dup 3)))
7479    (clobber (reg:CC FLAGS_REG))]
7480   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7481   "#"
7482   [(set_attr "type" "multi")])
7484 (define_insn "*divmoddi_noext_rex64"
7485   [(set (match_operand:DI 0 "register_operand" "=a")
7486         (div:DI (match_operand:DI 1 "register_operand" "0")
7487                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7488    (set (match_operand:DI 3 "register_operand" "=d")
7489         (mod:DI (match_dup 1) (match_dup 2)))
7490    (use (match_operand:DI 4 "register_operand" "3"))
7491    (clobber (reg:CC FLAGS_REG))]
7492   "TARGET_64BIT"
7493   "idiv{q}\t%2"
7494   [(set_attr "type" "idiv")
7495    (set_attr "mode" "DI")])
7497 (define_split
7498   [(set (match_operand:DI 0 "register_operand" "")
7499         (div:DI (match_operand:DI 1 "register_operand" "")
7500                 (match_operand:DI 2 "nonimmediate_operand" "")))
7501    (set (match_operand:DI 3 "register_operand" "")
7502         (mod:DI (match_dup 1) (match_dup 2)))
7503    (clobber (reg:CC FLAGS_REG))]
7504   "TARGET_64BIT && reload_completed"
7505   [(parallel [(set (match_dup 3)
7506                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7507               (clobber (reg:CC FLAGS_REG))])
7508    (parallel [(set (match_dup 0)
7509                    (div:DI (reg:DI 0) (match_dup 2)))
7510               (set (match_dup 3)
7511                    (mod:DI (reg:DI 0) (match_dup 2)))
7512               (use (match_dup 3))
7513               (clobber (reg:CC FLAGS_REG))])]
7515   /* Avoid use of cltd in favor of a mov+shift.  */
7516   if (!TARGET_USE_CLTD && !optimize_size)
7517     {
7518       if (true_regnum (operands[1]))
7519         emit_move_insn (operands[0], operands[1]);
7520       else
7521         emit_move_insn (operands[3], operands[1]);
7522       operands[4] = operands[3];
7523     }
7524   else
7525     {
7526       if (true_regnum (operands[1]))
7527         abort();
7528       operands[4] = operands[1];
7529     }
7533 (define_expand "divmodsi4"
7534   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7535                    (div:SI (match_operand:SI 1 "register_operand" "")
7536                            (match_operand:SI 2 "nonimmediate_operand" "")))
7537               (set (match_operand:SI 3 "register_operand" "")
7538                    (mod:SI (match_dup 1) (match_dup 2)))
7539               (clobber (reg:CC FLAGS_REG))])]
7540   ""
7541   "")
7543 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7544 ;; Penalize eax case slightly because it results in worse scheduling
7545 ;; of code.
7546 (define_insn "*divmodsi4_nocltd"
7547   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7548         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7549                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7550    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7551         (mod:SI (match_dup 2) (match_dup 3)))
7552    (clobber (reg:CC FLAGS_REG))]
7553   "!optimize_size && !TARGET_USE_CLTD"
7554   "#"
7555   [(set_attr "type" "multi")])
7557 (define_insn "*divmodsi4_cltd"
7558   [(set (match_operand:SI 0 "register_operand" "=a")
7559         (div:SI (match_operand:SI 2 "register_operand" "a")
7560                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7561    (set (match_operand:SI 1 "register_operand" "=&d")
7562         (mod:SI (match_dup 2) (match_dup 3)))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "optimize_size || TARGET_USE_CLTD"
7565   "#"
7566   [(set_attr "type" "multi")])
7568 (define_insn "*divmodsi_noext"
7569   [(set (match_operand:SI 0 "register_operand" "=a")
7570         (div:SI (match_operand:SI 1 "register_operand" "0")
7571                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7572    (set (match_operand:SI 3 "register_operand" "=d")
7573         (mod:SI (match_dup 1) (match_dup 2)))
7574    (use (match_operand:SI 4 "register_operand" "3"))
7575    (clobber (reg:CC FLAGS_REG))]
7576   ""
7577   "idiv{l}\t%2"
7578   [(set_attr "type" "idiv")
7579    (set_attr "mode" "SI")])
7581 (define_split
7582   [(set (match_operand:SI 0 "register_operand" "")
7583         (div:SI (match_operand:SI 1 "register_operand" "")
7584                 (match_operand:SI 2 "nonimmediate_operand" "")))
7585    (set (match_operand:SI 3 "register_operand" "")
7586         (mod:SI (match_dup 1) (match_dup 2)))
7587    (clobber (reg:CC FLAGS_REG))]
7588   "reload_completed"
7589   [(parallel [(set (match_dup 3)
7590                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7591               (clobber (reg:CC FLAGS_REG))])
7592    (parallel [(set (match_dup 0)
7593                    (div:SI (reg:SI 0) (match_dup 2)))
7594               (set (match_dup 3)
7595                    (mod:SI (reg:SI 0) (match_dup 2)))
7596               (use (match_dup 3))
7597               (clobber (reg:CC FLAGS_REG))])]
7599   /* Avoid use of cltd in favor of a mov+shift.  */
7600   if (!TARGET_USE_CLTD && !optimize_size)
7601     {
7602       if (true_regnum (operands[1]))
7603         emit_move_insn (operands[0], operands[1]);
7604       else
7605         emit_move_insn (operands[3], operands[1]);
7606       operands[4] = operands[3];
7607     }
7608   else
7609     {
7610       if (true_regnum (operands[1]))
7611         abort();
7612       operands[4] = operands[1];
7613     }
7615 ;; %%% Split me.
7616 (define_insn "divmodhi4"
7617   [(set (match_operand:HI 0 "register_operand" "=a")
7618         (div:HI (match_operand:HI 1 "register_operand" "0")
7619                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7620    (set (match_operand:HI 3 "register_operand" "=&d")
7621         (mod:HI (match_dup 1) (match_dup 2)))
7622    (clobber (reg:CC FLAGS_REG))]
7623   "TARGET_HIMODE_MATH"
7624   "cwtd\;idiv{w}\t%2"
7625   [(set_attr "type" "multi")
7626    (set_attr "length_immediate" "0")
7627    (set_attr "mode" "SI")])
7629 (define_insn "udivmoddi4"
7630   [(set (match_operand:DI 0 "register_operand" "=a")
7631         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7632                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7633    (set (match_operand:DI 3 "register_operand" "=&d")
7634         (umod:DI (match_dup 1) (match_dup 2)))
7635    (clobber (reg:CC FLAGS_REG))]
7636   "TARGET_64BIT"
7637   "xor{q}\t%3, %3\;div{q}\t%2"
7638   [(set_attr "type" "multi")
7639    (set_attr "length_immediate" "0")
7640    (set_attr "mode" "DI")])
7642 (define_insn "*udivmoddi4_noext"
7643   [(set (match_operand:DI 0 "register_operand" "=a")
7644         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7645                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7646    (set (match_operand:DI 3 "register_operand" "=d")
7647         (umod:DI (match_dup 1) (match_dup 2)))
7648    (use (match_dup 3))
7649    (clobber (reg:CC FLAGS_REG))]
7650   "TARGET_64BIT"
7651   "div{q}\t%2"
7652   [(set_attr "type" "idiv")
7653    (set_attr "mode" "DI")])
7655 (define_split
7656   [(set (match_operand:DI 0 "register_operand" "")
7657         (udiv:DI (match_operand:DI 1 "register_operand" "")
7658                  (match_operand:DI 2 "nonimmediate_operand" "")))
7659    (set (match_operand:DI 3 "register_operand" "")
7660         (umod:DI (match_dup 1) (match_dup 2)))
7661    (clobber (reg:CC FLAGS_REG))]
7662   "TARGET_64BIT && reload_completed"
7663   [(set (match_dup 3) (const_int 0))
7664    (parallel [(set (match_dup 0)
7665                    (udiv:DI (match_dup 1) (match_dup 2)))
7666               (set (match_dup 3)
7667                    (umod:DI (match_dup 1) (match_dup 2)))
7668               (use (match_dup 3))
7669               (clobber (reg:CC FLAGS_REG))])]
7670   "")
7672 (define_insn "udivmodsi4"
7673   [(set (match_operand:SI 0 "register_operand" "=a")
7674         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7675                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7676    (set (match_operand:SI 3 "register_operand" "=&d")
7677         (umod:SI (match_dup 1) (match_dup 2)))
7678    (clobber (reg:CC FLAGS_REG))]
7679   ""
7680   "xor{l}\t%3, %3\;div{l}\t%2"
7681   [(set_attr "type" "multi")
7682    (set_attr "length_immediate" "0")
7683    (set_attr "mode" "SI")])
7685 (define_insn "*udivmodsi4_noext"
7686   [(set (match_operand:SI 0 "register_operand" "=a")
7687         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7688                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7689    (set (match_operand:SI 3 "register_operand" "=d")
7690         (umod:SI (match_dup 1) (match_dup 2)))
7691    (use (match_dup 3))
7692    (clobber (reg:CC FLAGS_REG))]
7693   ""
7694   "div{l}\t%2"
7695   [(set_attr "type" "idiv")
7696    (set_attr "mode" "SI")])
7698 (define_split
7699   [(set (match_operand:SI 0 "register_operand" "")
7700         (udiv:SI (match_operand:SI 1 "register_operand" "")
7701                  (match_operand:SI 2 "nonimmediate_operand" "")))
7702    (set (match_operand:SI 3 "register_operand" "")
7703         (umod:SI (match_dup 1) (match_dup 2)))
7704    (clobber (reg:CC FLAGS_REG))]
7705   "reload_completed"
7706   [(set (match_dup 3) (const_int 0))
7707    (parallel [(set (match_dup 0)
7708                    (udiv:SI (match_dup 1) (match_dup 2)))
7709               (set (match_dup 3)
7710                    (umod:SI (match_dup 1) (match_dup 2)))
7711               (use (match_dup 3))
7712               (clobber (reg:CC FLAGS_REG))])]
7713   "")
7715 (define_expand "udivmodhi4"
7716   [(set (match_dup 4) (const_int 0))
7717    (parallel [(set (match_operand:HI 0 "register_operand" "")
7718                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7719                             (match_operand:HI 2 "nonimmediate_operand" "")))
7720               (set (match_operand:HI 3 "register_operand" "")
7721                    (umod:HI (match_dup 1) (match_dup 2)))
7722               (use (match_dup 4))
7723               (clobber (reg:CC FLAGS_REG))])]
7724   "TARGET_HIMODE_MATH"
7725   "operands[4] = gen_reg_rtx (HImode);")
7727 (define_insn "*udivmodhi_noext"
7728   [(set (match_operand:HI 0 "register_operand" "=a")
7729         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7730                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7731    (set (match_operand:HI 3 "register_operand" "=d")
7732         (umod:HI (match_dup 1) (match_dup 2)))
7733    (use (match_operand:HI 4 "register_operand" "3"))
7734    (clobber (reg:CC FLAGS_REG))]
7735   ""
7736   "div{w}\t%2"
7737   [(set_attr "type" "idiv")
7738    (set_attr "mode" "HI")])
7740 ;; We cannot use div/idiv for double division, because it causes
7741 ;; "division by zero" on the overflow and that's not what we expect
7742 ;; from truncate.  Because true (non truncating) double division is
7743 ;; never generated, we can't create this insn anyway.
7745 ;(define_insn ""
7746 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7747 ;       (truncate:SI
7748 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7749 ;                  (zero_extend:DI
7750 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7751 ;   (set (match_operand:SI 3 "register_operand" "=d")
7752 ;       (truncate:SI
7753 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7754 ;   (clobber (reg:CC FLAGS_REG))]
7755 ;  ""
7756 ;  "div{l}\t{%2, %0|%0, %2}"
7757 ;  [(set_attr "type" "idiv")])
7759 ;;- Logical AND instructions
7761 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7762 ;; Note that this excludes ah.
7764 (define_insn "*testdi_1_rex64"
7765   [(set (reg FLAGS_REG)
7766         (compare
7767           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7768                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7769           (const_int 0)))]
7770   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7771    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7772   "@
7773    test{l}\t{%k1, %k0|%k0, %k1}
7774    test{l}\t{%k1, %k0|%k0, %k1}
7775    test{q}\t{%1, %0|%0, %1}
7776    test{q}\t{%1, %0|%0, %1}
7777    test{q}\t{%1, %0|%0, %1}"
7778   [(set_attr "type" "test")
7779    (set_attr "modrm" "0,1,0,1,1")
7780    (set_attr "mode" "SI,SI,DI,DI,DI")
7781    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7783 (define_insn "testsi_1"
7784   [(set (reg FLAGS_REG)
7785         (compare
7786           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7787                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7788           (const_int 0)))]
7789   "ix86_match_ccmode (insn, CCNOmode)
7790    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7791   "test{l}\t{%1, %0|%0, %1}"
7792   [(set_attr "type" "test")
7793    (set_attr "modrm" "0,1,1")
7794    (set_attr "mode" "SI")
7795    (set_attr "pent_pair" "uv,np,uv")])
7797 (define_expand "testsi_ccno_1"
7798   [(set (reg:CCNO FLAGS_REG)
7799         (compare:CCNO
7800           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7801                   (match_operand:SI 1 "nonmemory_operand" ""))
7802           (const_int 0)))]
7803   ""
7804   "")
7806 (define_insn "*testhi_1"
7807   [(set (reg FLAGS_REG)
7808         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7809                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7810                  (const_int 0)))]
7811   "ix86_match_ccmode (insn, CCNOmode)
7812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7813   "test{w}\t{%1, %0|%0, %1}"
7814   [(set_attr "type" "test")
7815    (set_attr "modrm" "0,1,1")
7816    (set_attr "mode" "HI")
7817    (set_attr "pent_pair" "uv,np,uv")])
7819 (define_expand "testqi_ccz_1"
7820   [(set (reg:CCZ FLAGS_REG)
7821         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7822                              (match_operand:QI 1 "nonmemory_operand" ""))
7823                  (const_int 0)))]
7824   ""
7825   "")
7827 (define_insn "*testqi_1_maybe_si"
7828   [(set (reg FLAGS_REG)
7829         (compare
7830           (and:QI
7831             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7832             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7833           (const_int 0)))]
7834    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7835     && ix86_match_ccmode (insn,
7836                          GET_CODE (operands[1]) == CONST_INT
7837                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7839   if (which_alternative == 3)
7840     {
7841       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7842         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7843       return "test{l}\t{%1, %k0|%k0, %1}";
7844     }
7845   return "test{b}\t{%1, %0|%0, %1}";
7847   [(set_attr "type" "test")
7848    (set_attr "modrm" "0,1,1,1")
7849    (set_attr "mode" "QI,QI,QI,SI")
7850    (set_attr "pent_pair" "uv,np,uv,np")])
7852 (define_insn "*testqi_1"
7853   [(set (reg FLAGS_REG)
7854         (compare
7855           (and:QI
7856             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7857             (match_operand:QI 1 "general_operand" "n,n,qn"))
7858           (const_int 0)))]
7859   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7860    && ix86_match_ccmode (insn, CCNOmode)"
7861   "test{b}\t{%1, %0|%0, %1}"
7862   [(set_attr "type" "test")
7863    (set_attr "modrm" "0,1,1")
7864    (set_attr "mode" "QI")
7865    (set_attr "pent_pair" "uv,np,uv")])
7867 (define_expand "testqi_ext_ccno_0"
7868   [(set (reg:CCNO FLAGS_REG)
7869         (compare:CCNO
7870           (and:SI
7871             (zero_extract:SI
7872               (match_operand 0 "ext_register_operand" "")
7873               (const_int 8)
7874               (const_int 8))
7875             (match_operand 1 "const_int_operand" ""))
7876           (const_int 0)))]
7877   ""
7878   "")
7880 (define_insn "*testqi_ext_0"
7881   [(set (reg FLAGS_REG)
7882         (compare
7883           (and:SI
7884             (zero_extract:SI
7885               (match_operand 0 "ext_register_operand" "Q")
7886               (const_int 8)
7887               (const_int 8))
7888             (match_operand 1 "const_int_operand" "n"))
7889           (const_int 0)))]
7890   "ix86_match_ccmode (insn, CCNOmode)"
7891   "test{b}\t{%1, %h0|%h0, %1}"
7892   [(set_attr "type" "test")
7893    (set_attr "mode" "QI")
7894    (set_attr "length_immediate" "1")
7895    (set_attr "pent_pair" "np")])
7897 (define_insn "*testqi_ext_1"
7898   [(set (reg FLAGS_REG)
7899         (compare
7900           (and:SI
7901             (zero_extract:SI
7902               (match_operand 0 "ext_register_operand" "Q")
7903               (const_int 8)
7904               (const_int 8))
7905             (zero_extend:SI
7906               (match_operand:QI 1 "general_operand" "Qm")))
7907           (const_int 0)))]
7908   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7909    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7910   "test{b}\t{%1, %h0|%h0, %1}"
7911   [(set_attr "type" "test")
7912    (set_attr "mode" "QI")])
7914 (define_insn "*testqi_ext_1_rex64"
7915   [(set (reg FLAGS_REG)
7916         (compare
7917           (and:SI
7918             (zero_extract:SI
7919               (match_operand 0 "ext_register_operand" "Q")
7920               (const_int 8)
7921               (const_int 8))
7922             (zero_extend:SI
7923               (match_operand:QI 1 "register_operand" "Q")))
7924           (const_int 0)))]
7925   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7926   "test{b}\t{%1, %h0|%h0, %1}"
7927   [(set_attr "type" "test")
7928    (set_attr "mode" "QI")])
7930 (define_insn "*testqi_ext_2"
7931   [(set (reg FLAGS_REG)
7932         (compare
7933           (and:SI
7934             (zero_extract:SI
7935               (match_operand 0 "ext_register_operand" "Q")
7936               (const_int 8)
7937               (const_int 8))
7938             (zero_extract:SI
7939               (match_operand 1 "ext_register_operand" "Q")
7940               (const_int 8)
7941               (const_int 8)))
7942           (const_int 0)))]
7943   "ix86_match_ccmode (insn, CCNOmode)"
7944   "test{b}\t{%h1, %h0|%h0, %h1}"
7945   [(set_attr "type" "test")
7946    (set_attr "mode" "QI")])
7948 ;; Combine likes to form bit extractions for some tests.  Humor it.
7949 (define_insn "*testqi_ext_3"
7950   [(set (reg FLAGS_REG)
7951         (compare (zero_extract:SI
7952                    (match_operand 0 "nonimmediate_operand" "rm")
7953                    (match_operand:SI 1 "const_int_operand" "")
7954                    (match_operand:SI 2 "const_int_operand" ""))
7955                  (const_int 0)))]
7956   "ix86_match_ccmode (insn, CCNOmode)
7957    && (GET_MODE (operands[0]) == SImode
7958        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7959        || GET_MODE (operands[0]) == HImode
7960        || GET_MODE (operands[0]) == QImode)"
7961   "#")
7963 (define_insn "*testqi_ext_3_rex64"
7964   [(set (reg FLAGS_REG)
7965         (compare (zero_extract:DI
7966                    (match_operand 0 "nonimmediate_operand" "rm")
7967                    (match_operand:DI 1 "const_int_operand" "")
7968                    (match_operand:DI 2 "const_int_operand" ""))
7969                  (const_int 0)))]
7970   "TARGET_64BIT
7971    && ix86_match_ccmode (insn, CCNOmode)
7972    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7973    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7974    /* Ensure that resulting mask is zero or sign extended operand.  */
7975    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7976        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7977            && INTVAL (operands[1]) > 32))
7978    && (GET_MODE (operands[0]) == SImode
7979        || GET_MODE (operands[0]) == DImode
7980        || GET_MODE (operands[0]) == HImode
7981        || GET_MODE (operands[0]) == QImode)"
7982   "#")
7984 (define_split
7985   [(set (match_operand 0 "flags_reg_operand" "")
7986         (match_operator 1 "compare_operator"
7987           [(zero_extract
7988              (match_operand 2 "nonimmediate_operand" "")
7989              (match_operand 3 "const_int_operand" "")
7990              (match_operand 4 "const_int_operand" ""))
7991            (const_int 0)]))]
7992   "ix86_match_ccmode (insn, CCNOmode)"
7993   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7995   rtx val = operands[2];
7996   HOST_WIDE_INT len = INTVAL (operands[3]);
7997   HOST_WIDE_INT pos = INTVAL (operands[4]);
7998   HOST_WIDE_INT mask;
7999   enum machine_mode mode, submode;
8001   mode = GET_MODE (val);
8002   if (GET_CODE (val) == MEM)
8003     {
8004       /* ??? Combine likes to put non-volatile mem extractions in QImode
8005          no matter the size of the test.  So find a mode that works.  */
8006       if (! MEM_VOLATILE_P (val))
8007         {
8008           mode = smallest_mode_for_size (pos + len, MODE_INT);
8009           val = adjust_address (val, mode, 0);
8010         }
8011     }
8012   else if (GET_CODE (val) == SUBREG
8013            && (submode = GET_MODE (SUBREG_REG (val)),
8014                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8015            && pos + len <= GET_MODE_BITSIZE (submode))
8016     {
8017       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8018       mode = submode;
8019       val = SUBREG_REG (val);
8020     }
8021   else if (mode == HImode && pos + len <= 8)
8022     {
8023       /* Small HImode tests can be converted to QImode.  */
8024       mode = QImode;
8025       val = gen_lowpart (QImode, val);
8026     }
8028   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8029   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8031   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8034 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8035 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8036 ;; this is relatively important trick.
8037 ;; Do the conversion only post-reload to avoid limiting of the register class
8038 ;; to QI regs.
8039 (define_split
8040   [(set (match_operand 0 "flags_reg_operand" "")
8041         (match_operator 1 "compare_operator"
8042           [(and (match_operand 2 "register_operand" "")
8043                 (match_operand 3 "const_int_operand" ""))
8044            (const_int 0)]))]
8045    "reload_completed
8046     && QI_REG_P (operands[2])
8047     && GET_MODE (operands[2]) != QImode
8048     && ((ix86_match_ccmode (insn, CCZmode)
8049          && !(INTVAL (operands[3]) & ~(255 << 8)))
8050         || (ix86_match_ccmode (insn, CCNOmode)
8051             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8052   [(set (match_dup 0)
8053         (match_op_dup 1
8054           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8055                    (match_dup 3))
8056            (const_int 0)]))]
8057   "operands[2] = gen_lowpart (SImode, operands[2]);
8058    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8060 (define_split
8061   [(set (match_operand 0 "flags_reg_operand" "")
8062         (match_operator 1 "compare_operator"
8063           [(and (match_operand 2 "nonimmediate_operand" "")
8064                 (match_operand 3 "const_int_operand" ""))
8065            (const_int 0)]))]
8066    "reload_completed
8067     && GET_MODE (operands[2]) != QImode
8068     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8069     && ((ix86_match_ccmode (insn, CCZmode)
8070          && !(INTVAL (operands[3]) & ~255))
8071         || (ix86_match_ccmode (insn, CCNOmode)
8072             && !(INTVAL (operands[3]) & ~127)))"
8073   [(set (match_dup 0)
8074         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8075                          (const_int 0)]))]
8076   "operands[2] = gen_lowpart (QImode, operands[2]);
8077    operands[3] = gen_lowpart (QImode, operands[3]);")
8080 ;; %%% This used to optimize known byte-wide and operations to memory,
8081 ;; and sometimes to QImode registers.  If this is considered useful,
8082 ;; it should be done with splitters.
8084 (define_expand "anddi3"
8085   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8086         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8087                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8088    (clobber (reg:CC FLAGS_REG))]
8089   "TARGET_64BIT"
8090   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8092 (define_insn "*anddi_1_rex64"
8093   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8094         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8095                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8096    (clobber (reg:CC FLAGS_REG))]
8097   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8099   switch (get_attr_type (insn))
8100     {
8101     case TYPE_IMOVX:
8102       {
8103         enum machine_mode mode;
8105         if (GET_CODE (operands[2]) != CONST_INT)
8106           abort ();
8107         if (INTVAL (operands[2]) == 0xff)
8108           mode = QImode;
8109         else if (INTVAL (operands[2]) == 0xffff)
8110           mode = HImode;
8111         else
8112           abort ();
8113         
8114         operands[1] = gen_lowpart (mode, operands[1]);
8115         if (mode == QImode)
8116           return "movz{bq|x}\t{%1,%0|%0, %1}";
8117         else
8118           return "movz{wq|x}\t{%1,%0|%0, %1}";
8119       }
8121     default:
8122       if (! rtx_equal_p (operands[0], operands[1]))
8123         abort ();
8124       if (get_attr_mode (insn) == MODE_SI)
8125         return "and{l}\t{%k2, %k0|%k0, %k2}";
8126       else
8127         return "and{q}\t{%2, %0|%0, %2}";
8128     }
8130   [(set_attr "type" "alu,alu,alu,imovx")
8131    (set_attr "length_immediate" "*,*,*,0")
8132    (set_attr "mode" "SI,DI,DI,DI")])
8134 (define_insn "*anddi_2"
8135   [(set (reg FLAGS_REG)
8136         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8137                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8138                  (const_int 0)))
8139    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8140         (and:DI (match_dup 1) (match_dup 2)))]
8141   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8142    && ix86_binary_operator_ok (AND, DImode, operands)"
8143   "@
8144    and{l}\t{%k2, %k0|%k0, %k2}
8145    and{q}\t{%2, %0|%0, %2}
8146    and{q}\t{%2, %0|%0, %2}"
8147   [(set_attr "type" "alu")
8148    (set_attr "mode" "SI,DI,DI")])
8150 (define_expand "andsi3"
8151   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8152         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8153                 (match_operand:SI 2 "general_operand" "")))
8154    (clobber (reg:CC FLAGS_REG))]
8155   ""
8156   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8158 (define_insn "*andsi_1"
8159   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8160         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8161                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8162    (clobber (reg:CC FLAGS_REG))]
8163   "ix86_binary_operator_ok (AND, SImode, operands)"
8165   switch (get_attr_type (insn))
8166     {
8167     case TYPE_IMOVX:
8168       {
8169         enum machine_mode mode;
8171         if (GET_CODE (operands[2]) != CONST_INT)
8172           abort ();
8173         if (INTVAL (operands[2]) == 0xff)
8174           mode = QImode;
8175         else if (INTVAL (operands[2]) == 0xffff)
8176           mode = HImode;
8177         else
8178           abort ();
8179         
8180         operands[1] = gen_lowpart (mode, operands[1]);
8181         if (mode == QImode)
8182           return "movz{bl|x}\t{%1,%0|%0, %1}";
8183         else
8184           return "movz{wl|x}\t{%1,%0|%0, %1}";
8185       }
8187     default:
8188       if (! rtx_equal_p (operands[0], operands[1]))
8189         abort ();
8190       return "and{l}\t{%2, %0|%0, %2}";
8191     }
8193   [(set_attr "type" "alu,alu,imovx")
8194    (set_attr "length_immediate" "*,*,0")
8195    (set_attr "mode" "SI")])
8197 (define_split
8198   [(set (match_operand 0 "register_operand" "")
8199         (and (match_dup 0)
8200              (const_int -65536)))
8201    (clobber (reg:CC FLAGS_REG))]
8202   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8203   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8204   "operands[1] = gen_lowpart (HImode, operands[0]);")
8206 (define_split
8207   [(set (match_operand 0 "ext_register_operand" "")
8208         (and (match_dup 0)
8209              (const_int -256)))
8210    (clobber (reg:CC FLAGS_REG))]
8211   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8212   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8213   "operands[1] = gen_lowpart (QImode, operands[0]);")
8215 (define_split
8216   [(set (match_operand 0 "ext_register_operand" "")
8217         (and (match_dup 0)
8218              (const_int -65281)))
8219    (clobber (reg:CC FLAGS_REG))]
8220   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8221   [(parallel [(set (zero_extract:SI (match_dup 0)
8222                                     (const_int 8)
8223                                     (const_int 8))
8224                    (xor:SI 
8225                      (zero_extract:SI (match_dup 0)
8226                                       (const_int 8)
8227                                       (const_int 8))
8228                      (zero_extract:SI (match_dup 0)
8229                                       (const_int 8)
8230                                       (const_int 8))))
8231               (clobber (reg:CC FLAGS_REG))])]
8232   "operands[0] = gen_lowpart (SImode, operands[0]);")
8234 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8235 (define_insn "*andsi_1_zext"
8236   [(set (match_operand:DI 0 "register_operand" "=r")
8237         (zero_extend:DI
8238           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8239                   (match_operand:SI 2 "general_operand" "rim"))))
8240    (clobber (reg:CC FLAGS_REG))]
8241   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8242   "and{l}\t{%2, %k0|%k0, %2}"
8243   [(set_attr "type" "alu")
8244    (set_attr "mode" "SI")])
8246 (define_insn "*andsi_2"
8247   [(set (reg FLAGS_REG)
8248         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8249                          (match_operand:SI 2 "general_operand" "rim,ri"))
8250                  (const_int 0)))
8251    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8252         (and:SI (match_dup 1) (match_dup 2)))]
8253   "ix86_match_ccmode (insn, CCNOmode)
8254    && ix86_binary_operator_ok (AND, SImode, operands)"
8255   "and{l}\t{%2, %0|%0, %2}"
8256   [(set_attr "type" "alu")
8257    (set_attr "mode" "SI")])
8259 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8260 (define_insn "*andsi_2_zext"
8261   [(set (reg FLAGS_REG)
8262         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8263                          (match_operand:SI 2 "general_operand" "rim"))
8264                  (const_int 0)))
8265    (set (match_operand:DI 0 "register_operand" "=r")
8266         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8267   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8268    && ix86_binary_operator_ok (AND, SImode, operands)"
8269   "and{l}\t{%2, %k0|%k0, %2}"
8270   [(set_attr "type" "alu")
8271    (set_attr "mode" "SI")])
8273 (define_expand "andhi3"
8274   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8275         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8276                 (match_operand:HI 2 "general_operand" "")))
8277    (clobber (reg:CC FLAGS_REG))]
8278   "TARGET_HIMODE_MATH"
8279   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8281 (define_insn "*andhi_1"
8282   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8283         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8284                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8285    (clobber (reg:CC FLAGS_REG))]
8286   "ix86_binary_operator_ok (AND, HImode, operands)"
8288   switch (get_attr_type (insn))
8289     {
8290     case TYPE_IMOVX:
8291       if (GET_CODE (operands[2]) != CONST_INT)
8292         abort ();
8293       if (INTVAL (operands[2]) == 0xff)
8294         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8295       abort ();
8297     default:
8298       if (! rtx_equal_p (operands[0], operands[1]))
8299         abort ();
8301       return "and{w}\t{%2, %0|%0, %2}";
8302     }
8304   [(set_attr "type" "alu,alu,imovx")
8305    (set_attr "length_immediate" "*,*,0")
8306    (set_attr "mode" "HI,HI,SI")])
8308 (define_insn "*andhi_2"
8309   [(set (reg FLAGS_REG)
8310         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8311                          (match_operand:HI 2 "general_operand" "rim,ri"))
8312                  (const_int 0)))
8313    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8314         (and:HI (match_dup 1) (match_dup 2)))]
8315   "ix86_match_ccmode (insn, CCNOmode)
8316    && ix86_binary_operator_ok (AND, HImode, operands)"
8317   "and{w}\t{%2, %0|%0, %2}"
8318   [(set_attr "type" "alu")
8319    (set_attr "mode" "HI")])
8321 (define_expand "andqi3"
8322   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8323         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8324                 (match_operand:QI 2 "general_operand" "")))
8325    (clobber (reg:CC FLAGS_REG))]
8326   "TARGET_QIMODE_MATH"
8327   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8329 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8330 (define_insn "*andqi_1"
8331   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8332         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8333                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8334    (clobber (reg:CC FLAGS_REG))]
8335   "ix86_binary_operator_ok (AND, QImode, operands)"
8336   "@
8337    and{b}\t{%2, %0|%0, %2}
8338    and{b}\t{%2, %0|%0, %2}
8339    and{l}\t{%k2, %k0|%k0, %k2}"
8340   [(set_attr "type" "alu")
8341    (set_attr "mode" "QI,QI,SI")])
8343 (define_insn "*andqi_1_slp"
8344   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8345         (and:QI (match_dup 0)
8346                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8347    (clobber (reg:CC FLAGS_REG))]
8348   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8349    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8350   "and{b}\t{%1, %0|%0, %1}"
8351   [(set_attr "type" "alu1")
8352    (set_attr "mode" "QI")])
8354 (define_insn "*andqi_2_maybe_si"
8355   [(set (reg FLAGS_REG)
8356         (compare (and:QI
8357                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8358                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8359                  (const_int 0)))
8360    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8361         (and:QI (match_dup 1) (match_dup 2)))]
8362   "ix86_binary_operator_ok (AND, QImode, operands)
8363    && ix86_match_ccmode (insn,
8364                          GET_CODE (operands[2]) == CONST_INT
8365                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8367   if (which_alternative == 2)
8368     {
8369       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8370         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8371       return "and{l}\t{%2, %k0|%k0, %2}";
8372     }
8373   return "and{b}\t{%2, %0|%0, %2}";
8375   [(set_attr "type" "alu")
8376    (set_attr "mode" "QI,QI,SI")])
8378 (define_insn "*andqi_2"
8379   [(set (reg FLAGS_REG)
8380         (compare (and:QI
8381                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8382                    (match_operand:QI 2 "general_operand" "qim,qi"))
8383                  (const_int 0)))
8384    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8385         (and:QI (match_dup 1) (match_dup 2)))]
8386   "ix86_match_ccmode (insn, CCNOmode)
8387    && ix86_binary_operator_ok (AND, QImode, operands)"
8388   "and{b}\t{%2, %0|%0, %2}"
8389   [(set_attr "type" "alu")
8390    (set_attr "mode" "QI")])
8392 (define_insn "*andqi_2_slp"
8393   [(set (reg FLAGS_REG)
8394         (compare (and:QI
8395                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8396                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8397                  (const_int 0)))
8398    (set (strict_low_part (match_dup 0))
8399         (and:QI (match_dup 0) (match_dup 1)))]
8400   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8401    && ix86_match_ccmode (insn, CCNOmode)
8402    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8403   "and{b}\t{%1, %0|%0, %1}"
8404   [(set_attr "type" "alu1")
8405    (set_attr "mode" "QI")])
8407 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8408 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8409 ;; for a QImode operand, which of course failed.
8411 (define_insn "andqi_ext_0"
8412   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8413                          (const_int 8)
8414                          (const_int 8))
8415         (and:SI 
8416           (zero_extract:SI
8417             (match_operand 1 "ext_register_operand" "0")
8418             (const_int 8)
8419             (const_int 8))
8420           (match_operand 2 "const_int_operand" "n")))
8421    (clobber (reg:CC FLAGS_REG))]
8422   ""
8423   "and{b}\t{%2, %h0|%h0, %2}"
8424   [(set_attr "type" "alu")
8425    (set_attr "length_immediate" "1")
8426    (set_attr "mode" "QI")])
8428 ;; Generated by peephole translating test to and.  This shows up
8429 ;; often in fp comparisons.
8431 (define_insn "*andqi_ext_0_cc"
8432   [(set (reg FLAGS_REG)
8433         (compare
8434           (and:SI
8435             (zero_extract:SI
8436               (match_operand 1 "ext_register_operand" "0")
8437               (const_int 8)
8438               (const_int 8))
8439             (match_operand 2 "const_int_operand" "n"))
8440           (const_int 0)))
8441    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8442                          (const_int 8)
8443                          (const_int 8))
8444         (and:SI 
8445           (zero_extract:SI
8446             (match_dup 1)
8447             (const_int 8)
8448             (const_int 8))
8449           (match_dup 2)))]
8450   "ix86_match_ccmode (insn, CCNOmode)"
8451   "and{b}\t{%2, %h0|%h0, %2}"
8452   [(set_attr "type" "alu")
8453    (set_attr "length_immediate" "1")
8454    (set_attr "mode" "QI")])
8456 (define_insn "*andqi_ext_1"
8457   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8458                          (const_int 8)
8459                          (const_int 8))
8460         (and:SI 
8461           (zero_extract:SI
8462             (match_operand 1 "ext_register_operand" "0")
8463             (const_int 8)
8464             (const_int 8))
8465           (zero_extend:SI
8466             (match_operand:QI 2 "general_operand" "Qm"))))
8467    (clobber (reg:CC FLAGS_REG))]
8468   "!TARGET_64BIT"
8469   "and{b}\t{%2, %h0|%h0, %2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "length_immediate" "0")
8472    (set_attr "mode" "QI")])
8474 (define_insn "*andqi_ext_1_rex64"
8475   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8476                          (const_int 8)
8477                          (const_int 8))
8478         (and:SI 
8479           (zero_extract:SI
8480             (match_operand 1 "ext_register_operand" "0")
8481             (const_int 8)
8482             (const_int 8))
8483           (zero_extend:SI
8484             (match_operand 2 "ext_register_operand" "Q"))))
8485    (clobber (reg:CC FLAGS_REG))]
8486   "TARGET_64BIT"
8487   "and{b}\t{%2, %h0|%h0, %2}"
8488   [(set_attr "type" "alu")
8489    (set_attr "length_immediate" "0")
8490    (set_attr "mode" "QI")])
8492 (define_insn "*andqi_ext_2"
8493   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8494                          (const_int 8)
8495                          (const_int 8))
8496         (and:SI
8497           (zero_extract:SI
8498             (match_operand 1 "ext_register_operand" "%0")
8499             (const_int 8)
8500             (const_int 8))
8501           (zero_extract:SI
8502             (match_operand 2 "ext_register_operand" "Q")
8503             (const_int 8)
8504             (const_int 8))))
8505    (clobber (reg:CC FLAGS_REG))]
8506   ""
8507   "and{b}\t{%h2, %h0|%h0, %h2}"
8508   [(set_attr "type" "alu")
8509    (set_attr "length_immediate" "0")
8510    (set_attr "mode" "QI")])
8512 ;; Convert wide AND instructions with immediate operand to shorter QImode
8513 ;; equivalents when possible.
8514 ;; Don't do the splitting with memory operands, since it introduces risk
8515 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8516 ;; for size, but that can (should?) be handled by generic code instead.
8517 (define_split
8518   [(set (match_operand 0 "register_operand" "")
8519         (and (match_operand 1 "register_operand" "")
8520              (match_operand 2 "const_int_operand" "")))
8521    (clobber (reg:CC FLAGS_REG))]
8522    "reload_completed
8523     && QI_REG_P (operands[0])
8524     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8525     && !(~INTVAL (operands[2]) & ~(255 << 8))
8526     && GET_MODE (operands[0]) != QImode"
8527   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8528                    (and:SI (zero_extract:SI (match_dup 1)
8529                                             (const_int 8) (const_int 8))
8530                            (match_dup 2)))
8531               (clobber (reg:CC FLAGS_REG))])]
8532   "operands[0] = gen_lowpart (SImode, operands[0]);
8533    operands[1] = gen_lowpart (SImode, operands[1]);
8534    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8536 ;; Since AND can be encoded with sign extended immediate, this is only
8537 ;; profitable when 7th bit is not set.
8538 (define_split
8539   [(set (match_operand 0 "register_operand" "")
8540         (and (match_operand 1 "general_operand" "")
8541              (match_operand 2 "const_int_operand" "")))
8542    (clobber (reg:CC FLAGS_REG))]
8543    "reload_completed
8544     && ANY_QI_REG_P (operands[0])
8545     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8546     && !(~INTVAL (operands[2]) & ~255)
8547     && !(INTVAL (operands[2]) & 128)
8548     && GET_MODE (operands[0]) != QImode"
8549   [(parallel [(set (strict_low_part (match_dup 0))
8550                    (and:QI (match_dup 1)
8551                            (match_dup 2)))
8552               (clobber (reg:CC FLAGS_REG))])]
8553   "operands[0] = gen_lowpart (QImode, operands[0]);
8554    operands[1] = gen_lowpart (QImode, operands[1]);
8555    operands[2] = gen_lowpart (QImode, operands[2]);")
8557 ;; Logical inclusive OR instructions
8559 ;; %%% This used to optimize known byte-wide and operations to memory.
8560 ;; If this is considered useful, it should be done with splitters.
8562 (define_expand "iordi3"
8563   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8564         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8565                 (match_operand:DI 2 "x86_64_general_operand" "")))
8566    (clobber (reg:CC FLAGS_REG))]
8567   "TARGET_64BIT"
8568   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8570 (define_insn "*iordi_1_rex64"
8571   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8572         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8573                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8574    (clobber (reg:CC FLAGS_REG))]
8575   "TARGET_64BIT
8576    && ix86_binary_operator_ok (IOR, DImode, operands)"
8577   "or{q}\t{%2, %0|%0, %2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "DI")])
8581 (define_insn "*iordi_2_rex64"
8582   [(set (reg FLAGS_REG)
8583         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8584                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8585                  (const_int 0)))
8586    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8587         (ior:DI (match_dup 1) (match_dup 2)))]
8588   "TARGET_64BIT
8589    && ix86_match_ccmode (insn, CCNOmode)
8590    && ix86_binary_operator_ok (IOR, DImode, operands)"
8591   "or{q}\t{%2, %0|%0, %2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "DI")])
8595 (define_insn "*iordi_3_rex64"
8596   [(set (reg FLAGS_REG)
8597         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8598                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8599                  (const_int 0)))
8600    (clobber (match_scratch:DI 0 "=r"))]
8601   "TARGET_64BIT
8602    && ix86_match_ccmode (insn, CCNOmode)
8603    && ix86_binary_operator_ok (IOR, DImode, operands)"
8604   "or{q}\t{%2, %0|%0, %2}"
8605   [(set_attr "type" "alu")
8606    (set_attr "mode" "DI")])
8609 (define_expand "iorsi3"
8610   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8611         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8612                 (match_operand:SI 2 "general_operand" "")))
8613    (clobber (reg:CC FLAGS_REG))]
8614   ""
8615   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8617 (define_insn "*iorsi_1"
8618   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8619         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8620                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8621    (clobber (reg:CC FLAGS_REG))]
8622   "ix86_binary_operator_ok (IOR, SImode, operands)"
8623   "or{l}\t{%2, %0|%0, %2}"
8624   [(set_attr "type" "alu")
8625    (set_attr "mode" "SI")])
8627 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8628 (define_insn "*iorsi_1_zext"
8629   [(set (match_operand:DI 0 "register_operand" "=rm")
8630         (zero_extend:DI
8631           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8632                   (match_operand:SI 2 "general_operand" "rim"))))
8633    (clobber (reg:CC FLAGS_REG))]
8634   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8635   "or{l}\t{%2, %k0|%k0, %2}"
8636   [(set_attr "type" "alu")
8637    (set_attr "mode" "SI")])
8639 (define_insn "*iorsi_1_zext_imm"
8640   [(set (match_operand:DI 0 "register_operand" "=rm")
8641         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8642                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8643    (clobber (reg:CC FLAGS_REG))]
8644   "TARGET_64BIT"
8645   "or{l}\t{%2, %k0|%k0, %2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "mode" "SI")])
8649 (define_insn "*iorsi_2"
8650   [(set (reg FLAGS_REG)
8651         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8652                          (match_operand:SI 2 "general_operand" "rim,ri"))
8653                  (const_int 0)))
8654    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8655         (ior:SI (match_dup 1) (match_dup 2)))]
8656   "ix86_match_ccmode (insn, CCNOmode)
8657    && ix86_binary_operator_ok (IOR, SImode, operands)"
8658   "or{l}\t{%2, %0|%0, %2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "mode" "SI")])
8662 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8663 ;; ??? Special case for immediate operand is missing - it is tricky.
8664 (define_insn "*iorsi_2_zext"
8665   [(set (reg FLAGS_REG)
8666         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8667                          (match_operand:SI 2 "general_operand" "rim"))
8668                  (const_int 0)))
8669    (set (match_operand:DI 0 "register_operand" "=r")
8670         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8671   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8672    && ix86_binary_operator_ok (IOR, SImode, operands)"
8673   "or{l}\t{%2, %k0|%k0, %2}"
8674   [(set_attr "type" "alu")
8675    (set_attr "mode" "SI")])
8677 (define_insn "*iorsi_2_zext_imm"
8678   [(set (reg FLAGS_REG)
8679         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8680                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8681                  (const_int 0)))
8682    (set (match_operand:DI 0 "register_operand" "=r")
8683         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8684   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8685    && ix86_binary_operator_ok (IOR, SImode, operands)"
8686   "or{l}\t{%2, %k0|%k0, %2}"
8687   [(set_attr "type" "alu")
8688    (set_attr "mode" "SI")])
8690 (define_insn "*iorsi_3"
8691   [(set (reg FLAGS_REG)
8692         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8693                          (match_operand:SI 2 "general_operand" "rim"))
8694                  (const_int 0)))
8695    (clobber (match_scratch:SI 0 "=r"))]
8696   "ix86_match_ccmode (insn, CCNOmode)
8697    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8698   "or{l}\t{%2, %0|%0, %2}"
8699   [(set_attr "type" "alu")
8700    (set_attr "mode" "SI")])
8702 (define_expand "iorhi3"
8703   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8704         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8705                 (match_operand:HI 2 "general_operand" "")))
8706    (clobber (reg:CC FLAGS_REG))]
8707   "TARGET_HIMODE_MATH"
8708   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8710 (define_insn "*iorhi_1"
8711   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8712         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8713                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8714    (clobber (reg:CC FLAGS_REG))]
8715   "ix86_binary_operator_ok (IOR, HImode, operands)"
8716   "or{w}\t{%2, %0|%0, %2}"
8717   [(set_attr "type" "alu")
8718    (set_attr "mode" "HI")])
8720 (define_insn "*iorhi_2"
8721   [(set (reg FLAGS_REG)
8722         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8723                          (match_operand:HI 2 "general_operand" "rim,ri"))
8724                  (const_int 0)))
8725    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8726         (ior:HI (match_dup 1) (match_dup 2)))]
8727   "ix86_match_ccmode (insn, CCNOmode)
8728    && ix86_binary_operator_ok (IOR, HImode, operands)"
8729   "or{w}\t{%2, %0|%0, %2}"
8730   [(set_attr "type" "alu")
8731    (set_attr "mode" "HI")])
8733 (define_insn "*iorhi_3"
8734   [(set (reg FLAGS_REG)
8735         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8736                          (match_operand:HI 2 "general_operand" "rim"))
8737                  (const_int 0)))
8738    (clobber (match_scratch:HI 0 "=r"))]
8739   "ix86_match_ccmode (insn, CCNOmode)
8740    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8741   "or{w}\t{%2, %0|%0, %2}"
8742   [(set_attr "type" "alu")
8743    (set_attr "mode" "HI")])
8745 (define_expand "iorqi3"
8746   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8747         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8748                 (match_operand:QI 2 "general_operand" "")))
8749    (clobber (reg:CC FLAGS_REG))]
8750   "TARGET_QIMODE_MATH"
8751   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8753 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8754 (define_insn "*iorqi_1"
8755   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8756         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8757                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8758    (clobber (reg:CC FLAGS_REG))]
8759   "ix86_binary_operator_ok (IOR, QImode, operands)"
8760   "@
8761    or{b}\t{%2, %0|%0, %2}
8762    or{b}\t{%2, %0|%0, %2}
8763    or{l}\t{%k2, %k0|%k0, %k2}"
8764   [(set_attr "type" "alu")
8765    (set_attr "mode" "QI,QI,SI")])
8767 (define_insn "*iorqi_1_slp"
8768   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8769         (ior:QI (match_dup 0)
8770                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8771    (clobber (reg:CC FLAGS_REG))]
8772   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8773    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8774   "or{b}\t{%1, %0|%0, %1}"
8775   [(set_attr "type" "alu1")
8776    (set_attr "mode" "QI")])
8778 (define_insn "*iorqi_2"
8779   [(set (reg FLAGS_REG)
8780         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8781                          (match_operand:QI 2 "general_operand" "qim,qi"))
8782                  (const_int 0)))
8783    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8784         (ior:QI (match_dup 1) (match_dup 2)))]
8785   "ix86_match_ccmode (insn, CCNOmode)
8786    && ix86_binary_operator_ok (IOR, QImode, operands)"
8787   "or{b}\t{%2, %0|%0, %2}"
8788   [(set_attr "type" "alu")
8789    (set_attr "mode" "QI")])
8791 (define_insn "*iorqi_2_slp"
8792   [(set (reg FLAGS_REG)
8793         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8794                          (match_operand:QI 1 "general_operand" "qim,qi"))
8795                  (const_int 0)))
8796    (set (strict_low_part (match_dup 0))
8797         (ior:QI (match_dup 0) (match_dup 1)))]
8798   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8799    && ix86_match_ccmode (insn, CCNOmode)
8800    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8801   "or{b}\t{%1, %0|%0, %1}"
8802   [(set_attr "type" "alu1")
8803    (set_attr "mode" "QI")])
8805 (define_insn "*iorqi_3"
8806   [(set (reg FLAGS_REG)
8807         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8808                          (match_operand:QI 2 "general_operand" "qim"))
8809                  (const_int 0)))
8810    (clobber (match_scratch:QI 0 "=q"))]
8811   "ix86_match_ccmode (insn, CCNOmode)
8812    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8813   "or{b}\t{%2, %0|%0, %2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "mode" "QI")])
8817 (define_insn "iorqi_ext_0"
8818   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8819                          (const_int 8)
8820                          (const_int 8))
8821         (ior:SI 
8822           (zero_extract:SI
8823             (match_operand 1 "ext_register_operand" "0")
8824             (const_int 8)
8825             (const_int 8))
8826           (match_operand 2 "const_int_operand" "n")))
8827    (clobber (reg:CC FLAGS_REG))]
8828   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8829   "or{b}\t{%2, %h0|%h0, %2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "length_immediate" "1")
8832    (set_attr "mode" "QI")])
8834 (define_insn "*iorqi_ext_1"
8835   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8836                          (const_int 8)
8837                          (const_int 8))
8838         (ior:SI 
8839           (zero_extract:SI
8840             (match_operand 1 "ext_register_operand" "0")
8841             (const_int 8)
8842             (const_int 8))
8843           (zero_extend:SI
8844             (match_operand:QI 2 "general_operand" "Qm"))))
8845    (clobber (reg:CC FLAGS_REG))]
8846   "!TARGET_64BIT
8847    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8848   "or{b}\t{%2, %h0|%h0, %2}"
8849   [(set_attr "type" "alu")
8850    (set_attr "length_immediate" "0")
8851    (set_attr "mode" "QI")])
8853 (define_insn "*iorqi_ext_1_rex64"
8854   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8855                          (const_int 8)
8856                          (const_int 8))
8857         (ior:SI 
8858           (zero_extract:SI
8859             (match_operand 1 "ext_register_operand" "0")
8860             (const_int 8)
8861             (const_int 8))
8862           (zero_extend:SI
8863             (match_operand 2 "ext_register_operand" "Q"))))
8864    (clobber (reg:CC FLAGS_REG))]
8865   "TARGET_64BIT
8866    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8867   "or{b}\t{%2, %h0|%h0, %2}"
8868   [(set_attr "type" "alu")
8869    (set_attr "length_immediate" "0")
8870    (set_attr "mode" "QI")])
8872 (define_insn "*iorqi_ext_2"
8873   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8874                          (const_int 8)
8875                          (const_int 8))
8876         (ior:SI 
8877           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8878                            (const_int 8)
8879                            (const_int 8))
8880           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8881                            (const_int 8)
8882                            (const_int 8))))
8883    (clobber (reg:CC FLAGS_REG))]
8884   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8885   "ior{b}\t{%h2, %h0|%h0, %h2}"
8886   [(set_attr "type" "alu")
8887    (set_attr "length_immediate" "0")
8888    (set_attr "mode" "QI")])
8890 (define_split
8891   [(set (match_operand 0 "register_operand" "")
8892         (ior (match_operand 1 "register_operand" "")
8893              (match_operand 2 "const_int_operand" "")))
8894    (clobber (reg:CC FLAGS_REG))]
8895    "reload_completed
8896     && QI_REG_P (operands[0])
8897     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8898     && !(INTVAL (operands[2]) & ~(255 << 8))
8899     && GET_MODE (operands[0]) != QImode"
8900   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8901                    (ior:SI (zero_extract:SI (match_dup 1)
8902                                             (const_int 8) (const_int 8))
8903                            (match_dup 2)))
8904               (clobber (reg:CC FLAGS_REG))])]
8905   "operands[0] = gen_lowpart (SImode, operands[0]);
8906    operands[1] = gen_lowpart (SImode, operands[1]);
8907    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8909 ;; Since OR can be encoded with sign extended immediate, this is only
8910 ;; profitable when 7th bit is set.
8911 (define_split
8912   [(set (match_operand 0 "register_operand" "")
8913         (ior (match_operand 1 "general_operand" "")
8914              (match_operand 2 "const_int_operand" "")))
8915    (clobber (reg:CC FLAGS_REG))]
8916    "reload_completed
8917     && ANY_QI_REG_P (operands[0])
8918     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8919     && !(INTVAL (operands[2]) & ~255)
8920     && (INTVAL (operands[2]) & 128)
8921     && GET_MODE (operands[0]) != QImode"
8922   [(parallel [(set (strict_low_part (match_dup 0))
8923                    (ior:QI (match_dup 1)
8924                            (match_dup 2)))
8925               (clobber (reg:CC FLAGS_REG))])]
8926   "operands[0] = gen_lowpart (QImode, operands[0]);
8927    operands[1] = gen_lowpart (QImode, operands[1]);
8928    operands[2] = gen_lowpart (QImode, operands[2]);")
8930 ;; Logical XOR instructions
8932 ;; %%% This used to optimize known byte-wide and operations to memory.
8933 ;; If this is considered useful, it should be done with splitters.
8935 (define_expand "xordi3"
8936   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8937         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8938                 (match_operand:DI 2 "x86_64_general_operand" "")))
8939    (clobber (reg:CC FLAGS_REG))]
8940   "TARGET_64BIT"
8941   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8943 (define_insn "*xordi_1_rex64"
8944   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8945         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8946                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8947    (clobber (reg:CC FLAGS_REG))]
8948   "TARGET_64BIT
8949    && ix86_binary_operator_ok (XOR, DImode, operands)"
8950   "@
8951    xor{q}\t{%2, %0|%0, %2}
8952    xor{q}\t{%2, %0|%0, %2}"
8953   [(set_attr "type" "alu")
8954    (set_attr "mode" "DI,DI")])
8956 (define_insn "*xordi_2_rex64"
8957   [(set (reg FLAGS_REG)
8958         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8959                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8960                  (const_int 0)))
8961    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8962         (xor:DI (match_dup 1) (match_dup 2)))]
8963   "TARGET_64BIT
8964    && ix86_match_ccmode (insn, CCNOmode)
8965    && ix86_binary_operator_ok (XOR, DImode, operands)"
8966   "@
8967    xor{q}\t{%2, %0|%0, %2}
8968    xor{q}\t{%2, %0|%0, %2}"
8969   [(set_attr "type" "alu")
8970    (set_attr "mode" "DI,DI")])
8972 (define_insn "*xordi_3_rex64"
8973   [(set (reg FLAGS_REG)
8974         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8975                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8976                  (const_int 0)))
8977    (clobber (match_scratch:DI 0 "=r"))]
8978   "TARGET_64BIT
8979    && ix86_match_ccmode (insn, CCNOmode)
8980    && ix86_binary_operator_ok (XOR, DImode, operands)"
8981   "xor{q}\t{%2, %0|%0, %2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "mode" "DI")])
8985 (define_expand "xorsi3"
8986   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8987         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8988                 (match_operand:SI 2 "general_operand" "")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   ""
8991   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8993 (define_insn "*xorsi_1"
8994   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8995         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8996                 (match_operand:SI 2 "general_operand" "ri,rm")))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "ix86_binary_operator_ok (XOR, SImode, operands)"
8999   "xor{l}\t{%2, %0|%0, %2}"
9000   [(set_attr "type" "alu")
9001    (set_attr "mode" "SI")])
9003 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9004 ;; Add speccase for immediates
9005 (define_insn "*xorsi_1_zext"
9006   [(set (match_operand:DI 0 "register_operand" "=r")
9007         (zero_extend:DI
9008           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9009                   (match_operand:SI 2 "general_operand" "rim"))))
9010    (clobber (reg:CC FLAGS_REG))]
9011   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9012   "xor{l}\t{%2, %k0|%k0, %2}"
9013   [(set_attr "type" "alu")
9014    (set_attr "mode" "SI")])
9016 (define_insn "*xorsi_1_zext_imm"
9017   [(set (match_operand:DI 0 "register_operand" "=r")
9018         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9019                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9020    (clobber (reg:CC FLAGS_REG))]
9021   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9022   "xor{l}\t{%2, %k0|%k0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "SI")])
9026 (define_insn "*xorsi_2"
9027   [(set (reg FLAGS_REG)
9028         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9029                          (match_operand:SI 2 "general_operand" "rim,ri"))
9030                  (const_int 0)))
9031    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9032         (xor:SI (match_dup 1) (match_dup 2)))]
9033   "ix86_match_ccmode (insn, CCNOmode)
9034    && ix86_binary_operator_ok (XOR, SImode, operands)"
9035   "xor{l}\t{%2, %0|%0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "SI")])
9039 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9040 ;; ??? Special case for immediate operand is missing - it is tricky.
9041 (define_insn "*xorsi_2_zext"
9042   [(set (reg FLAGS_REG)
9043         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9044                          (match_operand:SI 2 "general_operand" "rim"))
9045                  (const_int 0)))
9046    (set (match_operand:DI 0 "register_operand" "=r")
9047         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9048   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9049    && ix86_binary_operator_ok (XOR, SImode, operands)"
9050   "xor{l}\t{%2, %k0|%k0, %2}"
9051   [(set_attr "type" "alu")
9052    (set_attr "mode" "SI")])
9054 (define_insn "*xorsi_2_zext_imm"
9055   [(set (reg FLAGS_REG)
9056         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9057                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9058                  (const_int 0)))
9059    (set (match_operand:DI 0 "register_operand" "=r")
9060         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9061   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9062    && ix86_binary_operator_ok (XOR, SImode, operands)"
9063   "xor{l}\t{%2, %k0|%k0, %2}"
9064   [(set_attr "type" "alu")
9065    (set_attr "mode" "SI")])
9067 (define_insn "*xorsi_3"
9068   [(set (reg FLAGS_REG)
9069         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9070                          (match_operand:SI 2 "general_operand" "rim"))
9071                  (const_int 0)))
9072    (clobber (match_scratch:SI 0 "=r"))]
9073   "ix86_match_ccmode (insn, CCNOmode)
9074    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9075   "xor{l}\t{%2, %0|%0, %2}"
9076   [(set_attr "type" "alu")
9077    (set_attr "mode" "SI")])
9079 (define_expand "xorhi3"
9080   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9081         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9082                 (match_operand:HI 2 "general_operand" "")))
9083    (clobber (reg:CC FLAGS_REG))]
9084   "TARGET_HIMODE_MATH"
9085   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9087 (define_insn "*xorhi_1"
9088   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9089         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9090                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9091    (clobber (reg:CC FLAGS_REG))]
9092   "ix86_binary_operator_ok (XOR, HImode, operands)"
9093   "xor{w}\t{%2, %0|%0, %2}"
9094   [(set_attr "type" "alu")
9095    (set_attr "mode" "HI")])
9097 (define_insn "*xorhi_2"
9098   [(set (reg FLAGS_REG)
9099         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9100                          (match_operand:HI 2 "general_operand" "rim,ri"))
9101                  (const_int 0)))
9102    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9103         (xor:HI (match_dup 1) (match_dup 2)))]
9104   "ix86_match_ccmode (insn, CCNOmode)
9105    && ix86_binary_operator_ok (XOR, HImode, operands)"
9106   "xor{w}\t{%2, %0|%0, %2}"
9107   [(set_attr "type" "alu")
9108    (set_attr "mode" "HI")])
9110 (define_insn "*xorhi_3"
9111   [(set (reg FLAGS_REG)
9112         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9113                          (match_operand:HI 2 "general_operand" "rim"))
9114                  (const_int 0)))
9115    (clobber (match_scratch:HI 0 "=r"))]
9116   "ix86_match_ccmode (insn, CCNOmode)
9117    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9118   "xor{w}\t{%2, %0|%0, %2}"
9119   [(set_attr "type" "alu")
9120    (set_attr "mode" "HI")])
9122 (define_expand "xorqi3"
9123   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9124         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9125                 (match_operand:QI 2 "general_operand" "")))
9126    (clobber (reg:CC FLAGS_REG))]
9127   "TARGET_QIMODE_MATH"
9128   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9130 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9131 (define_insn "*xorqi_1"
9132   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9133         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9134                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9135    (clobber (reg:CC FLAGS_REG))]
9136   "ix86_binary_operator_ok (XOR, QImode, operands)"
9137   "@
9138    xor{b}\t{%2, %0|%0, %2}
9139    xor{b}\t{%2, %0|%0, %2}
9140    xor{l}\t{%k2, %k0|%k0, %k2}"
9141   [(set_attr "type" "alu")
9142    (set_attr "mode" "QI,QI,SI")])
9144 (define_insn "*xorqi_1_slp"
9145   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9146         (xor:QI (match_dup 0)
9147                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9148    (clobber (reg:CC FLAGS_REG))]
9149   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9150    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9151   "xor{b}\t{%1, %0|%0, %1}"
9152   [(set_attr "type" "alu1")
9153    (set_attr "mode" "QI")])
9155 (define_insn "xorqi_ext_0"
9156   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9157                          (const_int 8)
9158                          (const_int 8))
9159         (xor:SI 
9160           (zero_extract:SI
9161             (match_operand 1 "ext_register_operand" "0")
9162             (const_int 8)
9163             (const_int 8))
9164           (match_operand 2 "const_int_operand" "n")))
9165    (clobber (reg:CC FLAGS_REG))]
9166   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167   "xor{b}\t{%2, %h0|%h0, %2}"
9168   [(set_attr "type" "alu")
9169    (set_attr "length_immediate" "1")
9170    (set_attr "mode" "QI")])
9172 (define_insn "*xorqi_ext_1"
9173   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9174                          (const_int 8)
9175                          (const_int 8))
9176         (xor:SI 
9177           (zero_extract:SI
9178             (match_operand 1 "ext_register_operand" "0")
9179             (const_int 8)
9180             (const_int 8))
9181           (zero_extend:SI
9182             (match_operand:QI 2 "general_operand" "Qm"))))
9183    (clobber (reg:CC FLAGS_REG))]
9184   "!TARGET_64BIT
9185    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9186   "xor{b}\t{%2, %h0|%h0, %2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "length_immediate" "0")
9189    (set_attr "mode" "QI")])
9191 (define_insn "*xorqi_ext_1_rex64"
9192   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9193                          (const_int 8)
9194                          (const_int 8))
9195         (xor:SI 
9196           (zero_extract:SI
9197             (match_operand 1 "ext_register_operand" "0")
9198             (const_int 8)
9199             (const_int 8))
9200           (zero_extend:SI
9201             (match_operand 2 "ext_register_operand" "Q"))))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "TARGET_64BIT
9204    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9205   "xor{b}\t{%2, %h0|%h0, %2}"
9206   [(set_attr "type" "alu")
9207    (set_attr "length_immediate" "0")
9208    (set_attr "mode" "QI")])
9210 (define_insn "*xorqi_ext_2"
9211   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9212                          (const_int 8)
9213                          (const_int 8))
9214         (xor:SI 
9215           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9216                            (const_int 8)
9217                            (const_int 8))
9218           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9219                            (const_int 8)
9220                            (const_int 8))))
9221    (clobber (reg:CC FLAGS_REG))]
9222   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9223   "xor{b}\t{%h2, %h0|%h0, %h2}"
9224   [(set_attr "type" "alu")
9225    (set_attr "length_immediate" "0")
9226    (set_attr "mode" "QI")])
9228 (define_insn "*xorqi_cc_1"
9229   [(set (reg FLAGS_REG)
9230         (compare
9231           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9232                   (match_operand:QI 2 "general_operand" "qim,qi"))
9233           (const_int 0)))
9234    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9235         (xor:QI (match_dup 1) (match_dup 2)))]
9236   "ix86_match_ccmode (insn, CCNOmode)
9237    && ix86_binary_operator_ok (XOR, QImode, operands)"
9238   "xor{b}\t{%2, %0|%0, %2}"
9239   [(set_attr "type" "alu")
9240    (set_attr "mode" "QI")])
9242 (define_insn "*xorqi_2_slp"
9243   [(set (reg FLAGS_REG)
9244         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9245                          (match_operand:QI 1 "general_operand" "qim,qi"))
9246                  (const_int 0)))
9247    (set (strict_low_part (match_dup 0))
9248         (xor:QI (match_dup 0) (match_dup 1)))]
9249   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9250    && ix86_match_ccmode (insn, CCNOmode)
9251    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9252   "xor{b}\t{%1, %0|%0, %1}"
9253   [(set_attr "type" "alu1")
9254    (set_attr "mode" "QI")])
9256 (define_insn "*xorqi_cc_2"
9257   [(set (reg FLAGS_REG)
9258         (compare
9259           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9260                   (match_operand:QI 2 "general_operand" "qim"))
9261           (const_int 0)))
9262    (clobber (match_scratch:QI 0 "=q"))]
9263   "ix86_match_ccmode (insn, CCNOmode)
9264    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9265   "xor{b}\t{%2, %0|%0, %2}"
9266   [(set_attr "type" "alu")
9267    (set_attr "mode" "QI")])
9269 (define_insn "*xorqi_cc_ext_1"
9270   [(set (reg FLAGS_REG)
9271         (compare
9272           (xor:SI
9273             (zero_extract:SI
9274               (match_operand 1 "ext_register_operand" "0")
9275               (const_int 8)
9276               (const_int 8))
9277             (match_operand:QI 2 "general_operand" "qmn"))
9278           (const_int 0)))
9279    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9280                          (const_int 8)
9281                          (const_int 8))
9282         (xor:SI 
9283           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9284           (match_dup 2)))]
9285   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9286   "xor{b}\t{%2, %h0|%h0, %2}"
9287   [(set_attr "type" "alu")
9288    (set_attr "mode" "QI")])
9290 (define_insn "*xorqi_cc_ext_1_rex64"
9291   [(set (reg FLAGS_REG)
9292         (compare
9293           (xor:SI
9294             (zero_extract:SI
9295               (match_operand 1 "ext_register_operand" "0")
9296               (const_int 8)
9297               (const_int 8))
9298             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9299           (const_int 0)))
9300    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9301                          (const_int 8)
9302                          (const_int 8))
9303         (xor:SI 
9304           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9305           (match_dup 2)))]
9306   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9307   "xor{b}\t{%2, %h0|%h0, %2}"
9308   [(set_attr "type" "alu")
9309    (set_attr "mode" "QI")])
9311 (define_expand "xorqi_cc_ext_1"
9312   [(parallel [
9313      (set (reg:CCNO FLAGS_REG)
9314           (compare:CCNO
9315             (xor:SI
9316               (zero_extract:SI
9317                 (match_operand 1 "ext_register_operand" "")
9318                 (const_int 8)
9319                 (const_int 8))
9320               (match_operand:QI 2 "general_operand" ""))
9321             (const_int 0)))
9322      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9323                            (const_int 8)
9324                            (const_int 8))
9325           (xor:SI 
9326             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9327             (match_dup 2)))])]
9328   ""
9329   "")
9331 (define_split
9332   [(set (match_operand 0 "register_operand" "")
9333         (xor (match_operand 1 "register_operand" "")
9334              (match_operand 2 "const_int_operand" "")))
9335    (clobber (reg:CC FLAGS_REG))]
9336    "reload_completed
9337     && QI_REG_P (operands[0])
9338     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9339     && !(INTVAL (operands[2]) & ~(255 << 8))
9340     && GET_MODE (operands[0]) != QImode"
9341   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9342                    (xor:SI (zero_extract:SI (match_dup 1)
9343                                             (const_int 8) (const_int 8))
9344                            (match_dup 2)))
9345               (clobber (reg:CC FLAGS_REG))])]
9346   "operands[0] = gen_lowpart (SImode, operands[0]);
9347    operands[1] = gen_lowpart (SImode, operands[1]);
9348    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9350 ;; Since XOR can be encoded with sign extended immediate, this is only
9351 ;; profitable when 7th bit is set.
9352 (define_split
9353   [(set (match_operand 0 "register_operand" "")
9354         (xor (match_operand 1 "general_operand" "")
9355              (match_operand 2 "const_int_operand" "")))
9356    (clobber (reg:CC FLAGS_REG))]
9357    "reload_completed
9358     && ANY_QI_REG_P (operands[0])
9359     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9360     && !(INTVAL (operands[2]) & ~255)
9361     && (INTVAL (operands[2]) & 128)
9362     && GET_MODE (operands[0]) != QImode"
9363   [(parallel [(set (strict_low_part (match_dup 0))
9364                    (xor:QI (match_dup 1)
9365                            (match_dup 2)))
9366               (clobber (reg:CC FLAGS_REG))])]
9367   "operands[0] = gen_lowpart (QImode, operands[0]);
9368    operands[1] = gen_lowpart (QImode, operands[1]);
9369    operands[2] = gen_lowpart (QImode, operands[2]);")
9371 ;; Negation instructions
9373 (define_expand "negdi2"
9374   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9375                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9376               (clobber (reg:CC FLAGS_REG))])]
9377   ""
9378   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9380 (define_insn "*negdi2_1"
9381   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9382         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9383    (clobber (reg:CC FLAGS_REG))]
9384   "!TARGET_64BIT
9385    && ix86_unary_operator_ok (NEG, DImode, operands)"
9386   "#")
9388 (define_split
9389   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9390         (neg:DI (match_operand:DI 1 "general_operand" "")))
9391    (clobber (reg:CC FLAGS_REG))]
9392   "!TARGET_64BIT && reload_completed"
9393   [(parallel
9394     [(set (reg:CCZ FLAGS_REG)
9395           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9396      (set (match_dup 0) (neg:SI (match_dup 2)))])
9397    (parallel
9398     [(set (match_dup 1)
9399           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9400                             (match_dup 3))
9401                    (const_int 0)))
9402      (clobber (reg:CC FLAGS_REG))])
9403    (parallel
9404     [(set (match_dup 1)
9405           (neg:SI (match_dup 1)))
9406      (clobber (reg:CC FLAGS_REG))])]
9407   "split_di (operands+1, 1, operands+2, operands+3);
9408    split_di (operands+0, 1, operands+0, operands+1);")
9410 (define_insn "*negdi2_1_rex64"
9411   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9412         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9413    (clobber (reg:CC FLAGS_REG))]
9414   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9415   "neg{q}\t%0"
9416   [(set_attr "type" "negnot")
9417    (set_attr "mode" "DI")])
9419 ;; The problem with neg is that it does not perform (compare x 0),
9420 ;; it really performs (compare 0 x), which leaves us with the zero
9421 ;; flag being the only useful item.
9423 (define_insn "*negdi2_cmpz_rex64"
9424   [(set (reg:CCZ FLAGS_REG)
9425         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9426                      (const_int 0)))
9427    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9428         (neg:DI (match_dup 1)))]
9429   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9430   "neg{q}\t%0"
9431   [(set_attr "type" "negnot")
9432    (set_attr "mode" "DI")])
9435 (define_expand "negsi2"
9436   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9437                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9438               (clobber (reg:CC FLAGS_REG))])]
9439   ""
9440   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9442 (define_insn "*negsi2_1"
9443   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9444         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9445    (clobber (reg:CC FLAGS_REG))]
9446   "ix86_unary_operator_ok (NEG, SImode, operands)"
9447   "neg{l}\t%0"
9448   [(set_attr "type" "negnot")
9449    (set_attr "mode" "SI")])
9451 ;; Combine is quite creative about this pattern.
9452 (define_insn "*negsi2_1_zext"
9453   [(set (match_operand:DI 0 "register_operand" "=r")
9454         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9455                                         (const_int 32)))
9456                      (const_int 32)))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9459   "neg{l}\t%k0"
9460   [(set_attr "type" "negnot")
9461    (set_attr "mode" "SI")])
9463 ;; The problem with neg is that it does not perform (compare x 0),
9464 ;; it really performs (compare 0 x), which leaves us with the zero
9465 ;; flag being the only useful item.
9467 (define_insn "*negsi2_cmpz"
9468   [(set (reg:CCZ FLAGS_REG)
9469         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9470                      (const_int 0)))
9471    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9472         (neg:SI (match_dup 1)))]
9473   "ix86_unary_operator_ok (NEG, SImode, operands)"
9474   "neg{l}\t%0"
9475   [(set_attr "type" "negnot")
9476    (set_attr "mode" "SI")])
9478 (define_insn "*negsi2_cmpz_zext"
9479   [(set (reg:CCZ FLAGS_REG)
9480         (compare:CCZ (lshiftrt:DI
9481                        (neg:DI (ashift:DI
9482                                  (match_operand:DI 1 "register_operand" "0")
9483                                  (const_int 32)))
9484                        (const_int 32))
9485                      (const_int 0)))
9486    (set (match_operand:DI 0 "register_operand" "=r")
9487         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9488                                         (const_int 32)))
9489                      (const_int 32)))]
9490   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9491   "neg{l}\t%k0"
9492   [(set_attr "type" "negnot")
9493    (set_attr "mode" "SI")])
9495 (define_expand "neghi2"
9496   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9497                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9498               (clobber (reg:CC FLAGS_REG))])]
9499   "TARGET_HIMODE_MATH"
9500   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9502 (define_insn "*neghi2_1"
9503   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9504         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9505    (clobber (reg:CC FLAGS_REG))]
9506   "ix86_unary_operator_ok (NEG, HImode, operands)"
9507   "neg{w}\t%0"
9508   [(set_attr "type" "negnot")
9509    (set_attr "mode" "HI")])
9511 (define_insn "*neghi2_cmpz"
9512   [(set (reg:CCZ FLAGS_REG)
9513         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9514                      (const_int 0)))
9515    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9516         (neg:HI (match_dup 1)))]
9517   "ix86_unary_operator_ok (NEG, HImode, operands)"
9518   "neg{w}\t%0"
9519   [(set_attr "type" "negnot")
9520    (set_attr "mode" "HI")])
9522 (define_expand "negqi2"
9523   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9524                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9525               (clobber (reg:CC FLAGS_REG))])]
9526   "TARGET_QIMODE_MATH"
9527   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9529 (define_insn "*negqi2_1"
9530   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9531         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9532    (clobber (reg:CC FLAGS_REG))]
9533   "ix86_unary_operator_ok (NEG, QImode, operands)"
9534   "neg{b}\t%0"
9535   [(set_attr "type" "negnot")
9536    (set_attr "mode" "QI")])
9538 (define_insn "*negqi2_cmpz"
9539   [(set (reg:CCZ FLAGS_REG)
9540         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9541                      (const_int 0)))
9542    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9543         (neg:QI (match_dup 1)))]
9544   "ix86_unary_operator_ok (NEG, QImode, operands)"
9545   "neg{b}\t%0"
9546   [(set_attr "type" "negnot")
9547    (set_attr "mode" "QI")])
9549 ;; Changing of sign for FP values is doable using integer unit too.
9551 (define_expand "negsf2"
9552   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9553         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9554   "TARGET_80387 || TARGET_SSE_MATH"
9555   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9557 (define_expand "abssf2"
9558   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9559         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9560   "TARGET_80387 || TARGET_SSE_MATH"
9561   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9563 (define_insn "*absnegsf2_mixed"
9564   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9565         (match_operator:SF 3 "absneg_operator"
9566           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9567    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9568    (clobber (reg:CC FLAGS_REG))]
9569   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9570    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9571   "#")
9573 (define_insn "*absnegsf2_sse"
9574   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9575         (match_operator:SF 3 "absneg_operator"
9576           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9577    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9578    (clobber (reg:CC FLAGS_REG))]
9579   "TARGET_SSE_MATH
9580    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9581   "#")
9583 (define_insn "*absnegsf2_i387"
9584   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9585         (match_operator:SF 3 "absneg_operator"
9586           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9587    (use (match_operand 2 "" ""))
9588    (clobber (reg:CC FLAGS_REG))]
9589   "TARGET_80387 && !TARGET_SSE_MATH
9590    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9591   "#")
9593 (define_expand "negdf2"
9594   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9595         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9596   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9597   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9599 (define_expand "absdf2"
9600   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9601         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9602   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9603   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9605 (define_insn "*absnegdf2_mixed"
9606   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9607         (match_operator:DF 3 "absneg_operator"
9608           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9609    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9610    (clobber (reg:CC FLAGS_REG))]
9611   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9612    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9613   "#")
9615 (define_insn "*absnegdf2_sse"
9616   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9617         (match_operator:DF 3 "absneg_operator"
9618           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9619    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9620    (clobber (reg:CC FLAGS_REG))]
9621   "TARGET_SSE2 && TARGET_SSE_MATH
9622    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9623   "#")
9625 (define_insn "*absnegdf2_i387"
9626   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9627         (match_operator:DF 3 "absneg_operator"
9628           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9629    (use (match_operand 2 "" ""))
9630    (clobber (reg:CC FLAGS_REG))]
9631   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9632    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9633   "#")
9635 (define_expand "negxf2"
9636   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9637         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9638   "TARGET_80387"
9639   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9641 (define_expand "absxf2"
9642   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9643         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9644   "TARGET_80387"
9645   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9647 (define_insn "*absnegxf2_i387"
9648   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9649         (match_operator:XF 3 "absneg_operator"
9650           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9651    (use (match_operand 2 "" ""))
9652    (clobber (reg:CC FLAGS_REG))]
9653   "TARGET_80387
9654    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9655   "#")
9657 ;; Splitters for fp abs and neg.
9659 (define_split
9660   [(set (match_operand 0 "fp_register_operand" "")
9661         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9662    (use (match_operand 2 "" ""))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "reload_completed"
9665   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9667 (define_split
9668   [(set (match_operand 0 "register_operand" "")
9669         (match_operator 3 "absneg_operator"
9670           [(match_operand 1 "register_operand" "")]))
9671    (use (match_operand 2 "nonimmediate_operand" ""))
9672    (clobber (reg:CC FLAGS_REG))]
9673   "reload_completed && SSE_REG_P (operands[0])"
9674   [(set (match_dup 0) (match_dup 3))]
9676   enum machine_mode mode = GET_MODE (operands[0]);
9677   enum machine_mode vmode = GET_MODE (operands[2]);
9678   rtx tmp;
9679   
9680   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9681   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9682   if (operands_match_p (operands[0], operands[2]))
9683     {
9684       tmp = operands[1];
9685       operands[1] = operands[2];
9686       operands[2] = tmp;
9687     }
9688   if (GET_CODE (operands[3]) == ABS)
9689     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9690   else
9691     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9692   operands[3] = tmp;
9695 (define_split
9696   [(set (match_operand:SF 0 "register_operand" "")
9697         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9698    (use (match_operand:V4SF 2 "" ""))
9699    (clobber (reg:CC FLAGS_REG))]
9700   "reload_completed"
9701   [(parallel [(set (match_dup 0) (match_dup 1))
9702               (clobber (reg:CC FLAGS_REG))])]
9704   rtx tmp;
9705   operands[0] = gen_lowpart (SImode, operands[0]);
9706   if (GET_CODE (operands[1]) == ABS)
9707     {
9708       tmp = gen_int_mode (0x7fffffff, SImode);
9709       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9710     }
9711   else
9712     {
9713       tmp = gen_int_mode (0x80000000, SImode);
9714       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9715     }
9716   operands[1] = tmp;
9719 (define_split
9720   [(set (match_operand:DF 0 "register_operand" "")
9721         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9722    (use (match_operand 2 "" ""))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "reload_completed"
9725   [(parallel [(set (match_dup 0) (match_dup 1))
9726               (clobber (reg:CC FLAGS_REG))])]
9728   rtx tmp;
9729   if (TARGET_64BIT)
9730     {
9731       tmp = gen_lowpart (DImode, operands[0]);
9732       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9733       operands[0] = tmp;
9735       if (GET_CODE (operands[1]) == ABS)
9736         tmp = const0_rtx;
9737       else
9738         tmp = gen_rtx_NOT (DImode, tmp);
9739     }
9740   else
9741     {
9742       operands[0] = gen_highpart (SImode, operands[0]);
9743       if (GET_CODE (operands[1]) == ABS)
9744         {
9745           tmp = gen_int_mode (0x7fffffff, SImode);
9746           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9747         }
9748       else
9749         {
9750           tmp = gen_int_mode (0x80000000, SImode);
9751           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9752         }
9753     }
9754   operands[1] = tmp;
9757 (define_split
9758   [(set (match_operand:XF 0 "register_operand" "")
9759         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9760    (use (match_operand 2 "" ""))
9761    (clobber (reg:CC FLAGS_REG))]
9762   "reload_completed"
9763   [(parallel [(set (match_dup 0) (match_dup 1))
9764               (clobber (reg:CC FLAGS_REG))])]
9766   rtx tmp;
9767   operands[0] = gen_rtx_REG (SImode,
9768                              true_regnum (operands[0])
9769                              + (TARGET_64BIT ? 1 : 2));
9770   if (GET_CODE (operands[1]) == ABS)
9771     {
9772       tmp = GEN_INT (0x7fff);
9773       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9774     }
9775   else
9776     {
9777       tmp = GEN_INT (0x8000);
9778       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9779     }
9780   operands[1] = tmp;
9783 (define_split
9784   [(set (match_operand 0 "memory_operand" "")
9785         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9786    (use (match_operand 2 "" ""))
9787    (clobber (reg:CC FLAGS_REG))]
9788   "reload_completed"
9789   [(parallel [(set (match_dup 0) (match_dup 1))
9790               (clobber (reg:CC FLAGS_REG))])]
9792   enum machine_mode mode = GET_MODE (operands[0]);
9793   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9794   rtx tmp;
9796   operands[0] = adjust_address (operands[0], QImode, size - 1);
9797   if (GET_CODE (operands[1]) == ABS)
9798     {
9799       tmp = gen_int_mode (0x7f, QImode);
9800       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9801     }
9802   else
9803     {
9804       tmp = gen_int_mode (0x80, QImode);
9805       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9806     }
9807   operands[1] = tmp;
9810 ;; Conditionalize these after reload. If they match before reload, we 
9811 ;; lose the clobber and ability to use integer instructions.
9813 (define_insn "*negsf2_1"
9814   [(set (match_operand:SF 0 "register_operand" "=f")
9815         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9816   "TARGET_80387 && reload_completed"
9817   "fchs"
9818   [(set_attr "type" "fsgn")
9819    (set_attr "mode" "SF")])
9821 (define_insn "*negdf2_1"
9822   [(set (match_operand:DF 0 "register_operand" "=f")
9823         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9824   "TARGET_80387 && reload_completed"
9825   "fchs"
9826   [(set_attr "type" "fsgn")
9827    (set_attr "mode" "DF")])
9829 (define_insn "*negxf2_1"
9830   [(set (match_operand:XF 0 "register_operand" "=f")
9831         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9832   "TARGET_80387 && reload_completed"
9833   "fchs"
9834   [(set_attr "type" "fsgn")
9835    (set_attr "mode" "XF")])
9837 (define_insn "*abssf2_1"
9838   [(set (match_operand:SF 0 "register_operand" "=f")
9839         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9840   "TARGET_80387 && reload_completed"
9841   "fabs"
9842   [(set_attr "type" "fsgn")
9843    (set_attr "mode" "SF")])
9845 (define_insn "*absdf2_1"
9846   [(set (match_operand:DF 0 "register_operand" "=f")
9847         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9848   "TARGET_80387 && reload_completed"
9849   "fabs"
9850   [(set_attr "type" "fsgn")
9851    (set_attr "mode" "DF")])
9853 (define_insn "*absxf2_1"
9854   [(set (match_operand:XF 0 "register_operand" "=f")
9855         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9856   "TARGET_80387 && reload_completed"
9857   "fabs"
9858   [(set_attr "type" "fsgn")
9859    (set_attr "mode" "DF")])
9861 (define_insn "*negextendsfdf2"
9862   [(set (match_operand:DF 0 "register_operand" "=f")
9863         (neg:DF (float_extend:DF
9864                   (match_operand:SF 1 "register_operand" "0"))))]
9865   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9866   "fchs"
9867   [(set_attr "type" "fsgn")
9868    (set_attr "mode" "DF")])
9870 (define_insn "*negextenddfxf2"
9871   [(set (match_operand:XF 0 "register_operand" "=f")
9872         (neg:XF (float_extend:XF
9873                   (match_operand:DF 1 "register_operand" "0"))))]
9874   "TARGET_80387"
9875   "fchs"
9876   [(set_attr "type" "fsgn")
9877    (set_attr "mode" "XF")])
9879 (define_insn "*negextendsfxf2"
9880   [(set (match_operand:XF 0 "register_operand" "=f")
9881         (neg:XF (float_extend:XF
9882                   (match_operand:SF 1 "register_operand" "0"))))]
9883   "TARGET_80387"
9884   "fchs"
9885   [(set_attr "type" "fsgn")
9886    (set_attr "mode" "XF")])
9888 (define_insn "*absextendsfdf2"
9889   [(set (match_operand:DF 0 "register_operand" "=f")
9890         (abs:DF (float_extend:DF
9891                   (match_operand:SF 1 "register_operand" "0"))))]
9892   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9893   "fabs"
9894   [(set_attr "type" "fsgn")
9895    (set_attr "mode" "DF")])
9897 (define_insn "*absextenddfxf2"
9898   [(set (match_operand:XF 0 "register_operand" "=f")
9899         (abs:XF (float_extend:XF
9900           (match_operand:DF 1 "register_operand" "0"))))]
9901   "TARGET_80387"
9902   "fabs"
9903   [(set_attr "type" "fsgn")
9904    (set_attr "mode" "XF")])
9906 (define_insn "*absextendsfxf2"
9907   [(set (match_operand:XF 0 "register_operand" "=f")
9908         (abs:XF (float_extend:XF
9909           (match_operand:SF 1 "register_operand" "0"))))]
9910   "TARGET_80387"
9911   "fabs"
9912   [(set_attr "type" "fsgn")
9913    (set_attr "mode" "XF")])
9915 ;; One complement instructions
9917 (define_expand "one_cmpldi2"
9918   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9919         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9920   "TARGET_64BIT"
9921   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9923 (define_insn "*one_cmpldi2_1_rex64"
9924   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9925         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9926   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9927   "not{q}\t%0"
9928   [(set_attr "type" "negnot")
9929    (set_attr "mode" "DI")])
9931 (define_insn "*one_cmpldi2_2_rex64"
9932   [(set (reg FLAGS_REG)
9933         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9934                  (const_int 0)))
9935    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9936         (not:DI (match_dup 1)))]
9937   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9938    && ix86_unary_operator_ok (NOT, DImode, operands)"
9939   "#"
9940   [(set_attr "type" "alu1")
9941    (set_attr "mode" "DI")])
9943 (define_split
9944   [(set (match_operand 0 "flags_reg_operand" "")
9945         (match_operator 2 "compare_operator"
9946           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9947            (const_int 0)]))
9948    (set (match_operand:DI 1 "nonimmediate_operand" "")
9949         (not:DI (match_dup 3)))]
9950   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9951   [(parallel [(set (match_dup 0)
9952                    (match_op_dup 2
9953                      [(xor:DI (match_dup 3) (const_int -1))
9954                       (const_int 0)]))
9955               (set (match_dup 1)
9956                    (xor:DI (match_dup 3) (const_int -1)))])]
9957   "")
9959 (define_expand "one_cmplsi2"
9960   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9961         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9962   ""
9963   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9965 (define_insn "*one_cmplsi2_1"
9966   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9967         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9968   "ix86_unary_operator_ok (NOT, SImode, operands)"
9969   "not{l}\t%0"
9970   [(set_attr "type" "negnot")
9971    (set_attr "mode" "SI")])
9973 ;; ??? Currently never generated - xor is used instead.
9974 (define_insn "*one_cmplsi2_1_zext"
9975   [(set (match_operand:DI 0 "register_operand" "=r")
9976         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9977   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9978   "not{l}\t%k0"
9979   [(set_attr "type" "negnot")
9980    (set_attr "mode" "SI")])
9982 (define_insn "*one_cmplsi2_2"
9983   [(set (reg FLAGS_REG)
9984         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9985                  (const_int 0)))
9986    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9987         (not:SI (match_dup 1)))]
9988   "ix86_match_ccmode (insn, CCNOmode)
9989    && ix86_unary_operator_ok (NOT, SImode, operands)"
9990   "#"
9991   [(set_attr "type" "alu1")
9992    (set_attr "mode" "SI")])
9994 (define_split
9995   [(set (match_operand 0 "flags_reg_operand" "")
9996         (match_operator 2 "compare_operator"
9997           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9998            (const_int 0)]))
9999    (set (match_operand:SI 1 "nonimmediate_operand" "")
10000         (not:SI (match_dup 3)))]
10001   "ix86_match_ccmode (insn, CCNOmode)"
10002   [(parallel [(set (match_dup 0)
10003                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10004                                     (const_int 0)]))
10005               (set (match_dup 1)
10006                    (xor:SI (match_dup 3) (const_int -1)))])]
10007   "")
10009 ;; ??? Currently never generated - xor is used instead.
10010 (define_insn "*one_cmplsi2_2_zext"
10011   [(set (reg FLAGS_REG)
10012         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10013                  (const_int 0)))
10014    (set (match_operand:DI 0 "register_operand" "=r")
10015         (zero_extend:DI (not:SI (match_dup 1))))]
10016   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10017    && ix86_unary_operator_ok (NOT, SImode, operands)"
10018   "#"
10019   [(set_attr "type" "alu1")
10020    (set_attr "mode" "SI")])
10022 (define_split
10023   [(set (match_operand 0 "flags_reg_operand" "")
10024         (match_operator 2 "compare_operator"
10025           [(not:SI (match_operand:SI 3 "register_operand" ""))
10026            (const_int 0)]))
10027    (set (match_operand:DI 1 "register_operand" "")
10028         (zero_extend:DI (not:SI (match_dup 3))))]
10029   "ix86_match_ccmode (insn, CCNOmode)"
10030   [(parallel [(set (match_dup 0)
10031                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10032                                     (const_int 0)]))
10033               (set (match_dup 1)
10034                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10035   "")
10037 (define_expand "one_cmplhi2"
10038   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10039         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10040   "TARGET_HIMODE_MATH"
10041   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10043 (define_insn "*one_cmplhi2_1"
10044   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10045         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10046   "ix86_unary_operator_ok (NOT, HImode, operands)"
10047   "not{w}\t%0"
10048   [(set_attr "type" "negnot")
10049    (set_attr "mode" "HI")])
10051 (define_insn "*one_cmplhi2_2"
10052   [(set (reg FLAGS_REG)
10053         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10054                  (const_int 0)))
10055    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10056         (not:HI (match_dup 1)))]
10057   "ix86_match_ccmode (insn, CCNOmode)
10058    && ix86_unary_operator_ok (NEG, HImode, operands)"
10059   "#"
10060   [(set_attr "type" "alu1")
10061    (set_attr "mode" "HI")])
10063 (define_split
10064   [(set (match_operand 0 "flags_reg_operand" "")
10065         (match_operator 2 "compare_operator"
10066           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10067            (const_int 0)]))
10068    (set (match_operand:HI 1 "nonimmediate_operand" "")
10069         (not:HI (match_dup 3)))]
10070   "ix86_match_ccmode (insn, CCNOmode)"
10071   [(parallel [(set (match_dup 0)
10072                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10073                                     (const_int 0)]))
10074               (set (match_dup 1)
10075                    (xor:HI (match_dup 3) (const_int -1)))])]
10076   "")
10078 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10079 (define_expand "one_cmplqi2"
10080   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10081         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10082   "TARGET_QIMODE_MATH"
10083   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10085 (define_insn "*one_cmplqi2_1"
10086   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10087         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10088   "ix86_unary_operator_ok (NOT, QImode, operands)"
10089   "@
10090    not{b}\t%0
10091    not{l}\t%k0"
10092   [(set_attr "type" "negnot")
10093    (set_attr "mode" "QI,SI")])
10095 (define_insn "*one_cmplqi2_2"
10096   [(set (reg FLAGS_REG)
10097         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10098                  (const_int 0)))
10099    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10100         (not:QI (match_dup 1)))]
10101   "ix86_match_ccmode (insn, CCNOmode)
10102    && ix86_unary_operator_ok (NOT, QImode, operands)"
10103   "#"
10104   [(set_attr "type" "alu1")
10105    (set_attr "mode" "QI")])
10107 (define_split
10108   [(set (match_operand 0 "flags_reg_operand" "")
10109         (match_operator 2 "compare_operator"
10110           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10111            (const_int 0)]))
10112    (set (match_operand:QI 1 "nonimmediate_operand" "")
10113         (not:QI (match_dup 3)))]
10114   "ix86_match_ccmode (insn, CCNOmode)"
10115   [(parallel [(set (match_dup 0)
10116                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10117                                     (const_int 0)]))
10118               (set (match_dup 1)
10119                    (xor:QI (match_dup 3) (const_int -1)))])]
10120   "")
10122 ;; Arithmetic shift instructions
10124 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10125 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10126 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10127 ;; from the assembler input.
10129 ;; This instruction shifts the target reg/mem as usual, but instead of
10130 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10131 ;; is a left shift double, bits are taken from the high order bits of
10132 ;; reg, else if the insn is a shift right double, bits are taken from the
10133 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10134 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10136 ;; Since sh[lr]d does not change the `reg' operand, that is done
10137 ;; separately, making all shifts emit pairs of shift double and normal
10138 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10139 ;; support a 63 bit shift, each shift where the count is in a reg expands
10140 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10142 ;; If the shift count is a constant, we need never emit more than one
10143 ;; shift pair, instead using moves and sign extension for counts greater
10144 ;; than 31.
10146 (define_expand "ashldi3"
10147   [(set (match_operand:DI 0 "shiftdi_operand" "")
10148         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10149                    (match_operand:QI 2 "nonmemory_operand" "")))]
10150   ""
10151   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10153 (define_insn "*ashldi3_1_rex64"
10154   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10155         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10156                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10157    (clobber (reg:CC FLAGS_REG))]
10158   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10160   switch (get_attr_type (insn))
10161     {
10162     case TYPE_ALU:
10163       if (operands[2] != const1_rtx)
10164         abort ();
10165       if (!rtx_equal_p (operands[0], operands[1]))
10166         abort ();
10167       return "add{q}\t{%0, %0|%0, %0}";
10169     case TYPE_LEA:
10170       if (GET_CODE (operands[2]) != CONST_INT
10171           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10172         abort ();
10173       operands[1] = gen_rtx_MULT (DImode, operands[1],
10174                                   GEN_INT (1 << INTVAL (operands[2])));
10175       return "lea{q}\t{%a1, %0|%0, %a1}";
10177     default:
10178       if (REG_P (operands[2]))
10179         return "sal{q}\t{%b2, %0|%0, %b2}";
10180       else if (operands[2] == const1_rtx
10181                && (TARGET_SHIFT1 || optimize_size))
10182         return "sal{q}\t%0";
10183       else
10184         return "sal{q}\t{%2, %0|%0, %2}";
10185     }
10187   [(set (attr "type")
10188      (cond [(eq_attr "alternative" "1")
10189               (const_string "lea")
10190             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10191                           (const_int 0))
10192                       (match_operand 0 "register_operand" ""))
10193                  (match_operand 2 "const1_operand" ""))
10194               (const_string "alu")
10195            ]
10196            (const_string "ishift")))
10197    (set_attr "mode" "DI")])
10199 ;; Convert lea to the lea pattern to avoid flags dependency.
10200 (define_split
10201   [(set (match_operand:DI 0 "register_operand" "")
10202         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10203                    (match_operand:QI 2 "immediate_operand" "")))
10204    (clobber (reg:CC FLAGS_REG))]
10205   "TARGET_64BIT && reload_completed
10206    && true_regnum (operands[0]) != true_regnum (operands[1])"
10207   [(set (match_dup 0)
10208         (mult:DI (match_dup 1)
10209                  (match_dup 2)))]
10210   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10212 ;; This pattern can't accept a variable shift count, since shifts by
10213 ;; zero don't affect the flags.  We assume that shifts by constant
10214 ;; zero are optimized away.
10215 (define_insn "*ashldi3_cmp_rex64"
10216   [(set (reg FLAGS_REG)
10217         (compare
10218           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10219                      (match_operand:QI 2 "immediate_operand" "e"))
10220           (const_int 0)))
10221    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10222         (ashift:DI (match_dup 1) (match_dup 2)))]
10223   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10224    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10226   switch (get_attr_type (insn))
10227     {
10228     case TYPE_ALU:
10229       if (operands[2] != const1_rtx)
10230         abort ();
10231       return "add{q}\t{%0, %0|%0, %0}";
10233     default:
10234       if (REG_P (operands[2]))
10235         return "sal{q}\t{%b2, %0|%0, %b2}";
10236       else if (operands[2] == const1_rtx
10237                && (TARGET_SHIFT1 || optimize_size))
10238         return "sal{q}\t%0";
10239       else
10240         return "sal{q}\t{%2, %0|%0, %2}";
10241     }
10243   [(set (attr "type")
10244      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10245                           (const_int 0))
10246                       (match_operand 0 "register_operand" ""))
10247                  (match_operand 2 "const1_operand" ""))
10248               (const_string "alu")
10249            ]
10250            (const_string "ishift")))
10251    (set_attr "mode" "DI")])
10253 (define_insn "*ashldi3_1"
10254   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10255         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10256                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10257    (clobber (reg:CC FLAGS_REG))]
10258   "!TARGET_64BIT"
10259   "#"
10260   [(set_attr "type" "multi")])
10262 ;; By default we don't ask for a scratch register, because when DImode
10263 ;; values are manipulated, registers are already at a premium.  But if
10264 ;; we have one handy, we won't turn it away.
10265 (define_peephole2
10266   [(match_scratch:SI 3 "r")
10267    (parallel [(set (match_operand:DI 0 "register_operand" "")
10268                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10269                               (match_operand:QI 2 "nonmemory_operand" "")))
10270               (clobber (reg:CC FLAGS_REG))])
10271    (match_dup 3)]
10272   "!TARGET_64BIT && TARGET_CMOVE"
10273   [(const_int 0)]
10274   "ix86_split_ashldi (operands, operands[3]); DONE;")
10276 (define_split
10277   [(set (match_operand:DI 0 "register_operand" "")
10278         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10279                    (match_operand:QI 2 "nonmemory_operand" "")))
10280    (clobber (reg:CC FLAGS_REG))]
10281   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10282   [(const_int 0)]
10283   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10285 (define_insn "x86_shld_1"
10286   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10287         (ior:SI (ashift:SI (match_dup 0)
10288                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10289                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10290                   (minus:QI (const_int 32) (match_dup 2)))))
10291    (clobber (reg:CC FLAGS_REG))]
10292   ""
10293   "@
10294    shld{l}\t{%2, %1, %0|%0, %1, %2}
10295    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10296   [(set_attr "type" "ishift")
10297    (set_attr "prefix_0f" "1")
10298    (set_attr "mode" "SI")
10299    (set_attr "pent_pair" "np")
10300    (set_attr "athlon_decode" "vector")])
10302 (define_expand "x86_shift_adj_1"
10303   [(set (reg:CCZ FLAGS_REG)
10304         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10305                              (const_int 32))
10306                      (const_int 0)))
10307    (set (match_operand:SI 0 "register_operand" "")
10308         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10309                          (match_operand:SI 1 "register_operand" "")
10310                          (match_dup 0)))
10311    (set (match_dup 1)
10312         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10313                          (match_operand:SI 3 "register_operand" "r")
10314                          (match_dup 1)))]
10315   "TARGET_CMOVE"
10316   "")
10318 (define_expand "x86_shift_adj_2"
10319   [(use (match_operand:SI 0 "register_operand" ""))
10320    (use (match_operand:SI 1 "register_operand" ""))
10321    (use (match_operand:QI 2 "register_operand" ""))]
10322   ""
10324   rtx label = gen_label_rtx ();
10325   rtx tmp;
10327   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10329   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10330   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10331   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10332                               gen_rtx_LABEL_REF (VOIDmode, label),
10333                               pc_rtx);
10334   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10335   JUMP_LABEL (tmp) = label;
10337   emit_move_insn (operands[0], operands[1]);
10338   ix86_expand_clear (operands[1]);
10340   emit_label (label);
10341   LABEL_NUSES (label) = 1;
10343   DONE;
10346 (define_expand "ashlsi3"
10347   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10348         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10349                    (match_operand:QI 2 "nonmemory_operand" "")))
10350    (clobber (reg:CC FLAGS_REG))]
10351   ""
10352   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10354 (define_insn "*ashlsi3_1"
10355   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10356         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10357                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10358    (clobber (reg:CC FLAGS_REG))]
10359   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10361   switch (get_attr_type (insn))
10362     {
10363     case TYPE_ALU:
10364       if (operands[2] != const1_rtx)
10365         abort ();
10366       if (!rtx_equal_p (operands[0], operands[1]))
10367         abort ();
10368       return "add{l}\t{%0, %0|%0, %0}";
10370     case TYPE_LEA:
10371       return "#";
10373     default:
10374       if (REG_P (operands[2]))
10375         return "sal{l}\t{%b2, %0|%0, %b2}";
10376       else if (operands[2] == const1_rtx
10377                && (TARGET_SHIFT1 || optimize_size))
10378         return "sal{l}\t%0";
10379       else
10380         return "sal{l}\t{%2, %0|%0, %2}";
10381     }
10383   [(set (attr "type")
10384      (cond [(eq_attr "alternative" "1")
10385               (const_string "lea")
10386             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10387                           (const_int 0))
10388                       (match_operand 0 "register_operand" ""))
10389                  (match_operand 2 "const1_operand" ""))
10390               (const_string "alu")
10391            ]
10392            (const_string "ishift")))
10393    (set_attr "mode" "SI")])
10395 ;; Convert lea to the lea pattern to avoid flags dependency.
10396 (define_split
10397   [(set (match_operand 0 "register_operand" "")
10398         (ashift (match_operand 1 "index_register_operand" "")
10399                 (match_operand:QI 2 "const_int_operand" "")))
10400    (clobber (reg:CC FLAGS_REG))]
10401   "reload_completed
10402    && true_regnum (operands[0]) != true_regnum (operands[1])
10403    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10404   [(const_int 0)]
10406   rtx pat;
10407   enum machine_mode mode = GET_MODE (operands[0]);
10409   if (GET_MODE_SIZE (mode) < 4)
10410     operands[0] = gen_lowpart (SImode, operands[0]);
10411   if (mode != Pmode)
10412     operands[1] = gen_lowpart (Pmode, operands[1]);
10413   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10415   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10416   if (Pmode != SImode)
10417     pat = gen_rtx_SUBREG (SImode, pat, 0);
10418   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10419   DONE;
10422 ;; Rare case of shifting RSP is handled by generating move and shift
10423 (define_split
10424   [(set (match_operand 0 "register_operand" "")
10425         (ashift (match_operand 1 "register_operand" "")
10426                 (match_operand:QI 2 "const_int_operand" "")))
10427    (clobber (reg:CC FLAGS_REG))]
10428   "reload_completed
10429    && true_regnum (operands[0]) != true_regnum (operands[1])"
10430   [(const_int 0)]
10432   rtx pat, clob;
10433   emit_move_insn (operands[1], operands[0]);
10434   pat = gen_rtx_SET (VOIDmode, operands[0],
10435                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10436                                      operands[0], operands[2]));
10437   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10438   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10439   DONE;
10442 (define_insn "*ashlsi3_1_zext"
10443   [(set (match_operand:DI 0 "register_operand" "=r,r")
10444         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10445                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10446    (clobber (reg:CC FLAGS_REG))]
10447   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10449   switch (get_attr_type (insn))
10450     {
10451     case TYPE_ALU:
10452       if (operands[2] != const1_rtx)
10453         abort ();
10454       return "add{l}\t{%k0, %k0|%k0, %k0}";
10456     case TYPE_LEA:
10457       return "#";
10459     default:
10460       if (REG_P (operands[2]))
10461         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10462       else if (operands[2] == const1_rtx
10463                && (TARGET_SHIFT1 || optimize_size))
10464         return "sal{l}\t%k0";
10465       else
10466         return "sal{l}\t{%2, %k0|%k0, %2}";
10467     }
10469   [(set (attr "type")
10470      (cond [(eq_attr "alternative" "1")
10471               (const_string "lea")
10472             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10473                      (const_int 0))
10474                  (match_operand 2 "const1_operand" ""))
10475               (const_string "alu")
10476            ]
10477            (const_string "ishift")))
10478    (set_attr "mode" "SI")])
10480 ;; Convert lea to the lea pattern to avoid flags dependency.
10481 (define_split
10482   [(set (match_operand:DI 0 "register_operand" "")
10483         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10484                                 (match_operand:QI 2 "const_int_operand" ""))))
10485    (clobber (reg:CC FLAGS_REG))]
10486   "TARGET_64BIT && reload_completed
10487    && true_regnum (operands[0]) != true_regnum (operands[1])"
10488   [(set (match_dup 0) (zero_extend:DI
10489                         (subreg:SI (mult:SI (match_dup 1)
10490                                             (match_dup 2)) 0)))]
10492   operands[1] = gen_lowpart (Pmode, operands[1]);
10493   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10496 ;; This pattern can't accept a variable shift count, since shifts by
10497 ;; zero don't affect the flags.  We assume that shifts by constant
10498 ;; zero are optimized away.
10499 (define_insn "*ashlsi3_cmp"
10500   [(set (reg FLAGS_REG)
10501         (compare
10502           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10503                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10504           (const_int 0)))
10505    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10506         (ashift:SI (match_dup 1) (match_dup 2)))]
10507   "ix86_match_ccmode (insn, CCGOCmode)
10508    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10510   switch (get_attr_type (insn))
10511     {
10512     case TYPE_ALU:
10513       if (operands[2] != const1_rtx)
10514         abort ();
10515       return "add{l}\t{%0, %0|%0, %0}";
10517     default:
10518       if (REG_P (operands[2]))
10519         return "sal{l}\t{%b2, %0|%0, %b2}";
10520       else if (operands[2] == const1_rtx
10521                && (TARGET_SHIFT1 || optimize_size))
10522         return "sal{l}\t%0";
10523       else
10524         return "sal{l}\t{%2, %0|%0, %2}";
10525     }
10527   [(set (attr "type")
10528      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10529                           (const_int 0))
10530                       (match_operand 0 "register_operand" ""))
10531                  (match_operand 2 "const1_operand" ""))
10532               (const_string "alu")
10533            ]
10534            (const_string "ishift")))
10535    (set_attr "mode" "SI")])
10537 (define_insn "*ashlsi3_cmp_zext"
10538   [(set (reg FLAGS_REG)
10539         (compare
10540           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10541                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10542           (const_int 0)))
10543    (set (match_operand:DI 0 "register_operand" "=r")
10544         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10545   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10546    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10548   switch (get_attr_type (insn))
10549     {
10550     case TYPE_ALU:
10551       if (operands[2] != const1_rtx)
10552         abort ();
10553       return "add{l}\t{%k0, %k0|%k0, %k0}";
10555     default:
10556       if (REG_P (operands[2]))
10557         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10558       else if (operands[2] == const1_rtx
10559                && (TARGET_SHIFT1 || optimize_size))
10560         return "sal{l}\t%k0";
10561       else
10562         return "sal{l}\t{%2, %k0|%k0, %2}";
10563     }
10565   [(set (attr "type")
10566      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10567                      (const_int 0))
10568                  (match_operand 2 "const1_operand" ""))
10569               (const_string "alu")
10570            ]
10571            (const_string "ishift")))
10572    (set_attr "mode" "SI")])
10574 (define_expand "ashlhi3"
10575   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10576         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10577                    (match_operand:QI 2 "nonmemory_operand" "")))
10578    (clobber (reg:CC FLAGS_REG))]
10579   "TARGET_HIMODE_MATH"
10580   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10582 (define_insn "*ashlhi3_1_lea"
10583   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10584         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10585                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10586    (clobber (reg:CC FLAGS_REG))]
10587   "!TARGET_PARTIAL_REG_STALL
10588    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10590   switch (get_attr_type (insn))
10591     {
10592     case TYPE_LEA:
10593       return "#";
10594     case TYPE_ALU:
10595       if (operands[2] != const1_rtx)
10596         abort ();
10597       return "add{w}\t{%0, %0|%0, %0}";
10599     default:
10600       if (REG_P (operands[2]))
10601         return "sal{w}\t{%b2, %0|%0, %b2}";
10602       else if (operands[2] == const1_rtx
10603                && (TARGET_SHIFT1 || optimize_size))
10604         return "sal{w}\t%0";
10605       else
10606         return "sal{w}\t{%2, %0|%0, %2}";
10607     }
10609   [(set (attr "type")
10610      (cond [(eq_attr "alternative" "1")
10611               (const_string "lea")
10612             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10613                           (const_int 0))
10614                       (match_operand 0 "register_operand" ""))
10615                  (match_operand 2 "const1_operand" ""))
10616               (const_string "alu")
10617            ]
10618            (const_string "ishift")))
10619    (set_attr "mode" "HI,SI")])
10621 (define_insn "*ashlhi3_1"
10622   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10623         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10624                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10625    (clobber (reg:CC FLAGS_REG))]
10626   "TARGET_PARTIAL_REG_STALL
10627    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10629   switch (get_attr_type (insn))
10630     {
10631     case TYPE_ALU:
10632       if (operands[2] != const1_rtx)
10633         abort ();
10634       return "add{w}\t{%0, %0|%0, %0}";
10636     default:
10637       if (REG_P (operands[2]))
10638         return "sal{w}\t{%b2, %0|%0, %b2}";
10639       else if (operands[2] == const1_rtx
10640                && (TARGET_SHIFT1 || optimize_size))
10641         return "sal{w}\t%0";
10642       else
10643         return "sal{w}\t{%2, %0|%0, %2}";
10644     }
10646   [(set (attr "type")
10647      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10648                           (const_int 0))
10649                       (match_operand 0 "register_operand" ""))
10650                  (match_operand 2 "const1_operand" ""))
10651               (const_string "alu")
10652            ]
10653            (const_string "ishift")))
10654    (set_attr "mode" "HI")])
10656 ;; This pattern can't accept a variable shift count, since shifts by
10657 ;; zero don't affect the flags.  We assume that shifts by constant
10658 ;; zero are optimized away.
10659 (define_insn "*ashlhi3_cmp"
10660   [(set (reg FLAGS_REG)
10661         (compare
10662           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10663                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10664           (const_int 0)))
10665    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10666         (ashift:HI (match_dup 1) (match_dup 2)))]
10667   "ix86_match_ccmode (insn, CCGOCmode)
10668    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10670   switch (get_attr_type (insn))
10671     {
10672     case TYPE_ALU:
10673       if (operands[2] != const1_rtx)
10674         abort ();
10675       return "add{w}\t{%0, %0|%0, %0}";
10677     default:
10678       if (REG_P (operands[2]))
10679         return "sal{w}\t{%b2, %0|%0, %b2}";
10680       else if (operands[2] == const1_rtx
10681                && (TARGET_SHIFT1 || optimize_size))
10682         return "sal{w}\t%0";
10683       else
10684         return "sal{w}\t{%2, %0|%0, %2}";
10685     }
10687   [(set (attr "type")
10688      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10689                           (const_int 0))
10690                       (match_operand 0 "register_operand" ""))
10691                  (match_operand 2 "const1_operand" ""))
10692               (const_string "alu")
10693            ]
10694            (const_string "ishift")))
10695    (set_attr "mode" "HI")])
10697 (define_expand "ashlqi3"
10698   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10699         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10700                    (match_operand:QI 2 "nonmemory_operand" "")))
10701    (clobber (reg:CC FLAGS_REG))]
10702   "TARGET_QIMODE_MATH"
10703   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10705 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10707 (define_insn "*ashlqi3_1_lea"
10708   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10709         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10710                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10711    (clobber (reg:CC FLAGS_REG))]
10712   "!TARGET_PARTIAL_REG_STALL
10713    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10715   switch (get_attr_type (insn))
10716     {
10717     case TYPE_LEA:
10718       return "#";
10719     case TYPE_ALU:
10720       if (operands[2] != const1_rtx)
10721         abort ();
10722       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10723         return "add{l}\t{%k0, %k0|%k0, %k0}";
10724       else
10725         return "add{b}\t{%0, %0|%0, %0}";
10727     default:
10728       if (REG_P (operands[2]))
10729         {
10730           if (get_attr_mode (insn) == MODE_SI)
10731             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10732           else
10733             return "sal{b}\t{%b2, %0|%0, %b2}";
10734         }
10735       else if (operands[2] == const1_rtx
10736                && (TARGET_SHIFT1 || optimize_size))
10737         {
10738           if (get_attr_mode (insn) == MODE_SI)
10739             return "sal{l}\t%0";
10740           else
10741             return "sal{b}\t%0";
10742         }
10743       else
10744         {
10745           if (get_attr_mode (insn) == MODE_SI)
10746             return "sal{l}\t{%2, %k0|%k0, %2}";
10747           else
10748             return "sal{b}\t{%2, %0|%0, %2}";
10749         }
10750     }
10752   [(set (attr "type")
10753      (cond [(eq_attr "alternative" "2")
10754               (const_string "lea")
10755             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10756                           (const_int 0))
10757                       (match_operand 0 "register_operand" ""))
10758                  (match_operand 2 "const1_operand" ""))
10759               (const_string "alu")
10760            ]
10761            (const_string "ishift")))
10762    (set_attr "mode" "QI,SI,SI")])
10764 (define_insn "*ashlqi3_1"
10765   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10766         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10767                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10768    (clobber (reg:CC FLAGS_REG))]
10769   "TARGET_PARTIAL_REG_STALL
10770    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10772   switch (get_attr_type (insn))
10773     {
10774     case TYPE_ALU:
10775       if (operands[2] != const1_rtx)
10776         abort ();
10777       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10778         return "add{l}\t{%k0, %k0|%k0, %k0}";
10779       else
10780         return "add{b}\t{%0, %0|%0, %0}";
10782     default:
10783       if (REG_P (operands[2]))
10784         {
10785           if (get_attr_mode (insn) == MODE_SI)
10786             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10787           else
10788             return "sal{b}\t{%b2, %0|%0, %b2}";
10789         }
10790       else if (operands[2] == const1_rtx
10791                && (TARGET_SHIFT1 || optimize_size))
10792         {
10793           if (get_attr_mode (insn) == MODE_SI)
10794             return "sal{l}\t%0";
10795           else
10796             return "sal{b}\t%0";
10797         }
10798       else
10799         {
10800           if (get_attr_mode (insn) == MODE_SI)
10801             return "sal{l}\t{%2, %k0|%k0, %2}";
10802           else
10803             return "sal{b}\t{%2, %0|%0, %2}";
10804         }
10805     }
10807   [(set (attr "type")
10808      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10809                           (const_int 0))
10810                       (match_operand 0 "register_operand" ""))
10811                  (match_operand 2 "const1_operand" ""))
10812               (const_string "alu")
10813            ]
10814            (const_string "ishift")))
10815    (set_attr "mode" "QI,SI")])
10817 ;; This pattern can't accept a variable shift count, since shifts by
10818 ;; zero don't affect the flags.  We assume that shifts by constant
10819 ;; zero are optimized away.
10820 (define_insn "*ashlqi3_cmp"
10821   [(set (reg FLAGS_REG)
10822         (compare
10823           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10824                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10825           (const_int 0)))
10826    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10827         (ashift:QI (match_dup 1) (match_dup 2)))]
10828   "ix86_match_ccmode (insn, CCGOCmode)
10829    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10831   switch (get_attr_type (insn))
10832     {
10833     case TYPE_ALU:
10834       if (operands[2] != const1_rtx)
10835         abort ();
10836       return "add{b}\t{%0, %0|%0, %0}";
10838     default:
10839       if (REG_P (operands[2]))
10840         return "sal{b}\t{%b2, %0|%0, %b2}";
10841       else if (operands[2] == const1_rtx
10842                && (TARGET_SHIFT1 || optimize_size))
10843         return "sal{b}\t%0";
10844       else
10845         return "sal{b}\t{%2, %0|%0, %2}";
10846     }
10848   [(set (attr "type")
10849      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10850                           (const_int 0))
10851                       (match_operand 0 "register_operand" ""))
10852                  (match_operand 2 "const1_operand" ""))
10853               (const_string "alu")
10854            ]
10855            (const_string "ishift")))
10856    (set_attr "mode" "QI")])
10858 ;; See comment above `ashldi3' about how this works.
10860 (define_expand "ashrdi3"
10861   [(set (match_operand:DI 0 "shiftdi_operand" "")
10862         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10863                      (match_operand:QI 2 "nonmemory_operand" "")))]
10864   ""
10865   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10867 (define_insn "*ashrdi3_63_rex64"
10868   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10869         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10870                      (match_operand:DI 2 "const_int_operand" "i,i")))
10871    (clobber (reg:CC FLAGS_REG))]
10872   "TARGET_64BIT && INTVAL (operands[2]) == 63
10873    && (TARGET_USE_CLTD || optimize_size)
10874    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10875   "@
10876    {cqto|cqo}
10877    sar{q}\t{%2, %0|%0, %2}"
10878   [(set_attr "type" "imovx,ishift")
10879    (set_attr "prefix_0f" "0,*")
10880    (set_attr "length_immediate" "0,*")
10881    (set_attr "modrm" "0,1")
10882    (set_attr "mode" "DI")])
10884 (define_insn "*ashrdi3_1_one_bit_rex64"
10885   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10886         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10887                      (match_operand:QI 2 "const1_operand" "")))
10888    (clobber (reg:CC FLAGS_REG))]
10889   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10890    && (TARGET_SHIFT1 || optimize_size)"
10891   "sar{q}\t%0"
10892   [(set_attr "type" "ishift")
10893    (set (attr "length") 
10894      (if_then_else (match_operand:DI 0 "register_operand" "") 
10895         (const_string "2")
10896         (const_string "*")))])
10898 (define_insn "*ashrdi3_1_rex64"
10899   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10900         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10901                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10902    (clobber (reg:CC FLAGS_REG))]
10903   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10904   "@
10905    sar{q}\t{%2, %0|%0, %2}
10906    sar{q}\t{%b2, %0|%0, %b2}"
10907   [(set_attr "type" "ishift")
10908    (set_attr "mode" "DI")])
10910 ;; This pattern can't accept a variable shift count, since shifts by
10911 ;; zero don't affect the flags.  We assume that shifts by constant
10912 ;; zero are optimized away.
10913 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10914   [(set (reg FLAGS_REG)
10915         (compare
10916           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10917                        (match_operand:QI 2 "const1_operand" ""))
10918           (const_int 0)))
10919    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10920         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10921   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10922    && (TARGET_SHIFT1 || optimize_size)
10923    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10924   "sar{q}\t%0"
10925   [(set_attr "type" "ishift")
10926    (set (attr "length") 
10927      (if_then_else (match_operand:DI 0 "register_operand" "") 
10928         (const_string "2")
10929         (const_string "*")))])
10931 ;; This pattern can't accept a variable shift count, since shifts by
10932 ;; zero don't affect the flags.  We assume that shifts by constant
10933 ;; zero are optimized away.
10934 (define_insn "*ashrdi3_cmp_rex64"
10935   [(set (reg FLAGS_REG)
10936         (compare
10937           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10938                        (match_operand:QI 2 "const_int_operand" "n"))
10939           (const_int 0)))
10940    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10941         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10942   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10943    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10944   "sar{q}\t{%2, %0|%0, %2}"
10945   [(set_attr "type" "ishift")
10946    (set_attr "mode" "DI")])
10948 (define_insn "*ashrdi3_1"
10949   [(set (match_operand:DI 0 "register_operand" "=r")
10950         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10951                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10952    (clobber (reg:CC FLAGS_REG))]
10953   "!TARGET_64BIT"
10954   "#"
10955   [(set_attr "type" "multi")])
10957 ;; By default we don't ask for a scratch register, because when DImode
10958 ;; values are manipulated, registers are already at a premium.  But if
10959 ;; we have one handy, we won't turn it away.
10960 (define_peephole2
10961   [(match_scratch:SI 3 "r")
10962    (parallel [(set (match_operand:DI 0 "register_operand" "")
10963                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10964                                 (match_operand:QI 2 "nonmemory_operand" "")))
10965               (clobber (reg:CC FLAGS_REG))])
10966    (match_dup 3)]
10967   "!TARGET_64BIT && TARGET_CMOVE"
10968   [(const_int 0)]
10969   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10971 (define_split
10972   [(set (match_operand:DI 0 "register_operand" "")
10973         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10974                      (match_operand:QI 2 "nonmemory_operand" "")))
10975    (clobber (reg:CC FLAGS_REG))]
10976   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10977   [(const_int 0)]
10978   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10980 (define_insn "x86_shrd_1"
10981   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10982         (ior:SI (ashiftrt:SI (match_dup 0)
10983                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10984                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10985                   (minus:QI (const_int 32) (match_dup 2)))))
10986    (clobber (reg:CC FLAGS_REG))]
10987   ""
10988   "@
10989    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10990    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10991   [(set_attr "type" "ishift")
10992    (set_attr "prefix_0f" "1")
10993    (set_attr "pent_pair" "np")
10994    (set_attr "mode" "SI")])
10996 (define_expand "x86_shift_adj_3"
10997   [(use (match_operand:SI 0 "register_operand" ""))
10998    (use (match_operand:SI 1 "register_operand" ""))
10999    (use (match_operand:QI 2 "register_operand" ""))]
11000   ""
11002   rtx label = gen_label_rtx ();
11003   rtx tmp;
11005   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11007   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11008   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11009   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11010                               gen_rtx_LABEL_REF (VOIDmode, label),
11011                               pc_rtx);
11012   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11013   JUMP_LABEL (tmp) = label;
11015   emit_move_insn (operands[0], operands[1]);
11016   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11018   emit_label (label);
11019   LABEL_NUSES (label) = 1;
11021   DONE;
11024 (define_insn "ashrsi3_31"
11025   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11026         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11027                      (match_operand:SI 2 "const_int_operand" "i,i")))
11028    (clobber (reg:CC FLAGS_REG))]
11029   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11030    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11031   "@
11032    {cltd|cdq}
11033    sar{l}\t{%2, %0|%0, %2}"
11034   [(set_attr "type" "imovx,ishift")
11035    (set_attr "prefix_0f" "0,*")
11036    (set_attr "length_immediate" "0,*")
11037    (set_attr "modrm" "0,1")
11038    (set_attr "mode" "SI")])
11040 (define_insn "*ashrsi3_31_zext"
11041   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11042         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11043                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11044    (clobber (reg:CC FLAGS_REG))]
11045   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11046    && INTVAL (operands[2]) == 31
11047    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11048   "@
11049    {cltd|cdq}
11050    sar{l}\t{%2, %k0|%k0, %2}"
11051   [(set_attr "type" "imovx,ishift")
11052    (set_attr "prefix_0f" "0,*")
11053    (set_attr "length_immediate" "0,*")
11054    (set_attr "modrm" "0,1")
11055    (set_attr "mode" "SI")])
11057 (define_expand "ashrsi3"
11058   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11059         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11060                      (match_operand:QI 2 "nonmemory_operand" "")))
11061    (clobber (reg:CC FLAGS_REG))]
11062   ""
11063   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11065 (define_insn "*ashrsi3_1_one_bit"
11066   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11067         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11068                      (match_operand:QI 2 "const1_operand" "")))
11069    (clobber (reg:CC FLAGS_REG))]
11070   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11071    && (TARGET_SHIFT1 || optimize_size)"
11072   "sar{l}\t%0"
11073   [(set_attr "type" "ishift")
11074    (set (attr "length") 
11075      (if_then_else (match_operand:SI 0 "register_operand" "") 
11076         (const_string "2")
11077         (const_string "*")))])
11079 (define_insn "*ashrsi3_1_one_bit_zext"
11080   [(set (match_operand:DI 0 "register_operand" "=r")
11081         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11082                                      (match_operand:QI 2 "const1_operand" ""))))
11083    (clobber (reg:CC FLAGS_REG))]
11084   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11085    && (TARGET_SHIFT1 || optimize_size)"
11086   "sar{l}\t%k0"
11087   [(set_attr "type" "ishift")
11088    (set_attr "length" "2")])
11090 (define_insn "*ashrsi3_1"
11091   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11092         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11093                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11094    (clobber (reg:CC FLAGS_REG))]
11095   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11096   "@
11097    sar{l}\t{%2, %0|%0, %2}
11098    sar{l}\t{%b2, %0|%0, %b2}"
11099   [(set_attr "type" "ishift")
11100    (set_attr "mode" "SI")])
11102 (define_insn "*ashrsi3_1_zext"
11103   [(set (match_operand:DI 0 "register_operand" "=r,r")
11104         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11105                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11106    (clobber (reg:CC FLAGS_REG))]
11107   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11108   "@
11109    sar{l}\t{%2, %k0|%k0, %2}
11110    sar{l}\t{%b2, %k0|%k0, %b2}"
11111   [(set_attr "type" "ishift")
11112    (set_attr "mode" "SI")])
11114 ;; This pattern can't accept a variable shift count, since shifts by
11115 ;; zero don't affect the flags.  We assume that shifts by constant
11116 ;; zero are optimized away.
11117 (define_insn "*ashrsi3_one_bit_cmp"
11118   [(set (reg FLAGS_REG)
11119         (compare
11120           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11121                        (match_operand:QI 2 "const1_operand" ""))
11122           (const_int 0)))
11123    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11124         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11125   "ix86_match_ccmode (insn, CCGOCmode)
11126    && (TARGET_SHIFT1 || optimize_size)
11127    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11128   "sar{l}\t%0"
11129   [(set_attr "type" "ishift")
11130    (set (attr "length") 
11131      (if_then_else (match_operand:SI 0 "register_operand" "") 
11132         (const_string "2")
11133         (const_string "*")))])
11135 (define_insn "*ashrsi3_one_bit_cmp_zext"
11136   [(set (reg FLAGS_REG)
11137         (compare
11138           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11139                        (match_operand:QI 2 "const1_operand" ""))
11140           (const_int 0)))
11141    (set (match_operand:DI 0 "register_operand" "=r")
11142         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11143   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11144    && (TARGET_SHIFT1 || optimize_size)
11145    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11146   "sar{l}\t%k0"
11147   [(set_attr "type" "ishift")
11148    (set_attr "length" "2")])
11150 ;; This pattern can't accept a variable shift count, since shifts by
11151 ;; zero don't affect the flags.  We assume that shifts by constant
11152 ;; zero are optimized away.
11153 (define_insn "*ashrsi3_cmp"
11154   [(set (reg FLAGS_REG)
11155         (compare
11156           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11157                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11158           (const_int 0)))
11159    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11160         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11161   "ix86_match_ccmode (insn, CCGOCmode)
11162    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11163   "sar{l}\t{%2, %0|%0, %2}"
11164   [(set_attr "type" "ishift")
11165    (set_attr "mode" "SI")])
11167 (define_insn "*ashrsi3_cmp_zext"
11168   [(set (reg FLAGS_REG)
11169         (compare
11170           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11171                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11172           (const_int 0)))
11173    (set (match_operand:DI 0 "register_operand" "=r")
11174         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11175   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11176    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11177   "sar{l}\t{%2, %k0|%k0, %2}"
11178   [(set_attr "type" "ishift")
11179    (set_attr "mode" "SI")])
11181 (define_expand "ashrhi3"
11182   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11183         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11184                      (match_operand:QI 2 "nonmemory_operand" "")))
11185    (clobber (reg:CC FLAGS_REG))]
11186   "TARGET_HIMODE_MATH"
11187   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11189 (define_insn "*ashrhi3_1_one_bit"
11190   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11191         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11192                      (match_operand:QI 2 "const1_operand" "")))
11193    (clobber (reg:CC FLAGS_REG))]
11194   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11195    && (TARGET_SHIFT1 || optimize_size)"
11196   "sar{w}\t%0"
11197   [(set_attr "type" "ishift")
11198    (set (attr "length") 
11199      (if_then_else (match_operand 0 "register_operand" "") 
11200         (const_string "2")
11201         (const_string "*")))])
11203 (define_insn "*ashrhi3_1"
11204   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11205         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11206                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11207    (clobber (reg:CC FLAGS_REG))]
11208   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11209   "@
11210    sar{w}\t{%2, %0|%0, %2}
11211    sar{w}\t{%b2, %0|%0, %b2}"
11212   [(set_attr "type" "ishift")
11213    (set_attr "mode" "HI")])
11215 ;; This pattern can't accept a variable shift count, since shifts by
11216 ;; zero don't affect the flags.  We assume that shifts by constant
11217 ;; zero are optimized away.
11218 (define_insn "*ashrhi3_one_bit_cmp"
11219   [(set (reg FLAGS_REG)
11220         (compare
11221           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11222                        (match_operand:QI 2 "const1_operand" ""))
11223           (const_int 0)))
11224    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11225         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11226   "ix86_match_ccmode (insn, CCGOCmode)
11227    && (TARGET_SHIFT1 || optimize_size)
11228    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11229   "sar{w}\t%0"
11230   [(set_attr "type" "ishift")
11231    (set (attr "length") 
11232      (if_then_else (match_operand 0 "register_operand" "") 
11233         (const_string "2")
11234         (const_string "*")))])
11236 ;; This pattern can't accept a variable shift count, since shifts by
11237 ;; zero don't affect the flags.  We assume that shifts by constant
11238 ;; zero are optimized away.
11239 (define_insn "*ashrhi3_cmp"
11240   [(set (reg FLAGS_REG)
11241         (compare
11242           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11243                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11244           (const_int 0)))
11245    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11246         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11247   "ix86_match_ccmode (insn, CCGOCmode)
11248    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11249   "sar{w}\t{%2, %0|%0, %2}"
11250   [(set_attr "type" "ishift")
11251    (set_attr "mode" "HI")])
11253 (define_expand "ashrqi3"
11254   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11255         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11256                      (match_operand:QI 2 "nonmemory_operand" "")))
11257    (clobber (reg:CC FLAGS_REG))]
11258   "TARGET_QIMODE_MATH"
11259   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11261 (define_insn "*ashrqi3_1_one_bit"
11262   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11263         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11264                      (match_operand:QI 2 "const1_operand" "")))
11265    (clobber (reg:CC FLAGS_REG))]
11266   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11267    && (TARGET_SHIFT1 || optimize_size)"
11268   "sar{b}\t%0"
11269   [(set_attr "type" "ishift")
11270    (set (attr "length") 
11271      (if_then_else (match_operand 0 "register_operand" "") 
11272         (const_string "2")
11273         (const_string "*")))])
11275 (define_insn "*ashrqi3_1_one_bit_slp"
11276   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11277         (ashiftrt:QI (match_dup 0)
11278                      (match_operand:QI 1 "const1_operand" "")))
11279    (clobber (reg:CC FLAGS_REG))]
11280   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11281    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11282    && (TARGET_SHIFT1 || optimize_size)"
11283   "sar{b}\t%0"
11284   [(set_attr "type" "ishift1")
11285    (set (attr "length") 
11286      (if_then_else (match_operand 0 "register_operand" "") 
11287         (const_string "2")
11288         (const_string "*")))])
11290 (define_insn "*ashrqi3_1"
11291   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11292         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11293                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11294    (clobber (reg:CC FLAGS_REG))]
11295   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11296   "@
11297    sar{b}\t{%2, %0|%0, %2}
11298    sar{b}\t{%b2, %0|%0, %b2}"
11299   [(set_attr "type" "ishift")
11300    (set_attr "mode" "QI")])
11302 (define_insn "*ashrqi3_1_slp"
11303   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11304         (ashiftrt:QI (match_dup 0)
11305                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11306    (clobber (reg:CC FLAGS_REG))]
11307   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11308    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11309   "@
11310    sar{b}\t{%1, %0|%0, %1}
11311    sar{b}\t{%b1, %0|%0, %b1}"
11312   [(set_attr "type" "ishift1")
11313    (set_attr "mode" "QI")])
11315 ;; This pattern can't accept a variable shift count, since shifts by
11316 ;; zero don't affect the flags.  We assume that shifts by constant
11317 ;; zero are optimized away.
11318 (define_insn "*ashrqi3_one_bit_cmp"
11319   [(set (reg FLAGS_REG)
11320         (compare
11321           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11322                        (match_operand:QI 2 "const1_operand" "I"))
11323           (const_int 0)))
11324    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11325         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11326   "ix86_match_ccmode (insn, CCGOCmode)
11327    && (TARGET_SHIFT1 || optimize_size)
11328    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11329   "sar{b}\t%0"
11330   [(set_attr "type" "ishift")
11331    (set (attr "length") 
11332      (if_then_else (match_operand 0 "register_operand" "") 
11333         (const_string "2")
11334         (const_string "*")))])
11336 ;; This pattern can't accept a variable shift count, since shifts by
11337 ;; zero don't affect the flags.  We assume that shifts by constant
11338 ;; zero are optimized away.
11339 (define_insn "*ashrqi3_cmp"
11340   [(set (reg FLAGS_REG)
11341         (compare
11342           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11343                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11344           (const_int 0)))
11345    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11346         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11347   "ix86_match_ccmode (insn, CCGOCmode)
11348    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11349   "sar{b}\t{%2, %0|%0, %2}"
11350   [(set_attr "type" "ishift")
11351    (set_attr "mode" "QI")])
11353 ;; Logical shift instructions
11355 ;; See comment above `ashldi3' about how this works.
11357 (define_expand "lshrdi3"
11358   [(set (match_operand:DI 0 "shiftdi_operand" "")
11359         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11360                      (match_operand:QI 2 "nonmemory_operand" "")))]
11361   ""
11362   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11364 (define_insn "*lshrdi3_1_one_bit_rex64"
11365   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11366         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11367                      (match_operand:QI 2 "const1_operand" "")))
11368    (clobber (reg:CC FLAGS_REG))]
11369   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11370    && (TARGET_SHIFT1 || optimize_size)"
11371   "shr{q}\t%0"
11372   [(set_attr "type" "ishift")
11373    (set (attr "length") 
11374      (if_then_else (match_operand:DI 0 "register_operand" "") 
11375         (const_string "2")
11376         (const_string "*")))])
11378 (define_insn "*lshrdi3_1_rex64"
11379   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11380         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11381                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11382    (clobber (reg:CC FLAGS_REG))]
11383   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11384   "@
11385    shr{q}\t{%2, %0|%0, %2}
11386    shr{q}\t{%b2, %0|%0, %b2}"
11387   [(set_attr "type" "ishift")
11388    (set_attr "mode" "DI")])
11390 ;; This pattern can't accept a variable shift count, since shifts by
11391 ;; zero don't affect the flags.  We assume that shifts by constant
11392 ;; zero are optimized away.
11393 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11394   [(set (reg FLAGS_REG)
11395         (compare
11396           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11397                        (match_operand:QI 2 "const1_operand" ""))
11398           (const_int 0)))
11399    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11400         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11401   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11402    && (TARGET_SHIFT1 || optimize_size)
11403    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11404   "shr{q}\t%0"
11405   [(set_attr "type" "ishift")
11406    (set (attr "length") 
11407      (if_then_else (match_operand:DI 0 "register_operand" "") 
11408         (const_string "2")
11409         (const_string "*")))])
11411 ;; This pattern can't accept a variable shift count, since shifts by
11412 ;; zero don't affect the flags.  We assume that shifts by constant
11413 ;; zero are optimized away.
11414 (define_insn "*lshrdi3_cmp_rex64"
11415   [(set (reg FLAGS_REG)
11416         (compare
11417           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11418                        (match_operand:QI 2 "const_int_operand" "e"))
11419           (const_int 0)))
11420    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11421         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11422   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11423    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11424   "shr{q}\t{%2, %0|%0, %2}"
11425   [(set_attr "type" "ishift")
11426    (set_attr "mode" "DI")])
11428 (define_insn "*lshrdi3_1"
11429   [(set (match_operand:DI 0 "register_operand" "=r")
11430         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11431                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11432    (clobber (reg:CC FLAGS_REG))]
11433   "!TARGET_64BIT"
11434   "#"
11435   [(set_attr "type" "multi")])
11437 ;; By default we don't ask for a scratch register, because when DImode
11438 ;; values are manipulated, registers are already at a premium.  But if
11439 ;; we have one handy, we won't turn it away.
11440 (define_peephole2
11441   [(match_scratch:SI 3 "r")
11442    (parallel [(set (match_operand:DI 0 "register_operand" "")
11443                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11444                                 (match_operand:QI 2 "nonmemory_operand" "")))
11445               (clobber (reg:CC FLAGS_REG))])
11446    (match_dup 3)]
11447   "!TARGET_64BIT && TARGET_CMOVE"
11448   [(const_int 0)]
11449   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11451 (define_split 
11452   [(set (match_operand:DI 0 "register_operand" "")
11453         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11454                      (match_operand:QI 2 "nonmemory_operand" "")))
11455    (clobber (reg:CC FLAGS_REG))]
11456   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11457   [(const_int 0)]
11458   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11460 (define_expand "lshrsi3"
11461   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11462         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11463                      (match_operand:QI 2 "nonmemory_operand" "")))
11464    (clobber (reg:CC FLAGS_REG))]
11465   ""
11466   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11468 (define_insn "*lshrsi3_1_one_bit"
11469   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11470         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11471                      (match_operand:QI 2 "const1_operand" "")))
11472    (clobber (reg:CC FLAGS_REG))]
11473   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11474    && (TARGET_SHIFT1 || optimize_size)"
11475   "shr{l}\t%0"
11476   [(set_attr "type" "ishift")
11477    (set (attr "length") 
11478      (if_then_else (match_operand:SI 0 "register_operand" "") 
11479         (const_string "2")
11480         (const_string "*")))])
11482 (define_insn "*lshrsi3_1_one_bit_zext"
11483   [(set (match_operand:DI 0 "register_operand" "=r")
11484         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11485                      (match_operand:QI 2 "const1_operand" "")))
11486    (clobber (reg:CC FLAGS_REG))]
11487   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11488    && (TARGET_SHIFT1 || optimize_size)"
11489   "shr{l}\t%k0"
11490   [(set_attr "type" "ishift")
11491    (set_attr "length" "2")])
11493 (define_insn "*lshrsi3_1"
11494   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11495         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11496                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11497    (clobber (reg:CC FLAGS_REG))]
11498   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11499   "@
11500    shr{l}\t{%2, %0|%0, %2}
11501    shr{l}\t{%b2, %0|%0, %b2}"
11502   [(set_attr "type" "ishift")
11503    (set_attr "mode" "SI")])
11505 (define_insn "*lshrsi3_1_zext"
11506   [(set (match_operand:DI 0 "register_operand" "=r,r")
11507         (zero_extend:DI
11508           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11509                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11510    (clobber (reg:CC FLAGS_REG))]
11511   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11512   "@
11513    shr{l}\t{%2, %k0|%k0, %2}
11514    shr{l}\t{%b2, %k0|%k0, %b2}"
11515   [(set_attr "type" "ishift")
11516    (set_attr "mode" "SI")])
11518 ;; This pattern can't accept a variable shift count, since shifts by
11519 ;; zero don't affect the flags.  We assume that shifts by constant
11520 ;; zero are optimized away.
11521 (define_insn "*lshrsi3_one_bit_cmp"
11522   [(set (reg FLAGS_REG)
11523         (compare
11524           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11525                        (match_operand:QI 2 "const1_operand" ""))
11526           (const_int 0)))
11527    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11528         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11529   "ix86_match_ccmode (insn, CCGOCmode)
11530    && (TARGET_SHIFT1 || optimize_size)
11531    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11532   "shr{l}\t%0"
11533   [(set_attr "type" "ishift")
11534    (set (attr "length") 
11535      (if_then_else (match_operand:SI 0 "register_operand" "") 
11536         (const_string "2")
11537         (const_string "*")))])
11539 (define_insn "*lshrsi3_cmp_one_bit_zext"
11540   [(set (reg FLAGS_REG)
11541         (compare
11542           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11543                        (match_operand:QI 2 "const1_operand" ""))
11544           (const_int 0)))
11545    (set (match_operand:DI 0 "register_operand" "=r")
11546         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11547   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11548    && (TARGET_SHIFT1 || optimize_size)
11549    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11550   "shr{l}\t%k0"
11551   [(set_attr "type" "ishift")
11552    (set_attr "length" "2")])
11554 ;; This pattern can't accept a variable shift count, since shifts by
11555 ;; zero don't affect the flags.  We assume that shifts by constant
11556 ;; zero are optimized away.
11557 (define_insn "*lshrsi3_cmp"
11558   [(set (reg FLAGS_REG)
11559         (compare
11560           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11561                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11562           (const_int 0)))
11563    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11564         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11565   "ix86_match_ccmode (insn, CCGOCmode)
11566    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11567   "shr{l}\t{%2, %0|%0, %2}"
11568   [(set_attr "type" "ishift")
11569    (set_attr "mode" "SI")])
11571 (define_insn "*lshrsi3_cmp_zext"
11572   [(set (reg FLAGS_REG)
11573         (compare
11574           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11575                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11576           (const_int 0)))
11577    (set (match_operand:DI 0 "register_operand" "=r")
11578         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11579   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11580    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11581   "shr{l}\t{%2, %k0|%k0, %2}"
11582   [(set_attr "type" "ishift")
11583    (set_attr "mode" "SI")])
11585 (define_expand "lshrhi3"
11586   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11587         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11588                      (match_operand:QI 2 "nonmemory_operand" "")))
11589    (clobber (reg:CC FLAGS_REG))]
11590   "TARGET_HIMODE_MATH"
11591   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11593 (define_insn "*lshrhi3_1_one_bit"
11594   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11595         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11596                      (match_operand:QI 2 "const1_operand" "")))
11597    (clobber (reg:CC FLAGS_REG))]
11598   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11599    && (TARGET_SHIFT1 || optimize_size)"
11600   "shr{w}\t%0"
11601   [(set_attr "type" "ishift")
11602    (set (attr "length") 
11603      (if_then_else (match_operand 0 "register_operand" "") 
11604         (const_string "2")
11605         (const_string "*")))])
11607 (define_insn "*lshrhi3_1"
11608   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11609         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11610                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11611    (clobber (reg:CC FLAGS_REG))]
11612   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11613   "@
11614    shr{w}\t{%2, %0|%0, %2}
11615    shr{w}\t{%b2, %0|%0, %b2}"
11616   [(set_attr "type" "ishift")
11617    (set_attr "mode" "HI")])
11619 ;; This pattern can't accept a variable shift count, since shifts by
11620 ;; zero don't affect the flags.  We assume that shifts by constant
11621 ;; zero are optimized away.
11622 (define_insn "*lshrhi3_one_bit_cmp"
11623   [(set (reg FLAGS_REG)
11624         (compare
11625           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11626                        (match_operand:QI 2 "const1_operand" ""))
11627           (const_int 0)))
11628    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11629         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11630   "ix86_match_ccmode (insn, CCGOCmode)
11631    && (TARGET_SHIFT1 || optimize_size)
11632    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11633   "shr{w}\t%0"
11634   [(set_attr "type" "ishift")
11635    (set (attr "length") 
11636      (if_then_else (match_operand:SI 0 "register_operand" "") 
11637         (const_string "2")
11638         (const_string "*")))])
11640 ;; This pattern can't accept a variable shift count, since shifts by
11641 ;; zero don't affect the flags.  We assume that shifts by constant
11642 ;; zero are optimized away.
11643 (define_insn "*lshrhi3_cmp"
11644   [(set (reg FLAGS_REG)
11645         (compare
11646           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11647                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11648           (const_int 0)))
11649    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11650         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11651   "ix86_match_ccmode (insn, CCGOCmode)
11652    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11653   "shr{w}\t{%2, %0|%0, %2}"
11654   [(set_attr "type" "ishift")
11655    (set_attr "mode" "HI")])
11657 (define_expand "lshrqi3"
11658   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11659         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11660                      (match_operand:QI 2 "nonmemory_operand" "")))
11661    (clobber (reg:CC FLAGS_REG))]
11662   "TARGET_QIMODE_MATH"
11663   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11665 (define_insn "*lshrqi3_1_one_bit"
11666   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11667         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11668                      (match_operand:QI 2 "const1_operand" "")))
11669    (clobber (reg:CC FLAGS_REG))]
11670   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11671    && (TARGET_SHIFT1 || optimize_size)"
11672   "shr{b}\t%0"
11673   [(set_attr "type" "ishift")
11674    (set (attr "length") 
11675      (if_then_else (match_operand 0 "register_operand" "") 
11676         (const_string "2")
11677         (const_string "*")))])
11679 (define_insn "*lshrqi3_1_one_bit_slp"
11680   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11681         (lshiftrt:QI (match_dup 0)
11682                      (match_operand:QI 1 "const1_operand" "")))
11683    (clobber (reg:CC FLAGS_REG))]
11684   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11685    && (TARGET_SHIFT1 || optimize_size)"
11686   "shr{b}\t%0"
11687   [(set_attr "type" "ishift1")
11688    (set (attr "length") 
11689      (if_then_else (match_operand 0 "register_operand" "") 
11690         (const_string "2")
11691         (const_string "*")))])
11693 (define_insn "*lshrqi3_1"
11694   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11695         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11696                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11697    (clobber (reg:CC FLAGS_REG))]
11698   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11699   "@
11700    shr{b}\t{%2, %0|%0, %2}
11701    shr{b}\t{%b2, %0|%0, %b2}"
11702   [(set_attr "type" "ishift")
11703    (set_attr "mode" "QI")])
11705 (define_insn "*lshrqi3_1_slp"
11706   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11707         (lshiftrt:QI (match_dup 0)
11708                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11709    (clobber (reg:CC FLAGS_REG))]
11710   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11711    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11712   "@
11713    shr{b}\t{%1, %0|%0, %1}
11714    shr{b}\t{%b1, %0|%0, %b1}"
11715   [(set_attr "type" "ishift1")
11716    (set_attr "mode" "QI")])
11718 ;; This pattern can't accept a variable shift count, since shifts by
11719 ;; zero don't affect the flags.  We assume that shifts by constant
11720 ;; zero are optimized away.
11721 (define_insn "*lshrqi2_one_bit_cmp"
11722   [(set (reg FLAGS_REG)
11723         (compare
11724           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11725                        (match_operand:QI 2 "const1_operand" ""))
11726           (const_int 0)))
11727    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11728         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11729   "ix86_match_ccmode (insn, CCGOCmode)
11730    && (TARGET_SHIFT1 || optimize_size)
11731    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11732   "shr{b}\t%0"
11733   [(set_attr "type" "ishift")
11734    (set (attr "length") 
11735      (if_then_else (match_operand:SI 0 "register_operand" "") 
11736         (const_string "2")
11737         (const_string "*")))])
11739 ;; This pattern can't accept a variable shift count, since shifts by
11740 ;; zero don't affect the flags.  We assume that shifts by constant
11741 ;; zero are optimized away.
11742 (define_insn "*lshrqi2_cmp"
11743   [(set (reg FLAGS_REG)
11744         (compare
11745           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11746                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11747           (const_int 0)))
11748    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11749         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11750   "ix86_match_ccmode (insn, CCGOCmode)
11751    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11752   "shr{b}\t{%2, %0|%0, %2}"
11753   [(set_attr "type" "ishift")
11754    (set_attr "mode" "QI")])
11756 ;; Rotate instructions
11758 (define_expand "rotldi3"
11759   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11760         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11761                    (match_operand:QI 2 "nonmemory_operand" "")))
11762    (clobber (reg:CC FLAGS_REG))]
11763   "TARGET_64BIT"
11764   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11766 (define_insn "*rotlsi3_1_one_bit_rex64"
11767   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11768         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11769                    (match_operand:QI 2 "const1_operand" "")))
11770    (clobber (reg:CC FLAGS_REG))]
11771   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11772    && (TARGET_SHIFT1 || optimize_size)"
11773   "rol{q}\t%0"
11774   [(set_attr "type" "rotate")
11775    (set (attr "length") 
11776      (if_then_else (match_operand:DI 0 "register_operand" "") 
11777         (const_string "2")
11778         (const_string "*")))])
11780 (define_insn "*rotldi3_1_rex64"
11781   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11782         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11783                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11784    (clobber (reg:CC FLAGS_REG))]
11785   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11786   "@
11787    rol{q}\t{%2, %0|%0, %2}
11788    rol{q}\t{%b2, %0|%0, %b2}"
11789   [(set_attr "type" "rotate")
11790    (set_attr "mode" "DI")])
11792 (define_expand "rotlsi3"
11793   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11794         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11795                    (match_operand:QI 2 "nonmemory_operand" "")))
11796    (clobber (reg:CC FLAGS_REG))]
11797   ""
11798   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11800 (define_insn "*rotlsi3_1_one_bit"
11801   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11802         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11803                    (match_operand:QI 2 "const1_operand" "")))
11804    (clobber (reg:CC FLAGS_REG))]
11805   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11806    && (TARGET_SHIFT1 || optimize_size)"
11807   "rol{l}\t%0"
11808   [(set_attr "type" "rotate")
11809    (set (attr "length") 
11810      (if_then_else (match_operand:SI 0 "register_operand" "") 
11811         (const_string "2")
11812         (const_string "*")))])
11814 (define_insn "*rotlsi3_1_one_bit_zext"
11815   [(set (match_operand:DI 0 "register_operand" "=r")
11816         (zero_extend:DI
11817           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11818                      (match_operand:QI 2 "const1_operand" ""))))
11819    (clobber (reg:CC FLAGS_REG))]
11820   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11821    && (TARGET_SHIFT1 || optimize_size)"
11822   "rol{l}\t%k0"
11823   [(set_attr "type" "rotate")
11824    (set_attr "length" "2")])
11826 (define_insn "*rotlsi3_1"
11827   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11828         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11829                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11830    (clobber (reg:CC FLAGS_REG))]
11831   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11832   "@
11833    rol{l}\t{%2, %0|%0, %2}
11834    rol{l}\t{%b2, %0|%0, %b2}"
11835   [(set_attr "type" "rotate")
11836    (set_attr "mode" "SI")])
11838 (define_insn "*rotlsi3_1_zext"
11839   [(set (match_operand:DI 0 "register_operand" "=r,r")
11840         (zero_extend:DI
11841           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11842                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11843    (clobber (reg:CC FLAGS_REG))]
11844   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11845   "@
11846    rol{l}\t{%2, %k0|%k0, %2}
11847    rol{l}\t{%b2, %k0|%k0, %b2}"
11848   [(set_attr "type" "rotate")
11849    (set_attr "mode" "SI")])
11851 (define_expand "rotlhi3"
11852   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11853         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11854                    (match_operand:QI 2 "nonmemory_operand" "")))
11855    (clobber (reg:CC FLAGS_REG))]
11856   "TARGET_HIMODE_MATH"
11857   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11859 (define_insn "*rotlhi3_1_one_bit"
11860   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11861         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11862                    (match_operand:QI 2 "const1_operand" "")))
11863    (clobber (reg:CC FLAGS_REG))]
11864   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11865    && (TARGET_SHIFT1 || optimize_size)"
11866   "rol{w}\t%0"
11867   [(set_attr "type" "rotate")
11868    (set (attr "length") 
11869      (if_then_else (match_operand 0 "register_operand" "") 
11870         (const_string "2")
11871         (const_string "*")))])
11873 (define_insn "*rotlhi3_1"
11874   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11875         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11876                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11877    (clobber (reg:CC FLAGS_REG))]
11878   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11879   "@
11880    rol{w}\t{%2, %0|%0, %2}
11881    rol{w}\t{%b2, %0|%0, %b2}"
11882   [(set_attr "type" "rotate")
11883    (set_attr "mode" "HI")])
11885 (define_expand "rotlqi3"
11886   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11887         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11888                    (match_operand:QI 2 "nonmemory_operand" "")))
11889    (clobber (reg:CC FLAGS_REG))]
11890   "TARGET_QIMODE_MATH"
11891   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11893 (define_insn "*rotlqi3_1_one_bit_slp"
11894   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11895         (rotate:QI (match_dup 0)
11896                    (match_operand:QI 1 "const1_operand" "")))
11897    (clobber (reg:CC FLAGS_REG))]
11898   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11899    && (TARGET_SHIFT1 || optimize_size)"
11900   "rol{b}\t%0"
11901   [(set_attr "type" "rotate1")
11902    (set (attr "length") 
11903      (if_then_else (match_operand 0 "register_operand" "") 
11904         (const_string "2")
11905         (const_string "*")))])
11907 (define_insn "*rotlqi3_1_one_bit"
11908   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11909         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11910                    (match_operand:QI 2 "const1_operand" "")))
11911    (clobber (reg:CC FLAGS_REG))]
11912   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11913    && (TARGET_SHIFT1 || optimize_size)"
11914   "rol{b}\t%0"
11915   [(set_attr "type" "rotate")
11916    (set (attr "length") 
11917      (if_then_else (match_operand 0 "register_operand" "") 
11918         (const_string "2")
11919         (const_string "*")))])
11921 (define_insn "*rotlqi3_1_slp"
11922   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11923         (rotate:QI (match_dup 0)
11924                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11925    (clobber (reg:CC FLAGS_REG))]
11926   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11927    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11928   "@
11929    rol{b}\t{%1, %0|%0, %1}
11930    rol{b}\t{%b1, %0|%0, %b1}"
11931   [(set_attr "type" "rotate1")
11932    (set_attr "mode" "QI")])
11934 (define_insn "*rotlqi3_1"
11935   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11936         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11937                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11938    (clobber (reg:CC FLAGS_REG))]
11939   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11940   "@
11941    rol{b}\t{%2, %0|%0, %2}
11942    rol{b}\t{%b2, %0|%0, %b2}"
11943   [(set_attr "type" "rotate")
11944    (set_attr "mode" "QI")])
11946 (define_expand "rotrdi3"
11947   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11948         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11949                      (match_operand:QI 2 "nonmemory_operand" "")))
11950    (clobber (reg:CC FLAGS_REG))]
11951   "TARGET_64BIT"
11952   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11954 (define_insn "*rotrdi3_1_one_bit_rex64"
11955   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11956         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11957                      (match_operand:QI 2 "const1_operand" "")))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11960    && (TARGET_SHIFT1 || optimize_size)"
11961   "ror{q}\t%0"
11962   [(set_attr "type" "rotate")
11963    (set (attr "length") 
11964      (if_then_else (match_operand:DI 0 "register_operand" "") 
11965         (const_string "2")
11966         (const_string "*")))])
11968 (define_insn "*rotrdi3_1_rex64"
11969   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11970         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11971                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11972    (clobber (reg:CC FLAGS_REG))]
11973   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11974   "@
11975    ror{q}\t{%2, %0|%0, %2}
11976    ror{q}\t{%b2, %0|%0, %b2}"
11977   [(set_attr "type" "rotate")
11978    (set_attr "mode" "DI")])
11980 (define_expand "rotrsi3"
11981   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11982         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11983                      (match_operand:QI 2 "nonmemory_operand" "")))
11984    (clobber (reg:CC FLAGS_REG))]
11985   ""
11986   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11988 (define_insn "*rotrsi3_1_one_bit"
11989   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11990         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11991                      (match_operand:QI 2 "const1_operand" "")))
11992    (clobber (reg:CC FLAGS_REG))]
11993   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11994    && (TARGET_SHIFT1 || optimize_size)"
11995   "ror{l}\t%0"
11996   [(set_attr "type" "rotate")
11997    (set (attr "length") 
11998      (if_then_else (match_operand:SI 0 "register_operand" "") 
11999         (const_string "2")
12000         (const_string "*")))])
12002 (define_insn "*rotrsi3_1_one_bit_zext"
12003   [(set (match_operand:DI 0 "register_operand" "=r")
12004         (zero_extend:DI
12005           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12006                        (match_operand:QI 2 "const1_operand" ""))))
12007    (clobber (reg:CC FLAGS_REG))]
12008   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12009    && (TARGET_SHIFT1 || optimize_size)"
12010   "ror{l}\t%k0"
12011   [(set_attr "type" "rotate")
12012    (set (attr "length") 
12013      (if_then_else (match_operand:SI 0 "register_operand" "") 
12014         (const_string "2")
12015         (const_string "*")))])
12017 (define_insn "*rotrsi3_1"
12018   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12019         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12020                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12021    (clobber (reg:CC FLAGS_REG))]
12022   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12023   "@
12024    ror{l}\t{%2, %0|%0, %2}
12025    ror{l}\t{%b2, %0|%0, %b2}"
12026   [(set_attr "type" "rotate")
12027    (set_attr "mode" "SI")])
12029 (define_insn "*rotrsi3_1_zext"
12030   [(set (match_operand:DI 0 "register_operand" "=r,r")
12031         (zero_extend:DI
12032           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12033                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12034    (clobber (reg:CC FLAGS_REG))]
12035   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12036   "@
12037    ror{l}\t{%2, %k0|%k0, %2}
12038    ror{l}\t{%b2, %k0|%k0, %b2}"
12039   [(set_attr "type" "rotate")
12040    (set_attr "mode" "SI")])
12042 (define_expand "rotrhi3"
12043   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12044         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12045                      (match_operand:QI 2 "nonmemory_operand" "")))
12046    (clobber (reg:CC FLAGS_REG))]
12047   "TARGET_HIMODE_MATH"
12048   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12050 (define_insn "*rotrhi3_one_bit"
12051   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12052         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12053                      (match_operand:QI 2 "const1_operand" "")))
12054    (clobber (reg:CC FLAGS_REG))]
12055   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12056    && (TARGET_SHIFT1 || optimize_size)"
12057   "ror{w}\t%0"
12058   [(set_attr "type" "rotate")
12059    (set (attr "length") 
12060      (if_then_else (match_operand 0 "register_operand" "") 
12061         (const_string "2")
12062         (const_string "*")))])
12064 (define_insn "*rotrhi3"
12065   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12066         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12067                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12068    (clobber (reg:CC FLAGS_REG))]
12069   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12070   "@
12071    ror{w}\t{%2, %0|%0, %2}
12072    ror{w}\t{%b2, %0|%0, %b2}"
12073   [(set_attr "type" "rotate")
12074    (set_attr "mode" "HI")])
12076 (define_expand "rotrqi3"
12077   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12078         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12079                      (match_operand:QI 2 "nonmemory_operand" "")))
12080    (clobber (reg:CC FLAGS_REG))]
12081   "TARGET_QIMODE_MATH"
12082   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12084 (define_insn "*rotrqi3_1_one_bit"
12085   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12086         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12087                      (match_operand:QI 2 "const1_operand" "")))
12088    (clobber (reg:CC FLAGS_REG))]
12089   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12090    && (TARGET_SHIFT1 || optimize_size)"
12091   "ror{b}\t%0"
12092   [(set_attr "type" "rotate")
12093    (set (attr "length") 
12094      (if_then_else (match_operand 0 "register_operand" "") 
12095         (const_string "2")
12096         (const_string "*")))])
12098 (define_insn "*rotrqi3_1_one_bit_slp"
12099   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12100         (rotatert:QI (match_dup 0)
12101                      (match_operand:QI 1 "const1_operand" "")))
12102    (clobber (reg:CC FLAGS_REG))]
12103   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12104    && (TARGET_SHIFT1 || optimize_size)"
12105   "ror{b}\t%0"
12106   [(set_attr "type" "rotate1")
12107    (set (attr "length") 
12108      (if_then_else (match_operand 0 "register_operand" "") 
12109         (const_string "2")
12110         (const_string "*")))])
12112 (define_insn "*rotrqi3_1"
12113   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12114         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12115                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12116    (clobber (reg:CC FLAGS_REG))]
12117   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12118   "@
12119    ror{b}\t{%2, %0|%0, %2}
12120    ror{b}\t{%b2, %0|%0, %b2}"
12121   [(set_attr "type" "rotate")
12122    (set_attr "mode" "QI")])
12124 (define_insn "*rotrqi3_1_slp"
12125   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12126         (rotatert:QI (match_dup 0)
12127                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12128    (clobber (reg:CC FLAGS_REG))]
12129   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12131   "@
12132    ror{b}\t{%1, %0|%0, %1}
12133    ror{b}\t{%b1, %0|%0, %b1}"
12134   [(set_attr "type" "rotate1")
12135    (set_attr "mode" "QI")])
12137 ;; Bit set / bit test instructions
12139 (define_expand "extv"
12140   [(set (match_operand:SI 0 "register_operand" "")
12141         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12142                          (match_operand:SI 2 "immediate_operand" "")
12143                          (match_operand:SI 3 "immediate_operand" "")))]
12144   ""
12146   /* Handle extractions from %ah et al.  */
12147   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12148     FAIL;
12150   /* From mips.md: extract_bit_field doesn't verify that our source
12151      matches the predicate, so check it again here.  */
12152   if (! ext_register_operand (operands[1], VOIDmode))
12153     FAIL;
12156 (define_expand "extzv"
12157   [(set (match_operand:SI 0 "register_operand" "")
12158         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12159                          (match_operand:SI 2 "immediate_operand" "")
12160                          (match_operand:SI 3 "immediate_operand" "")))]
12161   ""
12163   /* Handle extractions from %ah et al.  */
12164   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12165     FAIL;
12167   /* From mips.md: extract_bit_field doesn't verify that our source
12168      matches the predicate, so check it again here.  */
12169   if (! ext_register_operand (operands[1], VOIDmode))
12170     FAIL;
12173 (define_expand "insv"
12174   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12175                       (match_operand 1 "immediate_operand" "")
12176                       (match_operand 2 "immediate_operand" ""))
12177         (match_operand 3 "register_operand" ""))]
12178   ""
12180   /* Handle extractions from %ah et al.  */
12181   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12182     FAIL;
12184   /* From mips.md: insert_bit_field doesn't verify that our source
12185      matches the predicate, so check it again here.  */
12186   if (! ext_register_operand (operands[0], VOIDmode))
12187     FAIL;
12189   if (TARGET_64BIT)
12190     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12191   else
12192     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12194   DONE;
12197 ;; %%% bts, btr, btc, bt.
12198 ;; In general these instructions are *slow* when applied to memory,
12199 ;; since they enforce atomic operation.  When applied to registers,
12200 ;; it depends on the cpu implementation.  They're never faster than
12201 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12202 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12203 ;; within the instruction itself, so operating on bits in the high
12204 ;; 32-bits of a register becomes easier.
12206 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12207 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12208 ;; negdf respectively, so they can never be disabled entirely.
12210 (define_insn "*btsq"
12211   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12212                          (const_int 1)
12213                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12214         (const_int 1))
12215    (clobber (reg:CC FLAGS_REG))]
12216   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12217   "bts{q} %1,%0"
12218   [(set_attr "type" "alu1")])
12220 (define_insn "*btrq"
12221   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12222                          (const_int 1)
12223                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12224         (const_int 0))
12225    (clobber (reg:CC FLAGS_REG))]
12226   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12227   "btr{q} %1,%0"
12228   [(set_attr "type" "alu1")])
12230 (define_insn "*btcq"
12231   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12232                          (const_int 1)
12233                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12234         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12235    (clobber (reg:CC FLAGS_REG))]
12236   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12237   "btc{q} %1,%0"
12238   [(set_attr "type" "alu1")])
12240 ;; Allow Nocona to avoid these instructions if a register is available.
12242 (define_peephole2
12243   [(match_scratch:DI 2 "r")
12244    (parallel [(set (zero_extract:DI
12245                      (match_operand:DI 0 "register_operand" "")
12246                      (const_int 1)
12247                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12248                    (const_int 1))
12249               (clobber (reg:CC FLAGS_REG))])]
12250   "TARGET_64BIT && !TARGET_USE_BT"
12251   [(const_int 0)]
12253   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12254   rtx op1;
12256   if (HOST_BITS_PER_WIDE_INT >= 64)
12257     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12258   else if (i < HOST_BITS_PER_WIDE_INT)
12259     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12260   else
12261     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12263   op1 = immed_double_const (lo, hi, DImode);
12264   if (i >= 31)
12265     {
12266       emit_move_insn (operands[2], op1);
12267       op1 = operands[2];
12268     }
12270   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12271   DONE;
12274 (define_peephole2
12275   [(match_scratch:DI 2 "r")
12276    (parallel [(set (zero_extract:DI
12277                      (match_operand:DI 0 "register_operand" "")
12278                      (const_int 1)
12279                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12280                    (const_int 0))
12281               (clobber (reg:CC FLAGS_REG))])]
12282   "TARGET_64BIT && !TARGET_USE_BT"
12283   [(const_int 0)]
12285   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12286   rtx op1;
12288   if (HOST_BITS_PER_WIDE_INT >= 64)
12289     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12290   else if (i < HOST_BITS_PER_WIDE_INT)
12291     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12292   else
12293     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12295   op1 = immed_double_const (~lo, ~hi, DImode);
12296   if (i >= 32)
12297     {
12298       emit_move_insn (operands[2], op1);
12299       op1 = operands[2];
12300     }
12302   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12303   DONE;
12306 (define_peephole2
12307   [(match_scratch:DI 2 "r")
12308    (parallel [(set (zero_extract:DI
12309                      (match_operand:DI 0 "register_operand" "")
12310                      (const_int 1)
12311                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12312               (not:DI (zero_extract:DI
12313                         (match_dup 0) (const_int 1) (match_dup 1))))
12314               (clobber (reg:CC FLAGS_REG))])]
12315   "TARGET_64BIT && !TARGET_USE_BT"
12316   [(const_int 0)]
12318   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12319   rtx op1;
12321   if (HOST_BITS_PER_WIDE_INT >= 64)
12322     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12323   else if (i < HOST_BITS_PER_WIDE_INT)
12324     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12325   else
12326     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12328   op1 = immed_double_const (lo, hi, DImode);
12329   if (i >= 31)
12330     {
12331       emit_move_insn (operands[2], op1);
12332       op1 = operands[2];
12333     }
12335   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12336   DONE;
12339 ;; Store-flag instructions.
12341 ;; For all sCOND expanders, also expand the compare or test insn that
12342 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12344 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12345 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12346 ;; way, which can later delete the movzx if only QImode is needed.
12348 (define_expand "seq"
12349   [(set (match_operand:QI 0 "register_operand" "")
12350         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12351   ""
12352   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12354 (define_expand "sne"
12355   [(set (match_operand:QI 0 "register_operand" "")
12356         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12357   ""
12358   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12360 (define_expand "sgt"
12361   [(set (match_operand:QI 0 "register_operand" "")
12362         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12363   ""
12364   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12366 (define_expand "sgtu"
12367   [(set (match_operand:QI 0 "register_operand" "")
12368         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12369   ""
12370   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12372 (define_expand "slt"
12373   [(set (match_operand:QI 0 "register_operand" "")
12374         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12375   ""
12376   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12378 (define_expand "sltu"
12379   [(set (match_operand:QI 0 "register_operand" "")
12380         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12381   ""
12382   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12384 (define_expand "sge"
12385   [(set (match_operand:QI 0 "register_operand" "")
12386         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12387   ""
12388   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12390 (define_expand "sgeu"
12391   [(set (match_operand:QI 0 "register_operand" "")
12392         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12393   ""
12394   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12396 (define_expand "sle"
12397   [(set (match_operand:QI 0 "register_operand" "")
12398         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12399   ""
12400   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12402 (define_expand "sleu"
12403   [(set (match_operand:QI 0 "register_operand" "")
12404         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12405   ""
12406   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12408 (define_expand "sunordered"
12409   [(set (match_operand:QI 0 "register_operand" "")
12410         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12411   "TARGET_80387 || TARGET_SSE"
12412   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12414 (define_expand "sordered"
12415   [(set (match_operand:QI 0 "register_operand" "")
12416         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12417   "TARGET_80387"
12418   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12420 (define_expand "suneq"
12421   [(set (match_operand:QI 0 "register_operand" "")
12422         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12423   "TARGET_80387 || TARGET_SSE"
12424   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12426 (define_expand "sunge"
12427   [(set (match_operand:QI 0 "register_operand" "")
12428         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12429   "TARGET_80387 || TARGET_SSE"
12430   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12432 (define_expand "sungt"
12433   [(set (match_operand:QI 0 "register_operand" "")
12434         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12435   "TARGET_80387 || TARGET_SSE"
12436   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12438 (define_expand "sunle"
12439   [(set (match_operand:QI 0 "register_operand" "")
12440         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12441   "TARGET_80387 || TARGET_SSE"
12442   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12444 (define_expand "sunlt"
12445   [(set (match_operand:QI 0 "register_operand" "")
12446         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12447   "TARGET_80387 || TARGET_SSE"
12448   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12450 (define_expand "sltgt"
12451   [(set (match_operand:QI 0 "register_operand" "")
12452         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12453   "TARGET_80387 || TARGET_SSE"
12454   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12456 (define_insn "*setcc_1"
12457   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12458         (match_operator:QI 1 "ix86_comparison_operator"
12459           [(reg FLAGS_REG) (const_int 0)]))]
12460   ""
12461   "set%C1\t%0"
12462   [(set_attr "type" "setcc")
12463    (set_attr "mode" "QI")])
12465 (define_insn "*setcc_2"
12466   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12467         (match_operator:QI 1 "ix86_comparison_operator"
12468           [(reg FLAGS_REG) (const_int 0)]))]
12469   ""
12470   "set%C1\t%0"
12471   [(set_attr "type" "setcc")
12472    (set_attr "mode" "QI")])
12474 ;; In general it is not safe to assume too much about CCmode registers,
12475 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12476 ;; conditions this is safe on x86, so help combine not create
12478 ;;      seta    %al
12479 ;;      testb   %al, %al
12480 ;;      sete    %al
12482 (define_split 
12483   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12484         (ne:QI (match_operator 1 "ix86_comparison_operator"
12485                  [(reg FLAGS_REG) (const_int 0)])
12486             (const_int 0)))]
12487   ""
12488   [(set (match_dup 0) (match_dup 1))]
12490   PUT_MODE (operands[1], QImode);
12493 (define_split 
12494   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12495         (ne: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   PUT_MODE (operands[1], QImode);
12504 (define_split 
12505   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12506         (eq:QI (match_operator 1 "ix86_comparison_operator"
12507                  [(reg FLAGS_REG) (const_int 0)])
12508             (const_int 0)))]
12509   ""
12510   [(set (match_dup 0) (match_dup 1))]
12512   rtx new_op1 = copy_rtx (operands[1]);
12513   operands[1] = new_op1;
12514   PUT_MODE (new_op1, QImode);
12515   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12516                                              GET_MODE (XEXP (new_op1, 0))));
12518   /* Make sure that (a) the CCmode we have for the flags is strong
12519      enough for the reversed compare or (b) we have a valid FP compare.  */
12520   if (! ix86_comparison_operator (new_op1, VOIDmode))
12521     FAIL;
12524 (define_split 
12525   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12526         (eq:QI (match_operator 1 "ix86_comparison_operator"
12527                  [(reg FLAGS_REG) (const_int 0)])
12528             (const_int 0)))]
12529   ""
12530   [(set (match_dup 0) (match_dup 1))]
12532   rtx new_op1 = copy_rtx (operands[1]);
12533   operands[1] = new_op1;
12534   PUT_MODE (new_op1, QImode);
12535   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12536                                              GET_MODE (XEXP (new_op1, 0))));
12538   /* Make sure that (a) the CCmode we have for the flags is strong
12539      enough for the reversed compare or (b) we have a valid FP compare.  */
12540   if (! ix86_comparison_operator (new_op1, VOIDmode))
12541     FAIL;
12544 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12545 ;; subsequent logical operations are used to imitate conditional moves.
12546 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12547 ;; it directly.  Further holding this value in pseudo register might bring
12548 ;; problem in implicit normalization in spill code.
12549 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12550 ;; instructions after reload by splitting the conditional move patterns.
12552 (define_insn "*sse_setccsf"
12553   [(set (match_operand:SF 0 "register_operand" "=x")
12554         (match_operator:SF 1 "sse_comparison_operator"
12555           [(match_operand:SF 2 "register_operand" "0")
12556            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12557   "TARGET_SSE && reload_completed"
12558   "cmp%D1ss\t{%3, %0|%0, %3}"
12559   [(set_attr "type" "ssecmp")
12560    (set_attr "mode" "SF")])
12562 (define_insn "*sse_setccdf"
12563   [(set (match_operand:DF 0 "register_operand" "=Y")
12564         (match_operator:DF 1 "sse_comparison_operator"
12565           [(match_operand:DF 2 "register_operand" "0")
12566            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12567   "TARGET_SSE2 && reload_completed"
12568   "cmp%D1sd\t{%3, %0|%0, %3}"
12569   [(set_attr "type" "ssecmp")
12570    (set_attr "mode" "DF")])
12572 ;; Basic conditional jump instructions.
12573 ;; We ignore the overflow flag for signed branch instructions.
12575 ;; For all bCOND expanders, also expand the compare or test insn that
12576 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12578 (define_expand "beq"
12579   [(set (pc)
12580         (if_then_else (match_dup 1)
12581                       (label_ref (match_operand 0 "" ""))
12582                       (pc)))]
12583   ""
12584   "ix86_expand_branch (EQ, operands[0]); DONE;")
12586 (define_expand "bne"
12587   [(set (pc)
12588         (if_then_else (match_dup 1)
12589                       (label_ref (match_operand 0 "" ""))
12590                       (pc)))]
12591   ""
12592   "ix86_expand_branch (NE, operands[0]); DONE;")
12594 (define_expand "bgt"
12595   [(set (pc)
12596         (if_then_else (match_dup 1)
12597                       (label_ref (match_operand 0 "" ""))
12598                       (pc)))]
12599   ""
12600   "ix86_expand_branch (GT, operands[0]); DONE;")
12602 (define_expand "bgtu"
12603   [(set (pc)
12604         (if_then_else (match_dup 1)
12605                       (label_ref (match_operand 0 "" ""))
12606                       (pc)))]
12607   ""
12608   "ix86_expand_branch (GTU, operands[0]); DONE;")
12610 (define_expand "blt"
12611   [(set (pc)
12612         (if_then_else (match_dup 1)
12613                       (label_ref (match_operand 0 "" ""))
12614                       (pc)))]
12615   ""
12616   "ix86_expand_branch (LT, operands[0]); DONE;")
12618 (define_expand "bltu"
12619   [(set (pc)
12620         (if_then_else (match_dup 1)
12621                       (label_ref (match_operand 0 "" ""))
12622                       (pc)))]
12623   ""
12624   "ix86_expand_branch (LTU, operands[0]); DONE;")
12626 (define_expand "bge"
12627   [(set (pc)
12628         (if_then_else (match_dup 1)
12629                       (label_ref (match_operand 0 "" ""))
12630                       (pc)))]
12631   ""
12632   "ix86_expand_branch (GE, operands[0]); DONE;")
12634 (define_expand "bgeu"
12635   [(set (pc)
12636         (if_then_else (match_dup 1)
12637                       (label_ref (match_operand 0 "" ""))
12638                       (pc)))]
12639   ""
12640   "ix86_expand_branch (GEU, operands[0]); DONE;")
12642 (define_expand "ble"
12643   [(set (pc)
12644         (if_then_else (match_dup 1)
12645                       (label_ref (match_operand 0 "" ""))
12646                       (pc)))]
12647   ""
12648   "ix86_expand_branch (LE, operands[0]); DONE;")
12650 (define_expand "bleu"
12651   [(set (pc)
12652         (if_then_else (match_dup 1)
12653                       (label_ref (match_operand 0 "" ""))
12654                       (pc)))]
12655   ""
12656   "ix86_expand_branch (LEU, operands[0]); DONE;")
12658 (define_expand "bunordered"
12659   [(set (pc)
12660         (if_then_else (match_dup 1)
12661                       (label_ref (match_operand 0 "" ""))
12662                       (pc)))]
12663   "TARGET_80387 || TARGET_SSE"
12664   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12666 (define_expand "bordered"
12667   [(set (pc)
12668         (if_then_else (match_dup 1)
12669                       (label_ref (match_operand 0 "" ""))
12670                       (pc)))]
12671   "TARGET_80387 || TARGET_SSE"
12672   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12674 (define_expand "buneq"
12675   [(set (pc)
12676         (if_then_else (match_dup 1)
12677                       (label_ref (match_operand 0 "" ""))
12678                       (pc)))]
12679   "TARGET_80387 || TARGET_SSE"
12680   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12682 (define_expand "bunge"
12683   [(set (pc)
12684         (if_then_else (match_dup 1)
12685                       (label_ref (match_operand 0 "" ""))
12686                       (pc)))]
12687   "TARGET_80387 || TARGET_SSE"
12688   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12690 (define_expand "bungt"
12691   [(set (pc)
12692         (if_then_else (match_dup 1)
12693                       (label_ref (match_operand 0 "" ""))
12694                       (pc)))]
12695   "TARGET_80387 || TARGET_SSE"
12696   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12698 (define_expand "bunle"
12699   [(set (pc)
12700         (if_then_else (match_dup 1)
12701                       (label_ref (match_operand 0 "" ""))
12702                       (pc)))]
12703   "TARGET_80387 || TARGET_SSE"
12704   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12706 (define_expand "bunlt"
12707   [(set (pc)
12708         (if_then_else (match_dup 1)
12709                       (label_ref (match_operand 0 "" ""))
12710                       (pc)))]
12711   "TARGET_80387 || TARGET_SSE"
12712   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12714 (define_expand "bltgt"
12715   [(set (pc)
12716         (if_then_else (match_dup 1)
12717                       (label_ref (match_operand 0 "" ""))
12718                       (pc)))]
12719   "TARGET_80387 || TARGET_SSE"
12720   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12722 (define_insn "*jcc_1"
12723   [(set (pc)
12724         (if_then_else (match_operator 1 "ix86_comparison_operator"
12725                                       [(reg FLAGS_REG) (const_int 0)])
12726                       (label_ref (match_operand 0 "" ""))
12727                       (pc)))]
12728   ""
12729   "%+j%C1\t%l0"
12730   [(set_attr "type" "ibr")
12731    (set_attr "modrm" "0")
12732    (set (attr "length")
12733            (if_then_else (and (ge (minus (match_dup 0) (pc))
12734                                   (const_int -126))
12735                               (lt (minus (match_dup 0) (pc))
12736                                   (const_int 128)))
12737              (const_int 2)
12738              (const_int 6)))])
12740 (define_insn "*jcc_2"
12741   [(set (pc)
12742         (if_then_else (match_operator 1 "ix86_comparison_operator"
12743                                       [(reg FLAGS_REG) (const_int 0)])
12744                       (pc)
12745                       (label_ref (match_operand 0 "" ""))))]
12746   ""
12747   "%+j%c1\t%l0"
12748   [(set_attr "type" "ibr")
12749    (set_attr "modrm" "0")
12750    (set (attr "length")
12751            (if_then_else (and (ge (minus (match_dup 0) (pc))
12752                                   (const_int -126))
12753                               (lt (minus (match_dup 0) (pc))
12754                                   (const_int 128)))
12755              (const_int 2)
12756              (const_int 6)))])
12758 ;; In general it is not safe to assume too much about CCmode registers,
12759 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12760 ;; conditions this is safe on x86, so help combine not create
12762 ;;      seta    %al
12763 ;;      testb   %al, %al
12764 ;;      je      Lfoo
12766 (define_split 
12767   [(set (pc)
12768         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12769                                       [(reg FLAGS_REG) (const_int 0)])
12770                           (const_int 0))
12771                       (label_ref (match_operand 1 "" ""))
12772                       (pc)))]
12773   ""
12774   [(set (pc)
12775         (if_then_else (match_dup 0)
12776                       (label_ref (match_dup 1))
12777                       (pc)))]
12779   PUT_MODE (operands[0], VOIDmode);
12781   
12782 (define_split 
12783   [(set (pc)
12784         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12785                                       [(reg FLAGS_REG) (const_int 0)])
12786                           (const_int 0))
12787                       (label_ref (match_operand 1 "" ""))
12788                       (pc)))]
12789   ""
12790   [(set (pc)
12791         (if_then_else (match_dup 0)
12792                       (label_ref (match_dup 1))
12793                       (pc)))]
12795   rtx new_op0 = copy_rtx (operands[0]);
12796   operands[0] = new_op0;
12797   PUT_MODE (new_op0, VOIDmode);
12798   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12799                                              GET_MODE (XEXP (new_op0, 0))));
12801   /* Make sure that (a) the CCmode we have for the flags is strong
12802      enough for the reversed compare or (b) we have a valid FP compare.  */
12803   if (! ix86_comparison_operator (new_op0, VOIDmode))
12804     FAIL;
12807 ;; Define combination compare-and-branch fp compare instructions to use
12808 ;; during early optimization.  Splitting the operation apart early makes
12809 ;; for bad code when we want to reverse the operation.
12811 (define_insn "*fp_jcc_1"
12812   [(set (pc)
12813         (if_then_else (match_operator 0 "comparison_operator"
12814                         [(match_operand 1 "register_operand" "f")
12815                          (match_operand 2 "register_operand" "f")])
12816           (label_ref (match_operand 3 "" ""))
12817           (pc)))
12818    (clobber (reg:CCFP FPSR_REG))
12819    (clobber (reg:CCFP FLAGS_REG))]
12820   "TARGET_CMOVE && TARGET_80387
12821    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12822    && FLOAT_MODE_P (GET_MODE (operands[1]))
12823    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12824    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12825   "#")
12827 (define_insn "*fp_jcc_1_sse"
12828   [(set (pc)
12829         (if_then_else (match_operator 0 "comparison_operator"
12830                         [(match_operand 1 "register_operand" "f#x,x#f")
12831                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12832           (label_ref (match_operand 3 "" ""))
12833           (pc)))
12834    (clobber (reg:CCFP FPSR_REG))
12835    (clobber (reg:CCFP FLAGS_REG))]
12836   "TARGET_80387
12837    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12838    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12839    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12840   "#")
12842 (define_insn "*fp_jcc_1_sse_only"
12843   [(set (pc)
12844         (if_then_else (match_operator 0 "comparison_operator"
12845                         [(match_operand 1 "register_operand" "x")
12846                          (match_operand 2 "nonimmediate_operand" "xm")])
12847           (label_ref (match_operand 3 "" ""))
12848           (pc)))
12849    (clobber (reg:CCFP FPSR_REG))
12850    (clobber (reg:CCFP FLAGS_REG))]
12851   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12852    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12853    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12854   "#")
12856 (define_insn "*fp_jcc_2"
12857   [(set (pc)
12858         (if_then_else (match_operator 0 "comparison_operator"
12859                         [(match_operand 1 "register_operand" "f")
12860                          (match_operand 2 "register_operand" "f")])
12861           (pc)
12862           (label_ref (match_operand 3 "" ""))))
12863    (clobber (reg:CCFP FPSR_REG))
12864    (clobber (reg:CCFP FLAGS_REG))]
12865   "TARGET_CMOVE && TARGET_80387
12866    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12867    && FLOAT_MODE_P (GET_MODE (operands[1]))
12868    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12869    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12870   "#")
12872 (define_insn "*fp_jcc_2_sse"
12873   [(set (pc)
12874         (if_then_else (match_operator 0 "comparison_operator"
12875                         [(match_operand 1 "register_operand" "f#x,x#f")
12876                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12877           (pc)
12878           (label_ref (match_operand 3 "" ""))))
12879    (clobber (reg:CCFP FPSR_REG))
12880    (clobber (reg:CCFP FLAGS_REG))]
12881   "TARGET_80387
12882    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12883    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12884    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12885   "#")
12887 (define_insn "*fp_jcc_2_sse_only"
12888   [(set (pc)
12889         (if_then_else (match_operator 0 "comparison_operator"
12890                         [(match_operand 1 "register_operand" "x")
12891                          (match_operand 2 "nonimmediate_operand" "xm")])
12892           (pc)
12893           (label_ref (match_operand 3 "" ""))))
12894    (clobber (reg:CCFP FPSR_REG))
12895    (clobber (reg:CCFP FLAGS_REG))]
12896   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12897    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12898    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12899   "#")
12901 (define_insn "*fp_jcc_3"
12902   [(set (pc)
12903         (if_then_else (match_operator 0 "comparison_operator"
12904                         [(match_operand 1 "register_operand" "f")
12905                          (match_operand 2 "nonimmediate_operand" "fm")])
12906           (label_ref (match_operand 3 "" ""))
12907           (pc)))
12908    (clobber (reg:CCFP FPSR_REG))
12909    (clobber (reg:CCFP FLAGS_REG))
12910    (clobber (match_scratch:HI 4 "=a"))]
12911   "TARGET_80387
12912    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12913    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12914    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12915    && SELECT_CC_MODE (GET_CODE (operands[0]),
12916                       operands[1], operands[2]) == CCFPmode
12917    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12918   "#")
12920 (define_insn "*fp_jcc_4"
12921   [(set (pc)
12922         (if_then_else (match_operator 0 "comparison_operator"
12923                         [(match_operand 1 "register_operand" "f")
12924                          (match_operand 2 "nonimmediate_operand" "fm")])
12925           (pc)
12926           (label_ref (match_operand 3 "" ""))))
12927    (clobber (reg:CCFP FPSR_REG))
12928    (clobber (reg:CCFP FLAGS_REG))
12929    (clobber (match_scratch:HI 4 "=a"))]
12930   "TARGET_80387
12931    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12932    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12933    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12934    && SELECT_CC_MODE (GET_CODE (operands[0]),
12935                       operands[1], operands[2]) == CCFPmode
12936    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12937   "#")
12939 (define_insn "*fp_jcc_5"
12940   [(set (pc)
12941         (if_then_else (match_operator 0 "comparison_operator"
12942                         [(match_operand 1 "register_operand" "f")
12943                          (match_operand 2 "register_operand" "f")])
12944           (label_ref (match_operand 3 "" ""))
12945           (pc)))
12946    (clobber (reg:CCFP FPSR_REG))
12947    (clobber (reg:CCFP FLAGS_REG))
12948    (clobber (match_scratch:HI 4 "=a"))]
12949   "TARGET_80387
12950    && FLOAT_MODE_P (GET_MODE (operands[1]))
12951    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12952    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12953   "#")
12955 (define_insn "*fp_jcc_6"
12956   [(set (pc)
12957         (if_then_else (match_operator 0 "comparison_operator"
12958                         [(match_operand 1 "register_operand" "f")
12959                          (match_operand 2 "register_operand" "f")])
12960           (pc)
12961           (label_ref (match_operand 3 "" ""))))
12962    (clobber (reg:CCFP FPSR_REG))
12963    (clobber (reg:CCFP FLAGS_REG))
12964    (clobber (match_scratch:HI 4 "=a"))]
12965   "TARGET_80387
12966    && FLOAT_MODE_P (GET_MODE (operands[1]))
12967    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12968    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12969   "#")
12971 (define_insn "*fp_jcc_7"
12972   [(set (pc)
12973         (if_then_else (match_operator 0 "comparison_operator"
12974                         [(match_operand 1 "register_operand" "f")
12975                          (match_operand 2 "const_double_operand" "C")])
12976           (label_ref (match_operand 3 "" ""))
12977           (pc)))
12978    (clobber (reg:CCFP FPSR_REG))
12979    (clobber (reg:CCFP FLAGS_REG))
12980    (clobber (match_scratch:HI 4 "=a"))]
12981   "TARGET_80387
12982    && FLOAT_MODE_P (GET_MODE (operands[1]))
12983    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
12984    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12985    && SELECT_CC_MODE (GET_CODE (operands[0]),
12986                       operands[1], operands[2]) == CCFPmode
12987    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12988   "#")
12990 ;; The order of operands in *fp_jcc_8 is forced by combine in
12991 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12992 ;; with a precedence over other operators and is always put in the first
12993 ;; place. Swap condition and operands to match ficom instruction.
12995 (define_insn "*fp_jcc_8"
12996   [(set (pc)
12997         (if_then_else (match_operator 0 "comparison_operator"
12998                         [(match_operator 1 "float_operator"
12999                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13000                            (match_operand 3 "register_operand" "f,f")])
13001           (label_ref (match_operand 4 "" ""))
13002           (pc)))
13003    (clobber (reg:CCFP FPSR_REG))
13004    (clobber (reg:CCFP FLAGS_REG))
13005    (clobber (match_scratch:HI 5 "=a,a"))]
13006   "TARGET_80387 && TARGET_USE_FIOP
13007    && FLOAT_MODE_P (GET_MODE (operands[3]))
13008    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13009    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13010    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13011    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13012   "#")
13014 (define_split
13015   [(set (pc)
13016         (if_then_else (match_operator 0 "comparison_operator"
13017                         [(match_operand 1 "register_operand" "")
13018                          (match_operand 2 "nonimmediate_operand" "")])
13019           (match_operand 3 "" "")
13020           (match_operand 4 "" "")))
13021    (clobber (reg:CCFP FPSR_REG))
13022    (clobber (reg:CCFP FLAGS_REG))]
13023   "reload_completed"
13024   [(const_int 0)]
13026   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13027                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13028   DONE;
13031 (define_split
13032   [(set (pc)
13033         (if_then_else (match_operator 0 "comparison_operator"
13034                         [(match_operand 1 "register_operand" "")
13035                          (match_operand 2 "general_operand" "")])
13036           (match_operand 3 "" "")
13037           (match_operand 4 "" "")))
13038    (clobber (reg:CCFP FPSR_REG))
13039    (clobber (reg:CCFP FLAGS_REG))
13040    (clobber (match_scratch:HI 5 "=a"))]
13041   "reload_completed"
13042   [(const_int 0)]
13044   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13045                         operands[3], operands[4], operands[5], NULL_RTX);
13046   DONE;
13049 (define_split
13050   [(set (pc)
13051         (if_then_else (match_operator 0 "comparison_operator"
13052                         [(match_operator 1 "float_operator"
13053                            [(match_operand:SI 2 "memory_operand" "")])
13054                            (match_operand 3 "register_operand" "")])
13055           (match_operand 4 "" "")
13056           (match_operand 5 "" "")))
13057    (clobber (reg:CCFP FPSR_REG))
13058    (clobber (reg:CCFP FLAGS_REG))
13059    (clobber (match_scratch:HI 6 "=a"))]
13060   "reload_completed"
13061   [(const_int 0)]
13063   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13064   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13065                         operands[3], operands[7],
13066                         operands[4], operands[5], operands[6], NULL_RTX);
13067   DONE;
13070 ;; %%% Kill this when reload knows how to do it.
13071 (define_split
13072   [(set (pc)
13073         (if_then_else (match_operator 0 "comparison_operator"
13074                         [(match_operator 1 "float_operator"
13075                            [(match_operand:SI 2 "register_operand" "")])
13076                            (match_operand 3 "register_operand" "")])
13077           (match_operand 4 "" "")
13078           (match_operand 5 "" "")))
13079    (clobber (reg:CCFP FPSR_REG))
13080    (clobber (reg:CCFP FLAGS_REG))
13081    (clobber (match_scratch:HI 6 "=a"))]
13082   "reload_completed"
13083   [(const_int 0)]
13085   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13086   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13087   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13088                         operands[3], operands[7],
13089                         operands[4], operands[5], operands[6], operands[2]);
13090   DONE;
13093 ;; Unconditional and other jump instructions
13095 (define_insn "jump"
13096   [(set (pc)
13097         (label_ref (match_operand 0 "" "")))]
13098   ""
13099   "jmp\t%l0"
13100   [(set_attr "type" "ibr")
13101    (set (attr "length")
13102            (if_then_else (and (ge (minus (match_dup 0) (pc))
13103                                   (const_int -126))
13104                               (lt (minus (match_dup 0) (pc))
13105                                   (const_int 128)))
13106              (const_int 2)
13107              (const_int 5)))
13108    (set_attr "modrm" "0")])
13110 (define_expand "indirect_jump"
13111   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13112   ""
13113   "")
13115 (define_insn "*indirect_jump"
13116   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13117   "!TARGET_64BIT"
13118   "jmp\t%A0"
13119   [(set_attr "type" "ibr")
13120    (set_attr "length_immediate" "0")])
13122 (define_insn "*indirect_jump_rtx64"
13123   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13124   "TARGET_64BIT"
13125   "jmp\t%A0"
13126   [(set_attr "type" "ibr")
13127    (set_attr "length_immediate" "0")])
13129 (define_expand "tablejump"
13130   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13131               (use (label_ref (match_operand 1 "" "")))])]
13132   ""
13134   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13135      relative.  Convert the relative address to an absolute address.  */
13136   if (flag_pic)
13137     {
13138       rtx op0, op1;
13139       enum rtx_code code;
13141       if (TARGET_64BIT)
13142         {
13143           code = PLUS;
13144           op0 = operands[0];
13145           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13146         }
13147       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13148         {
13149           code = PLUS;
13150           op0 = operands[0];
13151           op1 = pic_offset_table_rtx;
13152         }
13153       else
13154         {
13155           code = MINUS;
13156           op0 = pic_offset_table_rtx;
13157           op1 = operands[0];
13158         }
13160       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13161                                          OPTAB_DIRECT);
13162     }
13165 (define_insn "*tablejump_1"
13166   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13167    (use (label_ref (match_operand 1 "" "")))]
13168   "!TARGET_64BIT"
13169   "jmp\t%A0"
13170   [(set_attr "type" "ibr")
13171    (set_attr "length_immediate" "0")])
13173 (define_insn "*tablejump_1_rtx64"
13174   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13175    (use (label_ref (match_operand 1 "" "")))]
13176   "TARGET_64BIT"
13177   "jmp\t%A0"
13178   [(set_attr "type" "ibr")
13179    (set_attr "length_immediate" "0")])
13181 ;; Loop instruction
13183 ;; This is all complicated by the fact that since this is a jump insn
13184 ;; we must handle our own reloads.
13186 (define_expand "doloop_end"
13187   [(use (match_operand 0 "" ""))        ; loop pseudo
13188    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13189    (use (match_operand 2 "" ""))        ; max iterations
13190    (use (match_operand 3 "" ""))        ; loop level 
13191    (use (match_operand 4 "" ""))]       ; label
13192   "!TARGET_64BIT && TARGET_USE_LOOP"
13193   "                                 
13195   /* Only use cloop on innermost loops.  */
13196   if (INTVAL (operands[3]) > 1)
13197     FAIL;
13198   if (GET_MODE (operands[0]) != SImode)
13199     FAIL;
13200   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13201                                            operands[0]));
13202   DONE;
13205 (define_insn "doloop_end_internal"
13206   [(set (pc)
13207         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13208                           (const_int 1))
13209                       (label_ref (match_operand 0 "" ""))
13210                       (pc)))
13211    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13212         (plus:SI (match_dup 1)
13213                  (const_int -1)))
13214    (clobber (match_scratch:SI 3 "=X,X,r"))
13215    (clobber (reg:CC FLAGS_REG))]
13216   "!TARGET_64BIT && TARGET_USE_LOOP
13217    && (reload_in_progress || reload_completed
13218        || register_operand (operands[2], VOIDmode))"
13220   if (which_alternative != 0)
13221     return "#";
13222   if (get_attr_length (insn) == 2)
13223     return "%+loop\t%l0";
13224   else
13225     return "dec{l}\t%1\;%+jne\t%l0";
13227   [(set (attr "length")
13228         (if_then_else (and (eq_attr "alternative" "0")
13229                            (and (ge (minus (match_dup 0) (pc))
13230                                     (const_int -126))
13231                                 (lt (minus (match_dup 0) (pc))
13232                                     (const_int 128))))
13233                       (const_int 2)
13234                       (const_int 16)))
13235    ;; We don't know the type before shorten branches.  Optimistically expect
13236    ;; the loop instruction to match.
13237    (set (attr "type") (const_string "ibr"))])
13239 (define_split
13240   [(set (pc)
13241         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13242                           (const_int 1))
13243                       (match_operand 0 "" "")
13244                       (pc)))
13245    (set (match_dup 1)
13246         (plus:SI (match_dup 1)
13247                  (const_int -1)))
13248    (clobber (match_scratch:SI 2 ""))
13249    (clobber (reg:CC FLAGS_REG))]
13250   "!TARGET_64BIT && TARGET_USE_LOOP
13251    && reload_completed
13252    && REGNO (operands[1]) != 2"
13253   [(parallel [(set (reg:CCZ FLAGS_REG)
13254                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13255                                  (const_int 0)))
13256               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13257    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13258                            (match_dup 0)
13259                            (pc)))]
13260   "")
13261   
13262 (define_split
13263   [(set (pc)
13264         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13265                           (const_int 1))
13266                       (match_operand 0 "" "")
13267                       (pc)))
13268    (set (match_operand:SI 2 "nonimmediate_operand" "")
13269         (plus:SI (match_dup 1)
13270                  (const_int -1)))
13271    (clobber (match_scratch:SI 3 ""))
13272    (clobber (reg:CC FLAGS_REG))]
13273   "!TARGET_64BIT && TARGET_USE_LOOP
13274    && reload_completed
13275    && (! REG_P (operands[2])
13276        || ! rtx_equal_p (operands[1], operands[2]))"
13277   [(set (match_dup 3) (match_dup 1))
13278    (parallel [(set (reg:CCZ FLAGS_REG)
13279                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13280                                 (const_int 0)))
13281               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13282    (set (match_dup 2) (match_dup 3))
13283    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13284                            (match_dup 0)
13285                            (pc)))]
13286   "")
13288 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13290 (define_peephole2
13291   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13292    (set (match_operand:QI 1 "register_operand" "")
13293         (match_operator:QI 2 "ix86_comparison_operator"
13294           [(reg FLAGS_REG) (const_int 0)]))
13295    (set (match_operand 3 "q_regs_operand" "")
13296         (zero_extend (match_dup 1)))]
13297   "(peep2_reg_dead_p (3, operands[1])
13298     || operands_match_p (operands[1], operands[3]))
13299    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13300   [(set (match_dup 4) (match_dup 0))
13301    (set (strict_low_part (match_dup 5))
13302         (match_dup 2))]
13304   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13305   operands[5] = gen_lowpart (QImode, operands[3]);
13306   ix86_expand_clear (operands[3]);
13309 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13311 (define_peephole2
13312   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13313    (set (match_operand:QI 1 "register_operand" "")
13314         (match_operator:QI 2 "ix86_comparison_operator"
13315           [(reg FLAGS_REG) (const_int 0)]))
13316    (parallel [(set (match_operand 3 "q_regs_operand" "")
13317                    (zero_extend (match_dup 1)))
13318               (clobber (reg:CC FLAGS_REG))])]
13319   "(peep2_reg_dead_p (3, operands[1])
13320     || operands_match_p (operands[1], operands[3]))
13321    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13322   [(set (match_dup 4) (match_dup 0))
13323    (set (strict_low_part (match_dup 5))
13324         (match_dup 2))]
13326   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13327   operands[5] = gen_lowpart (QImode, operands[3]);
13328   ix86_expand_clear (operands[3]);
13331 ;; Call instructions.
13333 ;; The predicates normally associated with named expanders are not properly
13334 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13335 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13337 ;; Call subroutine returning no value.
13339 (define_expand "call_pop"
13340   [(parallel [(call (match_operand:QI 0 "" "")
13341                     (match_operand:SI 1 "" ""))
13342               (set (reg:SI SP_REG)
13343                    (plus:SI (reg:SI SP_REG)
13344                             (match_operand:SI 3 "" "")))])]
13345   "!TARGET_64BIT"
13347   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13348   DONE;
13351 (define_insn "*call_pop_0"
13352   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13353          (match_operand:SI 1 "" ""))
13354    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13355                             (match_operand:SI 2 "immediate_operand" "")))]
13356   "!TARGET_64BIT"
13358   if (SIBLING_CALL_P (insn))
13359     return "jmp\t%P0";
13360   else
13361     return "call\t%P0";
13363   [(set_attr "type" "call")])
13364   
13365 (define_insn "*call_pop_1"
13366   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13367          (match_operand:SI 1 "" ""))
13368    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13369                             (match_operand:SI 2 "immediate_operand" "i")))]
13370   "!TARGET_64BIT"
13372   if (constant_call_address_operand (operands[0], Pmode))
13373     {
13374       if (SIBLING_CALL_P (insn))
13375         return "jmp\t%P0";
13376       else
13377         return "call\t%P0";
13378     }
13379   if (SIBLING_CALL_P (insn))
13380     return "jmp\t%A0";
13381   else
13382     return "call\t%A0";
13384   [(set_attr "type" "call")])
13386 (define_expand "call"
13387   [(call (match_operand:QI 0 "" "")
13388          (match_operand 1 "" ""))
13389    (use (match_operand 2 "" ""))]
13390   ""
13392   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13393   DONE;
13396 (define_expand "sibcall"
13397   [(call (match_operand:QI 0 "" "")
13398          (match_operand 1 "" ""))
13399    (use (match_operand 2 "" ""))]
13400   ""
13402   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13403   DONE;
13406 (define_insn "*call_0"
13407   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13408          (match_operand 1 "" ""))]
13409   ""
13411   if (SIBLING_CALL_P (insn))
13412     return "jmp\t%P0";
13413   else
13414     return "call\t%P0";
13416   [(set_attr "type" "call")])
13418 (define_insn "*call_1"
13419   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13420          (match_operand 1 "" ""))]
13421   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13423   if (constant_call_address_operand (operands[0], Pmode))
13424     return "call\t%P0";
13425   return "call\t%A0";
13427   [(set_attr "type" "call")])
13429 (define_insn "*sibcall_1"
13430   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13431          (match_operand 1 "" ""))]
13432   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13434   if (constant_call_address_operand (operands[0], Pmode))
13435     return "jmp\t%P0";
13436   return "jmp\t%A0";
13438   [(set_attr "type" "call")])
13440 (define_insn "*call_1_rex64"
13441   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13442          (match_operand 1 "" ""))]
13443   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13445   if (constant_call_address_operand (operands[0], Pmode))
13446     return "call\t%P0";
13447   return "call\t%A0";
13449   [(set_attr "type" "call")])
13451 (define_insn "*sibcall_1_rex64"
13452   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13453          (match_operand 1 "" ""))]
13454   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13455   "jmp\t%P0"
13456   [(set_attr "type" "call")])
13458 (define_insn "*sibcall_1_rex64_v"
13459   [(call (mem:QI (reg:DI 40))
13460          (match_operand 0 "" ""))]
13461   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13462   "jmp\t*%%r11"
13463   [(set_attr "type" "call")])
13466 ;; Call subroutine, returning value in operand 0
13468 (define_expand "call_value_pop"
13469   [(parallel [(set (match_operand 0 "" "")
13470                    (call (match_operand:QI 1 "" "")
13471                          (match_operand:SI 2 "" "")))
13472               (set (reg:SI SP_REG)
13473                    (plus:SI (reg:SI SP_REG)
13474                             (match_operand:SI 4 "" "")))])]
13475   "!TARGET_64BIT"
13477   ix86_expand_call (operands[0], operands[1], operands[2],
13478                     operands[3], operands[4], 0);
13479   DONE;
13482 (define_expand "call_value"
13483   [(set (match_operand 0 "" "")
13484         (call (match_operand:QI 1 "" "")
13485               (match_operand:SI 2 "" "")))
13486    (use (match_operand:SI 3 "" ""))]
13487   ;; Operand 2 not used on the i386.
13488   ""
13490   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13491   DONE;
13494 (define_expand "sibcall_value"
13495   [(set (match_operand 0 "" "")
13496         (call (match_operand:QI 1 "" "")
13497               (match_operand:SI 2 "" "")))
13498    (use (match_operand:SI 3 "" ""))]
13499   ;; Operand 2 not used on the i386.
13500   ""
13502   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13503   DONE;
13506 ;; Call subroutine returning any type.
13508 (define_expand "untyped_call"
13509   [(parallel [(call (match_operand 0 "" "")
13510                     (const_int 0))
13511               (match_operand 1 "" "")
13512               (match_operand 2 "" "")])]
13513   ""
13515   int i;
13517   /* In order to give reg-stack an easier job in validating two
13518      coprocessor registers as containing a possible return value,
13519      simply pretend the untyped call returns a complex long double
13520      value.  */
13522   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13523                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13524                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13525                     NULL, 0);
13527   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13528     {
13529       rtx set = XVECEXP (operands[2], 0, i);
13530       emit_move_insn (SET_DEST (set), SET_SRC (set));
13531     }
13533   /* The optimizer does not know that the call sets the function value
13534      registers we stored in the result block.  We avoid problems by
13535      claiming that all hard registers are used and clobbered at this
13536      point.  */
13537   emit_insn (gen_blockage (const0_rtx));
13539   DONE;
13542 ;; Prologue and epilogue instructions
13544 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13545 ;; all of memory.  This blocks insns from being moved across this point.
13547 (define_insn "blockage"
13548   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13549   ""
13550   ""
13551   [(set_attr "length" "0")])
13553 ;; Insn emitted into the body of a function to return from a function.
13554 ;; This is only done if the function's epilogue is known to be simple.
13555 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13557 (define_expand "return"
13558   [(return)]
13559   "ix86_can_use_return_insn_p ()"
13561   if (current_function_pops_args)
13562     {
13563       rtx popc = GEN_INT (current_function_pops_args);
13564       emit_jump_insn (gen_return_pop_internal (popc));
13565       DONE;
13566     }
13569 (define_insn "return_internal"
13570   [(return)]
13571   "reload_completed"
13572   "ret"
13573   [(set_attr "length" "1")
13574    (set_attr "length_immediate" "0")
13575    (set_attr "modrm" "0")])
13577 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13578 ;; instruction Athlon and K8 have.
13580 (define_insn "return_internal_long"
13581   [(return)
13582    (unspec [(const_int 0)] UNSPEC_REP)]
13583   "reload_completed"
13584   "rep {;} ret"
13585   [(set_attr "length" "1")
13586    (set_attr "length_immediate" "0")
13587    (set_attr "prefix_rep" "1")
13588    (set_attr "modrm" "0")])
13590 (define_insn "return_pop_internal"
13591   [(return)
13592    (use (match_operand:SI 0 "const_int_operand" ""))]
13593   "reload_completed"
13594   "ret\t%0"
13595   [(set_attr "length" "3")
13596    (set_attr "length_immediate" "2")
13597    (set_attr "modrm" "0")])
13599 (define_insn "return_indirect_internal"
13600   [(return)
13601    (use (match_operand:SI 0 "register_operand" "r"))]
13602   "reload_completed"
13603   "jmp\t%A0"
13604   [(set_attr "type" "ibr")
13605    (set_attr "length_immediate" "0")])
13607 (define_insn "nop"
13608   [(const_int 0)]
13609   ""
13610   "nop"
13611   [(set_attr "length" "1")
13612    (set_attr "length_immediate" "0")
13613    (set_attr "modrm" "0")])
13615 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13616 ;; branch prediction penalty for the third jump in a 16-byte
13617 ;; block on K8.
13619 (define_insn "align"
13620   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13621   ""
13623 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13624   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13625 #else
13626   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13627      The align insn is used to avoid 3 jump instructions in the row to improve
13628      branch prediction and the benefits hardly outweight the cost of extra 8
13629      nops on the average inserted by full alignment pseudo operation.  */
13630 #endif
13631   return "";
13633   [(set_attr "length" "16")])
13635 (define_expand "prologue"
13636   [(const_int 1)]
13637   ""
13638   "ix86_expand_prologue (); DONE;")
13640 (define_insn "set_got"
13641   [(set (match_operand:SI 0 "register_operand" "=r")
13642         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13643    (clobber (reg:CC FLAGS_REG))]
13644   "!TARGET_64BIT"
13645   { return output_set_got (operands[0]); }
13646   [(set_attr "type" "multi")
13647    (set_attr "length" "12")])
13649 (define_expand "epilogue"
13650   [(const_int 1)]
13651   ""
13652   "ix86_expand_epilogue (1); DONE;")
13654 (define_expand "sibcall_epilogue"
13655   [(const_int 1)]
13656   ""
13657   "ix86_expand_epilogue (0); DONE;")
13659 (define_expand "eh_return"
13660   [(use (match_operand 0 "register_operand" ""))]
13661   ""
13663   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13665   /* Tricky bit: we write the address of the handler to which we will
13666      be returning into someone else's stack frame, one word below the
13667      stack address we wish to restore.  */
13668   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13669   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13670   tmp = gen_rtx_MEM (Pmode, tmp);
13671   emit_move_insn (tmp, ra);
13673   if (Pmode == SImode)
13674     emit_jump_insn (gen_eh_return_si (sa));
13675   else
13676     emit_jump_insn (gen_eh_return_di (sa));
13677   emit_barrier ();
13678   DONE;
13681 (define_insn_and_split "eh_return_si"
13682   [(set (pc) 
13683         (unspec [(match_operand:SI 0 "register_operand" "c")]
13684                  UNSPEC_EH_RETURN))]
13685   "!TARGET_64BIT"
13686   "#"
13687   "reload_completed"
13688   [(const_int 1)]
13689   "ix86_expand_epilogue (2); DONE;")
13691 (define_insn_and_split "eh_return_di"
13692   [(set (pc) 
13693         (unspec [(match_operand:DI 0 "register_operand" "c")]
13694                  UNSPEC_EH_RETURN))]
13695   "TARGET_64BIT"
13696   "#"
13697   "reload_completed"
13698   [(const_int 1)]
13699   "ix86_expand_epilogue (2); DONE;")
13701 (define_insn "leave"
13702   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13703    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13704    (clobber (mem:BLK (scratch)))]
13705   "!TARGET_64BIT"
13706   "leave"
13707   [(set_attr "type" "leave")])
13709 (define_insn "leave_rex64"
13710   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13711    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13712    (clobber (mem:BLK (scratch)))]
13713   "TARGET_64BIT"
13714   "leave"
13715   [(set_attr "type" "leave")])
13717 (define_expand "ffssi2"
13718   [(parallel
13719      [(set (match_operand:SI 0 "register_operand" "") 
13720            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13721       (clobber (match_scratch:SI 2 ""))
13722       (clobber (reg:CC FLAGS_REG))])]
13723   ""
13724   "")
13726 (define_insn_and_split "*ffs_cmove"
13727   [(set (match_operand:SI 0 "register_operand" "=r") 
13728         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13729    (clobber (match_scratch:SI 2 "=&r"))
13730    (clobber (reg:CC FLAGS_REG))]
13731   "TARGET_CMOVE"
13732   "#"
13733   "&& reload_completed"
13734   [(set (match_dup 2) (const_int -1))
13735    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13736               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13737    (set (match_dup 0) (if_then_else:SI
13738                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13739                         (match_dup 2)
13740                         (match_dup 0)))
13741    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13742               (clobber (reg:CC FLAGS_REG))])]
13743   "")
13745 (define_insn_and_split "*ffs_no_cmove"
13746   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13747         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13748    (clobber (match_scratch:SI 2 "=&q"))
13749    (clobber (reg:CC FLAGS_REG))]
13750   ""
13751   "#"
13752   "reload_completed"
13753   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13754               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13755    (set (strict_low_part (match_dup 3))
13756         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13757    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13758               (clobber (reg:CC FLAGS_REG))])
13759    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13760               (clobber (reg:CC FLAGS_REG))])
13761    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13762               (clobber (reg:CC FLAGS_REG))])]
13764   operands[3] = gen_lowpart (QImode, operands[2]);
13765   ix86_expand_clear (operands[2]);
13768 (define_insn "*ffssi_1"
13769   [(set (reg:CCZ FLAGS_REG)
13770         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13771                      (const_int 0)))
13772    (set (match_operand:SI 0 "register_operand" "=r")
13773         (ctz:SI (match_dup 1)))]
13774   ""
13775   "bsf{l}\t{%1, %0|%0, %1}"
13776   [(set_attr "prefix_0f" "1")])
13778 (define_expand "ffsdi2"
13779   [(parallel
13780      [(set (match_operand:DI 0 "register_operand" "") 
13781            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13782       (clobber (match_scratch:DI 2 ""))
13783       (clobber (reg:CC FLAGS_REG))])]
13784   "TARGET_64BIT && TARGET_CMOVE"
13785   "")
13787 (define_insn_and_split "*ffs_rex64"
13788   [(set (match_operand:DI 0 "register_operand" "=r") 
13789         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13790    (clobber (match_scratch:DI 2 "=&r"))
13791    (clobber (reg:CC FLAGS_REG))]
13792   "TARGET_64BIT && TARGET_CMOVE"
13793   "#"
13794   "&& reload_completed"
13795   [(set (match_dup 2) (const_int -1))
13796    (parallel [(set (reg:CCZ FLAGS_REG)
13797                    (compare:CCZ (match_dup 1) (const_int 0)))
13798               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13799    (set (match_dup 0) (if_then_else:DI
13800                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13801                         (match_dup 2)
13802                         (match_dup 0)))
13803    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13804               (clobber (reg:CC FLAGS_REG))])]
13805   "")
13807 (define_insn "*ffsdi_1"
13808   [(set (reg:CCZ FLAGS_REG)
13809         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13810                      (const_int 0)))
13811    (set (match_operand:DI 0 "register_operand" "=r")
13812         (ctz:DI (match_dup 1)))]
13813   "TARGET_64BIT"
13814   "bsf{q}\t{%1, %0|%0, %1}"
13815   [(set_attr "prefix_0f" "1")])
13817 (define_insn "ctzsi2"
13818   [(set (match_operand:SI 0 "register_operand" "=r")
13819         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13820    (clobber (reg:CC FLAGS_REG))]
13821   ""
13822   "bsf{l}\t{%1, %0|%0, %1}"
13823   [(set_attr "prefix_0f" "1")])
13825 (define_insn "ctzdi2"
13826   [(set (match_operand:DI 0 "register_operand" "=r")
13827         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13828    (clobber (reg:CC FLAGS_REG))]
13829   "TARGET_64BIT"
13830   "bsf{q}\t{%1, %0|%0, %1}"
13831   [(set_attr "prefix_0f" "1")])
13833 (define_expand "clzsi2"
13834   [(parallel
13835      [(set (match_operand:SI 0 "register_operand" "")
13836            (minus:SI (const_int 31)
13837                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13838       (clobber (reg:CC FLAGS_REG))])
13839    (parallel
13840      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13841       (clobber (reg:CC FLAGS_REG))])]
13842   ""
13843   "")
13845 (define_insn "*bsr"
13846   [(set (match_operand:SI 0 "register_operand" "=r")
13847         (minus:SI (const_int 31)
13848                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13849    (clobber (reg:CC FLAGS_REG))]
13850   ""
13851   "bsr{l}\t{%1, %0|%0, %1}"
13852   [(set_attr "prefix_0f" "1")])
13854 (define_expand "clzdi2"
13855   [(parallel
13856      [(set (match_operand:DI 0 "register_operand" "")
13857            (minus:DI (const_int 63)
13858                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13859       (clobber (reg:CC FLAGS_REG))])
13860    (parallel
13861      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13862       (clobber (reg:CC FLAGS_REG))])]
13863   "TARGET_64BIT"
13864   "")
13866 (define_insn "*bsr_rex64"
13867   [(set (match_operand:DI 0 "register_operand" "=r")
13868         (minus:DI (const_int 63)
13869                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13870    (clobber (reg:CC FLAGS_REG))]
13871   "TARGET_64BIT"
13872   "bsr{q}\t{%1, %0|%0, %1}"
13873   [(set_attr "prefix_0f" "1")])
13875 ;; Thread-local storage patterns for ELF.
13877 ;; Note that these code sequences must appear exactly as shown
13878 ;; in order to allow linker relaxation.
13880 (define_insn "*tls_global_dynamic_32_gnu"
13881   [(set (match_operand:SI 0 "register_operand" "=a")
13882         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13883                     (match_operand:SI 2 "tls_symbolic_operand" "")
13884                     (match_operand:SI 3 "call_insn_operand" "")]
13885                     UNSPEC_TLS_GD))
13886    (clobber (match_scratch:SI 4 "=d"))
13887    (clobber (match_scratch:SI 5 "=c"))
13888    (clobber (reg:CC FLAGS_REG))]
13889   "!TARGET_64BIT && TARGET_GNU_TLS"
13890   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13891   [(set_attr "type" "multi")
13892    (set_attr "length" "12")])
13894 (define_insn "*tls_global_dynamic_32_sun"
13895   [(set (match_operand:SI 0 "register_operand" "=a")
13896         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13897                     (match_operand:SI 2 "tls_symbolic_operand" "")
13898                     (match_operand:SI 3 "call_insn_operand" "")]
13899                     UNSPEC_TLS_GD))
13900    (clobber (match_scratch:SI 4 "=d"))
13901    (clobber (match_scratch:SI 5 "=c"))
13902    (clobber (reg:CC FLAGS_REG))]
13903   "!TARGET_64BIT && TARGET_SUN_TLS"
13904   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13905         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13906   [(set_attr "type" "multi")
13907    (set_attr "length" "14")])
13909 (define_expand "tls_global_dynamic_32"
13910   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13911                    (unspec:SI
13912                     [(match_dup 2)
13913                      (match_operand:SI 1 "tls_symbolic_operand" "")
13914                      (match_dup 3)]
13915                     UNSPEC_TLS_GD))
13916               (clobber (match_scratch:SI 4 ""))
13917               (clobber (match_scratch:SI 5 ""))
13918               (clobber (reg:CC FLAGS_REG))])]
13919   ""
13921   if (flag_pic)
13922     operands[2] = pic_offset_table_rtx;
13923   else
13924     {
13925       operands[2] = gen_reg_rtx (Pmode);
13926       emit_insn (gen_set_got (operands[2]));
13927     }
13928   operands[3] = ix86_tls_get_addr ();
13931 (define_insn "*tls_global_dynamic_64"
13932   [(set (match_operand:DI 0 "register_operand" "=a")
13933         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13934                       (match_operand:DI 3 "" "")))
13935    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13936               UNSPEC_TLS_GD)]
13937   "TARGET_64BIT"
13938   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13939   [(set_attr "type" "multi")
13940    (set_attr "length" "16")])
13942 (define_expand "tls_global_dynamic_64"
13943   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13944                    (call (mem:QI (match_dup 2)) (const_int 0)))
13945               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13946                          UNSPEC_TLS_GD)])]
13947   ""
13949   operands[2] = ix86_tls_get_addr ();
13952 (define_insn "*tls_local_dynamic_base_32_gnu"
13953   [(set (match_operand:SI 0 "register_operand" "=a")
13954         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13955                     (match_operand:SI 2 "call_insn_operand" "")]
13956                    UNSPEC_TLS_LD_BASE))
13957    (clobber (match_scratch:SI 3 "=d"))
13958    (clobber (match_scratch:SI 4 "=c"))
13959    (clobber (reg:CC FLAGS_REG))]
13960   "!TARGET_64BIT && TARGET_GNU_TLS"
13961   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13962   [(set_attr "type" "multi")
13963    (set_attr "length" "11")])
13965 (define_insn "*tls_local_dynamic_base_32_sun"
13966   [(set (match_operand:SI 0 "register_operand" "=a")
13967         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13968                     (match_operand:SI 2 "call_insn_operand" "")]
13969                    UNSPEC_TLS_LD_BASE))
13970    (clobber (match_scratch:SI 3 "=d"))
13971    (clobber (match_scratch:SI 4 "=c"))
13972    (clobber (reg:CC FLAGS_REG))]
13973   "!TARGET_64BIT && TARGET_SUN_TLS"
13974   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13975         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13976   [(set_attr "type" "multi")
13977    (set_attr "length" "13")])
13979 (define_expand "tls_local_dynamic_base_32"
13980   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13981                    (unspec:SI [(match_dup 1) (match_dup 2)]
13982                               UNSPEC_TLS_LD_BASE))
13983               (clobber (match_scratch:SI 3 ""))
13984               (clobber (match_scratch:SI 4 ""))
13985               (clobber (reg:CC FLAGS_REG))])]
13986   ""
13988   if (flag_pic)
13989     operands[1] = pic_offset_table_rtx;
13990   else
13991     {
13992       operands[1] = gen_reg_rtx (Pmode);
13993       emit_insn (gen_set_got (operands[1]));
13994     }
13995   operands[2] = ix86_tls_get_addr ();
13998 (define_insn "*tls_local_dynamic_base_64"
13999   [(set (match_operand:DI 0 "register_operand" "=a")
14000         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14001                       (match_operand:DI 2 "" "")))
14002    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14003   "TARGET_64BIT"
14004   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14005   [(set_attr "type" "multi")
14006    (set_attr "length" "12")])
14008 (define_expand "tls_local_dynamic_base_64"
14009   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14010                    (call (mem:QI (match_dup 1)) (const_int 0)))
14011               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14012   ""
14014   operands[1] = ix86_tls_get_addr ();
14017 ;; Local dynamic of a single variable is a lose.  Show combine how
14018 ;; to convert that back to global dynamic.
14020 (define_insn_and_split "*tls_local_dynamic_32_once"
14021   [(set (match_operand:SI 0 "register_operand" "=a")
14022         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14023                              (match_operand:SI 2 "call_insn_operand" "")]
14024                             UNSPEC_TLS_LD_BASE)
14025                  (const:SI (unspec:SI
14026                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14027                             UNSPEC_DTPOFF))))
14028    (clobber (match_scratch:SI 4 "=d"))
14029    (clobber (match_scratch:SI 5 "=c"))
14030    (clobber (reg:CC FLAGS_REG))]
14031   ""
14032   "#"
14033   ""
14034   [(parallel [(set (match_dup 0)
14035                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14036                               UNSPEC_TLS_GD))
14037               (clobber (match_dup 4))
14038               (clobber (match_dup 5))
14039               (clobber (reg:CC FLAGS_REG))])]
14040   "")
14042 ;; Load and add the thread base pointer from %gs:0.
14044 (define_insn "*load_tp_si"
14045   [(set (match_operand:SI 0 "register_operand" "=r")
14046         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14047   "!TARGET_64BIT"
14048   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14049   [(set_attr "type" "imov")
14050    (set_attr "modrm" "0")
14051    (set_attr "length" "7")
14052    (set_attr "memory" "load")
14053    (set_attr "imm_disp" "false")])
14055 (define_insn "*add_tp_si"
14056   [(set (match_operand:SI 0 "register_operand" "=r")
14057         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14058                  (match_operand:SI 1 "register_operand" "0")))
14059    (clobber (reg:CC FLAGS_REG))]
14060   "!TARGET_64BIT"
14061   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14062   [(set_attr "type" "alu")
14063    (set_attr "modrm" "0")
14064    (set_attr "length" "7")
14065    (set_attr "memory" "load")
14066    (set_attr "imm_disp" "false")])
14068 (define_insn "*load_tp_di"
14069   [(set (match_operand:DI 0 "register_operand" "=r")
14070         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14071   "TARGET_64BIT"
14072   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14073   [(set_attr "type" "imov")
14074    (set_attr "modrm" "0")
14075    (set_attr "length" "7")
14076    (set_attr "memory" "load")
14077    (set_attr "imm_disp" "false")])
14079 (define_insn "*add_tp_di"
14080   [(set (match_operand:DI 0 "register_operand" "=r")
14081         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14082                  (match_operand:DI 1 "register_operand" "0")))
14083    (clobber (reg:CC FLAGS_REG))]
14084   "TARGET_64BIT"
14085   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14086   [(set_attr "type" "alu")
14087    (set_attr "modrm" "0")
14088    (set_attr "length" "7")
14089    (set_attr "memory" "load")
14090    (set_attr "imm_disp" "false")])
14092 ;; These patterns match the binary 387 instructions for addM3, subM3,
14093 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14094 ;; SFmode.  The first is the normal insn, the second the same insn but
14095 ;; with one operand a conversion, and the third the same insn but with
14096 ;; the other operand a conversion.  The conversion may be SFmode or
14097 ;; SImode if the target mode DFmode, but only SImode if the target mode
14098 ;; is SFmode.
14100 ;; Gcc is slightly more smart about handling normal two address instructions
14101 ;; so use special patterns for add and mull.
14103 (define_insn "*fop_sf_comm_mixed"
14104   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14105         (match_operator:SF 3 "binary_fp_operator"
14106                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14107                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14108   "TARGET_MIX_SSE_I387
14109    && COMMUTATIVE_ARITH_P (operands[3])
14110    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14111   "* return output_387_binary_op (insn, operands);"
14112   [(set (attr "type") 
14113         (if_then_else (eq_attr "alternative" "1")
14114            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14115               (const_string "ssemul")
14116               (const_string "sseadd"))
14117            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14118               (const_string "fmul")
14119               (const_string "fop"))))
14120    (set_attr "mode" "SF")])
14122 (define_insn "*fop_sf_comm_sse"
14123   [(set (match_operand:SF 0 "register_operand" "=x")
14124         (match_operator:SF 3 "binary_fp_operator"
14125                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14126                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14127   "TARGET_SSE_MATH
14128    && COMMUTATIVE_ARITH_P (operands[3])
14129    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14130   "* return output_387_binary_op (insn, operands);"
14131   [(set (attr "type") 
14132         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14133            (const_string "ssemul")
14134            (const_string "sseadd")))
14135    (set_attr "mode" "SF")])
14137 (define_insn "*fop_sf_comm_i387"
14138   [(set (match_operand:SF 0 "register_operand" "=f")
14139         (match_operator:SF 3 "binary_fp_operator"
14140                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14141                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14142   "TARGET_80387
14143    && COMMUTATIVE_ARITH_P (operands[3])
14144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14145   "* return output_387_binary_op (insn, operands);"
14146   [(set (attr "type") 
14147         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14148            (const_string "fmul")
14149            (const_string "fop")))
14150    (set_attr "mode" "SF")])
14152 (define_insn "*fop_sf_1_mixed"
14153   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14154         (match_operator:SF 3 "binary_fp_operator"
14155                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14156                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14157   "TARGET_MIX_SSE_I387
14158    && !COMMUTATIVE_ARITH_P (operands[3])
14159    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14160   "* return output_387_binary_op (insn, operands);"
14161   [(set (attr "type") 
14162         (cond [(and (eq_attr "alternative" "2")
14163                     (match_operand:SF 3 "mult_operator" ""))
14164                  (const_string "ssemul")
14165                (and (eq_attr "alternative" "2")
14166                     (match_operand:SF 3 "div_operator" ""))
14167                  (const_string "ssediv")
14168                (eq_attr "alternative" "2")
14169                  (const_string "sseadd")
14170                (match_operand:SF 3 "mult_operator" "") 
14171                  (const_string "fmul")
14172                (match_operand:SF 3 "div_operator" "") 
14173                  (const_string "fdiv")
14174               ]
14175               (const_string "fop")))
14176    (set_attr "mode" "SF")])
14178 (define_insn "*fop_sf_1_sse"
14179   [(set (match_operand:SF 0 "register_operand" "=x")
14180         (match_operator:SF 3 "binary_fp_operator"
14181                         [(match_operand:SF 1 "register_operand" "0")
14182                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14183   "TARGET_SSE_MATH
14184    && !COMMUTATIVE_ARITH_P (operands[3])"
14185   "* return output_387_binary_op (insn, operands);"
14186   [(set (attr "type") 
14187         (cond [(match_operand:SF 3 "mult_operator" "")
14188                  (const_string "ssemul")
14189                (match_operand:SF 3 "div_operator" "")
14190                  (const_string "ssediv")
14191               ]
14192               (const_string "sseadd")))
14193    (set_attr "mode" "SF")])
14195 (define_insn "*fop_sf_1_i387"
14196   [(set (match_operand:SF 0 "register_operand" "=f,f")
14197         (match_operator:SF 3 "binary_fp_operator"
14198                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14199                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14200   "TARGET_80387
14201    && !COMMUTATIVE_ARITH_P (operands[3])
14202    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14203   "* return output_387_binary_op (insn, operands);"
14204   [(set (attr "type") 
14205         (cond [(match_operand:SF 3 "mult_operator" "") 
14206                  (const_string "fmul")
14207                (match_operand:SF 3 "div_operator" "") 
14208                  (const_string "fdiv")
14209               ]
14210               (const_string "fop")))
14211    (set_attr "mode" "SF")])
14214 ;; ??? Add SSE splitters for these!
14215 (define_insn "*fop_sf_2_i387"
14216   [(set (match_operand:SF 0 "register_operand" "=f,f")
14217         (match_operator:SF 3 "binary_fp_operator"
14218           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14219            (match_operand:SF 2 "register_operand" "0,0")]))]
14220   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14221   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14222   [(set (attr "type") 
14223         (cond [(match_operand:SF 3 "mult_operator" "") 
14224                  (const_string "fmul")
14225                (match_operand:SF 3 "div_operator" "") 
14226                  (const_string "fdiv")
14227               ]
14228               (const_string "fop")))
14229    (set_attr "fp_int_src" "true")
14230    (set_attr "mode" "SI")])
14232 (define_insn "*fop_sf_3_i387"
14233   [(set (match_operand:SF 0 "register_operand" "=f,f")
14234         (match_operator:SF 3 "binary_fp_operator"
14235           [(match_operand:SF 1 "register_operand" "0,0")
14236            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14237   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14238   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14239   [(set (attr "type") 
14240         (cond [(match_operand:SF 3 "mult_operator" "") 
14241                  (const_string "fmul")
14242                (match_operand:SF 3 "div_operator" "") 
14243                  (const_string "fdiv")
14244               ]
14245               (const_string "fop")))
14246    (set_attr "fp_int_src" "true")
14247    (set_attr "mode" "SI")])
14249 (define_insn "*fop_df_comm_mixed"
14250   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14251         (match_operator:DF 3 "binary_fp_operator"
14252                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14253                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14254   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14255    && COMMUTATIVE_ARITH_P (operands[3])
14256    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14257   "* return output_387_binary_op (insn, operands);"
14258   [(set (attr "type") 
14259         (if_then_else (eq_attr "alternative" "1")
14260            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14261               (const_string "ssemul")
14262               (const_string "sseadd"))
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_comm_sse"
14269   [(set (match_operand:DF 0 "register_operand" "=Y")
14270         (match_operator:DF 3 "binary_fp_operator"
14271                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14272                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14273   "TARGET_SSE2 && TARGET_SSE_MATH
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         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14279            (const_string "ssemul")
14280            (const_string "sseadd")))
14281    (set_attr "mode" "DF")])
14283 (define_insn "*fop_df_comm_i387"
14284   [(set (match_operand:DF 0 "register_operand" "=f")
14285         (match_operator:DF 3 "binary_fp_operator"
14286                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14287                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14288   "TARGET_80387
14289    && COMMUTATIVE_ARITH_P (operands[3])
14290    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14291   "* return output_387_binary_op (insn, operands);"
14292   [(set (attr "type") 
14293         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14294            (const_string "fmul")
14295            (const_string "fop")))
14296    (set_attr "mode" "DF")])
14298 (define_insn "*fop_df_1_mixed"
14299   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14300         (match_operator:DF 3 "binary_fp_operator"
14301                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14302                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14303   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14304    && !COMMUTATIVE_ARITH_P (operands[3])
14305    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14306   "* return output_387_binary_op (insn, operands);"
14307   [(set (attr "type") 
14308         (cond [(and (eq_attr "alternative" "2")
14309                     (match_operand:SF 3 "mult_operator" ""))
14310                  (const_string "ssemul")
14311                (and (eq_attr "alternative" "2")
14312                     (match_operand:SF 3 "div_operator" ""))
14313                  (const_string "ssediv")
14314                (eq_attr "alternative" "2")
14315                  (const_string "sseadd")
14316                (match_operand:DF 3 "mult_operator" "") 
14317                  (const_string "fmul")
14318                (match_operand:DF 3 "div_operator" "") 
14319                  (const_string "fdiv")
14320               ]
14321               (const_string "fop")))
14322    (set_attr "mode" "DF")])
14324 (define_insn "*fop_df_1_sse"
14325   [(set (match_operand:DF 0 "register_operand" "=Y")
14326         (match_operator:DF 3 "binary_fp_operator"
14327                         [(match_operand:DF 1 "register_operand" "0")
14328                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14329   "TARGET_SSE2 && TARGET_SSE_MATH
14330    && !COMMUTATIVE_ARITH_P (operands[3])"
14331   "* return output_387_binary_op (insn, operands);"
14332   [(set_attr "mode" "DF")
14333    (set (attr "type") 
14334         (cond [(match_operand:SF 3 "mult_operator" "")
14335                  (const_string "ssemul")
14336                (match_operand:SF 3 "div_operator" "")
14337                  (const_string "ssediv")
14338               ]
14339               (const_string "sseadd")))])
14341 (define_insn "*fop_df_1_i387"
14342   [(set (match_operand:DF 0 "register_operand" "=f,f")
14343         (match_operator:DF 3 "binary_fp_operator"
14344                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14345                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14346   "TARGET_80387
14347    && !COMMUTATIVE_ARITH_P (operands[3])
14348    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14349   "* return output_387_binary_op (insn, operands);"
14350   [(set (attr "type") 
14351         (cond [(match_operand:DF 3 "mult_operator" "") 
14352                  (const_string "fmul")
14353                (match_operand:DF 3 "div_operator" "")
14354                  (const_string "fdiv")
14355               ]
14356               (const_string "fop")))
14357    (set_attr "mode" "DF")])
14359 ;; ??? Add SSE splitters for these!
14360 (define_insn "*fop_df_2_i387"
14361   [(set (match_operand:DF 0 "register_operand" "=f,f")
14362         (match_operator:DF 3 "binary_fp_operator"
14363            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14364             (match_operand:DF 2 "register_operand" "0,0")]))]
14365   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14366   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14367   [(set (attr "type") 
14368         (cond [(match_operand:DF 3 "mult_operator" "") 
14369                  (const_string "fmul")
14370                (match_operand:DF 3 "div_operator" "") 
14371                  (const_string "fdiv")
14372               ]
14373               (const_string "fop")))
14374    (set_attr "fp_int_src" "true")
14375    (set_attr "mode" "SI")])
14377 (define_insn "*fop_df_3_i387"
14378   [(set (match_operand:DF 0 "register_operand" "=f,f")
14379         (match_operator:DF 3 "binary_fp_operator"
14380            [(match_operand:DF 1 "register_operand" "0,0")
14381             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14382   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14383   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14384   [(set (attr "type") 
14385         (cond [(match_operand:DF 3 "mult_operator" "") 
14386                  (const_string "fmul")
14387                (match_operand:DF 3 "div_operator" "") 
14388                  (const_string "fdiv")
14389               ]
14390               (const_string "fop")))
14391    (set_attr "fp_int_src" "true")
14392    (set_attr "mode" "SI")])
14394 (define_insn "*fop_df_4_i387"
14395   [(set (match_operand:DF 0 "register_operand" "=f,f")
14396         (match_operator:DF 3 "binary_fp_operator"
14397            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14398             (match_operand:DF 2 "register_operand" "0,f")]))]
14399   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14400    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14401   "* return output_387_binary_op (insn, operands);"
14402   [(set (attr "type") 
14403         (cond [(match_operand:DF 3 "mult_operator" "") 
14404                  (const_string "fmul")
14405                (match_operand:DF 3 "div_operator" "") 
14406                  (const_string "fdiv")
14407               ]
14408               (const_string "fop")))
14409    (set_attr "mode" "SF")])
14411 (define_insn "*fop_df_5_i387"
14412   [(set (match_operand:DF 0 "register_operand" "=f,f")
14413         (match_operator:DF 3 "binary_fp_operator"
14414           [(match_operand:DF 1 "register_operand" "0,f")
14415            (float_extend:DF
14416             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14417   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14418   "* return output_387_binary_op (insn, operands);"
14419   [(set (attr "type") 
14420         (cond [(match_operand:DF 3 "mult_operator" "") 
14421                  (const_string "fmul")
14422                (match_operand:DF 3 "div_operator" "") 
14423                  (const_string "fdiv")
14424               ]
14425               (const_string "fop")))
14426    (set_attr "mode" "SF")])
14428 (define_insn "*fop_df_6_i387"
14429   [(set (match_operand:DF 0 "register_operand" "=f,f")
14430         (match_operator:DF 3 "binary_fp_operator"
14431           [(float_extend:DF
14432             (match_operand:SF 1 "register_operand" "0,f"))
14433            (float_extend:DF
14434             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14435   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14436   "* return output_387_binary_op (insn, operands);"
14437   [(set (attr "type") 
14438         (cond [(match_operand:DF 3 "mult_operator" "") 
14439                  (const_string "fmul")
14440                (match_operand:DF 3 "div_operator" "") 
14441                  (const_string "fdiv")
14442               ]
14443               (const_string "fop")))
14444    (set_attr "mode" "SF")])
14446 (define_insn "*fop_xf_comm_i387"
14447   [(set (match_operand:XF 0 "register_operand" "=f")
14448         (match_operator:XF 3 "binary_fp_operator"
14449                         [(match_operand:XF 1 "register_operand" "%0")
14450                          (match_operand:XF 2 "register_operand" "f")]))]
14451   "TARGET_80387
14452    && COMMUTATIVE_ARITH_P (operands[3])"
14453   "* return output_387_binary_op (insn, operands);"
14454   [(set (attr "type") 
14455         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14456            (const_string "fmul")
14457            (const_string "fop")))
14458    (set_attr "mode" "XF")])
14460 (define_insn "*fop_xf_1_i387"
14461   [(set (match_operand:XF 0 "register_operand" "=f,f")
14462         (match_operator:XF 3 "binary_fp_operator"
14463                         [(match_operand:XF 1 "register_operand" "0,f")
14464                          (match_operand:XF 2 "register_operand" "f,0")]))]
14465   "TARGET_80387
14466    && !COMMUTATIVE_ARITH_P (operands[3])"
14467   "* return output_387_binary_op (insn, operands);"
14468   [(set (attr "type") 
14469         (cond [(match_operand:XF 3 "mult_operator" "") 
14470                  (const_string "fmul")
14471                (match_operand:XF 3 "div_operator" "") 
14472                  (const_string "fdiv")
14473               ]
14474               (const_string "fop")))
14475    (set_attr "mode" "XF")])
14477 (define_insn "*fop_xf_2_i387"
14478   [(set (match_operand:XF 0 "register_operand" "=f,f")
14479         (match_operator:XF 3 "binary_fp_operator"
14480            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14481             (match_operand:XF 2 "register_operand" "0,0")]))]
14482   "TARGET_80387 && TARGET_USE_FIOP"
14483   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14484   [(set (attr "type") 
14485         (cond [(match_operand:XF 3 "mult_operator" "") 
14486                  (const_string "fmul")
14487                (match_operand:XF 3 "div_operator" "") 
14488                  (const_string "fdiv")
14489               ]
14490               (const_string "fop")))
14491    (set_attr "fp_int_src" "true")
14492    (set_attr "mode" "SI")])
14494 (define_insn "*fop_xf_3_i387"
14495   [(set (match_operand:XF 0 "register_operand" "=f,f")
14496         (match_operator:XF 3 "binary_fp_operator"
14497           [(match_operand:XF 1 "register_operand" "0,0")
14498            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14499   "TARGET_80387 && TARGET_USE_FIOP"
14500   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14501   [(set (attr "type") 
14502         (cond [(match_operand:XF 3 "mult_operator" "") 
14503                  (const_string "fmul")
14504                (match_operand:XF 3 "div_operator" "") 
14505                  (const_string "fdiv")
14506               ]
14507               (const_string "fop")))
14508    (set_attr "fp_int_src" "true")
14509    (set_attr "mode" "SI")])
14511 (define_insn "*fop_xf_4_i387"
14512   [(set (match_operand:XF 0 "register_operand" "=f,f")
14513         (match_operator:XF 3 "binary_fp_operator"
14514            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14515             (match_operand:XF 2 "register_operand" "0,f")]))]
14516   "TARGET_80387"
14517   "* return output_387_binary_op (insn, operands);"
14518   [(set (attr "type") 
14519         (cond [(match_operand:XF 3 "mult_operator" "") 
14520                  (const_string "fmul")
14521                (match_operand:XF 3 "div_operator" "") 
14522                  (const_string "fdiv")
14523               ]
14524               (const_string "fop")))
14525    (set_attr "mode" "SF")])
14527 (define_insn "*fop_xf_5_i387"
14528   [(set (match_operand:XF 0 "register_operand" "=f,f")
14529         (match_operator:XF 3 "binary_fp_operator"
14530           [(match_operand:XF 1 "register_operand" "0,f")
14531            (float_extend:XF
14532             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14533   "TARGET_80387"
14534   "* return output_387_binary_op (insn, operands);"
14535   [(set (attr "type") 
14536         (cond [(match_operand:XF 3 "mult_operator" "") 
14537                  (const_string "fmul")
14538                (match_operand:XF 3 "div_operator" "") 
14539                  (const_string "fdiv")
14540               ]
14541               (const_string "fop")))
14542    (set_attr "mode" "SF")])
14544 (define_insn "*fop_xf_6_i387"
14545   [(set (match_operand:XF 0 "register_operand" "=f,f")
14546         (match_operator:XF 3 "binary_fp_operator"
14547           [(float_extend:XF
14548             (match_operand 1 "register_operand" "0,f"))
14549            (float_extend:XF
14550             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14551   "TARGET_80387"
14552   "* return output_387_binary_op (insn, operands);"
14553   [(set (attr "type") 
14554         (cond [(match_operand:XF 3 "mult_operator" "") 
14555                  (const_string "fmul")
14556                (match_operand:XF 3 "div_operator" "") 
14557                  (const_string "fdiv")
14558               ]
14559               (const_string "fop")))
14560    (set_attr "mode" "SF")])
14562 (define_split
14563   [(set (match_operand 0 "register_operand" "")
14564         (match_operator 3 "binary_fp_operator"
14565            [(float (match_operand:SI 1 "register_operand" ""))
14566             (match_operand 2 "register_operand" "")]))]
14567   "TARGET_80387 && reload_completed
14568    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14569   [(const_int 0)]
14571   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14572   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14573   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14574                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14575                                           GET_MODE (operands[3]),
14576                                           operands[4],
14577                                           operands[2])));
14578   ix86_free_from_memory (GET_MODE (operands[1]));
14579   DONE;
14582 (define_split
14583   [(set (match_operand 0 "register_operand" "")
14584         (match_operator 3 "binary_fp_operator"
14585            [(match_operand 1 "register_operand" "")
14586             (float (match_operand:SI 2 "register_operand" ""))]))]
14587   "TARGET_80387 && reload_completed
14588    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14589   [(const_int 0)]
14591   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14592   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14593   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14594                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14595                                           GET_MODE (operands[3]),
14596                                           operands[1],
14597                                           operands[4])));
14598   ix86_free_from_memory (GET_MODE (operands[2]));
14599   DONE;
14602 ;; FPU special functions.
14604 (define_expand "sqrtsf2"
14605   [(set (match_operand:SF 0 "register_operand" "")
14606         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14607   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14609   if (!TARGET_SSE_MATH)
14610     operands[1] = force_reg (SFmode, operands[1]);
14613 (define_insn "*sqrtsf2_mixed"
14614   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14615         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14616   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14617   "@
14618    fsqrt
14619    sqrtss\t{%1, %0|%0, %1}"
14620   [(set_attr "type" "fpspc,sse")
14621    (set_attr "mode" "SF,SF")
14622    (set_attr "athlon_decode" "direct,*")])
14624 (define_insn "*sqrtsf2_sse"
14625   [(set (match_operand:SF 0 "register_operand" "=x")
14626         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14627   "TARGET_SSE_MATH"
14628   "sqrtss\t{%1, %0|%0, %1}"
14629   [(set_attr "type" "sse")
14630    (set_attr "mode" "SF")
14631    (set_attr "athlon_decode" "*")])
14633 (define_insn "*sqrtsf2_i387"
14634   [(set (match_operand:SF 0 "register_operand" "=f")
14635         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14636   "TARGET_USE_FANCY_MATH_387"
14637   "fsqrt"
14638   [(set_attr "type" "fpspc")
14639    (set_attr "mode" "SF")
14640    (set_attr "athlon_decode" "direct")])
14642 (define_expand "sqrtdf2"
14643   [(set (match_operand:DF 0 "register_operand" "")
14644         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14645   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14647   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14648     operands[1] = force_reg (DFmode, operands[1]);
14651 (define_insn "*sqrtdf2_mixed"
14652   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14653         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14654   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14655   "@
14656    fsqrt
14657    sqrtsd\t{%1, %0|%0, %1}"
14658   [(set_attr "type" "fpspc,sse")
14659    (set_attr "mode" "DF,DF")
14660    (set_attr "athlon_decode" "direct,*")])
14662 (define_insn "*sqrtdf2_sse"
14663   [(set (match_operand:DF 0 "register_operand" "=Y")
14664         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14665   "TARGET_SSE2 && TARGET_SSE_MATH"
14666   "sqrtsd\t{%1, %0|%0, %1}"
14667   [(set_attr "type" "sse")
14668    (set_attr "mode" "DF")
14669    (set_attr "athlon_decode" "*")])
14671 (define_insn "*sqrtdf2_i387"
14672   [(set (match_operand:DF 0 "register_operand" "=f")
14673         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14674   "TARGET_USE_FANCY_MATH_387"
14675   "fsqrt"
14676   [(set_attr "type" "fpspc")
14677    (set_attr "mode" "DF")
14678    (set_attr "athlon_decode" "direct")])
14680 (define_insn "*sqrtextendsfdf2_i387"
14681   [(set (match_operand:DF 0 "register_operand" "=f")
14682         (sqrt:DF (float_extend:DF
14683                   (match_operand:SF 1 "register_operand" "0"))))]
14684   "TARGET_USE_FANCY_MATH_387
14685    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14686   "fsqrt"
14687   [(set_attr "type" "fpspc")
14688    (set_attr "mode" "DF")
14689    (set_attr "athlon_decode" "direct")])
14691 (define_insn "sqrtxf2"
14692   [(set (match_operand:XF 0 "register_operand" "=f")
14693         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14694   "TARGET_USE_FANCY_MATH_387 
14695    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14696   "fsqrt"
14697   [(set_attr "type" "fpspc")
14698    (set_attr "mode" "XF")
14699    (set_attr "athlon_decode" "direct")])
14701 (define_insn "*sqrtextendsfxf2_i387"
14702   [(set (match_operand:XF 0 "register_operand" "=f")
14703         (sqrt:XF (float_extend:XF
14704                   (match_operand:SF 1 "register_operand" "0"))))]
14705   "TARGET_USE_FANCY_MATH_387"
14706   "fsqrt"
14707   [(set_attr "type" "fpspc")
14708    (set_attr "mode" "XF")
14709    (set_attr "athlon_decode" "direct")])
14711 (define_insn "*sqrtextenddfxf2_i387"
14712   [(set (match_operand:XF 0 "register_operand" "=f")
14713         (sqrt:XF (float_extend:XF
14714                   (match_operand:DF 1 "register_operand" "0"))))]
14715   "TARGET_USE_FANCY_MATH_387"
14716   "fsqrt"
14717   [(set_attr "type" "fpspc")
14718    (set_attr "mode" "XF")
14719    (set_attr "athlon_decode" "direct")])
14721 (define_insn "fpremxf4"
14722   [(set (match_operand:XF 0 "register_operand" "=f")
14723         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14724                     (match_operand:XF 3 "register_operand" "1")]
14725                    UNSPEC_FPREM_F))
14726    (set (match_operand:XF 1 "register_operand" "=u")
14727         (unspec:XF [(match_dup 2) (match_dup 3)]
14728                    UNSPEC_FPREM_U))
14729    (set (reg:CCFP FPSR_REG)
14730         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14731   "TARGET_USE_FANCY_MATH_387
14732    && flag_unsafe_math_optimizations"
14733   "fprem"
14734   [(set_attr "type" "fpspc")
14735    (set_attr "mode" "XF")])
14737 (define_expand "fmodsf3"
14738   [(use (match_operand:SF 0 "register_operand" ""))
14739    (use (match_operand:SF 1 "register_operand" ""))
14740    (use (match_operand:SF 2 "register_operand" ""))]
14741   "TARGET_USE_FANCY_MATH_387
14742    && flag_unsafe_math_optimizations"
14744   rtx label = gen_label_rtx ();
14746   rtx op1 = gen_reg_rtx (XFmode);
14747   rtx op2 = gen_reg_rtx (XFmode);
14749   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14750   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14752   emit_label (label);
14754   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14755   ix86_emit_fp_unordered_jump (label);
14757   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14758   DONE;
14761 (define_expand "fmoddf3"
14762   [(use (match_operand:DF 0 "register_operand" ""))
14763    (use (match_operand:DF 1 "register_operand" ""))
14764    (use (match_operand:DF 2 "register_operand" ""))]
14765   "TARGET_USE_FANCY_MATH_387
14766    && flag_unsafe_math_optimizations"
14768   rtx label = gen_label_rtx ();
14770   rtx op1 = gen_reg_rtx (XFmode);
14771   rtx op2 = gen_reg_rtx (XFmode);
14773   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14774   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14776   emit_label (label);
14778   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14779   ix86_emit_fp_unordered_jump (label);
14781   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14782   DONE;
14785 (define_expand "fmodxf3"
14786   [(use (match_operand:XF 0 "register_operand" ""))
14787    (use (match_operand:XF 1 "register_operand" ""))
14788    (use (match_operand:XF 2 "register_operand" ""))]
14789   "TARGET_USE_FANCY_MATH_387
14790    && flag_unsafe_math_optimizations"
14792   rtx label = gen_label_rtx ();
14794   emit_label (label);
14796   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14797                            operands[1], operands[2]));
14798   ix86_emit_fp_unordered_jump (label);
14800   emit_move_insn (operands[0], operands[1]);
14801   DONE;
14804 (define_insn "fprem1xf4"
14805   [(set (match_operand:XF 0 "register_operand" "=f")
14806         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14807                     (match_operand:XF 3 "register_operand" "1")]
14808                    UNSPEC_FPREM1_F))
14809    (set (match_operand:XF 1 "register_operand" "=u")
14810         (unspec:XF [(match_dup 2) (match_dup 3)]
14811                    UNSPEC_FPREM1_U))
14812    (set (reg:CCFP FPSR_REG)
14813         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14814   "TARGET_USE_FANCY_MATH_387
14815    && flag_unsafe_math_optimizations"
14816   "fprem1"
14817   [(set_attr "type" "fpspc")
14818    (set_attr "mode" "XF")])
14820 (define_expand "dremsf3"
14821   [(use (match_operand:SF 0 "register_operand" ""))
14822    (use (match_operand:SF 1 "register_operand" ""))
14823    (use (match_operand:SF 2 "register_operand" ""))]
14824   "TARGET_USE_FANCY_MATH_387
14825    && flag_unsafe_math_optimizations"
14827   rtx label = gen_label_rtx ();
14829   rtx op1 = gen_reg_rtx (XFmode);
14830   rtx op2 = gen_reg_rtx (XFmode);
14832   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14833   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14835   emit_label (label);
14837   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14838   ix86_emit_fp_unordered_jump (label);
14840   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14841   DONE;
14844 (define_expand "dremdf3"
14845   [(use (match_operand:DF 0 "register_operand" ""))
14846    (use (match_operand:DF 1 "register_operand" ""))
14847    (use (match_operand:DF 2 "register_operand" ""))]
14848   "TARGET_USE_FANCY_MATH_387
14849    && flag_unsafe_math_optimizations"
14851   rtx label = gen_label_rtx ();
14853   rtx op1 = gen_reg_rtx (XFmode);
14854   rtx op2 = gen_reg_rtx (XFmode);
14856   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14857   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14859   emit_label (label);
14861   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14862   ix86_emit_fp_unordered_jump (label);
14864   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14865   DONE;
14868 (define_expand "dremxf3"
14869   [(use (match_operand:XF 0 "register_operand" ""))
14870    (use (match_operand:XF 1 "register_operand" ""))
14871    (use (match_operand:XF 2 "register_operand" ""))]
14872   "TARGET_USE_FANCY_MATH_387
14873    && flag_unsafe_math_optimizations"
14875   rtx label = gen_label_rtx ();
14877   emit_label (label);
14879   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14880                             operands[1], operands[2]));
14881   ix86_emit_fp_unordered_jump (label);
14883   emit_move_insn (operands[0], operands[1]);
14884   DONE;
14887 (define_insn "*sindf2"
14888   [(set (match_operand:DF 0 "register_operand" "=f")
14889         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14890   "TARGET_USE_FANCY_MATH_387
14891    && flag_unsafe_math_optimizations"
14892   "fsin"
14893   [(set_attr "type" "fpspc")
14894    (set_attr "mode" "DF")])
14896 (define_insn "*sinsf2"
14897   [(set (match_operand:SF 0 "register_operand" "=f")
14898         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14899   "TARGET_USE_FANCY_MATH_387
14900    && flag_unsafe_math_optimizations"
14901   "fsin"
14902   [(set_attr "type" "fpspc")
14903    (set_attr "mode" "SF")])
14905 (define_insn "*sinextendsfdf2"
14906   [(set (match_operand:DF 0 "register_operand" "=f")
14907         (unspec:DF [(float_extend:DF
14908                      (match_operand:SF 1 "register_operand" "0"))]
14909                    UNSPEC_SIN))]
14910   "TARGET_USE_FANCY_MATH_387
14911    && flag_unsafe_math_optimizations"
14912   "fsin"
14913   [(set_attr "type" "fpspc")
14914    (set_attr "mode" "DF")])
14916 (define_insn "*sinxf2"
14917   [(set (match_operand:XF 0 "register_operand" "=f")
14918         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14919   "TARGET_USE_FANCY_MATH_387
14920    && flag_unsafe_math_optimizations"
14921   "fsin"
14922   [(set_attr "type" "fpspc")
14923    (set_attr "mode" "XF")])
14925 (define_insn "*cosdf2"
14926   [(set (match_operand:DF 0 "register_operand" "=f")
14927         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14928   "TARGET_USE_FANCY_MATH_387
14929    && flag_unsafe_math_optimizations"
14930   "fcos"
14931   [(set_attr "type" "fpspc")
14932    (set_attr "mode" "DF")])
14934 (define_insn "*cossf2"
14935   [(set (match_operand:SF 0 "register_operand" "=f")
14936         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14937   "TARGET_USE_FANCY_MATH_387
14938    && flag_unsafe_math_optimizations"
14939   "fcos"
14940   [(set_attr "type" "fpspc")
14941    (set_attr "mode" "SF")])
14943 (define_insn "*cosextendsfdf2"
14944   [(set (match_operand:DF 0 "register_operand" "=f")
14945         (unspec:DF [(float_extend:DF
14946                      (match_operand:SF 1 "register_operand" "0"))]
14947                    UNSPEC_COS))]
14948   "TARGET_USE_FANCY_MATH_387
14949    && flag_unsafe_math_optimizations"
14950   "fcos"
14951   [(set_attr "type" "fpspc")
14952    (set_attr "mode" "DF")])
14954 (define_insn "*cosxf2"
14955   [(set (match_operand:XF 0 "register_operand" "=f")
14956         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14957   "TARGET_USE_FANCY_MATH_387
14958    && flag_unsafe_math_optimizations"
14959   "fcos"
14960   [(set_attr "type" "fpspc")
14961    (set_attr "mode" "XF")])
14963 ;; With sincos pattern defined, sin and cos builtin function will be
14964 ;; expanded to sincos pattern with one of its outputs left unused. 
14965 ;; Cse pass  will detected, if two sincos patterns can be combined,
14966 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14967 ;; depending on the unused output.
14969 (define_insn "sincosdf3"
14970   [(set (match_operand:DF 0 "register_operand" "=f")
14971         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14972                    UNSPEC_SINCOS_COS))
14973    (set (match_operand:DF 1 "register_operand" "=u")
14974         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14975   "TARGET_USE_FANCY_MATH_387
14976    && flag_unsafe_math_optimizations"
14977   "fsincos"
14978   [(set_attr "type" "fpspc")
14979    (set_attr "mode" "DF")])
14981 (define_split
14982   [(set (match_operand:DF 0 "register_operand" "")
14983         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14984                    UNSPEC_SINCOS_COS))
14985    (set (match_operand:DF 1 "register_operand" "")
14986         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14987   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14988    && !reload_completed && !reload_in_progress"
14989   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14990   "")
14992 (define_split
14993   [(set (match_operand:DF 0 "register_operand" "")
14994         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14995                    UNSPEC_SINCOS_COS))
14996    (set (match_operand:DF 1 "register_operand" "")
14997         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14998   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14999    && !reload_completed && !reload_in_progress"
15000   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15001   "")
15003 (define_insn "sincossf3"
15004   [(set (match_operand:SF 0 "register_operand" "=f")
15005         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15006                    UNSPEC_SINCOS_COS))
15007    (set (match_operand:SF 1 "register_operand" "=u")
15008         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15009   "TARGET_USE_FANCY_MATH_387
15010    && flag_unsafe_math_optimizations"
15011   "fsincos"
15012   [(set_attr "type" "fpspc")
15013    (set_attr "mode" "SF")])
15015 (define_split
15016   [(set (match_operand:SF 0 "register_operand" "")
15017         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15018                    UNSPEC_SINCOS_COS))
15019    (set (match_operand:SF 1 "register_operand" "")
15020         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15021   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15022    && !reload_completed && !reload_in_progress"
15023   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15024   "")
15026 (define_split
15027   [(set (match_operand:SF 0 "register_operand" "")
15028         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15029                    UNSPEC_SINCOS_COS))
15030    (set (match_operand:SF 1 "register_operand" "")
15031         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15032   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15033    && !reload_completed && !reload_in_progress"
15034   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15035   "")
15037 (define_insn "*sincosextendsfdf3"
15038   [(set (match_operand:DF 0 "register_operand" "=f")
15039         (unspec:DF [(float_extend:DF
15040                      (match_operand:SF 2 "register_operand" "0"))]
15041                    UNSPEC_SINCOS_COS))
15042    (set (match_operand:DF 1 "register_operand" "=u")
15043         (unspec:DF [(float_extend:DF
15044                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15045   "TARGET_USE_FANCY_MATH_387
15046    && flag_unsafe_math_optimizations"
15047   "fsincos"
15048   [(set_attr "type" "fpspc")
15049    (set_attr "mode" "DF")])
15051 (define_split
15052   [(set (match_operand:DF 0 "register_operand" "")
15053         (unspec:DF [(float_extend:DF
15054                      (match_operand:SF 2 "register_operand" ""))]
15055                    UNSPEC_SINCOS_COS))
15056    (set (match_operand:DF 1 "register_operand" "")
15057         (unspec:DF [(float_extend:DF
15058                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15059   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15060    && !reload_completed && !reload_in_progress"
15061   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15062                                    (match_dup 2))] UNSPEC_SIN))]
15063   "")
15065 (define_split
15066   [(set (match_operand:DF 0 "register_operand" "")
15067         (unspec:DF [(float_extend:DF
15068                      (match_operand:SF 2 "register_operand" ""))]
15069                    UNSPEC_SINCOS_COS))
15070    (set (match_operand:DF 1 "register_operand" "")
15071         (unspec:DF [(float_extend:DF
15072                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15073   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15074    && !reload_completed && !reload_in_progress"
15075   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15076                                    (match_dup 2))] UNSPEC_COS))]
15077   "")
15079 (define_insn "sincosxf3"
15080   [(set (match_operand:XF 0 "register_operand" "=f")
15081         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15082                    UNSPEC_SINCOS_COS))
15083    (set (match_operand:XF 1 "register_operand" "=u")
15084         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15085   "TARGET_USE_FANCY_MATH_387
15086    && flag_unsafe_math_optimizations"
15087   "fsincos"
15088   [(set_attr "type" "fpspc")
15089    (set_attr "mode" "XF")])
15091 (define_split
15092   [(set (match_operand:XF 0 "register_operand" "")
15093         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15094                    UNSPEC_SINCOS_COS))
15095    (set (match_operand:XF 1 "register_operand" "")
15096         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15097   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15098    && !reload_completed && !reload_in_progress"
15099   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15100   "")
15102 (define_split
15103   [(set (match_operand:XF 0 "register_operand" "")
15104         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15105                    UNSPEC_SINCOS_COS))
15106    (set (match_operand:XF 1 "register_operand" "")
15107         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15108   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15109    && !reload_completed && !reload_in_progress"
15110   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15111   "")
15113 (define_insn "*tandf3_1"
15114   [(set (match_operand:DF 0 "register_operand" "=f")
15115         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15116                    UNSPEC_TAN_ONE))
15117    (set (match_operand:DF 1 "register_operand" "=u")
15118         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15119   "TARGET_USE_FANCY_MATH_387
15120    && flag_unsafe_math_optimizations"
15121   "fptan"
15122   [(set_attr "type" "fpspc")
15123    (set_attr "mode" "DF")])
15125 ;; optimize sequence: fptan
15126 ;;                    fstp    %st(0)
15127 ;;                    fld1
15128 ;; into fptan insn.
15130 (define_peephole2
15131   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15132                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15133                              UNSPEC_TAN_ONE))
15134              (set (match_operand:DF 1 "register_operand" "")
15135                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15136    (set (match_dup 0)
15137         (match_operand:DF 3 "immediate_operand" ""))]
15138   "standard_80387_constant_p (operands[3]) == 2"
15139   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15140              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15141   "")
15143 (define_expand "tandf2"
15144   [(parallel [(set (match_dup 2)
15145                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15146                               UNSPEC_TAN_ONE))
15147               (set (match_operand:DF 0 "register_operand" "")
15148                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15149   "TARGET_USE_FANCY_MATH_387
15150    && flag_unsafe_math_optimizations"
15152   operands[2] = gen_reg_rtx (DFmode);
15155 (define_insn "*tansf3_1"
15156   [(set (match_operand:SF 0 "register_operand" "=f")
15157         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15158                    UNSPEC_TAN_ONE))
15159    (set (match_operand:SF 1 "register_operand" "=u")
15160         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15161   "TARGET_USE_FANCY_MATH_387
15162    && flag_unsafe_math_optimizations"
15163   "fptan"
15164   [(set_attr "type" "fpspc")
15165    (set_attr "mode" "SF")])
15167 ;; optimize sequence: fptan
15168 ;;                    fstp    %st(0)
15169 ;;                    fld1
15170 ;; into fptan insn.
15172 (define_peephole2
15173   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15174                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15175                              UNSPEC_TAN_ONE))
15176              (set (match_operand:SF 1 "register_operand" "")
15177                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15178    (set (match_dup 0)
15179         (match_operand:SF 3 "immediate_operand" ""))]
15180   "standard_80387_constant_p (operands[3]) == 2"
15181   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15182              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15183   "")
15185 (define_expand "tansf2"
15186   [(parallel [(set (match_dup 2)
15187                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15188                               UNSPEC_TAN_ONE))
15189               (set (match_operand:SF 0 "register_operand" "")
15190                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15191   "TARGET_USE_FANCY_MATH_387
15192    && flag_unsafe_math_optimizations"
15194   operands[2] = gen_reg_rtx (SFmode);
15197 (define_insn "*tanxf3_1"
15198   [(set (match_operand:XF 0 "register_operand" "=f")
15199         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15200                    UNSPEC_TAN_ONE))
15201    (set (match_operand:XF 1 "register_operand" "=u")
15202         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15203   "TARGET_USE_FANCY_MATH_387
15204    && flag_unsafe_math_optimizations"
15205   "fptan"
15206   [(set_attr "type" "fpspc")
15207    (set_attr "mode" "XF")])
15209 ;; optimize sequence: fptan
15210 ;;                    fstp    %st(0)
15211 ;;                    fld1
15212 ;; into fptan insn.
15214 (define_peephole2
15215   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15216                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15217                              UNSPEC_TAN_ONE))
15218              (set (match_operand:XF 1 "register_operand" "")
15219                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15220    (set (match_dup 0)
15221         (match_operand:XF 3 "immediate_operand" ""))]
15222   "standard_80387_constant_p (operands[3]) == 2"
15223   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15224              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15225   "")
15227 (define_expand "tanxf2"
15228   [(parallel [(set (match_dup 2)
15229                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15230                               UNSPEC_TAN_ONE))
15231               (set (match_operand:XF 0 "register_operand" "")
15232                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15233   "TARGET_USE_FANCY_MATH_387
15234    && flag_unsafe_math_optimizations"
15236   operands[2] = gen_reg_rtx (XFmode);
15239 (define_insn "atan2df3_1"
15240   [(set (match_operand:DF 0 "register_operand" "=f")
15241         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15242                     (match_operand:DF 1 "register_operand" "u")]
15243                    UNSPEC_FPATAN))
15244    (clobber (match_scratch:DF 3 "=1"))]
15245   "TARGET_USE_FANCY_MATH_387
15246    && flag_unsafe_math_optimizations"
15247   "fpatan"
15248   [(set_attr "type" "fpspc")
15249    (set_attr "mode" "DF")])
15251 (define_expand "atan2df3"
15252   [(use (match_operand:DF 0 "register_operand" "=f"))
15253    (use (match_operand:DF 2 "register_operand" "0"))
15254    (use (match_operand:DF 1 "register_operand" "u"))]
15255   "TARGET_USE_FANCY_MATH_387
15256    && flag_unsafe_math_optimizations"
15258   rtx copy = gen_reg_rtx (DFmode);
15259   emit_move_insn (copy, operands[1]);
15260   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15261   DONE;
15264 (define_expand "atandf2"
15265   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15266                    (unspec:DF [(match_dup 2)
15267                                (match_operand:DF 1 "register_operand" "")]
15268                     UNSPEC_FPATAN))
15269               (clobber (match_scratch:DF 3 ""))])]
15270   "TARGET_USE_FANCY_MATH_387
15271    && flag_unsafe_math_optimizations"
15273   operands[2] = gen_reg_rtx (DFmode);
15274   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15277 (define_insn "atan2sf3_1"
15278   [(set (match_operand:SF 0 "register_operand" "=f")
15279         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15280                     (match_operand:SF 1 "register_operand" "u")]
15281                    UNSPEC_FPATAN))
15282    (clobber (match_scratch:SF 3 "=1"))]
15283   "TARGET_USE_FANCY_MATH_387
15284    && flag_unsafe_math_optimizations"
15285   "fpatan"
15286   [(set_attr "type" "fpspc")
15287    (set_attr "mode" "SF")])
15289 (define_expand "atan2sf3"
15290   [(use (match_operand:SF 0 "register_operand" "=f"))
15291    (use (match_operand:SF 2 "register_operand" "0"))
15292    (use (match_operand:SF 1 "register_operand" "u"))]
15293   "TARGET_USE_FANCY_MATH_387
15294    && flag_unsafe_math_optimizations"
15296   rtx copy = gen_reg_rtx (SFmode);
15297   emit_move_insn (copy, operands[1]);
15298   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15299   DONE;
15302 (define_expand "atansf2"
15303   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15304                    (unspec:SF [(match_dup 2)
15305                                (match_operand:SF 1 "register_operand" "")]
15306                     UNSPEC_FPATAN))
15307               (clobber (match_scratch:SF 3 ""))])]
15308   "TARGET_USE_FANCY_MATH_387
15309    && flag_unsafe_math_optimizations"
15311   operands[2] = gen_reg_rtx (SFmode);
15312   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15315 (define_insn "atan2xf3_1"
15316   [(set (match_operand:XF 0 "register_operand" "=f")
15317         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15318                     (match_operand:XF 1 "register_operand" "u")]
15319                    UNSPEC_FPATAN))
15320    (clobber (match_scratch:XF 3 "=1"))]
15321   "TARGET_USE_FANCY_MATH_387
15322    && flag_unsafe_math_optimizations"
15323   "fpatan"
15324   [(set_attr "type" "fpspc")
15325    (set_attr "mode" "XF")])
15327 (define_expand "atan2xf3"
15328   [(use (match_operand:XF 0 "register_operand" "=f"))
15329    (use (match_operand:XF 2 "register_operand" "0"))
15330    (use (match_operand:XF 1 "register_operand" "u"))]
15331   "TARGET_USE_FANCY_MATH_387
15332    && flag_unsafe_math_optimizations"
15334   rtx copy = gen_reg_rtx (XFmode);
15335   emit_move_insn (copy, operands[1]);
15336   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15337   DONE;
15340 (define_expand "atanxf2"
15341   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15342                    (unspec:XF [(match_dup 2)
15343                                (match_operand:XF 1 "register_operand" "")]
15344                     UNSPEC_FPATAN))
15345               (clobber (match_scratch:XF 3 ""))])]
15346   "TARGET_USE_FANCY_MATH_387
15347    && flag_unsafe_math_optimizations"
15349   operands[2] = gen_reg_rtx (XFmode);
15350   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15353 (define_expand "asindf2"
15354   [(set (match_dup 2)
15355         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15356    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15357    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15358    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15359    (parallel [(set (match_dup 7)
15360                    (unspec:XF [(match_dup 6) (match_dup 2)]
15361                               UNSPEC_FPATAN))
15362               (clobber (match_scratch:XF 8 ""))])
15363    (set (match_operand:DF 0 "register_operand" "")
15364         (float_truncate:DF (match_dup 7)))]
15365   "TARGET_USE_FANCY_MATH_387
15366    && flag_unsafe_math_optimizations"
15368   int i;
15370   for (i=2; i<8; i++)
15371     operands[i] = gen_reg_rtx (XFmode);
15373   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15376 (define_expand "asinsf2"
15377   [(set (match_dup 2)
15378         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15379    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15380    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15381    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15382    (parallel [(set (match_dup 7)
15383                    (unspec:XF [(match_dup 6) (match_dup 2)]
15384                               UNSPEC_FPATAN))
15385               (clobber (match_scratch:XF 8 ""))])
15386    (set (match_operand:SF 0 "register_operand" "")
15387         (float_truncate:SF (match_dup 7)))]
15388   "TARGET_USE_FANCY_MATH_387
15389    && flag_unsafe_math_optimizations"
15391   int i;
15393   for (i=2; i<8; i++)
15394     operands[i] = gen_reg_rtx (XFmode);
15396   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15399 (define_expand "asinxf2"
15400   [(set (match_dup 2)
15401         (mult:XF (match_operand:XF 1 "register_operand" "")
15402                  (match_dup 1)))
15403    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15404    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15405    (parallel [(set (match_operand:XF 0 "register_operand" "")
15406                    (unspec:XF [(match_dup 5) (match_dup 1)]
15407                               UNSPEC_FPATAN))
15408               (clobber (match_scratch:XF 6 ""))])]
15409   "TARGET_USE_FANCY_MATH_387
15410    && flag_unsafe_math_optimizations"
15412   int i;
15414   for (i=2; i<6; i++)
15415     operands[i] = gen_reg_rtx (XFmode);
15417   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15420 (define_expand "acosdf2"
15421   [(set (match_dup 2)
15422         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15423    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15424    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15425    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15426    (parallel [(set (match_dup 7)
15427                    (unspec:XF [(match_dup 2) (match_dup 6)]
15428                               UNSPEC_FPATAN))
15429               (clobber (match_scratch:XF 8 ""))])
15430    (set (match_operand:DF 0 "register_operand" "")
15431         (float_truncate:DF (match_dup 7)))]
15432   "TARGET_USE_FANCY_MATH_387
15433    && flag_unsafe_math_optimizations"
15435   int i;
15437   for (i=2; i<8; i++)
15438     operands[i] = gen_reg_rtx (XFmode);
15440   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15443 (define_expand "acossf2"
15444   [(set (match_dup 2)
15445         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15446    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15447    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15448    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15449    (parallel [(set (match_dup 7)
15450                    (unspec:XF [(match_dup 2) (match_dup 6)]
15451                               UNSPEC_FPATAN))
15452               (clobber (match_scratch:XF 8 ""))])
15453    (set (match_operand:SF 0 "register_operand" "")
15454         (float_truncate:SF (match_dup 7)))]
15455   "TARGET_USE_FANCY_MATH_387
15456    && flag_unsafe_math_optimizations"
15458   int i;
15460   for (i=2; i<8; i++)
15461     operands[i] = gen_reg_rtx (XFmode);
15463   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15466 (define_expand "acosxf2"
15467   [(set (match_dup 2)
15468         (mult:XF (match_operand:XF 1 "register_operand" "")
15469                  (match_dup 1)))
15470    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15471    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15472    (parallel [(set (match_operand:XF 0 "register_operand" "")
15473                    (unspec:XF [(match_dup 1) (match_dup 5)]
15474                               UNSPEC_FPATAN))
15475               (clobber (match_scratch:XF 6 ""))])]
15476   "TARGET_USE_FANCY_MATH_387
15477    && flag_unsafe_math_optimizations"
15479   int i;
15481   for (i=2; i<6; i++)
15482     operands[i] = gen_reg_rtx (XFmode);
15484   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15487 (define_insn "fyl2x_xf3"
15488   [(set (match_operand:XF 0 "register_operand" "=f")
15489         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15490                     (match_operand:XF 1 "register_operand" "u")]
15491                    UNSPEC_FYL2X))
15492    (clobber (match_scratch:XF 3 "=1"))]
15493   "TARGET_USE_FANCY_MATH_387
15494    && flag_unsafe_math_optimizations"
15495   "fyl2x"
15496   [(set_attr "type" "fpspc")
15497    (set_attr "mode" "XF")])
15499 (define_expand "logsf2"
15500   [(set (match_dup 2)
15501         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15502    (parallel [(set (match_dup 4)
15503                    (unspec:XF [(match_dup 2)
15504                                (match_dup 3)] UNSPEC_FYL2X))
15505               (clobber (match_scratch:XF 5 ""))])
15506    (set (match_operand:SF 0 "register_operand" "")
15507         (float_truncate:SF (match_dup 4)))]
15508   "TARGET_USE_FANCY_MATH_387
15509    && flag_unsafe_math_optimizations"
15511   rtx temp;
15513   operands[2] = gen_reg_rtx (XFmode);
15514   operands[3] = gen_reg_rtx (XFmode);
15515   operands[4] = gen_reg_rtx (XFmode);
15517   temp = standard_80387_constant_rtx (4); /* fldln2 */
15518   emit_move_insn (operands[3], temp);
15521 (define_expand "logdf2"
15522   [(set (match_dup 2)
15523         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15524    (parallel [(set (match_dup 4)
15525                    (unspec:XF [(match_dup 2)
15526                                (match_dup 3)] UNSPEC_FYL2X))
15527               (clobber (match_scratch:XF 5 ""))])
15528    (set (match_operand:DF 0 "register_operand" "")
15529         (float_truncate:DF (match_dup 4)))]
15530   "TARGET_USE_FANCY_MATH_387
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    && flag_unsafe_math_optimizations"
15570   rtx temp;
15572   operands[2] = gen_reg_rtx (XFmode);
15573   operands[3] = gen_reg_rtx (XFmode);
15574   operands[4] = gen_reg_rtx (XFmode);
15576   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15577   emit_move_insn (operands[3], temp);
15580 (define_expand "log10df2"
15581   [(set (match_dup 2)
15582         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15583    (parallel [(set (match_dup 4)
15584                    (unspec:XF [(match_dup 2)
15585                                (match_dup 3)] UNSPEC_FYL2X))
15586               (clobber (match_scratch:XF 5 ""))])
15587    (set (match_operand:DF 0 "register_operand" "")
15588         (float_truncate:DF (match_dup 4)))]
15589   "TARGET_USE_FANCY_MATH_387
15590    && flag_unsafe_math_optimizations"
15592   rtx temp;
15594   operands[2] = gen_reg_rtx (XFmode);
15595   operands[3] = gen_reg_rtx (XFmode);
15596   operands[4] = gen_reg_rtx (XFmode);
15598   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15599   emit_move_insn (operands[3], temp);
15602 (define_expand "log10xf2"
15603   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15604                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15605                                (match_dup 2)] UNSPEC_FYL2X))
15606               (clobber (match_scratch:XF 3 ""))])]
15607   "TARGET_USE_FANCY_MATH_387
15608    && flag_unsafe_math_optimizations"
15610   rtx temp;
15612   operands[2] = gen_reg_rtx (XFmode);
15613   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15614   emit_move_insn (operands[2], temp);
15617 (define_expand "log2sf2"
15618   [(set (match_dup 2)
15619         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15620    (parallel [(set (match_dup 4)
15621                    (unspec:XF [(match_dup 2)
15622                                (match_dup 3)] UNSPEC_FYL2X))
15623               (clobber (match_scratch:XF 5 ""))])
15624    (set (match_operand:SF 0 "register_operand" "")
15625         (float_truncate:SF (match_dup 4)))]
15626   "TARGET_USE_FANCY_MATH_387
15627    && flag_unsafe_math_optimizations"
15629   operands[2] = gen_reg_rtx (XFmode);
15630   operands[3] = gen_reg_rtx (XFmode);
15631   operands[4] = gen_reg_rtx (XFmode);
15633   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15636 (define_expand "log2df2"
15637   [(set (match_dup 2)
15638         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15639    (parallel [(set (match_dup 4)
15640                    (unspec:XF [(match_dup 2)
15641                                (match_dup 3)] UNSPEC_FYL2X))
15642               (clobber (match_scratch:XF 5 ""))])
15643    (set (match_operand:DF 0 "register_operand" "")
15644         (float_truncate:DF (match_dup 4)))]
15645   "TARGET_USE_FANCY_MATH_387
15646    && flag_unsafe_math_optimizations"
15648   operands[2] = gen_reg_rtx (XFmode);
15649   operands[3] = gen_reg_rtx (XFmode);
15650   operands[4] = gen_reg_rtx (XFmode);
15652   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15655 (define_expand "log2xf2"
15656   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15657                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15658                                (match_dup 2)] UNSPEC_FYL2X))
15659               (clobber (match_scratch:XF 3 ""))])]
15660   "TARGET_USE_FANCY_MATH_387
15661    && flag_unsafe_math_optimizations"
15663   operands[2] = gen_reg_rtx (XFmode);
15664   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15667 (define_insn "fyl2xp1_xf3"
15668   [(set (match_operand:XF 0 "register_operand" "=f")
15669         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15670                     (match_operand:XF 1 "register_operand" "u")]
15671                    UNSPEC_FYL2XP1))
15672    (clobber (match_scratch:XF 3 "=1"))]
15673   "TARGET_USE_FANCY_MATH_387
15674    && flag_unsafe_math_optimizations"
15675   "fyl2xp1"
15676   [(set_attr "type" "fpspc")
15677    (set_attr "mode" "XF")])
15679 (define_expand "log1psf2"
15680   [(use (match_operand:SF 0 "register_operand" ""))
15681    (use (match_operand:SF 1 "register_operand" ""))]
15682   "TARGET_USE_FANCY_MATH_387
15683    && flag_unsafe_math_optimizations"
15685   rtx op0 = gen_reg_rtx (XFmode);
15686   rtx op1 = gen_reg_rtx (XFmode);
15688   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15689   ix86_emit_i387_log1p (op0, op1);
15690   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15691   DONE;
15694 (define_expand "log1pdf2"
15695   [(use (match_operand:DF 0 "register_operand" ""))
15696    (use (match_operand:DF 1 "register_operand" ""))]
15697   "TARGET_USE_FANCY_MATH_387
15698    && flag_unsafe_math_optimizations"
15700   rtx op0 = gen_reg_rtx (XFmode);
15701   rtx op1 = gen_reg_rtx (XFmode);
15703   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15704   ix86_emit_i387_log1p (op0, op1);
15705   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15706   DONE;
15709 (define_expand "log1pxf2"
15710   [(use (match_operand:XF 0 "register_operand" ""))
15711    (use (match_operand:XF 1 "register_operand" ""))]
15712   "TARGET_USE_FANCY_MATH_387
15713    && flag_unsafe_math_optimizations"
15715   ix86_emit_i387_log1p (operands[0], operands[1]);
15716   DONE;
15719 (define_insn "*fxtractxf3"
15720   [(set (match_operand:XF 0 "register_operand" "=f")
15721         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15722                    UNSPEC_XTRACT_FRACT))
15723    (set (match_operand:XF 1 "register_operand" "=u")
15724         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15725   "TARGET_USE_FANCY_MATH_387
15726    && flag_unsafe_math_optimizations"
15727   "fxtract"
15728   [(set_attr "type" "fpspc")
15729    (set_attr "mode" "XF")])
15731 (define_expand "logbsf2"
15732   [(set (match_dup 2)
15733         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15734    (parallel [(set (match_dup 3)
15735                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15736               (set (match_dup 4)
15737                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15738    (set (match_operand:SF 0 "register_operand" "")
15739         (float_truncate:SF (match_dup 4)))]
15740   "TARGET_USE_FANCY_MATH_387
15741    && flag_unsafe_math_optimizations"
15743   operands[2] = gen_reg_rtx (XFmode);
15744   operands[3] = gen_reg_rtx (XFmode);
15745   operands[4] = gen_reg_rtx (XFmode);
15748 (define_expand "logbdf2"
15749   [(set (match_dup 2)
15750         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15751    (parallel [(set (match_dup 3)
15752                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15753               (set (match_dup 4)
15754                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15755    (set (match_operand:DF 0 "register_operand" "")
15756         (float_truncate:DF (match_dup 4)))]
15757   "TARGET_USE_FANCY_MATH_387
15758    && flag_unsafe_math_optimizations"
15760   operands[2] = gen_reg_rtx (XFmode);
15761   operands[3] = gen_reg_rtx (XFmode);
15762   operands[4] = gen_reg_rtx (XFmode);
15765 (define_expand "logbxf2"
15766   [(parallel [(set (match_dup 2)
15767                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15768                               UNSPEC_XTRACT_FRACT))
15769               (set (match_operand:XF 0 "register_operand" "")
15770                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15771   "TARGET_USE_FANCY_MATH_387
15772    && flag_unsafe_math_optimizations"
15774   operands[2] = gen_reg_rtx (XFmode);
15777 (define_expand "ilogbsi2"
15778   [(parallel [(set (match_dup 2)
15779                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15780                               UNSPEC_XTRACT_FRACT))
15781               (set (match_operand:XF 3 "register_operand" "")
15782                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15783    (parallel [(set (match_operand:SI 0 "register_operand" "")
15784                    (fix:SI (match_dup 3)))
15785               (clobber (reg:CC FLAGS_REG))])]
15786   "TARGET_USE_FANCY_MATH_387
15787    && flag_unsafe_math_optimizations"
15789   operands[2] = gen_reg_rtx (XFmode);
15790   operands[3] = gen_reg_rtx (XFmode);
15793 (define_insn "*f2xm1xf2"
15794   [(set (match_operand:XF 0 "register_operand" "=f")
15795         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15796          UNSPEC_F2XM1))]
15797   "TARGET_USE_FANCY_MATH_387
15798    && flag_unsafe_math_optimizations"
15799   "f2xm1"
15800   [(set_attr "type" "fpspc")
15801    (set_attr "mode" "XF")])
15803 (define_insn "*fscalexf4"
15804   [(set (match_operand:XF 0 "register_operand" "=f")
15805         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15806                     (match_operand:XF 3 "register_operand" "1")]
15807                    UNSPEC_FSCALE_FRACT))
15808    (set (match_operand:XF 1 "register_operand" "=u")
15809         (unspec:XF [(match_dup 2) (match_dup 3)]
15810                    UNSPEC_FSCALE_EXP))]
15811   "TARGET_USE_FANCY_MATH_387
15812    && flag_unsafe_math_optimizations"
15813   "fscale"
15814   [(set_attr "type" "fpspc")
15815    (set_attr "mode" "XF")])
15817 (define_expand "expsf2"
15818   [(set (match_dup 2)
15819         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15820    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15821    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15822    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15823    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15824    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15825    (parallel [(set (match_dup 10)
15826                    (unspec:XF [(match_dup 9) (match_dup 5)]
15827                               UNSPEC_FSCALE_FRACT))
15828               (set (match_dup 11)
15829                    (unspec:XF [(match_dup 9) (match_dup 5)]
15830                               UNSPEC_FSCALE_EXP))])
15831    (set (match_operand:SF 0 "register_operand" "")
15832         (float_truncate:SF (match_dup 10)))]
15833   "TARGET_USE_FANCY_MATH_387
15834    && flag_unsafe_math_optimizations"
15836   rtx temp;
15837   int i;
15839   for (i=2; i<12; i++)
15840     operands[i] = gen_reg_rtx (XFmode);
15841   temp = standard_80387_constant_rtx (5); /* fldl2e */
15842   emit_move_insn (operands[3], temp);
15843   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15846 (define_expand "expdf2"
15847   [(set (match_dup 2)
15848         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15849    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15850    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15851    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15852    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15853    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15854    (parallel [(set (match_dup 10)
15855                    (unspec:XF [(match_dup 9) (match_dup 5)]
15856                               UNSPEC_FSCALE_FRACT))
15857               (set (match_dup 11)
15858                    (unspec:XF [(match_dup 9) (match_dup 5)]
15859                               UNSPEC_FSCALE_EXP))])
15860    (set (match_operand:DF 0 "register_operand" "")
15861         (float_truncate:DF (match_dup 10)))]
15862   "TARGET_USE_FANCY_MATH_387
15863    && flag_unsafe_math_optimizations"
15865   rtx temp;
15866   int i;
15868   for (i=2; i<12; i++)
15869     operands[i] = gen_reg_rtx (XFmode);
15870   temp = standard_80387_constant_rtx (5); /* fldl2e */
15871   emit_move_insn (operands[3], temp);
15872   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15875 (define_expand "expxf2"
15876   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15877                                (match_dup 2)))
15878    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15879    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15880    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15881    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15882    (parallel [(set (match_operand:XF 0 "register_operand" "")
15883                    (unspec:XF [(match_dup 8) (match_dup 4)]
15884                               UNSPEC_FSCALE_FRACT))
15885               (set (match_dup 9)
15886                    (unspec:XF [(match_dup 8) (match_dup 4)]
15887                               UNSPEC_FSCALE_EXP))])]
15888   "TARGET_USE_FANCY_MATH_387
15889    && flag_unsafe_math_optimizations"
15891   rtx temp;
15892   int i;
15894   for (i=2; i<10; i++)
15895     operands[i] = gen_reg_rtx (XFmode);
15896   temp = standard_80387_constant_rtx (5); /* fldl2e */
15897   emit_move_insn (operands[2], temp);
15898   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15901 (define_expand "exp10sf2"
15902   [(set (match_dup 2)
15903         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15904    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15905    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15906    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15907    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15908    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15909    (parallel [(set (match_dup 10)
15910                    (unspec:XF [(match_dup 9) (match_dup 5)]
15911                               UNSPEC_FSCALE_FRACT))
15912               (set (match_dup 11)
15913                    (unspec:XF [(match_dup 9) (match_dup 5)]
15914                               UNSPEC_FSCALE_EXP))])
15915    (set (match_operand:SF 0 "register_operand" "")
15916         (float_truncate:SF (match_dup 10)))]
15917   "TARGET_USE_FANCY_MATH_387
15918    && flag_unsafe_math_optimizations"
15920   rtx temp;
15921   int i;
15923   for (i=2; i<12; i++)
15924     operands[i] = gen_reg_rtx (XFmode);
15925   temp = standard_80387_constant_rtx (6); /* fldl2t */
15926   emit_move_insn (operands[3], temp);
15927   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15930 (define_expand "exp10df2"
15931   [(set (match_dup 2)
15932         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15933    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15934    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15935    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15936    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15937    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15938    (parallel [(set (match_dup 10)
15939                    (unspec:XF [(match_dup 9) (match_dup 5)]
15940                               UNSPEC_FSCALE_FRACT))
15941               (set (match_dup 11)
15942                    (unspec:XF [(match_dup 9) (match_dup 5)]
15943                               UNSPEC_FSCALE_EXP))])
15944    (set (match_operand:DF 0 "register_operand" "")
15945         (float_truncate:DF (match_dup 10)))]
15946   "TARGET_USE_FANCY_MATH_387
15947    && flag_unsafe_math_optimizations"
15949   rtx temp;
15950   int i;
15952   for (i=2; i<12; i++)
15953     operands[i] = gen_reg_rtx (XFmode);
15954   temp = standard_80387_constant_rtx (6); /* fldl2t */
15955   emit_move_insn (operands[3], temp);
15956   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15959 (define_expand "exp10xf2"
15960   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15961                                (match_dup 2)))
15962    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15963    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15964    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15965    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15966    (parallel [(set (match_operand:XF 0 "register_operand" "")
15967                    (unspec:XF [(match_dup 8) (match_dup 4)]
15968                               UNSPEC_FSCALE_FRACT))
15969               (set (match_dup 9)
15970                    (unspec:XF [(match_dup 8) (match_dup 4)]
15971                               UNSPEC_FSCALE_EXP))])]
15972   "TARGET_USE_FANCY_MATH_387
15973    && flag_unsafe_math_optimizations"
15975   rtx temp;
15976   int i;
15978   for (i=2; i<10; i++)
15979     operands[i] = gen_reg_rtx (XFmode);
15980   temp = standard_80387_constant_rtx (6); /* fldl2t */
15981   emit_move_insn (operands[2], temp);
15982   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15985 (define_expand "exp2sf2"
15986   [(set (match_dup 2)
15987         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15988    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15989    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15990    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15991    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15992    (parallel [(set (match_dup 8)
15993                    (unspec:XF [(match_dup 7) (match_dup 3)]
15994                               UNSPEC_FSCALE_FRACT))
15995               (set (match_dup 9)
15996                    (unspec:XF [(match_dup 7) (match_dup 3)]
15997                               UNSPEC_FSCALE_EXP))])
15998    (set (match_operand:SF 0 "register_operand" "")
15999         (float_truncate:SF (match_dup 8)))]
16000   "TARGET_USE_FANCY_MATH_387
16001    && flag_unsafe_math_optimizations"
16003   int i;
16005   for (i=2; i<10; i++)
16006     operands[i] = gen_reg_rtx (XFmode);
16007   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16010 (define_expand "exp2df2"
16011   [(set (match_dup 2)
16012         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16013    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16014    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16015    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16016    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16017    (parallel [(set (match_dup 8)
16018                    (unspec:XF [(match_dup 7) (match_dup 3)]
16019                               UNSPEC_FSCALE_FRACT))
16020               (set (match_dup 9)
16021                    (unspec:XF [(match_dup 7) (match_dup 3)]
16022                               UNSPEC_FSCALE_EXP))])
16023    (set (match_operand:DF 0 "register_operand" "")
16024         (float_truncate:DF (match_dup 8)))]
16025   "TARGET_USE_FANCY_MATH_387
16026    && flag_unsafe_math_optimizations"
16028   int i;
16030   for (i=2; i<10; i++)
16031     operands[i] = gen_reg_rtx (XFmode);
16032   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16035 (define_expand "exp2xf2"
16036   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16037    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16038    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16039    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16040    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16041    (parallel [(set (match_operand:XF 0 "register_operand" "")
16042                    (unspec:XF [(match_dup 7) (match_dup 3)]
16043                               UNSPEC_FSCALE_FRACT))
16044               (set (match_dup 8)
16045                    (unspec:XF [(match_dup 7) (match_dup 3)]
16046                               UNSPEC_FSCALE_EXP))])]
16047   "TARGET_USE_FANCY_MATH_387
16048    && flag_unsafe_math_optimizations"
16050   int i;
16052   for (i=2; i<9; i++)
16053     operands[i] = gen_reg_rtx (XFmode);
16054   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16057 (define_expand "expm1df2"
16058   [(set (match_dup 2)
16059         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16060    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16061    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16062    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16063    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16064    (parallel [(set (match_dup 8)
16065                    (unspec:XF [(match_dup 7) (match_dup 5)]
16066                               UNSPEC_FSCALE_FRACT))
16067                    (set (match_dup 9)
16068                    (unspec:XF [(match_dup 7) (match_dup 5)]
16069                               UNSPEC_FSCALE_EXP))])
16070    (parallel [(set (match_dup 11)
16071                    (unspec:XF [(match_dup 10) (match_dup 9)]
16072                               UNSPEC_FSCALE_FRACT))
16073               (set (match_dup 12)
16074                    (unspec:XF [(match_dup 10) (match_dup 9)]
16075                               UNSPEC_FSCALE_EXP))])
16076    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16077    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16078    (set (match_operand:DF 0 "register_operand" "")
16079         (float_truncate:DF (match_dup 14)))]
16080   "TARGET_USE_FANCY_MATH_387
16081    && flag_unsafe_math_optimizations"
16083   rtx temp;
16084   int i;
16086   for (i=2; i<15; i++)
16087     operands[i] = gen_reg_rtx (XFmode);
16088   temp = standard_80387_constant_rtx (5); /* fldl2e */
16089   emit_move_insn (operands[3], temp);
16090   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16093 (define_expand "expm1sf2"
16094   [(set (match_dup 2)
16095         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16096    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16097    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16098    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16099    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16100    (parallel [(set (match_dup 8)
16101                    (unspec:XF [(match_dup 7) (match_dup 5)]
16102                               UNSPEC_FSCALE_FRACT))
16103                    (set (match_dup 9)
16104                    (unspec:XF [(match_dup 7) (match_dup 5)]
16105                               UNSPEC_FSCALE_EXP))])
16106    (parallel [(set (match_dup 11)
16107                    (unspec:XF [(match_dup 10) (match_dup 9)]
16108                               UNSPEC_FSCALE_FRACT))
16109               (set (match_dup 12)
16110                    (unspec:XF [(match_dup 10) (match_dup 9)]
16111                               UNSPEC_FSCALE_EXP))])
16112    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16113    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16114    (set (match_operand:SF 0 "register_operand" "")
16115         (float_truncate:SF (match_dup 14)))]
16116   "TARGET_USE_FANCY_MATH_387
16117    && flag_unsafe_math_optimizations"
16119   rtx temp;
16120   int i;
16122   for (i=2; i<15; i++)
16123     operands[i] = gen_reg_rtx (XFmode);
16124   temp = standard_80387_constant_rtx (5); /* fldl2e */
16125   emit_move_insn (operands[3], temp);
16126   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16129 (define_expand "expm1xf2"
16130   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16131                                (match_dup 2)))
16132    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16133    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16134    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16135    (parallel [(set (match_dup 7)
16136                    (unspec:XF [(match_dup 6) (match_dup 4)]
16137                               UNSPEC_FSCALE_FRACT))
16138                    (set (match_dup 8)
16139                    (unspec:XF [(match_dup 6) (match_dup 4)]
16140                               UNSPEC_FSCALE_EXP))])
16141    (parallel [(set (match_dup 10)
16142                    (unspec:XF [(match_dup 9) (match_dup 8)]
16143                               UNSPEC_FSCALE_FRACT))
16144               (set (match_dup 11)
16145                    (unspec:XF [(match_dup 9) (match_dup 8)]
16146                               UNSPEC_FSCALE_EXP))])
16147    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16148    (set (match_operand:XF 0 "register_operand" "")
16149         (plus:XF (match_dup 12) (match_dup 7)))]
16150   "TARGET_USE_FANCY_MATH_387
16151    && flag_unsafe_math_optimizations"
16153   rtx temp;
16154   int i;
16156   for (i=2; i<13; i++)
16157     operands[i] = gen_reg_rtx (XFmode);
16158   temp = standard_80387_constant_rtx (5); /* fldl2e */
16159   emit_move_insn (operands[2], temp);
16160   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16164 (define_insn "frndintxf2"
16165   [(set (match_operand:XF 0 "register_operand" "=f")
16166         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16167          UNSPEC_FRNDINT))]
16168   "TARGET_USE_FANCY_MATH_387
16169    && flag_unsafe_math_optimizations"
16170   "frndint"
16171   [(set_attr "type" "fpspc")
16172    (set_attr "mode" "XF")])
16174 (define_expand "rintdf2"
16175   [(use (match_operand:DF 0 "register_operand" ""))
16176    (use (match_operand:DF 1 "register_operand" ""))]
16177   "TARGET_USE_FANCY_MATH_387
16178    && flag_unsafe_math_optimizations"
16180   rtx op0 = gen_reg_rtx (XFmode);
16181   rtx op1 = gen_reg_rtx (XFmode);
16183   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16184   emit_insn (gen_frndintxf2 (op0, op1));
16186   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16187   DONE;
16190 (define_expand "rintsf2"
16191   [(use (match_operand:SF 0 "register_operand" ""))
16192    (use (match_operand:SF 1 "register_operand" ""))]
16193   "TARGET_USE_FANCY_MATH_387
16194    && flag_unsafe_math_optimizations"
16196   rtx op0 = gen_reg_rtx (XFmode);
16197   rtx op1 = gen_reg_rtx (XFmode);
16199   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16200   emit_insn (gen_frndintxf2 (op0, op1));
16202   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16203   DONE;
16206 (define_expand "rintxf2"
16207   [(use (match_operand:XF 0 "register_operand" ""))
16208    (use (match_operand:XF 1 "register_operand" ""))]
16209   "TARGET_USE_FANCY_MATH_387
16210    && flag_unsafe_math_optimizations"
16212   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16213   DONE;
16216 (define_insn "frndintxf2_floor"
16217   [(set (match_operand:XF 0 "register_operand" "=f")
16218         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16219          UNSPEC_FRNDINT_FLOOR))
16220    (use (match_operand:HI 2 "memory_operand" "m"))
16221    (use (match_operand:HI 3 "memory_operand" "m"))]
16222   "TARGET_USE_FANCY_MATH_387
16223    && flag_unsafe_math_optimizations"
16224   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16225   [(set_attr "type" "frndint")
16226    (set_attr "i387_cw" "floor")
16227    (set_attr "mode" "XF")])
16229 (define_expand "floordf2"
16230   [(use (match_operand:DF 0 "register_operand" ""))
16231    (use (match_operand:DF 1 "register_operand" ""))]
16232   "TARGET_USE_FANCY_MATH_387
16233    && flag_unsafe_math_optimizations"
16235   rtx op0 = gen_reg_rtx (XFmode);
16236   rtx op1 = gen_reg_rtx (XFmode);
16237   rtx op2 = assign_386_stack_local (HImode, 1);
16238   rtx op3 = assign_386_stack_local (HImode, 2);
16239         
16240   ix86_optimize_mode_switching = 1;
16242   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16243   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16245   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16246   DONE;
16249 (define_expand "floorsf2"
16250   [(use (match_operand:SF 0 "register_operand" ""))
16251    (use (match_operand:SF 1 "register_operand" ""))]
16252   "TARGET_USE_FANCY_MATH_387
16253    && flag_unsafe_math_optimizations"
16255   rtx op0 = gen_reg_rtx (XFmode);
16256   rtx op1 = gen_reg_rtx (XFmode);
16257   rtx op2 = assign_386_stack_local (HImode, 1);
16258   rtx op3 = assign_386_stack_local (HImode, 2);
16259         
16260   ix86_optimize_mode_switching = 1;
16262   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16263   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16265   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16266   DONE;
16269 (define_expand "floorxf2"
16270   [(use (match_operand:XF 0 "register_operand" ""))
16271    (use (match_operand:XF 1 "register_operand" ""))]
16272   "TARGET_USE_FANCY_MATH_387
16273    && flag_unsafe_math_optimizations"
16275   rtx op2 = assign_386_stack_local (HImode, 1);
16276   rtx op3 = assign_386_stack_local (HImode, 2);
16277         
16278   ix86_optimize_mode_switching = 1;
16280   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16281   DONE;
16284 (define_insn "frndintxf2_ceil"
16285   [(set (match_operand:XF 0 "register_operand" "=f")
16286         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16287          UNSPEC_FRNDINT_CEIL))
16288    (use (match_operand:HI 2 "memory_operand" "m"))
16289    (use (match_operand:HI 3 "memory_operand" "m"))]
16290   "TARGET_USE_FANCY_MATH_387
16291    && flag_unsafe_math_optimizations"
16292   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16293   [(set_attr "type" "frndint")
16294    (set_attr "i387_cw" "ceil")
16295    (set_attr "mode" "XF")])
16297 (define_expand "ceildf2"
16298   [(use (match_operand:DF 0 "register_operand" ""))
16299    (use (match_operand:DF 1 "register_operand" ""))]
16300   "TARGET_USE_FANCY_MATH_387
16301    && flag_unsafe_math_optimizations"
16303   rtx op0 = gen_reg_rtx (XFmode);
16304   rtx op1 = gen_reg_rtx (XFmode);
16305   rtx op2 = assign_386_stack_local (HImode, 1);
16306   rtx op3 = assign_386_stack_local (HImode, 2);
16307         
16308   ix86_optimize_mode_switching = 1;
16310   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16311   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16313   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16314   DONE;
16317 (define_expand "ceilsf2"
16318   [(use (match_operand:SF 0 "register_operand" ""))
16319    (use (match_operand:SF 1 "register_operand" ""))]
16320   "TARGET_USE_FANCY_MATH_387
16321    && flag_unsafe_math_optimizations"
16323   rtx op0 = gen_reg_rtx (XFmode);
16324   rtx op1 = gen_reg_rtx (XFmode);
16325   rtx op2 = assign_386_stack_local (HImode, 1);
16326   rtx op3 = assign_386_stack_local (HImode, 2);
16327         
16328   ix86_optimize_mode_switching = 1;
16330   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16331   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16333   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16334   DONE;
16337 (define_expand "ceilxf2"
16338   [(use (match_operand:XF 0 "register_operand" ""))
16339    (use (match_operand:XF 1 "register_operand" ""))]
16340   "TARGET_USE_FANCY_MATH_387
16341    && flag_unsafe_math_optimizations"
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_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16349   DONE;
16352 (define_insn "frndintxf2_trunc"
16353   [(set (match_operand:XF 0 "register_operand" "=f")
16354         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16355          UNSPEC_FRNDINT_TRUNC))
16356    (use (match_operand:HI 2 "memory_operand" "m"))
16357    (use (match_operand:HI 3 "memory_operand" "m"))]
16358   "TARGET_USE_FANCY_MATH_387
16359    && flag_unsafe_math_optimizations"
16360   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16361   [(set_attr "type" "frndint")
16362    (set_attr "i387_cw" "trunc")
16363    (set_attr "mode" "XF")])
16365 (define_expand "btruncdf2"
16366   [(use (match_operand:DF 0 "register_operand" ""))
16367    (use (match_operand:DF 1 "register_operand" ""))]
16368   "TARGET_USE_FANCY_MATH_387
16369    && flag_unsafe_math_optimizations"
16371   rtx op0 = gen_reg_rtx (XFmode);
16372   rtx op1 = gen_reg_rtx (XFmode);
16373   rtx op2 = assign_386_stack_local (HImode, 1);
16374   rtx op3 = assign_386_stack_local (HImode, 2);
16375         
16376   ix86_optimize_mode_switching = 1;
16378   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16379   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16381   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16382   DONE;
16385 (define_expand "btruncsf2"
16386   [(use (match_operand:SF 0 "register_operand" ""))
16387    (use (match_operand:SF 1 "register_operand" ""))]
16388   "TARGET_USE_FANCY_MATH_387
16389    && flag_unsafe_math_optimizations"
16391   rtx op0 = gen_reg_rtx (XFmode);
16392   rtx op1 = gen_reg_rtx (XFmode);
16393   rtx op2 = assign_386_stack_local (HImode, 1);
16394   rtx op3 = assign_386_stack_local (HImode, 2);
16395         
16396   ix86_optimize_mode_switching = 1;
16398   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16399   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16401   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16402   DONE;
16405 (define_expand "btruncxf2"
16406   [(use (match_operand:XF 0 "register_operand" ""))
16407    (use (match_operand:XF 1 "register_operand" ""))]
16408   "TARGET_USE_FANCY_MATH_387
16409    && flag_unsafe_math_optimizations"
16411   rtx op2 = assign_386_stack_local (HImode, 1);
16412   rtx op3 = assign_386_stack_local (HImode, 2);
16413         
16414   ix86_optimize_mode_switching = 1;
16416   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16417   DONE;
16420 (define_insn "frndintxf2_mask_pm"
16421   [(set (match_operand:XF 0 "register_operand" "=f")
16422         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16423          UNSPEC_FRNDINT_MASK_PM))
16424    (use (match_operand:HI 2 "memory_operand" "m"))
16425    (use (match_operand:HI 3 "memory_operand" "m"))]
16426   "TARGET_USE_FANCY_MATH_387
16427    && flag_unsafe_math_optimizations"
16428   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16429   [(set_attr "type" "frndint")
16430    (set_attr "i387_cw" "mask_pm")
16431    (set_attr "mode" "XF")])
16433 (define_expand "nearbyintdf2"
16434   [(use (match_operand:DF 0 "register_operand" ""))
16435    (use (match_operand:DF 1 "register_operand" ""))]
16436   "TARGET_USE_FANCY_MATH_387
16437    && flag_unsafe_math_optimizations"
16439   rtx op0 = gen_reg_rtx (XFmode);
16440   rtx op1 = gen_reg_rtx (XFmode);
16441   rtx op2 = assign_386_stack_local (HImode, 1);
16442   rtx op3 = assign_386_stack_local (HImode, 2);
16443         
16444   ix86_optimize_mode_switching = 1;
16446   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16447   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16449   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16450   DONE;
16453 (define_expand "nearbyintsf2"
16454   [(use (match_operand:SF 0 "register_operand" ""))
16455    (use (match_operand:SF 1 "register_operand" ""))]
16456   "TARGET_USE_FANCY_MATH_387
16457    && flag_unsafe_math_optimizations"
16459   rtx op0 = gen_reg_rtx (XFmode);
16460   rtx op1 = gen_reg_rtx (XFmode);
16461   rtx op2 = assign_386_stack_local (HImode, 1);
16462   rtx op3 = assign_386_stack_local (HImode, 2);
16463         
16464   ix86_optimize_mode_switching = 1;
16466   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16467   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16469   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16470   DONE;
16473 (define_expand "nearbyintxf2"
16474   [(use (match_operand:XF 0 "register_operand" ""))
16475    (use (match_operand:XF 1 "register_operand" ""))]
16476   "TARGET_USE_FANCY_MATH_387
16477    && flag_unsafe_math_optimizations"
16479   rtx op2 = assign_386_stack_local (HImode, 1);
16480   rtx op3 = assign_386_stack_local (HImode, 2);
16481         
16482   ix86_optimize_mode_switching = 1;
16484   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16485                                      op2, op3));
16486   DONE;
16490 ;; Block operation instructions
16492 (define_insn "cld"
16493  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16494  ""
16495  "cld"
16496   [(set_attr "type" "cld")])
16498 (define_expand "movmemsi"
16499   [(use (match_operand:BLK 0 "memory_operand" ""))
16500    (use (match_operand:BLK 1 "memory_operand" ""))
16501    (use (match_operand:SI 2 "nonmemory_operand" ""))
16502    (use (match_operand:SI 3 "const_int_operand" ""))]
16503   "! optimize_size"
16505  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16506    DONE;
16507  else
16508    FAIL;
16511 (define_expand "movmemdi"
16512   [(use (match_operand:BLK 0 "memory_operand" ""))
16513    (use (match_operand:BLK 1 "memory_operand" ""))
16514    (use (match_operand:DI 2 "nonmemory_operand" ""))
16515    (use (match_operand:DI 3 "const_int_operand" ""))]
16516   "TARGET_64BIT"
16518  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16519    DONE;
16520  else
16521    FAIL;
16524 ;; Most CPUs don't like single string operations
16525 ;; Handle this case here to simplify previous expander.
16527 (define_expand "strmov"
16528   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16529    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16530    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16531               (clobber (reg:CC FLAGS_REG))])
16532    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16533               (clobber (reg:CC FLAGS_REG))])]
16534   ""
16536   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16538   /* If .md ever supports :P for Pmode, these can be directly
16539      in the pattern above.  */
16540   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16541   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16543   if (TARGET_SINGLE_STRINGOP || optimize_size)
16544     {
16545       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16546                                       operands[2], operands[3],
16547                                       operands[5], operands[6]));
16548       DONE;
16549     }
16551   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16554 (define_expand "strmov_singleop"
16555   [(parallel [(set (match_operand 1 "memory_operand" "")
16556                    (match_operand 3 "memory_operand" ""))
16557               (set (match_operand 0 "register_operand" "")
16558                    (match_operand 4 "" ""))
16559               (set (match_operand 2 "register_operand" "")
16560                    (match_operand 5 "" ""))
16561               (use (reg:SI DIRFLAG_REG))])]
16562   "TARGET_SINGLE_STRINGOP || optimize_size"
16563   "")
16565 (define_insn "*strmovdi_rex_1"
16566   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16567         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16568    (set (match_operand:DI 0 "register_operand" "=D")
16569         (plus:DI (match_dup 2)
16570                  (const_int 8)))
16571    (set (match_operand:DI 1 "register_operand" "=S")
16572         (plus:DI (match_dup 3)
16573                  (const_int 8)))
16574    (use (reg:SI DIRFLAG_REG))]
16575   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16576   "movsq"
16577   [(set_attr "type" "str")
16578    (set_attr "mode" "DI")
16579    (set_attr "memory" "both")])
16581 (define_insn "*strmovsi_1"
16582   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16583         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16584    (set (match_operand:SI 0 "register_operand" "=D")
16585         (plus:SI (match_dup 2)
16586                  (const_int 4)))
16587    (set (match_operand:SI 1 "register_operand" "=S")
16588         (plus:SI (match_dup 3)
16589                  (const_int 4)))
16590    (use (reg:SI DIRFLAG_REG))]
16591   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16592   "{movsl|movsd}"
16593   [(set_attr "type" "str")
16594    (set_attr "mode" "SI")
16595    (set_attr "memory" "both")])
16597 (define_insn "*strmovsi_rex_1"
16598   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16599         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16600    (set (match_operand:DI 0 "register_operand" "=D")
16601         (plus:DI (match_dup 2)
16602                  (const_int 4)))
16603    (set (match_operand:DI 1 "register_operand" "=S")
16604         (plus:DI (match_dup 3)
16605                  (const_int 4)))
16606    (use (reg:SI DIRFLAG_REG))]
16607   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16608   "{movsl|movsd}"
16609   [(set_attr "type" "str")
16610    (set_attr "mode" "SI")
16611    (set_attr "memory" "both")])
16613 (define_insn "*strmovhi_1"
16614   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16615         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16616    (set (match_operand:SI 0 "register_operand" "=D")
16617         (plus:SI (match_dup 2)
16618                  (const_int 2)))
16619    (set (match_operand:SI 1 "register_operand" "=S")
16620         (plus:SI (match_dup 3)
16621                  (const_int 2)))
16622    (use (reg:SI DIRFLAG_REG))]
16623   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16624   "movsw"
16625   [(set_attr "type" "str")
16626    (set_attr "memory" "both")
16627    (set_attr "mode" "HI")])
16629 (define_insn "*strmovhi_rex_1"
16630   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16631         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16632    (set (match_operand:DI 0 "register_operand" "=D")
16633         (plus:DI (match_dup 2)
16634                  (const_int 2)))
16635    (set (match_operand:DI 1 "register_operand" "=S")
16636         (plus:DI (match_dup 3)
16637                  (const_int 2)))
16638    (use (reg:SI DIRFLAG_REG))]
16639   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16640   "movsw"
16641   [(set_attr "type" "str")
16642    (set_attr "memory" "both")
16643    (set_attr "mode" "HI")])
16645 (define_insn "*strmovqi_1"
16646   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16647         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16648    (set (match_operand:SI 0 "register_operand" "=D")
16649         (plus:SI (match_dup 2)
16650                  (const_int 1)))
16651    (set (match_operand:SI 1 "register_operand" "=S")
16652         (plus:SI (match_dup 3)
16653                  (const_int 1)))
16654    (use (reg:SI DIRFLAG_REG))]
16655   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16656   "movsb"
16657   [(set_attr "type" "str")
16658    (set_attr "memory" "both")
16659    (set_attr "mode" "QI")])
16661 (define_insn "*strmovqi_rex_1"
16662   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16663         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16664    (set (match_operand:DI 0 "register_operand" "=D")
16665         (plus:DI (match_dup 2)
16666                  (const_int 1)))
16667    (set (match_operand:DI 1 "register_operand" "=S")
16668         (plus:DI (match_dup 3)
16669                  (const_int 1)))
16670    (use (reg:SI DIRFLAG_REG))]
16671   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16672   "movsb"
16673   [(set_attr "type" "str")
16674    (set_attr "memory" "both")
16675    (set_attr "mode" "QI")])
16677 (define_expand "rep_mov"
16678   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16679               (set (match_operand 0 "register_operand" "")
16680                    (match_operand 5 "" ""))
16681               (set (match_operand 2 "register_operand" "")
16682                    (match_operand 6 "" ""))
16683               (set (match_operand 1 "memory_operand" "")
16684                    (match_operand 3 "memory_operand" ""))
16685               (use (match_dup 4))
16686               (use (reg:SI DIRFLAG_REG))])]
16687   ""
16688   "")
16690 (define_insn "*rep_movdi_rex64"
16691   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16692    (set (match_operand:DI 0 "register_operand" "=D") 
16693         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16694                             (const_int 3))
16695                  (match_operand:DI 3 "register_operand" "0")))
16696    (set (match_operand:DI 1 "register_operand" "=S") 
16697         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16698                  (match_operand:DI 4 "register_operand" "1")))
16699    (set (mem:BLK (match_dup 3))
16700         (mem:BLK (match_dup 4)))
16701    (use (match_dup 5))
16702    (use (reg:SI DIRFLAG_REG))]
16703   "TARGET_64BIT"
16704   "{rep\;movsq|rep movsq}"
16705   [(set_attr "type" "str")
16706    (set_attr "prefix_rep" "1")
16707    (set_attr "memory" "both")
16708    (set_attr "mode" "DI")])
16710 (define_insn "*rep_movsi"
16711   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16712    (set (match_operand:SI 0 "register_operand" "=D") 
16713         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16714                             (const_int 2))
16715                  (match_operand:SI 3 "register_operand" "0")))
16716    (set (match_operand:SI 1 "register_operand" "=S") 
16717         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16718                  (match_operand:SI 4 "register_operand" "1")))
16719    (set (mem:BLK (match_dup 3))
16720         (mem:BLK (match_dup 4)))
16721    (use (match_dup 5))
16722    (use (reg:SI DIRFLAG_REG))]
16723   "!TARGET_64BIT"
16724   "{rep\;movsl|rep movsd}"
16725   [(set_attr "type" "str")
16726    (set_attr "prefix_rep" "1")
16727    (set_attr "memory" "both")
16728    (set_attr "mode" "SI")])
16730 (define_insn "*rep_movsi_rex64"
16731   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16732    (set (match_operand:DI 0 "register_operand" "=D") 
16733         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16734                             (const_int 2))
16735                  (match_operand:DI 3 "register_operand" "0")))
16736    (set (match_operand:DI 1 "register_operand" "=S") 
16737         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16738                  (match_operand:DI 4 "register_operand" "1")))
16739    (set (mem:BLK (match_dup 3))
16740         (mem:BLK (match_dup 4)))
16741    (use (match_dup 5))
16742    (use (reg:SI DIRFLAG_REG))]
16743   "TARGET_64BIT"
16744   "{rep\;movsl|rep movsd}"
16745   [(set_attr "type" "str")
16746    (set_attr "prefix_rep" "1")
16747    (set_attr "memory" "both")
16748    (set_attr "mode" "SI")])
16750 (define_insn "*rep_movqi"
16751   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16752    (set (match_operand:SI 0 "register_operand" "=D") 
16753         (plus:SI (match_operand:SI 3 "register_operand" "0")
16754                  (match_operand:SI 5 "register_operand" "2")))
16755    (set (match_operand:SI 1 "register_operand" "=S") 
16756         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16757    (set (mem:BLK (match_dup 3))
16758         (mem:BLK (match_dup 4)))
16759    (use (match_dup 5))
16760    (use (reg:SI DIRFLAG_REG))]
16761   "!TARGET_64BIT"
16762   "{rep\;movsb|rep movsb}"
16763   [(set_attr "type" "str")
16764    (set_attr "prefix_rep" "1")
16765    (set_attr "memory" "both")
16766    (set_attr "mode" "SI")])
16768 (define_insn "*rep_movqi_rex64"
16769   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16770    (set (match_operand:DI 0 "register_operand" "=D") 
16771         (plus:DI (match_operand:DI 3 "register_operand" "0")
16772                  (match_operand:DI 5 "register_operand" "2")))
16773    (set (match_operand:DI 1 "register_operand" "=S") 
16774         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16775    (set (mem:BLK (match_dup 3))
16776         (mem:BLK (match_dup 4)))
16777    (use (match_dup 5))
16778    (use (reg:SI DIRFLAG_REG))]
16779   "TARGET_64BIT"
16780   "{rep\;movsb|rep movsb}"
16781   [(set_attr "type" "str")
16782    (set_attr "prefix_rep" "1")
16783    (set_attr "memory" "both")
16784    (set_attr "mode" "SI")])
16786 (define_expand "clrmemsi"
16787    [(use (match_operand:BLK 0 "memory_operand" ""))
16788     (use (match_operand:SI 1 "nonmemory_operand" ""))
16789     (use (match_operand 2 "const_int_operand" ""))]
16790   ""
16792  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16793    DONE;
16794  else
16795    FAIL;
16798 (define_expand "clrmemdi"
16799    [(use (match_operand:BLK 0 "memory_operand" ""))
16800     (use (match_operand:DI 1 "nonmemory_operand" ""))
16801     (use (match_operand 2 "const_int_operand" ""))]
16802   "TARGET_64BIT"
16804  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16805    DONE;
16806  else
16807    FAIL;
16810 ;; Most CPUs don't like single string operations
16811 ;; Handle this case here to simplify previous expander.
16813 (define_expand "strset"
16814   [(set (match_operand 1 "memory_operand" "")
16815         (match_operand 2 "register_operand" ""))
16816    (parallel [(set (match_operand 0 "register_operand" "")
16817                    (match_dup 3))
16818               (clobber (reg:CC FLAGS_REG))])]
16819   ""
16821   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16822     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16824   /* If .md ever supports :P for Pmode, this can be directly
16825      in the pattern above.  */
16826   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16827                               GEN_INT (GET_MODE_SIZE (GET_MODE
16828                                                       (operands[2]))));
16829   if (TARGET_SINGLE_STRINGOP || optimize_size)
16830     {
16831       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16832                                       operands[3]));
16833       DONE;
16834     }
16837 (define_expand "strset_singleop"
16838   [(parallel [(set (match_operand 1 "memory_operand" "")
16839                    (match_operand 2 "register_operand" ""))
16840               (set (match_operand 0 "register_operand" "")
16841                    (match_operand 3 "" ""))
16842               (use (reg:SI DIRFLAG_REG))])]
16843   "TARGET_SINGLE_STRINGOP || optimize_size"
16844   "")
16846 (define_insn "*strsetdi_rex_1"
16847   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16848         (match_operand:DI 2 "register_operand" "a"))
16849    (set (match_operand:DI 0 "register_operand" "=D")
16850         (plus:DI (match_dup 1)
16851                  (const_int 8)))
16852    (use (reg:SI DIRFLAG_REG))]
16853   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16854   "stosq"
16855   [(set_attr "type" "str")
16856    (set_attr "memory" "store")
16857    (set_attr "mode" "DI")])
16859 (define_insn "*strsetsi_1"
16860   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16861         (match_operand:SI 2 "register_operand" "a"))
16862    (set (match_operand:SI 0 "register_operand" "=D")
16863         (plus:SI (match_dup 1)
16864                  (const_int 4)))
16865    (use (reg:SI DIRFLAG_REG))]
16866   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16867   "{stosl|stosd}"
16868   [(set_attr "type" "str")
16869    (set_attr "memory" "store")
16870    (set_attr "mode" "SI")])
16872 (define_insn "*strsetsi_rex_1"
16873   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16874         (match_operand:SI 2 "register_operand" "a"))
16875    (set (match_operand:DI 0 "register_operand" "=D")
16876         (plus:DI (match_dup 1)
16877                  (const_int 4)))
16878    (use (reg:SI DIRFLAG_REG))]
16879   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16880   "{stosl|stosd}"
16881   [(set_attr "type" "str")
16882    (set_attr "memory" "store")
16883    (set_attr "mode" "SI")])
16885 (define_insn "*strsethi_1"
16886   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16887         (match_operand:HI 2 "register_operand" "a"))
16888    (set (match_operand:SI 0 "register_operand" "=D")
16889         (plus:SI (match_dup 1)
16890                  (const_int 2)))
16891    (use (reg:SI DIRFLAG_REG))]
16892   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16893   "stosw"
16894   [(set_attr "type" "str")
16895    (set_attr "memory" "store")
16896    (set_attr "mode" "HI")])
16898 (define_insn "*strsethi_rex_1"
16899   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16900         (match_operand:HI 2 "register_operand" "a"))
16901    (set (match_operand:DI 0 "register_operand" "=D")
16902         (plus:DI (match_dup 1)
16903                  (const_int 2)))
16904    (use (reg:SI DIRFLAG_REG))]
16905   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16906   "stosw"
16907   [(set_attr "type" "str")
16908    (set_attr "memory" "store")
16909    (set_attr "mode" "HI")])
16911 (define_insn "*strsetqi_1"
16912   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16913         (match_operand:QI 2 "register_operand" "a"))
16914    (set (match_operand:SI 0 "register_operand" "=D")
16915         (plus:SI (match_dup 1)
16916                  (const_int 1)))
16917    (use (reg:SI DIRFLAG_REG))]
16918   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16919   "stosb"
16920   [(set_attr "type" "str")
16921    (set_attr "memory" "store")
16922    (set_attr "mode" "QI")])
16924 (define_insn "*strsetqi_rex_1"
16925   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16926         (match_operand:QI 2 "register_operand" "a"))
16927    (set (match_operand:DI 0 "register_operand" "=D")
16928         (plus:DI (match_dup 1)
16929                  (const_int 1)))
16930    (use (reg:SI DIRFLAG_REG))]
16931   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16932   "stosb"
16933   [(set_attr "type" "str")
16934    (set_attr "memory" "store")
16935    (set_attr "mode" "QI")])
16937 (define_expand "rep_stos"
16938   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16939               (set (match_operand 0 "register_operand" "")
16940                    (match_operand 4 "" ""))
16941               (set (match_operand 2 "memory_operand" "") (const_int 0))
16942               (use (match_operand 3 "register_operand" ""))
16943               (use (match_dup 1))
16944               (use (reg:SI DIRFLAG_REG))])]
16945   ""
16946   "")
16948 (define_insn "*rep_stosdi_rex64"
16949   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16950    (set (match_operand:DI 0 "register_operand" "=D") 
16951         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16952                             (const_int 3))
16953                  (match_operand:DI 3 "register_operand" "0")))
16954    (set (mem:BLK (match_dup 3))
16955         (const_int 0))
16956    (use (match_operand:DI 2 "register_operand" "a"))
16957    (use (match_dup 4))
16958    (use (reg:SI DIRFLAG_REG))]
16959   "TARGET_64BIT"
16960   "{rep\;stosq|rep stosq}"
16961   [(set_attr "type" "str")
16962    (set_attr "prefix_rep" "1")
16963    (set_attr "memory" "store")
16964    (set_attr "mode" "DI")])
16966 (define_insn "*rep_stossi"
16967   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16968    (set (match_operand:SI 0 "register_operand" "=D") 
16969         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16970                             (const_int 2))
16971                  (match_operand:SI 3 "register_operand" "0")))
16972    (set (mem:BLK (match_dup 3))
16973         (const_int 0))
16974    (use (match_operand:SI 2 "register_operand" "a"))
16975    (use (match_dup 4))
16976    (use (reg:SI DIRFLAG_REG))]
16977   "!TARGET_64BIT"
16978   "{rep\;stosl|rep stosd}"
16979   [(set_attr "type" "str")
16980    (set_attr "prefix_rep" "1")
16981    (set_attr "memory" "store")
16982    (set_attr "mode" "SI")])
16984 (define_insn "*rep_stossi_rex64"
16985   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16986    (set (match_operand:DI 0 "register_operand" "=D") 
16987         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16988                             (const_int 2))
16989                  (match_operand:DI 3 "register_operand" "0")))
16990    (set (mem:BLK (match_dup 3))
16991         (const_int 0))
16992    (use (match_operand:SI 2 "register_operand" "a"))
16993    (use (match_dup 4))
16994    (use (reg:SI DIRFLAG_REG))]
16995   "TARGET_64BIT"
16996   "{rep\;stosl|rep stosd}"
16997   [(set_attr "type" "str")
16998    (set_attr "prefix_rep" "1")
16999    (set_attr "memory" "store")
17000    (set_attr "mode" "SI")])
17002 (define_insn "*rep_stosqi"
17003   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17004    (set (match_operand:SI 0 "register_operand" "=D") 
17005         (plus:SI (match_operand:SI 3 "register_operand" "0")
17006                  (match_operand:SI 4 "register_operand" "1")))
17007    (set (mem:BLK (match_dup 3))
17008         (const_int 0))
17009    (use (match_operand:QI 2 "register_operand" "a"))
17010    (use (match_dup 4))
17011    (use (reg:SI DIRFLAG_REG))]
17012   "!TARGET_64BIT"
17013   "{rep\;stosb|rep stosb}"
17014   [(set_attr "type" "str")
17015    (set_attr "prefix_rep" "1")
17016    (set_attr "memory" "store")
17017    (set_attr "mode" "QI")])
17019 (define_insn "*rep_stosqi_rex64"
17020   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17021    (set (match_operand:DI 0 "register_operand" "=D") 
17022         (plus:DI (match_operand:DI 3 "register_operand" "0")
17023                  (match_operand:DI 4 "register_operand" "1")))
17024    (set (mem:BLK (match_dup 3))
17025         (const_int 0))
17026    (use (match_operand:QI 2 "register_operand" "a"))
17027    (use (match_dup 4))
17028    (use (reg:SI DIRFLAG_REG))]
17029   "TARGET_64BIT"
17030   "{rep\;stosb|rep stosb}"
17031   [(set_attr "type" "str")
17032    (set_attr "prefix_rep" "1")
17033    (set_attr "memory" "store")
17034    (set_attr "mode" "QI")])
17036 (define_expand "cmpstrsi"
17037   [(set (match_operand:SI 0 "register_operand" "")
17038         (compare:SI (match_operand:BLK 1 "general_operand" "")
17039                     (match_operand:BLK 2 "general_operand" "")))
17040    (use (match_operand 3 "general_operand" ""))
17041    (use (match_operand 4 "immediate_operand" ""))]
17042   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17044   rtx addr1, addr2, out, outlow, count, countreg, align;
17046   /* Can't use this if the user has appropriated esi or edi.  */
17047   if (global_regs[4] || global_regs[5])
17048     FAIL;
17050   out = operands[0];
17051   if (GET_CODE (out) != REG)
17052     out = gen_reg_rtx (SImode);
17054   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17055   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17056   if (addr1 != XEXP (operands[1], 0))
17057     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17058   if (addr2 != XEXP (operands[2], 0))
17059     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17061   count = operands[3];
17062   countreg = ix86_zero_extend_to_Pmode (count);
17064   /* %%% Iff we are testing strict equality, we can use known alignment
17065      to good advantage.  This may be possible with combine, particularly
17066      once cc0 is dead.  */
17067   align = operands[4];
17069   emit_insn (gen_cld ());
17070   if (GET_CODE (count) == CONST_INT)
17071     {
17072       if (INTVAL (count) == 0)
17073         {
17074           emit_move_insn (operands[0], const0_rtx);
17075           DONE;
17076         }
17077       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17078                                     operands[1], operands[2]));
17079     }
17080   else
17081     {
17082       if (TARGET_64BIT)
17083         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17084       else
17085         emit_insn (gen_cmpsi_1 (countreg, countreg));
17086       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17087                                  operands[1], operands[2]));
17088     }
17090   outlow = gen_lowpart (QImode, out);
17091   emit_insn (gen_cmpintqi (outlow));
17092   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17094   if (operands[0] != out)
17095     emit_move_insn (operands[0], out);
17097   DONE;
17100 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17102 (define_expand "cmpintqi"
17103   [(set (match_dup 1)
17104         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17105    (set (match_dup 2)
17106         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17107    (parallel [(set (match_operand:QI 0 "register_operand" "")
17108                    (minus:QI (match_dup 1)
17109                              (match_dup 2)))
17110               (clobber (reg:CC FLAGS_REG))])]
17111   ""
17112   "operands[1] = gen_reg_rtx (QImode);
17113    operands[2] = gen_reg_rtx (QImode);")
17115 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17116 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17118 (define_expand "cmpstrqi_nz_1"
17119   [(parallel [(set (reg:CC FLAGS_REG)
17120                    (compare:CC (match_operand 4 "memory_operand" "")
17121                                (match_operand 5 "memory_operand" "")))
17122               (use (match_operand 2 "register_operand" ""))
17123               (use (match_operand:SI 3 "immediate_operand" ""))
17124               (use (reg:SI DIRFLAG_REG))
17125               (clobber (match_operand 0 "register_operand" ""))
17126               (clobber (match_operand 1 "register_operand" ""))
17127               (clobber (match_dup 2))])]
17128   ""
17129   "")
17131 (define_insn "*cmpstrqi_nz_1"
17132   [(set (reg:CC FLAGS_REG)
17133         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17134                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17135    (use (match_operand:SI 6 "register_operand" "2"))
17136    (use (match_operand:SI 3 "immediate_operand" "i"))
17137    (use (reg:SI DIRFLAG_REG))
17138    (clobber (match_operand:SI 0 "register_operand" "=S"))
17139    (clobber (match_operand:SI 1 "register_operand" "=D"))
17140    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17141   "!TARGET_64BIT"
17142   "repz{\;| }cmpsb"
17143   [(set_attr "type" "str")
17144    (set_attr "mode" "QI")
17145    (set_attr "prefix_rep" "1")])
17147 (define_insn "*cmpstrqi_nz_rex_1"
17148   [(set (reg:CC FLAGS_REG)
17149         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17150                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17151    (use (match_operand:DI 6 "register_operand" "2"))
17152    (use (match_operand:SI 3 "immediate_operand" "i"))
17153    (use (reg:SI DIRFLAG_REG))
17154    (clobber (match_operand:DI 0 "register_operand" "=S"))
17155    (clobber (match_operand:DI 1 "register_operand" "=D"))
17156    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17157   "TARGET_64BIT"
17158   "repz{\;| }cmpsb"
17159   [(set_attr "type" "str")
17160    (set_attr "mode" "QI")
17161    (set_attr "prefix_rep" "1")])
17163 ;; The same, but the count is not known to not be zero.
17165 (define_expand "cmpstrqi_1"
17166   [(parallel [(set (reg:CC FLAGS_REG)
17167                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17168                                      (const_int 0))
17169                   (compare:CC (match_operand 4 "memory_operand" "")
17170                               (match_operand 5 "memory_operand" ""))
17171                   (const_int 0)))
17172               (use (match_operand:SI 3 "immediate_operand" ""))
17173               (use (reg:CC FLAGS_REG))
17174               (use (reg:SI DIRFLAG_REG))
17175               (clobber (match_operand 0 "register_operand" ""))
17176               (clobber (match_operand 1 "register_operand" ""))
17177               (clobber (match_dup 2))])]
17178   ""
17179   "")
17181 (define_insn "*cmpstrqi_1"
17182   [(set (reg:CC FLAGS_REG)
17183         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17184                              (const_int 0))
17185           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17186                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17187           (const_int 0)))
17188    (use (match_operand:SI 3 "immediate_operand" "i"))
17189    (use (reg:CC FLAGS_REG))
17190    (use (reg:SI DIRFLAG_REG))
17191    (clobber (match_operand:SI 0 "register_operand" "=S"))
17192    (clobber (match_operand:SI 1 "register_operand" "=D"))
17193    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17194   "!TARGET_64BIT"
17195   "repz{\;| }cmpsb"
17196   [(set_attr "type" "str")
17197    (set_attr "mode" "QI")
17198    (set_attr "prefix_rep" "1")])
17200 (define_insn "*cmpstrqi_rex_1"
17201   [(set (reg:CC FLAGS_REG)
17202         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17203                              (const_int 0))
17204           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17205                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17206           (const_int 0)))
17207    (use (match_operand:SI 3 "immediate_operand" "i"))
17208    (use (reg:CC FLAGS_REG))
17209    (use (reg:SI DIRFLAG_REG))
17210    (clobber (match_operand:DI 0 "register_operand" "=S"))
17211    (clobber (match_operand:DI 1 "register_operand" "=D"))
17212    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17213   "TARGET_64BIT"
17214   "repz{\;| }cmpsb"
17215   [(set_attr "type" "str")
17216    (set_attr "mode" "QI")
17217    (set_attr "prefix_rep" "1")])
17219 (define_expand "strlensi"
17220   [(set (match_operand:SI 0 "register_operand" "")
17221         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17222                     (match_operand:QI 2 "immediate_operand" "")
17223                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17224   ""
17226  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17227    DONE;
17228  else
17229    FAIL;
17232 (define_expand "strlendi"
17233   [(set (match_operand:DI 0 "register_operand" "")
17234         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17235                     (match_operand:QI 2 "immediate_operand" "")
17236                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17237   ""
17239  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17240    DONE;
17241  else
17242    FAIL;
17245 (define_expand "strlenqi_1"
17246   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17247               (use (reg:SI DIRFLAG_REG))
17248               (clobber (match_operand 1 "register_operand" ""))
17249               (clobber (reg:CC FLAGS_REG))])]
17250   ""
17251   "")
17253 (define_insn "*strlenqi_1"
17254   [(set (match_operand:SI 0 "register_operand" "=&c")
17255         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17256                     (match_operand:QI 2 "register_operand" "a")
17257                     (match_operand:SI 3 "immediate_operand" "i")
17258                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17259    (use (reg:SI DIRFLAG_REG))
17260    (clobber (match_operand:SI 1 "register_operand" "=D"))
17261    (clobber (reg:CC FLAGS_REG))]
17262   "!TARGET_64BIT"
17263   "repnz{\;| }scasb"
17264   [(set_attr "type" "str")
17265    (set_attr "mode" "QI")
17266    (set_attr "prefix_rep" "1")])
17268 (define_insn "*strlenqi_rex_1"
17269   [(set (match_operand:DI 0 "register_operand" "=&c")
17270         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17271                     (match_operand:QI 2 "register_operand" "a")
17272                     (match_operand:DI 3 "immediate_operand" "i")
17273                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17274    (use (reg:SI DIRFLAG_REG))
17275    (clobber (match_operand:DI 1 "register_operand" "=D"))
17276    (clobber (reg:CC FLAGS_REG))]
17277   "TARGET_64BIT"
17278   "repnz{\;| }scasb"
17279   [(set_attr "type" "str")
17280    (set_attr "mode" "QI")
17281    (set_attr "prefix_rep" "1")])
17283 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17284 ;; handled in combine, but it is not currently up to the task.
17285 ;; When used for their truth value, the cmpstr* expanders generate
17286 ;; code like this:
17288 ;;   repz cmpsb
17289 ;;   seta       %al
17290 ;;   setb       %dl
17291 ;;   cmpb       %al, %dl
17292 ;;   jcc        label
17294 ;; The intermediate three instructions are unnecessary.
17296 ;; This one handles cmpstr*_nz_1...
17297 (define_peephole2
17298   [(parallel[
17299      (set (reg:CC FLAGS_REG)
17300           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17301                       (mem:BLK (match_operand 5 "register_operand" ""))))
17302      (use (match_operand 6 "register_operand" ""))
17303      (use (match_operand:SI 3 "immediate_operand" ""))
17304      (use (reg:SI DIRFLAG_REG))
17305      (clobber (match_operand 0 "register_operand" ""))
17306      (clobber (match_operand 1 "register_operand" ""))
17307      (clobber (match_operand 2 "register_operand" ""))])
17308    (set (match_operand:QI 7 "register_operand" "")
17309         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17310    (set (match_operand:QI 8 "register_operand" "")
17311         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17312    (set (reg FLAGS_REG)
17313         (compare (match_dup 7) (match_dup 8)))
17314   ]
17315   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17316   [(parallel[
17317      (set (reg:CC FLAGS_REG)
17318           (compare:CC (mem:BLK (match_dup 4))
17319                       (mem:BLK (match_dup 5))))
17320      (use (match_dup 6))
17321      (use (match_dup 3))
17322      (use (reg:SI DIRFLAG_REG))
17323      (clobber (match_dup 0))
17324      (clobber (match_dup 1))
17325      (clobber (match_dup 2))])]
17326   "")
17328 ;; ...and this one handles cmpstr*_1.
17329 (define_peephole2
17330   [(parallel[
17331      (set (reg:CC FLAGS_REG)
17332           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17333                                (const_int 0))
17334             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17335                         (mem:BLK (match_operand 5 "register_operand" "")))
17336             (const_int 0)))
17337      (use (match_operand:SI 3 "immediate_operand" ""))
17338      (use (reg:CC FLAGS_REG))
17339      (use (reg:SI DIRFLAG_REG))
17340      (clobber (match_operand 0 "register_operand" ""))
17341      (clobber (match_operand 1 "register_operand" ""))
17342      (clobber (match_operand 2 "register_operand" ""))])
17343    (set (match_operand:QI 7 "register_operand" "")
17344         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17345    (set (match_operand:QI 8 "register_operand" "")
17346         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17347    (set (reg FLAGS_REG)
17348         (compare (match_dup 7) (match_dup 8)))
17349   ]
17350   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17351   [(parallel[
17352      (set (reg:CC FLAGS_REG)
17353           (if_then_else:CC (ne (match_dup 6)
17354                                (const_int 0))
17355             (compare:CC (mem:BLK (match_dup 4))
17356                         (mem:BLK (match_dup 5)))
17357             (const_int 0)))
17358      (use (match_dup 3))
17359      (use (reg:CC FLAGS_REG))
17360      (use (reg:SI DIRFLAG_REG))
17361      (clobber (match_dup 0))
17362      (clobber (match_dup 1))
17363      (clobber (match_dup 2))])]
17364   "")
17368 ;; Conditional move instructions.
17370 (define_expand "movdicc"
17371   [(set (match_operand:DI 0 "register_operand" "")
17372         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17373                          (match_operand:DI 2 "general_operand" "")
17374                          (match_operand:DI 3 "general_operand" "")))]
17375   "TARGET_64BIT"
17376   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17378 (define_insn "x86_movdicc_0_m1_rex64"
17379   [(set (match_operand:DI 0 "register_operand" "=r")
17380         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17381           (const_int -1)
17382           (const_int 0)))
17383    (clobber (reg:CC FLAGS_REG))]
17384   "TARGET_64BIT"
17385   "sbb{q}\t%0, %0"
17386   ; Since we don't have the proper number of operands for an alu insn,
17387   ; fill in all the blanks.
17388   [(set_attr "type" "alu")
17389    (set_attr "pent_pair" "pu")
17390    (set_attr "memory" "none")
17391    (set_attr "imm_disp" "false")
17392    (set_attr "mode" "DI")
17393    (set_attr "length_immediate" "0")])
17395 (define_insn "movdicc_c_rex64"
17396   [(set (match_operand:DI 0 "register_operand" "=r,r")
17397         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17398                                 [(reg FLAGS_REG) (const_int 0)])
17399                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17400                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17401   "TARGET_64BIT && TARGET_CMOVE
17402    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17403   "@
17404    cmov%O2%C1\t{%2, %0|%0, %2}
17405    cmov%O2%c1\t{%3, %0|%0, %3}"
17406   [(set_attr "type" "icmov")
17407    (set_attr "mode" "DI")])
17409 (define_expand "movsicc"
17410   [(set (match_operand:SI 0 "register_operand" "")
17411         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17412                          (match_operand:SI 2 "general_operand" "")
17413                          (match_operand:SI 3 "general_operand" "")))]
17414   ""
17415   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17417 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17418 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17419 ;; So just document what we're doing explicitly.
17421 (define_insn "x86_movsicc_0_m1"
17422   [(set (match_operand:SI 0 "register_operand" "=r")
17423         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17424           (const_int -1)
17425           (const_int 0)))
17426    (clobber (reg:CC FLAGS_REG))]
17427   ""
17428   "sbb{l}\t%0, %0"
17429   ; Since we don't have the proper number of operands for an alu insn,
17430   ; fill in all the blanks.
17431   [(set_attr "type" "alu")
17432    (set_attr "pent_pair" "pu")
17433    (set_attr "memory" "none")
17434    (set_attr "imm_disp" "false")
17435    (set_attr "mode" "SI")
17436    (set_attr "length_immediate" "0")])
17438 (define_insn "*movsicc_noc"
17439   [(set (match_operand:SI 0 "register_operand" "=r,r")
17440         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17441                                 [(reg FLAGS_REG) (const_int 0)])
17442                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17443                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17444   "TARGET_CMOVE
17445    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17446   "@
17447    cmov%O2%C1\t{%2, %0|%0, %2}
17448    cmov%O2%c1\t{%3, %0|%0, %3}"
17449   [(set_attr "type" "icmov")
17450    (set_attr "mode" "SI")])
17452 (define_expand "movhicc"
17453   [(set (match_operand:HI 0 "register_operand" "")
17454         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17455                          (match_operand:HI 2 "general_operand" "")
17456                          (match_operand:HI 3 "general_operand" "")))]
17457   "TARGET_HIMODE_MATH"
17458   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17460 (define_insn "*movhicc_noc"
17461   [(set (match_operand:HI 0 "register_operand" "=r,r")
17462         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17463                                 [(reg FLAGS_REG) (const_int 0)])
17464                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17465                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17466   "TARGET_CMOVE
17467    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17468   "@
17469    cmov%O2%C1\t{%2, %0|%0, %2}
17470    cmov%O2%c1\t{%3, %0|%0, %3}"
17471   [(set_attr "type" "icmov")
17472    (set_attr "mode" "HI")])
17474 (define_expand "movqicc"
17475   [(set (match_operand:QI 0 "register_operand" "")
17476         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17477                          (match_operand:QI 2 "general_operand" "")
17478                          (match_operand:QI 3 "general_operand" "")))]
17479   "TARGET_QIMODE_MATH"
17480   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17482 (define_insn_and_split "*movqicc_noc"
17483   [(set (match_operand:QI 0 "register_operand" "=r,r")
17484         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17485                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17486                       (match_operand:QI 2 "register_operand" "r,0")
17487                       (match_operand:QI 3 "register_operand" "0,r")))]
17488   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17489   "#"
17490   "&& reload_completed"
17491   [(set (match_dup 0)
17492         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17493                       (match_dup 2)
17494                       (match_dup 3)))]
17495   "operands[0] = gen_lowpart (SImode, operands[0]);
17496    operands[2] = gen_lowpart (SImode, operands[2]);
17497    operands[3] = gen_lowpart (SImode, operands[3]);"
17498   [(set_attr "type" "icmov")
17499    (set_attr "mode" "SI")])
17501 (define_expand "movsfcc"
17502   [(set (match_operand:SF 0 "register_operand" "")
17503         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17504                          (match_operand:SF 2 "register_operand" "")
17505                          (match_operand:SF 3 "register_operand" "")))]
17506   "TARGET_CMOVE"
17507   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17509 (define_insn "*movsfcc_1"
17510   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17511         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17512                                 [(reg FLAGS_REG) (const_int 0)])
17513                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17514                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17515   "TARGET_CMOVE
17516    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17517   "@
17518    fcmov%F1\t{%2, %0|%0, %2}
17519    fcmov%f1\t{%3, %0|%0, %3}
17520    cmov%O2%C1\t{%2, %0|%0, %2}
17521    cmov%O2%c1\t{%3, %0|%0, %3}"
17522   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17523    (set_attr "mode" "SF,SF,SI,SI")])
17525 (define_expand "movdfcc"
17526   [(set (match_operand:DF 0 "register_operand" "")
17527         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17528                          (match_operand:DF 2 "register_operand" "")
17529                          (match_operand:DF 3 "register_operand" "")))]
17530   "TARGET_CMOVE"
17531   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17533 (define_insn "*movdfcc_1"
17534   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17535         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17536                                 [(reg FLAGS_REG) (const_int 0)])
17537                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17538                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17539   "!TARGET_64BIT && TARGET_CMOVE
17540    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17541   "@
17542    fcmov%F1\t{%2, %0|%0, %2}
17543    fcmov%f1\t{%3, %0|%0, %3}
17544    #
17545    #"
17546   [(set_attr "type" "fcmov,fcmov,multi,multi")
17547    (set_attr "mode" "DF")])
17549 (define_insn "*movdfcc_1_rex64"
17550   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17551         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17552                                 [(reg FLAGS_REG) (const_int 0)])
17553                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17554                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17555   "TARGET_64BIT && TARGET_CMOVE
17556    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17557   "@
17558    fcmov%F1\t{%2, %0|%0, %2}
17559    fcmov%f1\t{%3, %0|%0, %3}
17560    cmov%O2%C1\t{%2, %0|%0, %2}
17561    cmov%O2%c1\t{%3, %0|%0, %3}"
17562   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17563    (set_attr "mode" "DF")])
17565 (define_split
17566   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17567         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17568                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17569                       (match_operand:DF 2 "nonimmediate_operand" "")
17570                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17571   "!TARGET_64BIT && reload_completed"
17572   [(set (match_dup 2)
17573         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17574                       (match_dup 5)
17575                       (match_dup 7)))
17576    (set (match_dup 3)
17577         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17578                       (match_dup 6)
17579                       (match_dup 8)))]
17580   "split_di (operands+2, 1, operands+5, operands+6);
17581    split_di (operands+3, 1, operands+7, operands+8);
17582    split_di (operands, 1, operands+2, operands+3);")
17584 (define_expand "movxfcc"
17585   [(set (match_operand:XF 0 "register_operand" "")
17586         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17587                          (match_operand:XF 2 "register_operand" "")
17588                          (match_operand:XF 3 "register_operand" "")))]
17589   "TARGET_CMOVE"
17590   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17592 (define_insn "*movxfcc_1"
17593   [(set (match_operand:XF 0 "register_operand" "=f,f")
17594         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17595                                 [(reg FLAGS_REG) (const_int 0)])
17596                       (match_operand:XF 2 "register_operand" "f,0")
17597                       (match_operand:XF 3 "register_operand" "0,f")))]
17598   "TARGET_CMOVE"
17599   "@
17600    fcmov%F1\t{%2, %0|%0, %2}
17601    fcmov%f1\t{%3, %0|%0, %3}"
17602   [(set_attr "type" "fcmov")
17603    (set_attr "mode" "XF")])
17605 (define_expand "minsf3"
17606   [(parallel [
17607      (set (match_operand:SF 0 "register_operand" "")
17608           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17609                                (match_operand:SF 2 "nonimmediate_operand" ""))
17610                            (match_dup 1)
17611                            (match_dup 2)))
17612      (clobber (reg:CC FLAGS_REG))])]
17613   "TARGET_SSE"
17614   "")
17616 (define_insn "*minsf"
17617   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17618         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17619                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17620                          (match_dup 1)
17621                          (match_dup 2)))
17622    (clobber (reg:CC FLAGS_REG))]
17623   "TARGET_SSE && TARGET_IEEE_FP"
17624   "#")
17626 (define_insn "*minsf_nonieee"
17627   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17628         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17629                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17630                          (match_dup 1)
17631                          (match_dup 2)))
17632    (clobber (reg:CC FLAGS_REG))]
17633   "TARGET_SSE && !TARGET_IEEE_FP
17634    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17635   "#")
17637 (define_split
17638   [(set (match_operand:SF 0 "register_operand" "")
17639         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17640                              (match_operand:SF 2 "nonimmediate_operand" ""))
17641                          (match_operand:SF 3 "register_operand" "")
17642                          (match_operand:SF 4 "nonimmediate_operand" "")))
17643    (clobber (reg:CC FLAGS_REG))]
17644   "SSE_REG_P (operands[0]) && reload_completed
17645    && ((operands_match_p (operands[1], operands[3])
17646         && operands_match_p (operands[2], operands[4]))
17647        || (operands_match_p (operands[1], operands[4])
17648            && operands_match_p (operands[2], operands[3])))"
17649   [(set (match_dup 0)
17650         (if_then_else:SF (lt (match_dup 1)
17651                              (match_dup 2))
17652                          (match_dup 1)
17653                          (match_dup 2)))])
17655 ;; Conditional addition patterns
17656 (define_expand "addqicc"
17657   [(match_operand:QI 0 "register_operand" "")
17658    (match_operand 1 "comparison_operator" "")
17659    (match_operand:QI 2 "register_operand" "")
17660    (match_operand:QI 3 "const_int_operand" "")]
17661   ""
17662   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17664 (define_expand "addhicc"
17665   [(match_operand:HI 0 "register_operand" "")
17666    (match_operand 1 "comparison_operator" "")
17667    (match_operand:HI 2 "register_operand" "")
17668    (match_operand:HI 3 "const_int_operand" "")]
17669   ""
17670   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17672 (define_expand "addsicc"
17673   [(match_operand:SI 0 "register_operand" "")
17674    (match_operand 1 "comparison_operator" "")
17675    (match_operand:SI 2 "register_operand" "")
17676    (match_operand:SI 3 "const_int_operand" "")]
17677   ""
17678   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17680 (define_expand "adddicc"
17681   [(match_operand:DI 0 "register_operand" "")
17682    (match_operand 1 "comparison_operator" "")
17683    (match_operand:DI 2 "register_operand" "")
17684    (match_operand:DI 3 "const_int_operand" "")]
17685   "TARGET_64BIT"
17686   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17688 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17690 (define_split
17691   [(set (match_operand:SF 0 "fp_register_operand" "")
17692         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17693                              (match_operand:SF 2 "register_operand" ""))
17694                          (match_operand:SF 3 "register_operand" "")
17695                          (match_operand:SF 4 "register_operand" "")))
17696    (clobber (reg:CC FLAGS_REG))]
17697   "reload_completed
17698    && ((operands_match_p (operands[1], operands[3])
17699         && operands_match_p (operands[2], operands[4]))
17700        || (operands_match_p (operands[1], operands[4])
17701            && operands_match_p (operands[2], operands[3])))"
17702   [(set (reg:CCFP FLAGS_REG)
17703         (compare:CCFP (match_dup 2)
17704                       (match_dup 1)))
17705    (set (match_dup 0)
17706         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17707                          (match_dup 1)
17708                          (match_dup 2)))])
17710 (define_insn "*minsf_sse"
17711   [(set (match_operand:SF 0 "register_operand" "=x")
17712         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17713                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17714                          (match_dup 1)
17715                          (match_dup 2)))]
17716   "TARGET_SSE && reload_completed"
17717   "minss\t{%2, %0|%0, %2}"
17718   [(set_attr "type" "sse")
17719    (set_attr "mode" "SF")])
17721 (define_expand "mindf3"
17722   [(parallel [
17723      (set (match_operand:DF 0 "register_operand" "")
17724           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17725                                (match_operand:DF 2 "nonimmediate_operand" ""))
17726                            (match_dup 1)
17727                            (match_dup 2)))
17728      (clobber (reg:CC FLAGS_REG))])]
17729   "TARGET_SSE2 && TARGET_SSE_MATH"
17730   "#")
17732 (define_insn "*mindf"
17733   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17734         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17735                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17736                          (match_dup 1)
17737                          (match_dup 2)))
17738    (clobber (reg:CC FLAGS_REG))]
17739   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17740   "#")
17742 (define_insn "*mindf_nonieee"
17743   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17744         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17745                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17746                          (match_dup 1)
17747                          (match_dup 2)))
17748    (clobber (reg:CC FLAGS_REG))]
17749   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17750    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17751   "#")
17753 (define_split
17754   [(set (match_operand:DF 0 "register_operand" "")
17755         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17756                              (match_operand:DF 2 "nonimmediate_operand" ""))
17757                          (match_operand:DF 3 "register_operand" "")
17758                          (match_operand:DF 4 "nonimmediate_operand" "")))
17759    (clobber (reg:CC FLAGS_REG))]
17760   "SSE_REG_P (operands[0]) && reload_completed
17761    && ((operands_match_p (operands[1], operands[3])
17762         && operands_match_p (operands[2], operands[4]))
17763        || (operands_match_p (operands[1], operands[4])
17764            && operands_match_p (operands[2], operands[3])))"
17765   [(set (match_dup 0)
17766         (if_then_else:DF (lt (match_dup 1)
17767                              (match_dup 2))
17768                          (match_dup 1)
17769                          (match_dup 2)))])
17771 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17772 (define_split
17773   [(set (match_operand:DF 0 "fp_register_operand" "")
17774         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17775                              (match_operand:DF 2 "register_operand" ""))
17776                          (match_operand:DF 3 "register_operand" "")
17777                          (match_operand:DF 4 "register_operand" "")))
17778    (clobber (reg:CC FLAGS_REG))]
17779   "reload_completed
17780    && ((operands_match_p (operands[1], operands[3])
17781         && operands_match_p (operands[2], operands[4]))
17782        || (operands_match_p (operands[1], operands[4])
17783            && operands_match_p (operands[2], operands[3])))"
17784   [(set (reg:CCFP FLAGS_REG)
17785         (compare:CCFP (match_dup 2)
17786                       (match_dup 1)))
17787    (set (match_dup 0)
17788         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17789                          (match_dup 1)
17790                          (match_dup 2)))])
17792 (define_insn "*mindf_sse"
17793   [(set (match_operand:DF 0 "register_operand" "=Y")
17794         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17795                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17796                          (match_dup 1)
17797                          (match_dup 2)))]
17798   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17799   "minsd\t{%2, %0|%0, %2}"
17800   [(set_attr "type" "sse")
17801    (set_attr "mode" "DF")])
17803 (define_expand "maxsf3"
17804   [(parallel [
17805      (set (match_operand:SF 0 "register_operand" "")
17806           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17807                                (match_operand:SF 2 "nonimmediate_operand" ""))
17808                            (match_dup 1)
17809                            (match_dup 2)))
17810      (clobber (reg:CC FLAGS_REG))])]
17811   "TARGET_SSE"
17812   "#")
17814 (define_insn "*maxsf"
17815   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17816         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17817                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17818                          (match_dup 1)
17819                          (match_dup 2)))
17820    (clobber (reg:CC FLAGS_REG))]
17821   "TARGET_SSE && TARGET_IEEE_FP"
17822   "#")
17824 (define_insn "*maxsf_nonieee"
17825   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17826         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17827                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17828                          (match_dup 1)
17829                          (match_dup 2)))
17830    (clobber (reg:CC FLAGS_REG))]
17831   "TARGET_SSE && !TARGET_IEEE_FP
17832    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17833   "#")
17835 (define_split
17836   [(set (match_operand:SF 0 "register_operand" "")
17837         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17838                              (match_operand:SF 2 "nonimmediate_operand" ""))
17839                          (match_operand:SF 3 "register_operand" "")
17840                          (match_operand:SF 4 "nonimmediate_operand" "")))
17841    (clobber (reg:CC FLAGS_REG))]
17842   "SSE_REG_P (operands[0]) && reload_completed
17843    && ((operands_match_p (operands[1], operands[3])
17844         && operands_match_p (operands[2], operands[4]))
17845        || (operands_match_p (operands[1], operands[4])
17846            && operands_match_p (operands[2], operands[3])))"
17847   [(set (match_dup 0)
17848         (if_then_else:SF (gt (match_dup 1)
17849                              (match_dup 2))
17850                          (match_dup 1)
17851                          (match_dup 2)))])
17853 (define_split
17854   [(set (match_operand:SF 0 "fp_register_operand" "")
17855         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17856                              (match_operand:SF 2 "register_operand" ""))
17857                          (match_operand:SF 3 "register_operand" "")
17858                          (match_operand:SF 4 "register_operand" "")))
17859    (clobber (reg:CC FLAGS_REG))]
17860   "reload_completed
17861    && ((operands_match_p (operands[1], operands[3])
17862         && operands_match_p (operands[2], operands[4]))
17863        || (operands_match_p (operands[1], operands[4])
17864            && operands_match_p (operands[2], operands[3])))"
17865   [(set (reg:CCFP FLAGS_REG)
17866         (compare:CCFP (match_dup 1)
17867                       (match_dup 2)))
17868    (set (match_dup 0)
17869         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17870                          (match_dup 1)
17871                          (match_dup 2)))])
17873 (define_insn "*maxsf_sse"
17874   [(set (match_operand:SF 0 "register_operand" "=x")
17875         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17876                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17877                          (match_dup 1)
17878                          (match_dup 2)))]
17879   "TARGET_SSE && reload_completed"
17880   "maxss\t{%2, %0|%0, %2}"
17881   [(set_attr "type" "sse")
17882    (set_attr "mode" "SF")])
17884 (define_expand "maxdf3"
17885   [(parallel [
17886      (set (match_operand:DF 0 "register_operand" "")
17887           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17888                                (match_operand:DF 2 "nonimmediate_operand" ""))
17889                            (match_dup 1)
17890                            (match_dup 2)))
17891      (clobber (reg:CC FLAGS_REG))])]
17892   "TARGET_SSE2 && TARGET_SSE_MATH"
17893   "#")
17895 (define_insn "*maxdf"
17896   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17897         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17898                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17899                          (match_dup 1)
17900                          (match_dup 2)))
17901    (clobber (reg:CC FLAGS_REG))]
17902   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17903   "#")
17905 (define_insn "*maxdf_nonieee"
17906   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17907         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17908                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17909                          (match_dup 1)
17910                          (match_dup 2)))
17911    (clobber (reg:CC FLAGS_REG))]
17912   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17913    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17914   "#")
17916 (define_split
17917   [(set (match_operand:DF 0 "register_operand" "")
17918         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17919                              (match_operand:DF 2 "nonimmediate_operand" ""))
17920                          (match_operand:DF 3 "register_operand" "")
17921                          (match_operand:DF 4 "nonimmediate_operand" "")))
17922    (clobber (reg:CC FLAGS_REG))]
17923   "SSE_REG_P (operands[0]) && reload_completed
17924    && ((operands_match_p (operands[1], operands[3])
17925         && operands_match_p (operands[2], operands[4]))
17926        || (operands_match_p (operands[1], operands[4])
17927            && operands_match_p (operands[2], operands[3])))"
17928   [(set (match_dup 0)
17929         (if_then_else:DF (gt (match_dup 1)
17930                              (match_dup 2))
17931                          (match_dup 1)
17932                          (match_dup 2)))])
17934 (define_split
17935   [(set (match_operand:DF 0 "fp_register_operand" "")
17936         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17937                              (match_operand:DF 2 "register_operand" ""))
17938                          (match_operand:DF 3 "register_operand" "")
17939                          (match_operand:DF 4 "register_operand" "")))
17940    (clobber (reg:CC FLAGS_REG))]
17941   "reload_completed
17942    && ((operands_match_p (operands[1], operands[3])
17943         && operands_match_p (operands[2], operands[4]))
17944        || (operands_match_p (operands[1], operands[4])
17945            && operands_match_p (operands[2], operands[3])))"
17946   [(set (reg:CCFP FLAGS_REG)
17947         (compare:CCFP (match_dup 1)
17948                       (match_dup 2)))
17949    (set (match_dup 0)
17950         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17951                          (match_dup 1)
17952                          (match_dup 2)))])
17954 (define_insn "*maxdf_sse"
17955   [(set (match_operand:DF 0 "register_operand" "=Y")
17956         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17957                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17958                          (match_dup 1)
17959                          (match_dup 2)))]
17960   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17961   "maxsd\t{%2, %0|%0, %2}"
17962   [(set_attr "type" "sse")
17963    (set_attr "mode" "DF")])
17965 ;; Misc patterns (?)
17967 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17968 ;; Otherwise there will be nothing to keep
17969 ;; 
17970 ;; [(set (reg ebp) (reg esp))]
17971 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17972 ;;  (clobber (eflags)]
17973 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17975 ;; in proper program order.
17976 (define_insn "pro_epilogue_adjust_stack_1"
17977   [(set (match_operand:SI 0 "register_operand" "=r,r")
17978         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17979                  (match_operand:SI 2 "immediate_operand" "i,i")))
17980    (clobber (reg:CC FLAGS_REG))
17981    (clobber (mem:BLK (scratch)))]
17982   "!TARGET_64BIT"
17984   switch (get_attr_type (insn))
17985     {
17986     case TYPE_IMOV:
17987       return "mov{l}\t{%1, %0|%0, %1}";
17989     case TYPE_ALU:
17990       if (GET_CODE (operands[2]) == CONST_INT
17991           && (INTVAL (operands[2]) == 128
17992               || (INTVAL (operands[2]) < 0
17993                   && INTVAL (operands[2]) != -128)))
17994         {
17995           operands[2] = GEN_INT (-INTVAL (operands[2]));
17996           return "sub{l}\t{%2, %0|%0, %2}";
17997         }
17998       return "add{l}\t{%2, %0|%0, %2}";
18000     case TYPE_LEA:
18001       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18002       return "lea{l}\t{%a2, %0|%0, %a2}";
18004     default:
18005       abort ();
18006     }
18008   [(set (attr "type")
18009         (cond [(eq_attr "alternative" "0")
18010                  (const_string "alu")
18011                (match_operand:SI 2 "const0_operand" "")
18012                  (const_string "imov")
18013               ]
18014               (const_string "lea")))
18015    (set_attr "mode" "SI")])
18017 (define_insn "pro_epilogue_adjust_stack_rex64"
18018   [(set (match_operand:DI 0 "register_operand" "=r,r")
18019         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18020                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18021    (clobber (reg:CC FLAGS_REG))
18022    (clobber (mem:BLK (scratch)))]
18023   "TARGET_64BIT"
18025   switch (get_attr_type (insn))
18026     {
18027     case TYPE_IMOV:
18028       return "mov{q}\t{%1, %0|%0, %1}";
18030     case TYPE_ALU:
18031       if (GET_CODE (operands[2]) == CONST_INT
18032           /* Avoid overflows.  */
18033           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18034           && (INTVAL (operands[2]) == 128
18035               || (INTVAL (operands[2]) < 0
18036                   && INTVAL (operands[2]) != -128)))
18037         {
18038           operands[2] = GEN_INT (-INTVAL (operands[2]));
18039           return "sub{q}\t{%2, %0|%0, %2}";
18040         }
18041       return "add{q}\t{%2, %0|%0, %2}";
18043     case TYPE_LEA:
18044       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18045       return "lea{q}\t{%a2, %0|%0, %a2}";
18047     default:
18048       abort ();
18049     }
18051   [(set (attr "type")
18052         (cond [(eq_attr "alternative" "0")
18053                  (const_string "alu")
18054                (match_operand:DI 2 "const0_operand" "")
18055                  (const_string "imov")
18056               ]
18057               (const_string "lea")))
18058    (set_attr "mode" "DI")])
18060 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18061   [(set (match_operand:DI 0 "register_operand" "=r,r")
18062         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18063                  (match_operand:DI 3 "immediate_operand" "i,i")))
18064    (use (match_operand:DI 2 "register_operand" "r,r"))
18065    (clobber (reg:CC FLAGS_REG))
18066    (clobber (mem:BLK (scratch)))]
18067   "TARGET_64BIT"
18069   switch (get_attr_type (insn))
18070     {
18071     case TYPE_ALU:
18072       return "add{q}\t{%2, %0|%0, %2}";
18074     case TYPE_LEA:
18075       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18076       return "lea{q}\t{%a2, %0|%0, %a2}";
18078     default:
18079       abort ();
18080     }
18082   [(set_attr "type" "alu,lea")
18083    (set_attr "mode" "DI")])
18085 ;; Placeholder for the conditional moves.  This one is split either to SSE
18086 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18087 ;; fact is that compares supported by the cmp??ss instructions are exactly
18088 ;; swapped of those supported by cmove sequence.
18089 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18090 ;; supported by i387 comparisons and we do need to emit two conditional moves
18091 ;; in tandem.
18093 (define_insn "sse_movsfcc"
18094   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
18095         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18096                         [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
18097                          (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
18098                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
18099                       (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
18100    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18101    (clobber (reg:CC FLAGS_REG))]
18102   "TARGET_SSE
18103    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18104    /* Avoid combine from being smart and converting min/max
18105       instruction patterns into conditional moves.  */
18106    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18107         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18108        || !rtx_equal_p (operands[4], operands[2])
18109        || !rtx_equal_p (operands[5], operands[3]))
18110    && (!TARGET_IEEE_FP
18111        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18112   "#")
18114 (define_insn "sse_movsfcc_eq"
18115   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18116         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18117                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18118                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18119                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18120    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18121    (clobber (reg:CC FLAGS_REG))]
18122   "TARGET_SSE
18123    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18124   "#")
18126 (define_insn "sse_movdfcc"
18127   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
18128         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18129                         [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
18130                          (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
18131                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
18132                       (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
18133    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18134    (clobber (reg:CC FLAGS_REG))]
18135   "TARGET_SSE2
18136    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18137    /* Avoid combine from being smart and converting min/max
18138       instruction patterns into conditional moves.  */
18139    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18140         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18141        || !rtx_equal_p (operands[4], operands[2])
18142        || !rtx_equal_p (operands[5], operands[3]))
18143    && (!TARGET_IEEE_FP
18144        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18145   "#")
18147 (define_insn "sse_movdfcc_eq"
18148   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18149         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18150                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18151                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18152                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18153    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18154    (clobber (reg:CC FLAGS_REG))]
18155   "TARGET_SSE
18156    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18157   "#")
18159 ;; For non-sse moves just expand the usual cmove sequence.
18160 (define_split
18161   [(set (match_operand 0 "register_operand" "")
18162         (if_then_else (match_operator 1 "comparison_operator"
18163                         [(match_operand 4 "nonimmediate_operand" "")
18164                          (match_operand 5 "register_operand" "")])
18165                       (match_operand 2 "nonimmediate_operand" "")
18166                       (match_operand 3 "nonimmediate_operand" "")))
18167    (clobber (match_operand 6 "" ""))
18168    (clobber (reg:CC FLAGS_REG))]
18169   "!SSE_REG_P (operands[0]) && reload_completed
18170    && (GET_MODE (operands[0]) == SFmode
18171        || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
18172   [(const_int 0)]
18174    ix86_compare_op0 = operands[5];
18175    ix86_compare_op1 = operands[4];
18176    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18177                                  VOIDmode, operands[5], operands[4]);
18178    ix86_expand_fp_movcc (operands);
18179    DONE;
18182 ;; Split SSE based conditional move into sequence:
18183 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18184 ;; and   op2, op0   -  zero op2 if comparison was false
18185 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18186 ;; or    op2, op0   -  get the nonzero one into the result.
18187 (define_split
18188   [(set (match_operand:SF 0 "register_operand" "")
18189         (if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
18190                            [(match_operand:SF 4 "register_operand" "")
18191                             (match_operand:SF 5 "nonimmediate_operand" "")])
18192                          (match_operand:SF 2 "register_operand" "")
18193                          (match_operand:SF 3 "register_operand" "")))
18194    (clobber (match_operand 6 "" ""))
18195    (clobber (reg:CC FLAGS_REG))]
18196   "SSE_REG_P (operands[0]) && reload_completed"
18197   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18198    (set (match_dup 2) (and:V4SF (match_dup 2)
18199                                 (match_dup 8)))
18200    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18201                                           (match_dup 3)))
18202    (set (match_dup 0) (ior:V4SF (match_dup 6)
18203                                 (match_dup 7)))]
18205   /* If op2 == op3, op3 would be clobbered before it is used.  */
18206   if (operands_match_p (operands[2], operands[3]))
18207     {
18208       emit_move_insn (operands[0], operands[2]);
18209       DONE;
18210     }
18212   PUT_MODE (operands[1], GET_MODE (operands[0]));
18213   if (operands_match_p (operands[0], operands[4]))
18214     operands[6] = operands[4], operands[7] = operands[2];
18215   else
18216     operands[6] = operands[2], operands[7] = operands[4];
18217   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18218   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18219   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18220   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18221   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18222   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18225 (define_split
18226   [(set (match_operand:DF 0 "register_operand" "")
18227         (if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
18228                            [(match_operand:DF 4 "register_operand" "")
18229                             (match_operand:DF 5 "nonimmediate_operand" "")])
18230                          (match_operand:DF 2 "register_operand" "")
18231                          (match_operand:DF 3 "register_operand" "")))
18232    (clobber (match_operand 6 "" ""))
18233    (clobber (reg:CC FLAGS_REG))]
18234   "SSE_REG_P (operands[0]) && reload_completed"
18235   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18236    (set (match_dup 2) (and:V2DF (match_dup 2)
18237                                 (match_dup 8)))
18238    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18239                                           (match_dup 3)))
18240    (set (match_dup 0) (ior:V2DF (match_dup 6)
18241                                 (match_dup 7)))]
18243   if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18244     {
18245       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18246       emit_insn (gen_sse2_unpcklpd (op, op, op));
18247       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18248       emit_insn (gen_sse2_unpcklpd (op, op, op));
18249     }
18251   /* If op2 == op3, op3 would be clobbered before it is used.  */
18252   if (operands_match_p (operands[2], operands[3]))
18253     {
18254       emit_move_insn (operands[0], operands[2]);
18255       DONE;
18256     }
18258   PUT_MODE (operands[1], GET_MODE (operands[0]));
18259   if (operands_match_p (operands[0], operands[4]))
18260     operands[6] = operands[4], operands[7] = operands[2];
18261   else
18262     operands[6] = operands[2], operands[7] = operands[4];
18263   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18264   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18265   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18266   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18267   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18268   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18271 ;; Special case of conditional move we can handle effectively.
18272 ;; Do not brother with the integer/floating point case, since these are
18273 ;; bot considerably slower, unlike in the generic case.
18274 (define_insn "*sse_movsfcc_const0_1"
18275   [(set (match_operand:SF 0 "register_operand" "=&x")
18276         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18277                         [(match_operand:SF 4 "register_operand" "0")
18278                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18279                       (match_operand:SF 2 "register_operand" "x")
18280                       (match_operand:SF 3 "const0_operand" "X")))]
18281   "TARGET_SSE"
18282   "#")
18284 (define_insn "*sse_movsfcc_const0_2"
18285   [(set (match_operand:SF 0 "register_operand" "=&x")
18286         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18287                         [(match_operand:SF 4 "register_operand" "0")
18288                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18289                       (match_operand:SF 2 "const0_operand" "X")
18290                       (match_operand:SF 3 "register_operand" "x")))]
18291   "TARGET_SSE"
18292   "#")
18294 (define_insn "*sse_movsfcc_const0_3"
18295   [(set (match_operand:SF 0 "register_operand" "=&x")
18296         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18297                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18298                          (match_operand:SF 5 "register_operand" "0")])
18299                       (match_operand:SF 2 "register_operand" "x")
18300                       (match_operand:SF 3 "const0_operand" "X")))]
18301   "TARGET_SSE"
18302   "#")
18304 (define_insn "*sse_movsfcc_const0_4"
18305   [(set (match_operand:SF 0 "register_operand" "=&x")
18306         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18307                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18308                          (match_operand:SF 5 "register_operand" "0")])
18309                       (match_operand:SF 2 "const0_operand" "X")
18310                       (match_operand:SF 3 "register_operand" "x")))]
18311   "TARGET_SSE"
18312   "#")
18314 (define_insn "*sse_movdfcc_const0_1"
18315   [(set (match_operand:DF 0 "register_operand" "=&Y")
18316         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18317                         [(match_operand:DF 4 "register_operand" "0")
18318                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18319                       (match_operand:DF 2 "register_operand" "Y")
18320                       (match_operand:DF 3 "const0_operand" "X")))]
18321   "TARGET_SSE2"
18322   "#")
18324 (define_insn "*sse_movdfcc_const0_2"
18325   [(set (match_operand:DF 0 "register_operand" "=&Y")
18326         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18327                         [(match_operand:DF 4 "register_operand" "0")
18328                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18329                       (match_operand:DF 2 "const0_operand" "X")
18330                       (match_operand:DF 3 "register_operand" "Y")))]
18331   "TARGET_SSE2"
18332   "#")
18334 (define_insn "*sse_movdfcc_const0_3"
18335   [(set (match_operand:DF 0 "register_operand" "=&Y")
18336         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18337                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18338                          (match_operand:DF 5 "register_operand" "0")])
18339                       (match_operand:DF 2 "register_operand" "Y")
18340                       (match_operand:DF 3 "const0_operand" "X")))]
18341   "TARGET_SSE2"
18342   "#")
18344 (define_insn "*sse_movdfcc_const0_4"
18345   [(set (match_operand:DF 0 "register_operand" "=&Y")
18346         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18347                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18348                          (match_operand:DF 5 "register_operand" "0")])
18349                       (match_operand:DF 2 "const0_operand" "X")
18350                       (match_operand:DF 3 "register_operand" "Y")))]
18351   "TARGET_SSE2"
18352   "#")
18354 (define_split
18355   [(set (match_operand:SF 0 "register_operand" "")
18356         (if_then_else:SF (match_operator 1 "comparison_operator"
18357                            [(match_operand:SF 4 "nonimmediate_operand" "")
18358                             (match_operand:SF 5 "nonimmediate_operand" "")])
18359                          (match_operand:SF 2 "nonmemory_operand" "")
18360                          (match_operand:SF 3 "nonmemory_operand" "")))]
18361   "SSE_REG_P (operands[0]) && reload_completed
18362    && (const0_operand (operands[2], GET_MODE (operands[0]))
18363        || const0_operand (operands[3], GET_MODE (operands[0])))"
18364   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18365    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18367   PUT_MODE (operands[1], GET_MODE (operands[0]));
18368   if (!sse_comparison_operator (operands[1], VOIDmode)
18369       || !rtx_equal_p (operands[0], operands[4]))
18370     {
18371       rtx tmp = operands[5];
18372       operands[5] = operands[4];
18373       operands[4] = tmp;
18374       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18375     }
18376   if (!rtx_equal_p (operands[0], operands[4]))
18377     abort ();
18378   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18379   if (const0_operand (operands[2], GET_MODE (operands[2])))
18380     {
18381       operands[7] = operands[3];
18382       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18383     }
18384   else
18385     {
18386       operands[7] = operands[2];
18387       operands[6] = operands[8];
18388     }
18389   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18392 (define_split
18393   [(set (match_operand:DF 0 "register_operand" "")
18394         (if_then_else:DF (match_operator 1 "comparison_operator"
18395                            [(match_operand:DF 4 "nonimmediate_operand" "")
18396                             (match_operand:DF 5 "nonimmediate_operand" "")])
18397                          (match_operand:DF 2 "nonmemory_operand" "")
18398                          (match_operand:DF 3 "nonmemory_operand" "")))]
18399   "SSE_REG_P (operands[0]) && reload_completed
18400    && (const0_operand (operands[2], GET_MODE (operands[0]))
18401        || const0_operand (operands[3], GET_MODE (operands[0])))"
18402   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18403    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18405   if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18406     {
18407       if (REG_P (operands[2]))
18408         {
18409           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18410           emit_insn (gen_sse2_unpcklpd (op, op, op));
18411         }
18412       if (REG_P (operands[3]))
18413         {
18414           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18415           emit_insn (gen_sse2_unpcklpd (op, op, op));
18416         }
18417     }
18418   PUT_MODE (operands[1], GET_MODE (operands[0]));
18419   if (!sse_comparison_operator (operands[1], VOIDmode)
18420       || !rtx_equal_p (operands[0], operands[4]))
18421     {
18422       rtx tmp = operands[5];
18423       operands[5] = operands[4];
18424       operands[4] = tmp;
18425       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18426     }
18427   if (!rtx_equal_p (operands[0], operands[4]))
18428     abort ();
18429   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18430   if (const0_operand (operands[2], GET_MODE (operands[2])))
18431     {
18432       operands[7] = operands[3];
18433       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18434     }
18435   else
18436     {
18437       operands[7] = operands[2];
18438       operands[6] = operands[8];
18439     }
18440   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18443 (define_expand "allocate_stack_worker"
18444   [(match_operand:SI 0 "register_operand" "")]
18445   "TARGET_STACK_PROBE"
18447   if (reload_completed)
18448     {
18449       if (TARGET_64BIT)
18450         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18451       else
18452         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18453     }
18454   else
18455     {
18456       if (TARGET_64BIT)
18457         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18458       else
18459         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18460     }
18461   DONE;
18464 (define_insn "allocate_stack_worker_1"
18465   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18466     UNSPECV_STACK_PROBE)
18467    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18468    (clobber (match_scratch:SI 1 "=0"))
18469    (clobber (reg:CC FLAGS_REG))]
18470   "!TARGET_64BIT && TARGET_STACK_PROBE"
18471   "call\t__alloca"
18472   [(set_attr "type" "multi")
18473    (set_attr "length" "5")])
18475 (define_expand "allocate_stack_worker_postreload"
18476   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18477                                     UNSPECV_STACK_PROBE)
18478               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18479               (clobber (match_dup 0))
18480               (clobber (reg:CC FLAGS_REG))])]
18481   ""
18482   "")
18484 (define_insn "allocate_stack_worker_rex64"
18485   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18486     UNSPECV_STACK_PROBE)
18487    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18488    (clobber (match_scratch:DI 1 "=0"))
18489    (clobber (reg:CC FLAGS_REG))]
18490   "TARGET_64BIT && TARGET_STACK_PROBE"
18491   "call\t__alloca"
18492   [(set_attr "type" "multi")
18493    (set_attr "length" "5")])
18495 (define_expand "allocate_stack_worker_rex64_postreload"
18496   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18497                                     UNSPECV_STACK_PROBE)
18498               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18499               (clobber (match_dup 0))
18500               (clobber (reg:CC FLAGS_REG))])]
18501   ""
18502   "")
18504 (define_expand "allocate_stack"
18505   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18506                    (minus:SI (reg:SI SP_REG)
18507                              (match_operand:SI 1 "general_operand" "")))
18508               (clobber (reg:CC FLAGS_REG))])
18509    (parallel [(set (reg:SI SP_REG)
18510                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18511               (clobber (reg:CC FLAGS_REG))])]
18512   "TARGET_STACK_PROBE"
18514 #ifdef CHECK_STACK_LIMIT
18515   if (GET_CODE (operands[1]) == CONST_INT
18516       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18517     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18518                            operands[1]));
18519   else 
18520 #endif
18521     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18522                                                             operands[1])));
18524   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18525   DONE;
18528 (define_expand "builtin_setjmp_receiver"
18529   [(label_ref (match_operand 0 "" ""))]
18530   "!TARGET_64BIT && flag_pic"
18532   emit_insn (gen_set_got (pic_offset_table_rtx));
18533   DONE;
18536 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18538 (define_split
18539   [(set (match_operand 0 "register_operand" "")
18540         (match_operator 3 "promotable_binary_operator"
18541            [(match_operand 1 "register_operand" "")
18542             (match_operand 2 "aligned_operand" "")]))
18543    (clobber (reg:CC FLAGS_REG))]
18544   "! TARGET_PARTIAL_REG_STALL && reload_completed
18545    && ((GET_MODE (operands[0]) == HImode 
18546         && ((!optimize_size && !TARGET_FAST_PREFIX)
18547             || GET_CODE (operands[2]) != CONST_INT
18548             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18549        || (GET_MODE (operands[0]) == QImode 
18550            && (TARGET_PROMOTE_QImode || optimize_size)))"
18551   [(parallel [(set (match_dup 0)
18552                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18553               (clobber (reg:CC FLAGS_REG))])]
18554   "operands[0] = gen_lowpart (SImode, operands[0]);
18555    operands[1] = gen_lowpart (SImode, operands[1]);
18556    if (GET_CODE (operands[3]) != ASHIFT)
18557      operands[2] = gen_lowpart (SImode, operands[2]);
18558    PUT_MODE (operands[3], SImode);")
18560 ; Promote the QImode tests, as i386 has encoding of the AND
18561 ; instruction with 32-bit sign-extended immediate and thus the
18562 ; instruction size is unchanged, except in the %eax case for
18563 ; which it is increased by one byte, hence the ! optimize_size.
18564 (define_split
18565   [(set (match_operand 0 "flags_reg_operand" "")
18566         (match_operator 2 "compare_operator"
18567           [(and (match_operand 3 "aligned_operand" "")
18568                 (match_operand 4 "const_int_operand" ""))
18569            (const_int 0)]))
18570    (set (match_operand 1 "register_operand" "")
18571         (and (match_dup 3) (match_dup 4)))]
18572   "! TARGET_PARTIAL_REG_STALL && reload_completed
18573    /* Ensure that the operand will remain sign-extended immediate.  */
18574    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18575    && ! optimize_size
18576    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18577        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18578   [(parallel [(set (match_dup 0)
18579                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18580                                     (const_int 0)]))
18581               (set (match_dup 1)
18582                    (and:SI (match_dup 3) (match_dup 4)))])]
18584   operands[4]
18585     = gen_int_mode (INTVAL (operands[4])
18586                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18587   operands[1] = gen_lowpart (SImode, operands[1]);
18588   operands[3] = gen_lowpart (SImode, operands[3]);
18591 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18592 ; the TEST instruction with 32-bit sign-extended immediate and thus
18593 ; the instruction size would at least double, which is not what we
18594 ; want even with ! optimize_size.
18595 (define_split
18596   [(set (match_operand 0 "flags_reg_operand" "")
18597         (match_operator 1 "compare_operator"
18598           [(and (match_operand:HI 2 "aligned_operand" "")
18599                 (match_operand:HI 3 "const_int_operand" ""))
18600            (const_int 0)]))]
18601   "! TARGET_PARTIAL_REG_STALL && reload_completed
18602    /* Ensure that the operand will remain sign-extended immediate.  */
18603    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18604    && ! TARGET_FAST_PREFIX
18605    && ! optimize_size"
18606   [(set (match_dup 0)
18607         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18608                          (const_int 0)]))]
18610   operands[3]
18611     = gen_int_mode (INTVAL (operands[3])
18612                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18613   operands[2] = gen_lowpart (SImode, operands[2]);
18616 (define_split
18617   [(set (match_operand 0 "register_operand" "")
18618         (neg (match_operand 1 "register_operand" "")))
18619    (clobber (reg:CC FLAGS_REG))]
18620   "! TARGET_PARTIAL_REG_STALL && reload_completed
18621    && (GET_MODE (operands[0]) == HImode
18622        || (GET_MODE (operands[0]) == QImode 
18623            && (TARGET_PROMOTE_QImode || optimize_size)))"
18624   [(parallel [(set (match_dup 0)
18625                    (neg:SI (match_dup 1)))
18626               (clobber (reg:CC FLAGS_REG))])]
18627   "operands[0] = gen_lowpart (SImode, operands[0]);
18628    operands[1] = gen_lowpart (SImode, operands[1]);")
18630 (define_split
18631   [(set (match_operand 0 "register_operand" "")
18632         (not (match_operand 1 "register_operand" "")))]
18633   "! TARGET_PARTIAL_REG_STALL && reload_completed
18634    && (GET_MODE (operands[0]) == HImode
18635        || (GET_MODE (operands[0]) == QImode 
18636            && (TARGET_PROMOTE_QImode || optimize_size)))"
18637   [(set (match_dup 0)
18638         (not:SI (match_dup 1)))]
18639   "operands[0] = gen_lowpart (SImode, operands[0]);
18640    operands[1] = gen_lowpart (SImode, operands[1]);")
18642 (define_split 
18643   [(set (match_operand 0 "register_operand" "")
18644         (if_then_else (match_operator 1 "comparison_operator" 
18645                                 [(reg FLAGS_REG) (const_int 0)])
18646                       (match_operand 2 "register_operand" "")
18647                       (match_operand 3 "register_operand" "")))]
18648   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18649    && (GET_MODE (operands[0]) == HImode
18650        || (GET_MODE (operands[0]) == QImode 
18651            && (TARGET_PROMOTE_QImode || optimize_size)))"
18652   [(set (match_dup 0)
18653         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18654   "operands[0] = gen_lowpart (SImode, operands[0]);
18655    operands[2] = gen_lowpart (SImode, operands[2]);
18656    operands[3] = gen_lowpart (SImode, operands[3]);")
18657                         
18659 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18660 ;; transform a complex memory operation into two memory to register operations.
18662 ;; Don't push memory operands
18663 (define_peephole2
18664   [(set (match_operand:SI 0 "push_operand" "")
18665         (match_operand:SI 1 "memory_operand" ""))
18666    (match_scratch:SI 2 "r")]
18667   "! optimize_size && ! TARGET_PUSH_MEMORY"
18668   [(set (match_dup 2) (match_dup 1))
18669    (set (match_dup 0) (match_dup 2))]
18670   "")
18672 (define_peephole2
18673   [(set (match_operand:DI 0 "push_operand" "")
18674         (match_operand:DI 1 "memory_operand" ""))
18675    (match_scratch:DI 2 "r")]
18676   "! optimize_size && ! TARGET_PUSH_MEMORY"
18677   [(set (match_dup 2) (match_dup 1))
18678    (set (match_dup 0) (match_dup 2))]
18679   "")
18681 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18682 ;; SImode pushes.
18683 (define_peephole2
18684   [(set (match_operand:SF 0 "push_operand" "")
18685         (match_operand:SF 1 "memory_operand" ""))
18686    (match_scratch:SF 2 "r")]
18687   "! optimize_size && ! TARGET_PUSH_MEMORY"
18688   [(set (match_dup 2) (match_dup 1))
18689    (set (match_dup 0) (match_dup 2))]
18690   "")
18692 (define_peephole2
18693   [(set (match_operand:HI 0 "push_operand" "")
18694         (match_operand:HI 1 "memory_operand" ""))
18695    (match_scratch:HI 2 "r")]
18696   "! optimize_size && ! TARGET_PUSH_MEMORY"
18697   [(set (match_dup 2) (match_dup 1))
18698    (set (match_dup 0) (match_dup 2))]
18699   "")
18701 (define_peephole2
18702   [(set (match_operand:QI 0 "push_operand" "")
18703         (match_operand:QI 1 "memory_operand" ""))
18704    (match_scratch:QI 2 "q")]
18705   "! optimize_size && ! TARGET_PUSH_MEMORY"
18706   [(set (match_dup 2) (match_dup 1))
18707    (set (match_dup 0) (match_dup 2))]
18708   "")
18710 ;; Don't move an immediate directly to memory when the instruction
18711 ;; gets too big.
18712 (define_peephole2
18713   [(match_scratch:SI 1 "r")
18714    (set (match_operand:SI 0 "memory_operand" "")
18715         (const_int 0))]
18716   "! optimize_size
18717    && ! TARGET_USE_MOV0
18718    && TARGET_SPLIT_LONG_MOVES
18719    && get_attr_length (insn) >= ix86_cost->large_insn
18720    && peep2_regno_dead_p (0, FLAGS_REG)"
18721   [(parallel [(set (match_dup 1) (const_int 0))
18722               (clobber (reg:CC FLAGS_REG))])
18723    (set (match_dup 0) (match_dup 1))]
18724   "")
18726 (define_peephole2
18727   [(match_scratch:HI 1 "r")
18728    (set (match_operand:HI 0 "memory_operand" "")
18729         (const_int 0))]
18730   "! optimize_size
18731    && ! TARGET_USE_MOV0
18732    && TARGET_SPLIT_LONG_MOVES
18733    && get_attr_length (insn) >= ix86_cost->large_insn
18734    && peep2_regno_dead_p (0, FLAGS_REG)"
18735   [(parallel [(set (match_dup 2) (const_int 0))
18736               (clobber (reg:CC FLAGS_REG))])
18737    (set (match_dup 0) (match_dup 1))]
18738   "operands[2] = gen_lowpart (SImode, operands[1]);")
18740 (define_peephole2
18741   [(match_scratch:QI 1 "q")
18742    (set (match_operand:QI 0 "memory_operand" "")
18743         (const_int 0))]
18744   "! optimize_size
18745    && ! TARGET_USE_MOV0
18746    && TARGET_SPLIT_LONG_MOVES
18747    && get_attr_length (insn) >= ix86_cost->large_insn
18748    && peep2_regno_dead_p (0, FLAGS_REG)"
18749   [(parallel [(set (match_dup 2) (const_int 0))
18750               (clobber (reg:CC FLAGS_REG))])
18751    (set (match_dup 0) (match_dup 1))]
18752   "operands[2] = gen_lowpart (SImode, operands[1]);")
18754 (define_peephole2
18755   [(match_scratch:SI 2 "r")
18756    (set (match_operand:SI 0 "memory_operand" "")
18757         (match_operand:SI 1 "immediate_operand" ""))]
18758   "! optimize_size
18759    && get_attr_length (insn) >= ix86_cost->large_insn
18760    && TARGET_SPLIT_LONG_MOVES"
18761   [(set (match_dup 2) (match_dup 1))
18762    (set (match_dup 0) (match_dup 2))]
18763   "")
18765 (define_peephole2
18766   [(match_scratch:HI 2 "r")
18767    (set (match_operand:HI 0 "memory_operand" "")
18768         (match_operand:HI 1 "immediate_operand" ""))]
18769   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18770   && TARGET_SPLIT_LONG_MOVES"
18771   [(set (match_dup 2) (match_dup 1))
18772    (set (match_dup 0) (match_dup 2))]
18773   "")
18775 (define_peephole2
18776   [(match_scratch:QI 2 "q")
18777    (set (match_operand:QI 0 "memory_operand" "")
18778         (match_operand:QI 1 "immediate_operand" ""))]
18779   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18780   && TARGET_SPLIT_LONG_MOVES"
18781   [(set (match_dup 2) (match_dup 1))
18782    (set (match_dup 0) (match_dup 2))]
18783   "")
18785 ;; Don't compare memory with zero, load and use a test instead.
18786 (define_peephole2
18787   [(set (match_operand 0 "flags_reg_operand" "")
18788         (match_operator 1 "compare_operator"
18789           [(match_operand:SI 2 "memory_operand" "")
18790            (const_int 0)]))
18791    (match_scratch:SI 3 "r")]
18792   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18793   [(set (match_dup 3) (match_dup 2))
18794    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18795   "")
18797 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18798 ;; Don't split NOTs with a displacement operand, because resulting XOR
18799 ;; will not be pairable anyway.
18801 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18802 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18803 ;; so this split helps here as well.
18805 ;; Note: Can't do this as a regular split because we can't get proper
18806 ;; lifetime information then.
18808 (define_peephole2
18809   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18810         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18811   "!optimize_size
18812    && peep2_regno_dead_p (0, FLAGS_REG)
18813    && ((TARGET_PENTIUM 
18814         && (GET_CODE (operands[0]) != MEM
18815             || !memory_displacement_operand (operands[0], SImode)))
18816        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18817   [(parallel [(set (match_dup 0)
18818                    (xor:SI (match_dup 1) (const_int -1)))
18819               (clobber (reg:CC FLAGS_REG))])]
18820   "")
18822 (define_peephole2
18823   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18824         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18825   "!optimize_size
18826    && peep2_regno_dead_p (0, FLAGS_REG)
18827    && ((TARGET_PENTIUM 
18828         && (GET_CODE (operands[0]) != MEM
18829             || !memory_displacement_operand (operands[0], HImode)))
18830        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18831   [(parallel [(set (match_dup 0)
18832                    (xor:HI (match_dup 1) (const_int -1)))
18833               (clobber (reg:CC FLAGS_REG))])]
18834   "")
18836 (define_peephole2
18837   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18838         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18839   "!optimize_size
18840    && peep2_regno_dead_p (0, FLAGS_REG)
18841    && ((TARGET_PENTIUM 
18842         && (GET_CODE (operands[0]) != MEM
18843             || !memory_displacement_operand (operands[0], QImode)))
18844        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18845   [(parallel [(set (match_dup 0)
18846                    (xor:QI (match_dup 1) (const_int -1)))
18847               (clobber (reg:CC FLAGS_REG))])]
18848   "")
18850 ;; Non pairable "test imm, reg" instructions can be translated to
18851 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18852 ;; byte opcode instead of two, have a short form for byte operands),
18853 ;; so do it for other CPUs as well.  Given that the value was dead,
18854 ;; this should not create any new dependencies.  Pass on the sub-word
18855 ;; versions if we're concerned about partial register stalls.
18857 (define_peephole2
18858   [(set (match_operand 0 "flags_reg_operand" "")
18859         (match_operator 1 "compare_operator"
18860           [(and:SI (match_operand:SI 2 "register_operand" "")
18861                    (match_operand:SI 3 "immediate_operand" ""))
18862            (const_int 0)]))]
18863   "ix86_match_ccmode (insn, CCNOmode)
18864    && (true_regnum (operands[2]) != 0
18865        || (GET_CODE (operands[3]) == CONST_INT
18866            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18867    && peep2_reg_dead_p (1, operands[2])"
18868   [(parallel
18869      [(set (match_dup 0)
18870            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18871                             (const_int 0)]))
18872       (set (match_dup 2)
18873            (and:SI (match_dup 2) (match_dup 3)))])]
18874   "")
18876 ;; We don't need to handle HImode case, because it will be promoted to SImode
18877 ;; on ! TARGET_PARTIAL_REG_STALL
18879 (define_peephole2
18880   [(set (match_operand 0 "flags_reg_operand" "")
18881         (match_operator 1 "compare_operator"
18882           [(and:QI (match_operand:QI 2 "register_operand" "")
18883                    (match_operand:QI 3 "immediate_operand" ""))
18884            (const_int 0)]))]
18885   "! TARGET_PARTIAL_REG_STALL
18886    && ix86_match_ccmode (insn, CCNOmode)
18887    && true_regnum (operands[2]) != 0
18888    && peep2_reg_dead_p (1, operands[2])"
18889   [(parallel
18890      [(set (match_dup 0)
18891            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18892                             (const_int 0)]))
18893       (set (match_dup 2)
18894            (and:QI (match_dup 2) (match_dup 3)))])]
18895   "")
18897 (define_peephole2
18898   [(set (match_operand 0 "flags_reg_operand" "")
18899         (match_operator 1 "compare_operator"
18900           [(and:SI
18901              (zero_extract:SI
18902                (match_operand 2 "ext_register_operand" "")
18903                (const_int 8)
18904                (const_int 8))
18905              (match_operand 3 "const_int_operand" ""))
18906            (const_int 0)]))]
18907   "! TARGET_PARTIAL_REG_STALL
18908    && ix86_match_ccmode (insn, CCNOmode)
18909    && true_regnum (operands[2]) != 0
18910    && peep2_reg_dead_p (1, operands[2])"
18911   [(parallel [(set (match_dup 0)
18912                    (match_op_dup 1
18913                      [(and:SI
18914                         (zero_extract:SI
18915                           (match_dup 2)
18916                           (const_int 8)
18917                           (const_int 8))
18918                         (match_dup 3))
18919                       (const_int 0)]))
18920               (set (zero_extract:SI (match_dup 2)
18921                                     (const_int 8)
18922                                     (const_int 8))
18923                    (and:SI 
18924                      (zero_extract:SI
18925                        (match_dup 2)
18926                        (const_int 8)
18927                        (const_int 8))
18928                      (match_dup 3)))])]
18929   "")
18931 ;; Don't do logical operations with memory inputs.
18932 (define_peephole2
18933   [(match_scratch:SI 2 "r")
18934    (parallel [(set (match_operand:SI 0 "register_operand" "")
18935                    (match_operator:SI 3 "arith_or_logical_operator"
18936                      [(match_dup 0)
18937                       (match_operand:SI 1 "memory_operand" "")]))
18938               (clobber (reg:CC FLAGS_REG))])]
18939   "! optimize_size && ! TARGET_READ_MODIFY"
18940   [(set (match_dup 2) (match_dup 1))
18941    (parallel [(set (match_dup 0)
18942                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18943               (clobber (reg:CC FLAGS_REG))])]
18944   "")
18946 (define_peephole2
18947   [(match_scratch:SI 2 "r")
18948    (parallel [(set (match_operand:SI 0 "register_operand" "")
18949                    (match_operator:SI 3 "arith_or_logical_operator"
18950                      [(match_operand:SI 1 "memory_operand" "")
18951                       (match_dup 0)]))
18952               (clobber (reg:CC FLAGS_REG))])]
18953   "! optimize_size && ! TARGET_READ_MODIFY"
18954   [(set (match_dup 2) (match_dup 1))
18955    (parallel [(set (match_dup 0)
18956                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18957               (clobber (reg:CC FLAGS_REG))])]
18958   "")
18960 ; Don't do logical operations with memory outputs
18962 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18963 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18964 ; the same decoder scheduling characteristics as the original.
18966 (define_peephole2
18967   [(match_scratch:SI 2 "r")
18968    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18969                    (match_operator:SI 3 "arith_or_logical_operator"
18970                      [(match_dup 0)
18971                       (match_operand:SI 1 "nonmemory_operand" "")]))
18972               (clobber (reg:CC FLAGS_REG))])]
18973   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18974   [(set (match_dup 2) (match_dup 0))
18975    (parallel [(set (match_dup 2)
18976                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18977               (clobber (reg:CC FLAGS_REG))])
18978    (set (match_dup 0) (match_dup 2))]
18979   "")
18981 (define_peephole2
18982   [(match_scratch:SI 2 "r")
18983    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18984                    (match_operator:SI 3 "arith_or_logical_operator"
18985                      [(match_operand:SI 1 "nonmemory_operand" "")
18986                       (match_dup 0)]))
18987               (clobber (reg:CC FLAGS_REG))])]
18988   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18989   [(set (match_dup 2) (match_dup 0))
18990    (parallel [(set (match_dup 2)
18991                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18992               (clobber (reg:CC FLAGS_REG))])
18993    (set (match_dup 0) (match_dup 2))]
18994   "")
18996 ;; Attempt to always use XOR for zeroing registers.
18997 (define_peephole2
18998   [(set (match_operand 0 "register_operand" "")
18999         (const_int 0))]
19000   "(GET_MODE (operands[0]) == QImode
19001     || GET_MODE (operands[0]) == HImode
19002     || GET_MODE (operands[0]) == SImode
19003     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19004    && (! TARGET_USE_MOV0 || optimize_size)
19005    && peep2_regno_dead_p (0, FLAGS_REG)"
19006   [(parallel [(set (match_dup 0) (const_int 0))
19007               (clobber (reg:CC FLAGS_REG))])]
19008   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19009                               operands[0]);")
19011 (define_peephole2
19012   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19013         (const_int 0))]
19014   "(GET_MODE (operands[0]) == QImode
19015     || GET_MODE (operands[0]) == HImode)
19016    && (! TARGET_USE_MOV0 || optimize_size)
19017    && peep2_regno_dead_p (0, FLAGS_REG)"
19018   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19019               (clobber (reg:CC FLAGS_REG))])])
19021 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19022 (define_peephole2
19023   [(set (match_operand 0 "register_operand" "")
19024         (const_int -1))]
19025   "(GET_MODE (operands[0]) == HImode
19026     || GET_MODE (operands[0]) == SImode 
19027     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19028    && (optimize_size || TARGET_PENTIUM)
19029    && peep2_regno_dead_p (0, FLAGS_REG)"
19030   [(parallel [(set (match_dup 0) (const_int -1))
19031               (clobber (reg:CC FLAGS_REG))])]
19032   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19033                               operands[0]);")
19035 ;; Attempt to convert simple leas to adds. These can be created by
19036 ;; move expanders.
19037 (define_peephole2
19038   [(set (match_operand:SI 0 "register_operand" "")
19039         (plus:SI (match_dup 0)
19040                  (match_operand:SI 1 "nonmemory_operand" "")))]
19041   "peep2_regno_dead_p (0, FLAGS_REG)"
19042   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19043               (clobber (reg:CC FLAGS_REG))])]
19044   "")
19046 (define_peephole2
19047   [(set (match_operand:SI 0 "register_operand" "")
19048         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19049                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19050   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19051   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19052               (clobber (reg:CC FLAGS_REG))])]
19053   "operands[2] = gen_lowpart (SImode, operands[2]);")
19055 (define_peephole2
19056   [(set (match_operand:DI 0 "register_operand" "")
19057         (plus:DI (match_dup 0)
19058                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19059   "peep2_regno_dead_p (0, FLAGS_REG)"
19060   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19061               (clobber (reg:CC FLAGS_REG))])]
19062   "")
19064 (define_peephole2
19065   [(set (match_operand:SI 0 "register_operand" "")
19066         (mult:SI (match_dup 0)
19067                  (match_operand:SI 1 "const_int_operand" "")))]
19068   "exact_log2 (INTVAL (operands[1])) >= 0
19069    && peep2_regno_dead_p (0, FLAGS_REG)"
19070   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19071               (clobber (reg:CC FLAGS_REG))])]
19072   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19074 (define_peephole2
19075   [(set (match_operand:DI 0 "register_operand" "")
19076         (mult:DI (match_dup 0)
19077                  (match_operand:DI 1 "const_int_operand" "")))]
19078   "exact_log2 (INTVAL (operands[1])) >= 0
19079    && peep2_regno_dead_p (0, FLAGS_REG)"
19080   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19081               (clobber (reg:CC FLAGS_REG))])]
19082   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19084 (define_peephole2
19085   [(set (match_operand:SI 0 "register_operand" "")
19086         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19087                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19088   "exact_log2 (INTVAL (operands[2])) >= 0
19089    && REGNO (operands[0]) == REGNO (operands[1])
19090    && peep2_regno_dead_p (0, FLAGS_REG)"
19091   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19092               (clobber (reg:CC FLAGS_REG))])]
19093   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19095 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19096 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19097 ;; many CPUs it is also faster, since special hardware to avoid esp
19098 ;; dependencies is present.
19100 ;; While some of these conversions may be done using splitters, we use peepholes
19101 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19103 ;; Convert prologue esp subtractions to push.
19104 ;; We need register to push.  In order to keep verify_flow_info happy we have
19105 ;; two choices
19106 ;; - use scratch and clobber it in order to avoid dependencies
19107 ;; - use already live register
19108 ;; We can't use the second way right now, since there is no reliable way how to
19109 ;; verify that given register is live.  First choice will also most likely in
19110 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19111 ;; call clobbered registers are dead.  We may want to use base pointer as an
19112 ;; alternative when no register is available later.
19114 (define_peephole2
19115   [(match_scratch:SI 0 "r")
19116    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19117               (clobber (reg:CC FLAGS_REG))
19118               (clobber (mem:BLK (scratch)))])]
19119   "optimize_size || !TARGET_SUB_ESP_4"
19120   [(clobber (match_dup 0))
19121    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19122               (clobber (mem:BLK (scratch)))])])
19124 (define_peephole2
19125   [(match_scratch:SI 0 "r")
19126    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19127               (clobber (reg:CC FLAGS_REG))
19128               (clobber (mem:BLK (scratch)))])]
19129   "optimize_size || !TARGET_SUB_ESP_8"
19130   [(clobber (match_dup 0))
19131    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19132    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19133               (clobber (mem:BLK (scratch)))])])
19135 ;; Convert esp subtractions to push.
19136 (define_peephole2
19137   [(match_scratch:SI 0 "r")
19138    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19139               (clobber (reg:CC FLAGS_REG))])]
19140   "optimize_size || !TARGET_SUB_ESP_4"
19141   [(clobber (match_dup 0))
19142    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19144 (define_peephole2
19145   [(match_scratch:SI 0 "r")
19146    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19147               (clobber (reg:CC FLAGS_REG))])]
19148   "optimize_size || !TARGET_SUB_ESP_8"
19149   [(clobber (match_dup 0))
19150    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19151    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19153 ;; Convert epilogue deallocator to pop.
19154 (define_peephole2
19155   [(match_scratch:SI 0 "r")
19156    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19157               (clobber (reg:CC FLAGS_REG))
19158               (clobber (mem:BLK (scratch)))])]
19159   "optimize_size || !TARGET_ADD_ESP_4"
19160   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19161               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19162               (clobber (mem:BLK (scratch)))])]
19163   "")
19165 ;; Two pops case is tricky, since pop causes dependency on destination register.
19166 ;; We use two registers if available.
19167 (define_peephole2
19168   [(match_scratch:SI 0 "r")
19169    (match_scratch:SI 1 "r")
19170    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19171               (clobber (reg:CC FLAGS_REG))
19172               (clobber (mem:BLK (scratch)))])]
19173   "optimize_size || !TARGET_ADD_ESP_8"
19174   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19175               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19176               (clobber (mem:BLK (scratch)))])
19177    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19178               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19179   "")
19181 (define_peephole2
19182   [(match_scratch:SI 0 "r")
19183    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19184               (clobber (reg:CC FLAGS_REG))
19185               (clobber (mem:BLK (scratch)))])]
19186   "optimize_size"
19187   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19188               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19189               (clobber (mem:BLK (scratch)))])
19190    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19191               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19192   "")
19194 ;; Convert esp additions to pop.
19195 (define_peephole2
19196   [(match_scratch:SI 0 "r")
19197    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19198               (clobber (reg:CC FLAGS_REG))])]
19199   ""
19200   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19201               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19202   "")
19204 ;; Two pops case is tricky, since pop causes dependency on destination register.
19205 ;; We use two registers if available.
19206 (define_peephole2
19207   [(match_scratch:SI 0 "r")
19208    (match_scratch:SI 1 "r")
19209    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19210               (clobber (reg:CC FLAGS_REG))])]
19211   ""
19212   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19213               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19214    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19215               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19216   "")
19218 (define_peephole2
19219   [(match_scratch:SI 0 "r")
19220    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19221               (clobber (reg:CC FLAGS_REG))])]
19222   "optimize_size"
19223   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19224               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19225    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19226               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19227   "")
19229 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19230 ;; required and register dies.  Similarly for 128 to plus -128.
19231 (define_peephole2
19232   [(set (match_operand 0 "flags_reg_operand" "")
19233         (match_operator 1 "compare_operator"
19234           [(match_operand 2 "register_operand" "")
19235            (match_operand 3 "const_int_operand" "")]))]
19236   "(INTVAL (operands[3]) == -1
19237     || INTVAL (operands[3]) == 1
19238     || INTVAL (operands[3]) == 128)
19239    && ix86_match_ccmode (insn, CCGCmode)
19240    && peep2_reg_dead_p (1, operands[2])"
19241   [(parallel [(set (match_dup 0)
19242                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19243               (clobber (match_dup 2))])]
19244   "")
19246 (define_peephole2
19247   [(match_scratch:DI 0 "r")
19248    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19249               (clobber (reg:CC FLAGS_REG))
19250               (clobber (mem:BLK (scratch)))])]
19251   "optimize_size || !TARGET_SUB_ESP_4"
19252   [(clobber (match_dup 0))
19253    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19254               (clobber (mem:BLK (scratch)))])])
19256 (define_peephole2
19257   [(match_scratch:DI 0 "r")
19258    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19259               (clobber (reg:CC FLAGS_REG))
19260               (clobber (mem:BLK (scratch)))])]
19261   "optimize_size || !TARGET_SUB_ESP_8"
19262   [(clobber (match_dup 0))
19263    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19264    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19265               (clobber (mem:BLK (scratch)))])])
19267 ;; Convert esp subtractions to push.
19268 (define_peephole2
19269   [(match_scratch:DI 0 "r")
19270    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19271               (clobber (reg:CC FLAGS_REG))])]
19272   "optimize_size || !TARGET_SUB_ESP_4"
19273   [(clobber (match_dup 0))
19274    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19276 (define_peephole2
19277   [(match_scratch:DI 0 "r")
19278    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19279               (clobber (reg:CC FLAGS_REG))])]
19280   "optimize_size || !TARGET_SUB_ESP_8"
19281   [(clobber (match_dup 0))
19282    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19283    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19285 ;; Convert epilogue deallocator to pop.
19286 (define_peephole2
19287   [(match_scratch:DI 0 "r")
19288    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19289               (clobber (reg:CC FLAGS_REG))
19290               (clobber (mem:BLK (scratch)))])]
19291   "optimize_size || !TARGET_ADD_ESP_4"
19292   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19293               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19294               (clobber (mem:BLK (scratch)))])]
19295   "")
19297 ;; Two pops case is tricky, since pop causes dependency on destination register.
19298 ;; We use two registers if available.
19299 (define_peephole2
19300   [(match_scratch:DI 0 "r")
19301    (match_scratch:DI 1 "r")
19302    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19303               (clobber (reg:CC FLAGS_REG))
19304               (clobber (mem:BLK (scratch)))])]
19305   "optimize_size || !TARGET_ADD_ESP_8"
19306   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19307               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19308               (clobber (mem:BLK (scratch)))])
19309    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19310               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19311   "")
19313 (define_peephole2
19314   [(match_scratch:DI 0 "r")
19315    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19316               (clobber (reg:CC FLAGS_REG))
19317               (clobber (mem:BLK (scratch)))])]
19318   "optimize_size"
19319   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19320               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19321               (clobber (mem:BLK (scratch)))])
19322    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19323               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19324   "")
19326 ;; Convert esp additions to pop.
19327 (define_peephole2
19328   [(match_scratch:DI 0 "r")
19329    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19330               (clobber (reg:CC FLAGS_REG))])]
19331   ""
19332   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19333               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19334   "")
19336 ;; Two pops case is tricky, since pop causes dependency on destination register.
19337 ;; We use two registers if available.
19338 (define_peephole2
19339   [(match_scratch:DI 0 "r")
19340    (match_scratch:DI 1 "r")
19341    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19342               (clobber (reg:CC FLAGS_REG))])]
19343   ""
19344   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19345               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19346    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19347               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19348   "")
19350 (define_peephole2
19351   [(match_scratch:DI 0 "r")
19352    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19353               (clobber (reg:CC FLAGS_REG))])]
19354   "optimize_size"
19355   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19356               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19357    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19358               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19359   "")
19361 ;; Convert imul by three, five and nine into lea
19362 (define_peephole2
19363   [(parallel
19364     [(set (match_operand:SI 0 "register_operand" "")
19365           (mult:SI (match_operand:SI 1 "register_operand" "")
19366                    (match_operand:SI 2 "const_int_operand" "")))
19367      (clobber (reg:CC FLAGS_REG))])]
19368   "INTVAL (operands[2]) == 3
19369    || INTVAL (operands[2]) == 5
19370    || INTVAL (operands[2]) == 9"
19371   [(set (match_dup 0)
19372         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19373                  (match_dup 1)))]
19374   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19376 (define_peephole2
19377   [(parallel
19378     [(set (match_operand:SI 0 "register_operand" "")
19379           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19380                    (match_operand:SI 2 "const_int_operand" "")))
19381      (clobber (reg:CC FLAGS_REG))])]
19382   "!optimize_size 
19383    && (INTVAL (operands[2]) == 3
19384        || INTVAL (operands[2]) == 5
19385        || INTVAL (operands[2]) == 9)"
19386   [(set (match_dup 0) (match_dup 1))
19387    (set (match_dup 0)
19388         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19389                  (match_dup 0)))]
19390   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19392 (define_peephole2
19393   [(parallel
19394     [(set (match_operand:DI 0 "register_operand" "")
19395           (mult:DI (match_operand:DI 1 "register_operand" "")
19396                    (match_operand:DI 2 "const_int_operand" "")))
19397      (clobber (reg:CC FLAGS_REG))])]
19398   "TARGET_64BIT
19399    && (INTVAL (operands[2]) == 3
19400        || INTVAL (operands[2]) == 5
19401        || INTVAL (operands[2]) == 9)"
19402   [(set (match_dup 0)
19403         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19404                  (match_dup 1)))]
19405   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19407 (define_peephole2
19408   [(parallel
19409     [(set (match_operand:DI 0 "register_operand" "")
19410           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19411                    (match_operand:DI 2 "const_int_operand" "")))
19412      (clobber (reg:CC FLAGS_REG))])]
19413   "TARGET_64BIT
19414    && !optimize_size 
19415    && (INTVAL (operands[2]) == 3
19416        || INTVAL (operands[2]) == 5
19417        || INTVAL (operands[2]) == 9)"
19418   [(set (match_dup 0) (match_dup 1))
19419    (set (match_dup 0)
19420         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19421                  (match_dup 0)))]
19422   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19424 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19425 ;; imul $32bit_imm, reg, reg is direct decoded.
19426 (define_peephole2
19427   [(match_scratch:DI 3 "r")
19428    (parallel [(set (match_operand:DI 0 "register_operand" "")
19429                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19430                             (match_operand:DI 2 "immediate_operand" "")))
19431               (clobber (reg:CC FLAGS_REG))])]
19432   "TARGET_K8 && !optimize_size
19433    && (GET_CODE (operands[2]) != CONST_INT
19434        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19435   [(set (match_dup 3) (match_dup 1))
19436    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19437               (clobber (reg:CC FLAGS_REG))])]
19440 (define_peephole2
19441   [(match_scratch:SI 3 "r")
19442    (parallel [(set (match_operand:SI 0 "register_operand" "")
19443                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19444                             (match_operand:SI 2 "immediate_operand" "")))
19445               (clobber (reg:CC FLAGS_REG))])]
19446   "TARGET_K8 && !optimize_size
19447    && (GET_CODE (operands[2]) != CONST_INT
19448        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19449   [(set (match_dup 3) (match_dup 1))
19450    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19451               (clobber (reg:CC FLAGS_REG))])]
19454 (define_peephole2
19455   [(match_scratch:SI 3 "r")
19456    (parallel [(set (match_operand:DI 0 "register_operand" "")
19457                    (zero_extend:DI
19458                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19459                               (match_operand:SI 2 "immediate_operand" ""))))
19460               (clobber (reg:CC FLAGS_REG))])]
19461   "TARGET_K8 && !optimize_size
19462    && (GET_CODE (operands[2]) != CONST_INT
19463        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19464   [(set (match_dup 3) (match_dup 1))
19465    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19466               (clobber (reg:CC FLAGS_REG))])]
19469 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19470 ;; Convert it into imul reg, reg
19471 ;; It would be better to force assembler to encode instruction using long
19472 ;; immediate, but there is apparently no way to do so.
19473 (define_peephole2
19474   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19475                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19476                             (match_operand:DI 2 "const_int_operand" "")))
19477               (clobber (reg:CC FLAGS_REG))])
19478    (match_scratch:DI 3 "r")]
19479   "TARGET_K8 && !optimize_size
19480    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19481   [(set (match_dup 3) (match_dup 2))
19482    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19483               (clobber (reg:CC FLAGS_REG))])]
19485   if (!rtx_equal_p (operands[0], operands[1]))
19486     emit_move_insn (operands[0], operands[1]);
19489 (define_peephole2
19490   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19491                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19492                             (match_operand:SI 2 "const_int_operand" "")))
19493               (clobber (reg:CC FLAGS_REG))])
19494    (match_scratch:SI 3 "r")]
19495   "TARGET_K8 && !optimize_size
19496    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19497   [(set (match_dup 3) (match_dup 2))
19498    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19499               (clobber (reg:CC FLAGS_REG))])]
19501   if (!rtx_equal_p (operands[0], operands[1]))
19502     emit_move_insn (operands[0], operands[1]);
19505 (define_peephole2
19506   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19507                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19508                             (match_operand:HI 2 "immediate_operand" "")))
19509               (clobber (reg:CC FLAGS_REG))])
19510    (match_scratch:HI 3 "r")]
19511   "TARGET_K8 && !optimize_size"
19512   [(set (match_dup 3) (match_dup 2))
19513    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19514               (clobber (reg:CC FLAGS_REG))])]
19516   if (!rtx_equal_p (operands[0], operands[1]))
19517     emit_move_insn (operands[0], operands[1]);
19520 ;; Call-value patterns last so that the wildcard operand does not
19521 ;; disrupt insn-recog's switch tables.
19523 (define_insn "*call_value_pop_0"
19524   [(set (match_operand 0 "" "")
19525         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19526               (match_operand:SI 2 "" "")))
19527    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19528                             (match_operand:SI 3 "immediate_operand" "")))]
19529   "!TARGET_64BIT"
19531   if (SIBLING_CALL_P (insn))
19532     return "jmp\t%P1";
19533   else
19534     return "call\t%P1";
19536   [(set_attr "type" "callv")])
19538 (define_insn "*call_value_pop_1"
19539   [(set (match_operand 0 "" "")
19540         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19541               (match_operand:SI 2 "" "")))
19542    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19543                             (match_operand:SI 3 "immediate_operand" "i")))]
19544   "!TARGET_64BIT"
19546   if (constant_call_address_operand (operands[1], Pmode))
19547     {
19548       if (SIBLING_CALL_P (insn))
19549         return "jmp\t%P1";
19550       else
19551         return "call\t%P1";
19552     }
19553   if (SIBLING_CALL_P (insn))
19554     return "jmp\t%A1";
19555   else
19556     return "call\t%A1";
19558   [(set_attr "type" "callv")])
19560 (define_insn "*call_value_0"
19561   [(set (match_operand 0 "" "")
19562         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19563               (match_operand:SI 2 "" "")))]
19564   "!TARGET_64BIT"
19566   if (SIBLING_CALL_P (insn))
19567     return "jmp\t%P1";
19568   else
19569     return "call\t%P1";
19571   [(set_attr "type" "callv")])
19573 (define_insn "*call_value_0_rex64"
19574   [(set (match_operand 0 "" "")
19575         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19576               (match_operand:DI 2 "const_int_operand" "")))]
19577   "TARGET_64BIT"
19579   if (SIBLING_CALL_P (insn))
19580     return "jmp\t%P1";
19581   else
19582     return "call\t%P1";
19584   [(set_attr "type" "callv")])
19586 (define_insn "*call_value_1"
19587   [(set (match_operand 0 "" "")
19588         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19589               (match_operand:SI 2 "" "")))]
19590   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19592   if (constant_call_address_operand (operands[1], Pmode))
19593     return "call\t%P1";
19594   return "call\t%A1";
19596   [(set_attr "type" "callv")])
19598 (define_insn "*sibcall_value_1"
19599   [(set (match_operand 0 "" "")
19600         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19601               (match_operand:SI 2 "" "")))]
19602   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19604   if (constant_call_address_operand (operands[1], Pmode))
19605     return "jmp\t%P1";
19606   return "jmp\t%A1";
19608   [(set_attr "type" "callv")])
19610 (define_insn "*call_value_1_rex64"
19611   [(set (match_operand 0 "" "")
19612         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19613               (match_operand:DI 2 "" "")))]
19614   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19616   if (constant_call_address_operand (operands[1], Pmode))
19617     return "call\t%P1";
19618   return "call\t%A1";
19620   [(set_attr "type" "callv")])
19622 (define_insn "*sibcall_value_1_rex64"
19623   [(set (match_operand 0 "" "")
19624         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19625               (match_operand:DI 2 "" "")))]
19626   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19627   "jmp\t%P1"
19628   [(set_attr "type" "callv")])
19630 (define_insn "*sibcall_value_1_rex64_v"
19631   [(set (match_operand 0 "" "")
19632         (call (mem:QI (reg:DI 40))
19633               (match_operand:DI 1 "" "")))]
19634   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19635   "jmp\t*%%r11"
19636   [(set_attr "type" "callv")])
19638 (define_insn "trap"
19639   [(trap_if (const_int 1) (const_int 5))]
19640   ""
19641   "int\t$5")
19643 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19644 ;;; for the sake of bounds checking.  By emitting bounds checks as
19645 ;;; conditional traps rather than as conditional jumps around
19646 ;;; unconditional traps we avoid introducing spurious basic-block
19647 ;;; boundaries and facilitate elimination of redundant checks.  In
19648 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19649 ;;; interrupt 5.
19650 ;;; 
19651 ;;; FIXME: Static branch prediction rules for ix86 are such that
19652 ;;; forward conditional branches predict as untaken.  As implemented
19653 ;;; below, pseudo conditional traps violate that rule.  We should use
19654 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19655 ;;; section loaded at the end of the text segment and branch forward
19656 ;;; there on bounds-failure, and then jump back immediately (in case
19657 ;;; the system chooses to ignore bounds violations, or to report
19658 ;;; violations and continue execution).
19660 (define_expand "conditional_trap"
19661   [(trap_if (match_operator 0 "comparison_operator"
19662              [(match_dup 2) (const_int 0)])
19663             (match_operand 1 "const_int_operand" ""))]
19664   ""
19666   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19667                               ix86_expand_compare (GET_CODE (operands[0]),
19668                                                    NULL, NULL),
19669                               operands[1]));
19670   DONE;
19673 (define_insn "*conditional_trap_1"
19674   [(trap_if (match_operator 0 "comparison_operator"
19675              [(reg FLAGS_REG) (const_int 0)])
19676             (match_operand 1 "const_int_operand" ""))]
19677   ""
19679   operands[2] = gen_label_rtx ();
19680   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19681   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19682                              CODE_LABEL_NUMBER (operands[2]));
19683   RET;
19686         ;; Pentium III SIMD instructions.
19688 ;; Moves for SSE/MMX regs.
19690 (define_expand "movv4sf"
19691   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19692         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19693   "TARGET_SSE"
19695   ix86_expand_vector_move (V4SFmode, operands);
19696   DONE;
19699 (define_insn "*movv4sf_internal"
19700   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19701         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19702   "TARGET_SSE"
19703   "@
19704     xorps\t%0, %0
19705     movaps\t{%1, %0|%0, %1}
19706     movaps\t{%1, %0|%0, %1}"
19707   [(set_attr "type" "ssemov")
19708    (set_attr "mode" "V4SF")])
19710 (define_split
19711   [(set (match_operand:V4SF 0 "register_operand" "")
19712         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19713   "TARGET_SSE && reload_completed"
19714   [(set (match_dup 0)
19715         (vec_merge:V4SF
19716          (vec_duplicate:V4SF (match_dup 1))
19717          (match_dup 2)
19718          (const_int 1)))]
19720   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19721   operands[2] = CONST0_RTX (V4SFmode);
19724 (define_expand "movv2df"
19725   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19726         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19727   "TARGET_SSE"
19729   ix86_expand_vector_move (V2DFmode, operands);
19730   DONE;
19733 (define_insn "*movv2df_internal"
19734   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19735         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19736   "TARGET_SSE
19737    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19739   switch (which_alternative)
19740     {
19741     case 0:
19742       if (get_attr_mode (insn) == MODE_V4SF)
19743         return "xorps\t%0, %0";
19744       else
19745         return "xorpd\t%0, %0";
19746     case 1:
19747     case 2:
19748       if (get_attr_mode (insn) == MODE_V4SF)
19749         return "movaps\t{%1, %0|%0, %1}";
19750       else
19751         return "movapd\t{%1, %0|%0, %1}";
19752     default:
19753       abort ();
19754     }
19756   [(set_attr "type" "ssemov")
19757    (set (attr "mode")
19758         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
19759                  (const_string "V4SF")
19760                (eq_attr "alternative" "0,1")
19761                  (if_then_else
19762                    (ne (symbol_ref "optimize_size")
19763                        (const_int 0))
19764                    (const_string "V4SF")
19765                    (const_string "V2DF"))
19766                (eq_attr "alternative" "2")
19767                  (if_then_else
19768                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19769                             (const_int 0))
19770                         (ne (symbol_ref "optimize_size")
19771                             (const_int 0)))
19772                    (const_string "V4SF")
19773                    (const_string "V2DF"))]
19774                (const_string "V2DF")))])
19776 (define_split
19777   [(set (match_operand:V2DF 0 "register_operand" "")
19778         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19779   "TARGET_SSE2 && reload_completed"
19780   [(set (match_dup 0)
19781         (vec_merge:V2DF
19782          (vec_duplicate:V2DF (match_dup 1))
19783          (match_dup 2)
19784          (const_int 1)))]
19786   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19787   operands[2] = CONST0_RTX (V2DFmode);
19790 ;; 16 byte integral modes handled by SSE, minus TImode, which gets
19791 ;; special-cased for TARGET_64BIT.
19792 (define_mode_macro SSEMODEI [V16QI V8HI V4SI V2DI])
19794 (define_expand "mov<mode>"
19795   [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "")
19796         (match_operand:SSEMODEI 1 "nonimmediate_operand" ""))]
19797   "TARGET_SSE"
19799   ix86_expand_vector_move (<MODE>mode, operands);
19800   DONE;
19803 (define_insn "*mov<mode>_internal"
19804   [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "=x,x ,m")
19805         (match_operand:SSEMODEI 1 "vector_move_operand"  "C ,xm,x"))]
19806   "TARGET_SSE
19807    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19809   switch (which_alternative)
19810     {
19811     case 0:
19812       if (get_attr_mode (insn) == MODE_V4SF)
19813         return "xorps\t%0, %0";
19814       else
19815         return "pxor\t%0, %0";
19816     case 1:
19817     case 2:
19818       if (get_attr_mode (insn) == MODE_V4SF)
19819         return "movaps\t{%1, %0|%0, %1}";
19820       else
19821         return "movdqa\t{%1, %0|%0, %1}";
19822     default:
19823       abort ();
19824     }
19826   [(set_attr "type" "ssemov")
19827    (set (attr "mode")
19828         (cond [(eq_attr "alternative" "0,1")
19829                  (if_then_else
19830                    (ne (symbol_ref "optimize_size")
19831                        (const_int 0))
19832                    (const_string "V4SF")
19833                    (const_string "TI"))
19834                (eq_attr "alternative" "2")
19835                  (if_then_else
19836                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19837                             (const_int 0))
19838                         (ne (symbol_ref "optimize_size")
19839                             (const_int 0)))
19840                    (const_string "V4SF")
19841                    (const_string "TI"))]
19842                (const_string "TI")))])
19844 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
19845 (define_mode_macro MMXMODEI [V8QI V4HI V2SI])
19847 (define_expand "mov<mode>"
19848   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" "")
19849         (match_operand:MMXMODEI 1 "nonimmediate_operand" ""))]
19850   "TARGET_MMX"
19852   ix86_expand_vector_move (<MODE>mode, operands);
19853   DONE;
19856 (define_insn "*mov<mode>_internal_rex64"
19857   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
19858                                 "=rm,r,*y,*y ,m ,*y,Y ,x,x ,m,r,x")
19859         (match_operand:MMXMODEI 1 "vector_move_operand"
19860                                 "Cr ,m,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
19861   "TARGET_64BIT && TARGET_MMX
19862    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19863   "@
19864     movq\t{%1, %0|%0, %1}
19865     movq\t{%1, %0|%0, %1}
19866     pxor\t%0, %0
19867     movq\t{%1, %0|%0, %1}
19868     movq\t{%1, %0|%0, %1}
19869     movdq2q\t{%1, %0|%0, %1}
19870     movq2dq\t{%1, %0|%0, %1}
19871     pxor\t%0, %0
19872     movq\t{%1, %0|%0, %1}
19873     movq\t{%1, %0|%0, %1}
19874     movd\t{%1, %0|%0, %1}
19875     movd\t{%1, %0|%0, %1}"
19876   [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
19877    (set_attr "mode" "DI")])
19879 (define_insn "*mov<mode>_internal"
19880   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
19881                                         "=*y,*y ,m ,*y,*Y,*x,*x ,m")
19882         (match_operand:MMXMODEI 1 "vector_move_operand"
19883                                         "C  ,*ym,*y,*Y,*y,C ,*xm,*x"))]
19884   "TARGET_MMX
19885    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19886   "@
19887     pxor\t%0, %0
19888     movq\t{%1, %0|%0, %1}
19889     movq\t{%1, %0|%0, %1}
19890     movdq2q\t{%1, %0|%0, %1}
19891     movq2dq\t{%1, %0|%0, %1}
19892     pxor\t%0, %0
19893     movq\t{%1, %0|%0, %1}
19894     movq\t{%1, %0|%0, %1}"
19895   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
19896    (set_attr "mode" "DI")])
19898 (define_expand "movv2sf"
19899   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19900         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19901   "TARGET_MMX"
19903   ix86_expand_vector_move (V2SFmode, operands);
19904   DONE;
19907 (define_insn "*movv2sf_internal_rex64"
19908   [(set (match_operand:V2SF 0 "nonimmediate_operand"
19909                                 "=rm,r,*y ,*y ,m ,*y,Y ,x,x ,m,r,x")
19910         (match_operand:V2SF 1 "vector_move_operand"
19911                                 "Cr ,m ,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
19912   "TARGET_64BIT && TARGET_MMX
19913    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19914   "@
19915     movq\t{%1, %0|%0, %1}
19916     movq\t{%1, %0|%0, %1}
19917     pxor\t%0, %0
19918     movq\t{%1, %0|%0, %1}
19919     movq\t{%1, %0|%0, %1}
19920     movdq2q\t{%1, %0|%0, %1}
19921     movq2dq\t{%1, %0|%0, %1}
19922     xorps\t%0, %0
19923     movlps\t{%1, %0|%0, %1}
19924     movlps\t{%1, %0|%0, %1}
19925     movd\t{%1, %0|%0, %1}
19926     movd\t{%1, %0|%0, %1}"
19927   [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
19928    (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V2SF,V2SF,DI,DI")])
19930 (define_insn "*movv2sf_internal"
19931   [(set (match_operand:V2SF 0 "nonimmediate_operand"
19932                                         "=*y,*y ,m,*y,*Y,*x,*x ,m")
19933         (match_operand:V2SF 1 "vector_move_operand"
19934                                         "C ,*ym,*y,*Y,*y,C ,*xm,*x"))]
19935   "TARGET_MMX
19936    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19937   "@
19938     pxor\t%0, %0
19939     movq\t{%1, %0|%0, %1}
19940     movq\t{%1, %0|%0, %1}
19941     movdq2q\t{%1, %0|%0, %1}
19942     movq2dq\t{%1, %0|%0, %1}
19943     xorps\t%0, %0
19944     movlps\t{%1, %0|%0, %1}
19945     movlps\t{%1, %0|%0, %1}"
19946   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
19947    (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V2SF,V2SF")])
19949 (define_expand "movti"
19950   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19951         (match_operand:TI 1 "nonimmediate_operand" ""))]
19952   "TARGET_SSE || TARGET_64BIT"
19954   if (TARGET_64BIT)
19955     ix86_expand_move (TImode, operands);
19956   else
19957     ix86_expand_vector_move (TImode, operands);
19958   DONE;
19961 (define_insn "*movti_internal"
19962   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19963         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19964   "TARGET_SSE && !TARGET_64BIT
19965    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19967   switch (which_alternative)
19968     {
19969     case 0:
19970       if (get_attr_mode (insn) == MODE_V4SF)
19971         return "xorps\t%0, %0";
19972       else
19973         return "pxor\t%0, %0";
19974     case 1:
19975     case 2:
19976       if (get_attr_mode (insn) == MODE_V4SF)
19977         return "movaps\t{%1, %0|%0, %1}";
19978       else
19979         return "movdqa\t{%1, %0|%0, %1}";
19980     default:
19981       abort ();
19982     }
19984   [(set_attr "type" "ssemov,ssemov,ssemov")
19985    (set (attr "mode")
19986         (cond [(eq_attr "alternative" "0,1")
19987                  (if_then_else
19988                    (ne (symbol_ref "optimize_size")
19989                        (const_int 0))
19990                    (const_string "V4SF")
19991                    (const_string "TI"))
19992                (eq_attr "alternative" "2")
19993                  (if_then_else
19994                    (ne (symbol_ref "optimize_size")
19995                        (const_int 0))
19996                    (const_string "V4SF")
19997                    (const_string "TI"))]
19998                (const_string "TI")))])
20000 (define_insn "*movti_rex64"
20001   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20002         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20003   "TARGET_64BIT
20004    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20006   switch (which_alternative)
20007     {
20008     case 0:
20009     case 1:
20010       return "#";
20011     case 2:
20012       if (get_attr_mode (insn) == MODE_V4SF)
20013         return "xorps\t%0, %0";
20014       else
20015         return "pxor\t%0, %0";
20016     case 3:
20017     case 4:
20018       if (get_attr_mode (insn) == MODE_V4SF)
20019         return "movaps\t{%1, %0|%0, %1}";
20020       else
20021         return "movdqa\t{%1, %0|%0, %1}";
20022     default:
20023       abort ();
20024     }
20026   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20027    (set (attr "mode")
20028         (cond [(eq_attr "alternative" "2,3")
20029                  (if_then_else
20030                    (ne (symbol_ref "optimize_size")
20031                        (const_int 0))
20032                    (const_string "V4SF")
20033                    (const_string "TI"))
20034                (eq_attr "alternative" "4")
20035                  (if_then_else
20036                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20037                             (const_int 0))
20038                         (ne (symbol_ref "optimize_size")
20039                             (const_int 0)))
20040                    (const_string "V4SF")
20041                    (const_string "TI"))]
20042                (const_string "DI")))])
20044 (define_expand "movtf"
20045   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20046         (match_operand:TF 1 "nonimmediate_operand" ""))]
20047   "TARGET_64BIT"
20049   ix86_expand_move (TFmode, operands);
20050   DONE;
20053 (define_insn "*movtf_internal"
20054   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20055         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20056   "TARGET_64BIT
20057    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20059   switch (which_alternative)
20060     {
20061     case 0:
20062     case 1:
20063       return "#";
20064     case 2:
20065       if (get_attr_mode (insn) == MODE_V4SF)
20066         return "xorps\t%0, %0";
20067       else
20068         return "pxor\t%0, %0";
20069     case 3:
20070     case 4:
20071       if (get_attr_mode (insn) == MODE_V4SF)
20072         return "movaps\t{%1, %0|%0, %1}";
20073       else
20074         return "movdqa\t{%1, %0|%0, %1}";
20075     default:
20076       abort ();
20077     }
20079   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20080    (set (attr "mode")
20081         (cond [(eq_attr "alternative" "2,3")
20082                  (if_then_else
20083                    (ne (symbol_ref "optimize_size")
20084                        (const_int 0))
20085                    (const_string "V4SF")
20086                    (const_string "TI"))
20087                (eq_attr "alternative" "4")
20088                  (if_then_else
20089                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20090                             (const_int 0))
20091                         (ne (symbol_ref "optimize_size")
20092                             (const_int 0)))
20093                    (const_string "V4SF")
20094                    (const_string "TI"))]
20095                (const_string "DI")))])
20097 (define_mode_macro SSEPUSH [V16QI V8HI V4SI V2DI TI V4SF V2DF])
20099 (define_insn "*push<mode>"
20100   [(set (match_operand:SSEPUSH 0 "push_operand" "=<")
20101         (match_operand:SSEPUSH 1 "register_operand" "x"))]
20102   "TARGET_SSE"
20103   "#")
20105 (define_mode_macro MMXPUSH [V8QI V4HI V2SI V2SF])
20107 (define_insn "*push<mode>"
20108   [(set (match_operand:MMXPUSH 0 "push_operand" "=<")
20109         (match_operand:MMXPUSH 1 "register_operand" "xy"))]
20110   "TARGET_MMX"
20111   "#")
20113 (define_split
20114   [(set (match_operand 0 "push_operand" "")
20115         (match_operand 1 "register_operand" ""))]
20116   "!TARGET_64BIT && reload_completed
20117    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20118   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20119    (set (match_dup 2) (match_dup 1))]
20120   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20121                                  stack_pointer_rtx);
20122    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20124 (define_split
20125   [(set (match_operand 0 "push_operand" "")
20126         (match_operand 1 "register_operand" ""))]
20127   "TARGET_64BIT && reload_completed
20128    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20129   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20130    (set (match_dup 2) (match_dup 1))]
20131   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20132                                  stack_pointer_rtx);
20133    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20136 (define_split
20137   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20138         (match_operand:TI 1 "general_operand" ""))]
20139   "reload_completed && !SSE_REG_P (operands[0])
20140    && !SSE_REG_P (operands[1])"
20141   [(const_int 0)]
20142   "ix86_split_long_move (operands); DONE;")
20144 (define_split
20145   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20146         (match_operand:TF 1 "general_operand" ""))]
20147   "reload_completed && !SSE_REG_P (operands[0])
20148    && !SSE_REG_P (operands[1])"
20149   [(const_int 0)]
20150   "ix86_split_long_move (operands); DONE;")
20152 ;; All 16-byte vector modes handled by SSE
20153 (define_mode_macro SSEMODE [V16QI V8HI V4SI V2DI V4SF V2DF])
20155 (define_expand "movmisalign<mode>"
20156   [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
20157         (match_operand:SSEMODE 1 "nonimmediate_operand" ""))]
20158   "TARGET_SSE"
20160   ix86_expand_vector_move_misalign (<MODE>mode, operands);
20161   DONE;
20164 ;; All 8-byte vector modes handled by MMX
20165 (define_mode_macro MMXMODE [V8QI V4HI V2SI V2SF])
20167 (define_expand "movmisalign<mode>"
20168   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
20169         (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
20170   "TARGET_MMX"
20172   ix86_expand_vector_move (<MODE>mode, operands);
20173   DONE;
20176 ;; These two patterns are useful for specifying exactly whether to use
20177 ;; movaps or movups
20178 (define_expand "sse_movaps"
20179   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20180         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20181                      UNSPEC_MOVA))]
20182   "TARGET_SSE"
20184   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20185     {
20186       rtx tmp = gen_reg_rtx (V4SFmode);
20187       emit_insn (gen_sse_movaps (tmp, operands[1]));
20188       emit_move_insn (operands[0], tmp);
20189       DONE;
20190     }
20193 (define_insn "*sse_movaps_1"
20194   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20195         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20196                      UNSPEC_MOVA))]
20197   "TARGET_SSE
20198    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20199   "movaps\t{%1, %0|%0, %1}"
20200   [(set_attr "type" "ssemov,ssemov")
20201    (set_attr "mode" "V4SF")])
20203 (define_expand "sse_movups"
20204   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20205         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20206                      UNSPEC_MOVU))]
20207   "TARGET_SSE"
20209   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20210     {
20211       rtx tmp = gen_reg_rtx (V4SFmode);
20212       emit_insn (gen_sse_movups (tmp, operands[1]));
20213       emit_move_insn (operands[0], tmp);
20214       DONE;
20215     }
20218 (define_insn "*sse_movups_1"
20219   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20220         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20221                      UNSPEC_MOVU))]
20222   "TARGET_SSE
20223    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20224   "movups\t{%1, %0|%0, %1}"
20225   [(set_attr "type" "ssecvt,ssecvt")
20226    (set_attr "mode" "V4SF")])
20228 ;; SSE Strange Moves.
20230 (define_insn "sse_movmskps"
20231   [(set (match_operand:SI 0 "register_operand" "=r")
20232         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20233                    UNSPEC_MOVMSK))]
20234   "TARGET_SSE"
20235   "movmskps\t{%1, %0|%0, %1}"
20236   [(set_attr "type" "ssecvt")
20237    (set_attr "mode" "V4SF")])
20239 (define_insn "mmx_pmovmskb"
20240   [(set (match_operand:SI 0 "register_operand" "=r")
20241         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20242                    UNSPEC_MOVMSK))]
20243   "TARGET_SSE || TARGET_3DNOW_A"
20244   "pmovmskb\t{%1, %0|%0, %1}"
20245   [(set_attr "type" "ssecvt")
20246    (set_attr "mode" "V4SF")])
20249 (define_insn "mmx_maskmovq"
20250   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20251         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20252                       (match_operand:V8QI 2 "register_operand" "y")]
20253                      UNSPEC_MASKMOV))]
20254   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20255   ;; @@@ check ordering of operands in intel/nonintel syntax
20256   "maskmovq\t{%2, %1|%1, %2}"
20257   [(set_attr "type" "mmxcvt")
20258    (set_attr "mode" "DI")])
20260 (define_insn "mmx_maskmovq_rex"
20261   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20262         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20263                       (match_operand:V8QI 2 "register_operand" "y")]
20264                      UNSPEC_MASKMOV))]
20265   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20266   ;; @@@ check ordering of operands in intel/nonintel syntax
20267   "maskmovq\t{%2, %1|%1, %2}"
20268   [(set_attr "type" "mmxcvt")
20269    (set_attr "mode" "DI")])
20271 (define_insn "sse_movntv4sf"
20272   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20273         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20274                      UNSPEC_MOVNT))]
20275   "TARGET_SSE"
20276   "movntps\t{%1, %0|%0, %1}"
20277   [(set_attr "type" "ssemov")
20278    (set_attr "mode" "V4SF")])
20280 (define_insn "sse_movntdi"
20281   [(set (match_operand:DI 0 "memory_operand" "=m")
20282         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20283                    UNSPEC_MOVNT))]
20284   "TARGET_SSE || TARGET_3DNOW_A"
20285   "movntq\t{%1, %0|%0, %1}"
20286   [(set_attr "type" "mmxmov")
20287    (set_attr "mode" "DI")])
20289 (define_insn "sse_movhlps"
20290   [(set (match_operand:V4SF 0 "register_operand" "=x")
20291         (vec_merge:V4SF
20292          (match_operand:V4SF 1 "register_operand" "0")
20293          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20294                           (parallel [(const_int 2)
20295                                      (const_int 3)
20296                                      (const_int 0)
20297                                      (const_int 1)]))
20298          (const_int 3)))]
20299   "TARGET_SSE"
20300   "movhlps\t{%2, %0|%0, %2}"
20301   [(set_attr "type" "ssecvt")
20302    (set_attr "mode" "V4SF")])
20304 (define_insn "sse_movlhps"
20305   [(set (match_operand:V4SF 0 "register_operand" "=x")
20306         (vec_merge:V4SF
20307          (match_operand:V4SF 1 "register_operand" "0")
20308          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20309                           (parallel [(const_int 2)
20310                                      (const_int 3)
20311                                      (const_int 0)
20312                                      (const_int 1)]))
20313          (const_int 12)))]
20314   "TARGET_SSE"
20315   "movlhps\t{%2, %0|%0, %2}"
20316   [(set_attr "type" "ssecvt")
20317    (set_attr "mode" "V4SF")])
20319 (define_insn "sse_movhps"
20320   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20321         (vec_merge:V4SF
20322          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20323          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20324          (const_int 12)))]
20325   "TARGET_SSE
20326    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20327   "movhps\t{%2, %0|%0, %2}"
20328   [(set_attr "type" "ssecvt")
20329    (set_attr "mode" "V4SF")])
20331 (define_insn "sse_movlps"
20332   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20333         (vec_merge:V4SF
20334          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20335          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20336          (const_int 3)))]
20337   "TARGET_SSE
20338    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20339   "movlps\t{%2, %0|%0, %2}"
20340   [(set_attr "type" "ssecvt")
20341    (set_attr "mode" "V4SF")])
20343 (define_expand "sse_loadss"
20344   [(match_operand:V4SF 0 "register_operand" "")
20345    (match_operand:SF 1 "memory_operand" "")]
20346   "TARGET_SSE"
20348   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20349                                CONST0_RTX (V4SFmode)));
20350   DONE;
20353 (define_insn "sse_loadss_1"
20354   [(set (match_operand:V4SF 0 "register_operand" "=x")
20355         (vec_merge:V4SF
20356          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20357          (match_operand:V4SF 2 "const0_operand" "X")
20358          (const_int 1)))]
20359   "TARGET_SSE"
20360   "movss\t{%1, %0|%0, %1}"
20361   [(set_attr "type" "ssemov")
20362    (set_attr "mode" "SF")])
20364 (define_insn "sse_movss"
20365   [(set (match_operand:V4SF 0 "register_operand" "=x")
20366         (vec_merge:V4SF
20367          (match_operand:V4SF 1 "register_operand" "0")
20368          (match_operand:V4SF 2 "register_operand" "x")
20369          (const_int 14)))]
20370   "TARGET_SSE"
20371   "movss\t{%2, %0|%0, %2}"
20372   [(set_attr "type" "ssemov")
20373    (set_attr "mode" "SF")])
20375 (define_insn "sse_storess"
20376   [(set (match_operand:SF 0 "memory_operand" "=m")
20377         (vec_select:SF
20378          (match_operand:V4SF 1 "register_operand" "x")
20379          (parallel [(const_int 0)])))]
20380   "TARGET_SSE"
20381   "movss\t{%1, %0|%0, %1}"
20382   [(set_attr "type" "ssemov")
20383    (set_attr "mode" "SF")])
20385 (define_insn "sse_shufps"
20386   [(set (match_operand:V4SF 0 "register_operand" "=x")
20387         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20388                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20389                       (match_operand:SI 3 "immediate_operand" "i")]
20390                      UNSPEC_SHUFFLE))]
20391   "TARGET_SSE"
20392   ;; @@@ check operand order for intel/nonintel syntax
20393   "shufps\t{%3, %2, %0|%0, %2, %3}"
20394   [(set_attr "type" "ssecvt")
20395    (set_attr "mode" "V4SF")])
20398 ;; SSE arithmetic
20400 (define_insn "addv4sf3"
20401   [(set (match_operand:V4SF 0 "register_operand" "=x")
20402         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20403                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20404   "TARGET_SSE"
20405   "addps\t{%2, %0|%0, %2}"
20406   [(set_attr "type" "sseadd")
20407    (set_attr "mode" "V4SF")])
20409 (define_insn "vmaddv4sf3"
20410   [(set (match_operand:V4SF 0 "register_operand" "=x")
20411         (vec_merge:V4SF
20412          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20413                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20414          (match_dup 1)
20415          (const_int 1)))]
20416   "TARGET_SSE"
20417   "addss\t{%2, %0|%0, %2}"
20418   [(set_attr "type" "sseadd")
20419    (set_attr "mode" "SF")])
20421 (define_insn "subv4sf3"
20422   [(set (match_operand:V4SF 0 "register_operand" "=x")
20423         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20424                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20425   "TARGET_SSE"
20426   "subps\t{%2, %0|%0, %2}"
20427   [(set_attr "type" "sseadd")
20428    (set_attr "mode" "V4SF")])
20430 (define_insn "vmsubv4sf3"
20431   [(set (match_operand:V4SF 0 "register_operand" "=x")
20432         (vec_merge:V4SF
20433          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20434                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20435          (match_dup 1)
20436          (const_int 1)))]
20437   "TARGET_SSE"
20438   "subss\t{%2, %0|%0, %2}"
20439   [(set_attr "type" "sseadd")
20440    (set_attr "mode" "SF")])
20442 ;; ??? Should probably be done by generic code instead.
20443 (define_expand "negv4sf2"
20444   [(set (match_operand:V4SF 0 "register_operand" "")
20445         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20446                   (match_dup 2)))]
20447   "TARGET_SSE"
20449   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20450   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20451   operands[2] = force_reg (V4SFmode, vm0);
20454 (define_insn "mulv4sf3"
20455   [(set (match_operand:V4SF 0 "register_operand" "=x")
20456         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20457                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20458   "TARGET_SSE"
20459   "mulps\t{%2, %0|%0, %2}"
20460   [(set_attr "type" "ssemul")
20461    (set_attr "mode" "V4SF")])
20463 (define_insn "vmmulv4sf3"
20464   [(set (match_operand:V4SF 0 "register_operand" "=x")
20465         (vec_merge:V4SF
20466          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20467                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20468          (match_dup 1)
20469          (const_int 1)))]
20470   "TARGET_SSE"
20471   "mulss\t{%2, %0|%0, %2}"
20472   [(set_attr "type" "ssemul")
20473    (set_attr "mode" "SF")])
20475 (define_insn "divv4sf3"
20476   [(set (match_operand:V4SF 0 "register_operand" "=x")
20477         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20478                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20479   "TARGET_SSE"
20480   "divps\t{%2, %0|%0, %2}"
20481   [(set_attr "type" "ssediv")
20482    (set_attr "mode" "V4SF")])
20484 (define_insn "vmdivv4sf3"
20485   [(set (match_operand:V4SF 0 "register_operand" "=x")
20486         (vec_merge:V4SF
20487          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20488                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20489          (match_dup 1)
20490          (const_int 1)))]
20491   "TARGET_SSE"
20492   "divss\t{%2, %0|%0, %2}"
20493   [(set_attr "type" "ssediv")
20494    (set_attr "mode" "SF")])
20497 ;; SSE square root/reciprocal
20499 (define_insn "rcpv4sf2"
20500   [(set (match_operand:V4SF 0 "register_operand" "=x")
20501         (unspec:V4SF
20502          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20503   "TARGET_SSE"
20504   "rcpps\t{%1, %0|%0, %1}"
20505   [(set_attr "type" "sse")
20506    (set_attr "mode" "V4SF")])
20508 (define_insn "vmrcpv4sf2"
20509   [(set (match_operand:V4SF 0 "register_operand" "=x")
20510         (vec_merge:V4SF
20511          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20512                       UNSPEC_RCP)
20513          (match_operand:V4SF 2 "register_operand" "0")
20514          (const_int 1)))]
20515   "TARGET_SSE"
20516   "rcpss\t{%1, %0|%0, %1}"
20517   [(set_attr "type" "sse")
20518    (set_attr "mode" "SF")])
20520 (define_insn "rsqrtv4sf2"
20521   [(set (match_operand:V4SF 0 "register_operand" "=x")
20522         (unspec:V4SF
20523          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20524   "TARGET_SSE"
20525   "rsqrtps\t{%1, %0|%0, %1}"
20526   [(set_attr "type" "sse")
20527    (set_attr "mode" "V4SF")])
20529 (define_insn "vmrsqrtv4sf2"
20530   [(set (match_operand:V4SF 0 "register_operand" "=x")
20531         (vec_merge:V4SF
20532          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20533                       UNSPEC_RSQRT)
20534          (match_operand:V4SF 2 "register_operand" "0")
20535          (const_int 1)))]
20536   "TARGET_SSE"
20537   "rsqrtss\t{%1, %0|%0, %1}"
20538   [(set_attr "type" "sse")
20539    (set_attr "mode" "SF")])
20541 (define_insn "sqrtv4sf2"
20542   [(set (match_operand:V4SF 0 "register_operand" "=x")
20543         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20544   "TARGET_SSE"
20545   "sqrtps\t{%1, %0|%0, %1}"
20546   [(set_attr "type" "sse")
20547    (set_attr "mode" "V4SF")])
20549 (define_insn "vmsqrtv4sf2"
20550   [(set (match_operand:V4SF 0 "register_operand" "=x")
20551         (vec_merge:V4SF
20552          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20553          (match_operand:V4SF 2 "register_operand" "0")
20554          (const_int 1)))]
20555   "TARGET_SSE"
20556   "sqrtss\t{%1, %0|%0, %1}"
20557   [(set_attr "type" "sse")
20558    (set_attr "mode" "SF")])
20560 ;; SSE logical operations.
20562 ;; SSE defines logical operations on floating point values.  This brings
20563 ;; interesting challenge to RTL representation where logicals are only valid
20564 ;; on integral types.  We deal with this by representing the floating point
20565 ;; logical as logical on arguments casted to TImode as this is what hardware
20566 ;; really does.  Unfortunately hardware requires the type information to be
20567 ;; present and thus we must avoid subregs from being simplified and eliminated
20568 ;; in later compilation phases.
20570 ;; We have following variants from each instruction:
20571 ;; sse_andsf3 - the operation taking V4SF vector operands
20572 ;;              and doing TImode cast on them
20573 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20574 ;;                      TImode, since backend insist on eliminating casts
20575 ;;                      on memory operands
20576 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20577 ;;                   We cannot accept memory operand here as instruction reads
20578 ;;                   whole scalar.  This is generated only post reload by GCC
20579 ;;                   scalar float operations that expands to logicals (fabs)
20580 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20581 ;;                   memory operand.  Eventually combine can be able
20582 ;;                   to synthesize these using splitter.
20583 ;; sse2_anddf3, *sse2_anddf3_memory
20584 ;;              
20585 ;; 
20586 ;; These are not called andti3 etc. because we really really don't want
20587 ;; the compiler to widen DImode ands to TImode ands and then try to move
20588 ;; into DImode subregs of SSE registers, and them together, and move out
20589 ;; of DImode subregs again!
20590 ;; SSE1 single precision floating point logical operation
20591 (define_expand "sse_andv4sf3"
20592   [(set (match_operand:V4SF 0 "register_operand" "")
20593         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20594                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20595   "TARGET_SSE"
20596   "")
20598 (define_insn "*sse_andv4sf3"
20599   [(set (match_operand:V4SF 0 "register_operand" "=x")
20600         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20601                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20602   "TARGET_SSE
20603    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20604   "andps\t{%2, %0|%0, %2}"
20605   [(set_attr "type" "sselog")
20606    (set_attr "mode" "V4SF")])
20608 (define_expand "sse_nandv4sf3"
20609   [(set (match_operand:V4SF 0 "register_operand" "")
20610         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20611                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20612   "TARGET_SSE"
20613   "")
20615 (define_insn "*sse_nandv4sf3"
20616   [(set (match_operand:V4SF 0 "register_operand" "=x")
20617         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20618                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20619   "TARGET_SSE"
20620   "andnps\t{%2, %0|%0, %2}"
20621   [(set_attr "type" "sselog")
20622    (set_attr "mode" "V4SF")])
20624 (define_expand "sse_iorv4sf3"
20625   [(set (match_operand:V4SF 0 "register_operand" "")
20626         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20627                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20628   "TARGET_SSE"
20629   "")
20631 (define_insn "*sse_iorv4sf3"
20632   [(set (match_operand:V4SF 0 "register_operand" "=x")
20633         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20634                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20635   "TARGET_SSE
20636    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20637   "orps\t{%2, %0|%0, %2}"
20638   [(set_attr "type" "sselog")
20639    (set_attr "mode" "V4SF")])
20641 (define_expand "sse_xorv4sf3"
20642   [(set (match_operand:V4SF 0 "register_operand" "")
20643         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20644                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20645   "TARGET_SSE"
20646   "")
20648 (define_insn "*sse_xorv4sf3"
20649   [(set (match_operand:V4SF 0 "register_operand" "=x")
20650         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20651                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20652   "TARGET_SSE
20653    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20654   "xorps\t{%2, %0|%0, %2}"
20655   [(set_attr "type" "sselog")
20656    (set_attr "mode" "V4SF")])
20658 ;; SSE2 double precision floating point logical operation
20660 (define_expand "sse2_andv2df3"
20661   [(set (match_operand:V2DF 0 "register_operand" "")
20662         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20663                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20664   "TARGET_SSE2"
20665   "")
20667 (define_insn "*sse2_andv2df3"
20668   [(set (match_operand:V2DF 0 "register_operand" "=x")
20669         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20670                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20671   "TARGET_SSE2
20672    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20673   "andpd\t{%2, %0|%0, %2}"
20674   [(set_attr "type" "sselog")
20675    (set_attr "mode" "V2DF")])
20677 (define_expand "sse2_nandv2df3"
20678   [(set (match_operand:V2DF 0 "register_operand" "")
20679         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20680                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20681   "TARGET_SSE2"
20682   "")
20684 (define_insn "*sse2_nandv2df3"
20685   [(set (match_operand:V2DF 0 "register_operand" "=x")
20686         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20687                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20688   "TARGET_SSE2"
20689   "andnpd\t{%2, %0|%0, %2}"
20690   [(set_attr "type" "sselog")
20691    (set_attr "mode" "V2DF")])
20693 (define_expand "sse2_iorv2df3"
20694   [(set (match_operand:V2DF 0 "register_operand" "")
20695         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20696                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20697   "TARGET_SSE2"
20698   "")
20700 (define_insn "*sse2_iorv2df3"
20701   [(set (match_operand:V2DF 0 "register_operand" "=x")
20702         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20703                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20704   "TARGET_SSE2
20705    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20706   "orpd\t{%2, %0|%0, %2}"
20707   [(set_attr "type" "sselog")
20708    (set_attr "mode" "V2DF")])
20710 (define_expand "sse2_xorv2df3"
20711   [(set (match_operand:V2DF 0 "register_operand" "")
20712         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20713                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20714   "TARGET_SSE2"
20715   "")
20717 (define_insn "*sse2_xorv2df3"
20718   [(set (match_operand:V2DF 0 "register_operand" "=x")
20719         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20720                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20721   "TARGET_SSE2
20722    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20723   "xorpd\t{%2, %0|%0, %2}"
20724   [(set_attr "type" "sselog")
20725    (set_attr "mode" "V2DF")])
20727 ;; SSE2 integral logicals.  These patterns must always come after floating
20728 ;; point ones since we don't want compiler to use integer opcodes on floating
20729 ;; point SSE values to avoid matching of subregs in the match_operand.
20730 (define_insn "*sse2_andti3"
20731   [(set (match_operand:TI 0 "register_operand" "=x")
20732         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20733                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20734   "TARGET_SSE2
20735    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20736   "pand\t{%2, %0|%0, %2}"
20737   [(set_attr "type" "sselog")
20738    (set_attr "mode" "TI")])
20740 (define_insn "sse2_andv2di3"
20741   [(set (match_operand:V2DI 0 "register_operand" "=x")
20742         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20743                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20744   "TARGET_SSE2
20745    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20746   "pand\t{%2, %0|%0, %2}"
20747   [(set_attr "type" "sselog")
20748    (set_attr "mode" "TI")])
20750 (define_insn "*sse2_nandti3"
20751   [(set (match_operand:TI 0 "register_operand" "=x")
20752         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20753                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20754   "TARGET_SSE2"
20755   "pandn\t{%2, %0|%0, %2}"
20756   [(set_attr "type" "sselog")
20757    (set_attr "mode" "TI")])
20759 (define_insn "sse2_nandv2di3"
20760   [(set (match_operand:V2DI 0 "register_operand" "=x")
20761         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20762                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20763   "TARGET_SSE2
20764    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20765   "pandn\t{%2, %0|%0, %2}"
20766   [(set_attr "type" "sselog")
20767    (set_attr "mode" "TI")])
20769 (define_insn "*sse2_iorti3"
20770   [(set (match_operand:TI 0 "register_operand" "=x")
20771         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20772                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20773   "TARGET_SSE2
20774    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20775   "por\t{%2, %0|%0, %2}"
20776   [(set_attr "type" "sselog")
20777    (set_attr "mode" "TI")])
20779 (define_insn "sse2_iorv2di3"
20780   [(set (match_operand:V2DI 0 "register_operand" "=x")
20781         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20782                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20783   "TARGET_SSE2
20784    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20785   "por\t{%2, %0|%0, %2}"
20786   [(set_attr "type" "sselog")
20787    (set_attr "mode" "TI")])
20789 (define_insn "*sse2_xorti3"
20790   [(set (match_operand:TI 0 "register_operand" "=x")
20791         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20792                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20793   "TARGET_SSE2
20794    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20795   "pxor\t{%2, %0|%0, %2}"
20796   [(set_attr "type" "sselog")
20797    (set_attr "mode" "TI")])
20799 (define_insn "sse2_xorv2di3"
20800   [(set (match_operand:V2DI 0 "register_operand" "=x")
20801         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20802                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20803   "TARGET_SSE2
20804    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20805   "pxor\t{%2, %0|%0, %2}"
20806   [(set_attr "type" "sselog")
20807    (set_attr "mode" "TI")])
20809 ;; Use xor, but don't show input operands so they aren't live before
20810 ;; this insn.
20811 (define_insn "sse_clrv4sf"
20812   [(set (match_operand:V4SF 0 "register_operand" "=x")
20813         (match_operand:V4SF 1 "const0_operand" "X"))]
20814   "TARGET_SSE"
20816   if (get_attr_mode (insn) == MODE_TI)
20817     return "pxor\t{%0, %0|%0, %0}";
20818   else
20819     return "xorps\t{%0, %0|%0, %0}";
20821   [(set_attr "type" "sselog")
20822    (set_attr "memory" "none")
20823    (set (attr "mode")
20824         (if_then_else
20825            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20826                          (const_int 0))
20827                      (ne (symbol_ref "TARGET_SSE2")
20828                          (const_int 0)))
20829                 (eq (symbol_ref "optimize_size")
20830                     (const_int 0)))
20831          (const_string "TI")
20832          (const_string "V4SF")))])
20834 ;; Use xor, but don't show input operands so they aren't live before
20835 ;; this insn.
20836 (define_insn "sse_clrv2df"
20837   [(set (match_operand:V2DF 0 "register_operand" "=x")
20838         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20839   "TARGET_SSE2"
20840   "xorpd\t{%0, %0|%0, %0}"
20841   [(set_attr "type" "sselog")
20842    (set_attr "memory" "none")
20843    (set_attr "mode" "V4SF")])
20845 ;; SSE mask-generating compares
20847 (define_insn "maskcmpv4sf3"
20848   [(set (match_operand:V4SI 0 "register_operand" "=x")
20849         (match_operator:V4SI 3 "sse_comparison_operator"
20850                 [(match_operand:V4SF 1 "register_operand" "0")
20851                  (match_operand:V4SF 2 "register_operand" "x")]))]
20852   "TARGET_SSE"
20853   "cmp%D3ps\t{%2, %0|%0, %2}"
20854   [(set_attr "type" "ssecmp")
20855    (set_attr "mode" "V4SF")])
20857 (define_insn "maskncmpv4sf3"
20858   [(set (match_operand:V4SI 0 "register_operand" "=x")
20859         (not:V4SI
20860          (match_operator:V4SI 3 "sse_comparison_operator"
20861                 [(match_operand:V4SF 1 "register_operand" "0")
20862                  (match_operand:V4SF 2 "register_operand" "x")])))]
20863   "TARGET_SSE"
20865   if (GET_CODE (operands[3]) == UNORDERED)
20866     return "cmpordps\t{%2, %0|%0, %2}";
20867   else
20868     return "cmpn%D3ps\t{%2, %0|%0, %2}";
20870   [(set_attr "type" "ssecmp")
20871    (set_attr "mode" "V4SF")])
20873 (define_insn "vmmaskcmpv4sf3"
20874   [(set (match_operand:V4SI 0 "register_operand" "=x")
20875         (vec_merge:V4SI
20876          (match_operator:V4SI 3 "sse_comparison_operator"
20877                 [(match_operand:V4SF 1 "register_operand" "0")
20878                  (match_operand:V4SF 2 "register_operand" "x")])
20879          (subreg:V4SI (match_dup 1) 0)
20880          (const_int 1)))]
20881   "TARGET_SSE"
20882   "cmp%D3ss\t{%2, %0|%0, %2}"
20883   [(set_attr "type" "ssecmp")
20884    (set_attr "mode" "SF")])
20886 (define_insn "vmmaskncmpv4sf3"
20887   [(set (match_operand:V4SI 0 "register_operand" "=x")
20888         (vec_merge:V4SI
20889          (not:V4SI
20890           (match_operator:V4SI 3 "sse_comparison_operator"
20891                 [(match_operand:V4SF 1 "register_operand" "0")
20892                  (match_operand:V4SF 2 "register_operand" "x")]))
20893          (subreg:V4SI (match_dup 1) 0)
20894          (const_int 1)))]
20895   "TARGET_SSE"
20897   if (GET_CODE (operands[3]) == UNORDERED)
20898     return "cmpordss\t{%2, %0|%0, %2}";
20899   else
20900     return "cmpn%D3ss\t{%2, %0|%0, %2}";
20902   [(set_attr "type" "ssecmp")
20903    (set_attr "mode" "SF")])
20905 (define_insn "sse_comi"
20906   [(set (reg:CCFP FLAGS_REG)
20907         (compare:CCFP (vec_select:SF
20908                        (match_operand:V4SF 0 "register_operand" "x")
20909                        (parallel [(const_int 0)]))
20910                       (vec_select:SF
20911                        (match_operand:V4SF 1 "register_operand" "x")
20912                        (parallel [(const_int 0)]))))]
20913   "TARGET_SSE"
20914   "comiss\t{%1, %0|%0, %1}"
20915   [(set_attr "type" "ssecomi")
20916    (set_attr "mode" "SF")])
20918 (define_insn "sse_ucomi"
20919   [(set (reg:CCFPU FLAGS_REG)
20920         (compare:CCFPU (vec_select:SF
20921                         (match_operand:V4SF 0 "register_operand" "x")
20922                         (parallel [(const_int 0)]))
20923                        (vec_select:SF
20924                         (match_operand:V4SF 1 "register_operand" "x")
20925                         (parallel [(const_int 0)]))))]
20926   "TARGET_SSE"
20927   "ucomiss\t{%1, %0|%0, %1}"
20928   [(set_attr "type" "ssecomi")
20929    (set_attr "mode" "SF")])
20932 ;; SSE unpack
20934 (define_insn "sse_unpckhps"
20935   [(set (match_operand:V4SF 0 "register_operand" "=x")
20936         (vec_merge:V4SF
20937          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20938                           (parallel [(const_int 2)
20939                                      (const_int 0)
20940                                      (const_int 3)
20941                                      (const_int 1)]))
20942          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20943                           (parallel [(const_int 0)
20944                                      (const_int 2)
20945                                      (const_int 1)
20946                                      (const_int 3)]))
20947          (const_int 5)))]
20948   "TARGET_SSE"
20949   "unpckhps\t{%2, %0|%0, %2}"
20950   [(set_attr "type" "ssecvt")
20951    (set_attr "mode" "V4SF")])
20953 (define_insn "sse_unpcklps"
20954   [(set (match_operand:V4SF 0 "register_operand" "=x")
20955         (vec_merge:V4SF
20956          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20957                           (parallel [(const_int 0)
20958                                      (const_int 2)
20959                                      (const_int 1)
20960                                      (const_int 3)]))
20961          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20962                           (parallel [(const_int 2)
20963                                      (const_int 0)
20964                                      (const_int 3)
20965                                      (const_int 1)]))
20966          (const_int 5)))]
20967   "TARGET_SSE"
20968   "unpcklps\t{%2, %0|%0, %2}"
20969   [(set_attr "type" "ssecvt")
20970    (set_attr "mode" "V4SF")])
20973 ;; SSE min/max
20975 (define_insn "smaxv4sf3"
20976   [(set (match_operand:V4SF 0 "register_operand" "=x")
20977         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20978                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20979   "TARGET_SSE"
20980   "maxps\t{%2, %0|%0, %2}"
20981   [(set_attr "type" "sse")
20982    (set_attr "mode" "V4SF")])
20984 (define_insn "vmsmaxv4sf3"
20985   [(set (match_operand:V4SF 0 "register_operand" "=x")
20986         (vec_merge:V4SF
20987          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20988                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20989          (match_dup 1)
20990          (const_int 1)))]
20991   "TARGET_SSE"
20992   "maxss\t{%2, %0|%0, %2}"
20993   [(set_attr "type" "sse")
20994    (set_attr "mode" "SF")])
20996 (define_insn "sminv4sf3"
20997   [(set (match_operand:V4SF 0 "register_operand" "=x")
20998         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20999                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21000   "TARGET_SSE"
21001   "minps\t{%2, %0|%0, %2}"
21002   [(set_attr "type" "sse")
21003    (set_attr "mode" "V4SF")])
21005 (define_insn "vmsminv4sf3"
21006   [(set (match_operand:V4SF 0 "register_operand" "=x")
21007         (vec_merge:V4SF
21008          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21009                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21010          (match_dup 1)
21011          (const_int 1)))]
21012   "TARGET_SSE"
21013   "minss\t{%2, %0|%0, %2}"
21014   [(set_attr "type" "sse")
21015    (set_attr "mode" "SF")])
21017 ;; SSE <-> integer/MMX conversions
21019 (define_insn "cvtpi2ps"
21020   [(set (match_operand:V4SF 0 "register_operand" "=x")
21021         (vec_merge:V4SF
21022          (match_operand:V4SF 1 "register_operand" "0")
21023          (vec_duplicate:V4SF
21024           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21025          (const_int 12)))]
21026   "TARGET_SSE"
21027   "cvtpi2ps\t{%2, %0|%0, %2}"
21028   [(set_attr "type" "ssecvt")
21029    (set_attr "mode" "V4SF")])
21031 (define_insn "cvtps2pi"
21032   [(set (match_operand:V2SI 0 "register_operand" "=y")
21033         (vec_select:V2SI
21034          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21035          (parallel [(const_int 0) (const_int 1)])))]
21036   "TARGET_SSE"
21037   "cvtps2pi\t{%1, %0|%0, %1}"
21038   [(set_attr "type" "ssecvt")
21039    (set_attr "mode" "V4SF")])
21041 (define_insn "cvttps2pi"
21042   [(set (match_operand:V2SI 0 "register_operand" "=y")
21043         (vec_select:V2SI
21044          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21045                       UNSPEC_FIX)
21046          (parallel [(const_int 0) (const_int 1)])))]
21047   "TARGET_SSE"
21048   "cvttps2pi\t{%1, %0|%0, %1}"
21049   [(set_attr "type" "ssecvt")
21050    (set_attr "mode" "SF")])
21052 (define_insn "cvtsi2ss"
21053   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21054         (vec_merge:V4SF
21055          (match_operand:V4SF 1 "register_operand" "0,0")
21056          (vec_duplicate:V4SF
21057           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21058          (const_int 14)))]
21059   "TARGET_SSE"
21060   "cvtsi2ss\t{%2, %0|%0, %2}"
21061   [(set_attr "type" "sseicvt")
21062    (set_attr "athlon_decode" "vector,double")
21063    (set_attr "mode" "SF")])
21065 (define_insn "cvtsi2ssq"
21066   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21067         (vec_merge:V4SF
21068          (match_operand:V4SF 1 "register_operand" "0,0")
21069          (vec_duplicate:V4SF
21070           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21071          (const_int 14)))]
21072   "TARGET_SSE && TARGET_64BIT"
21073   "cvtsi2ssq\t{%2, %0|%0, %2}"
21074   [(set_attr "type" "sseicvt")
21075    (set_attr "athlon_decode" "vector,double")
21076    (set_attr "mode" "SF")])
21078 (define_insn "cvtss2si"
21079   [(set (match_operand:SI 0 "register_operand" "=r,r")
21080         (vec_select:SI
21081          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21082          (parallel [(const_int 0)])))]
21083   "TARGET_SSE"
21084   "cvtss2si\t{%1, %0|%0, %1}"
21085   [(set_attr "type" "sseicvt")
21086    (set_attr "athlon_decode" "double,vector")
21087    (set_attr "mode" "SI")])
21089 (define_insn "cvtss2siq"
21090   [(set (match_operand:DI 0 "register_operand" "=r,r")
21091         (vec_select:DI
21092          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21093          (parallel [(const_int 0)])))]
21094   "TARGET_SSE"
21095   "cvtss2siq\t{%1, %0|%0, %1}"
21096   [(set_attr "type" "sseicvt")
21097    (set_attr "athlon_decode" "double,vector")
21098    (set_attr "mode" "DI")])
21100 (define_insn "cvttss2si"
21101   [(set (match_operand:SI 0 "register_operand" "=r,r")
21102         (vec_select:SI
21103          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21104                       UNSPEC_FIX)
21105          (parallel [(const_int 0)])))]
21106   "TARGET_SSE"
21107   "cvttss2si\t{%1, %0|%0, %1}"
21108   [(set_attr "type" "sseicvt")
21109    (set_attr "mode" "SF")
21110    (set_attr "athlon_decode" "double,vector")])
21112 (define_insn "cvttss2siq"
21113   [(set (match_operand:DI 0 "register_operand" "=r,r")
21114         (vec_select:DI
21115          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21116                       UNSPEC_FIX)
21117          (parallel [(const_int 0)])))]
21118   "TARGET_SSE && TARGET_64BIT"
21119   "cvttss2siq\t{%1, %0|%0, %1}"
21120   [(set_attr "type" "sseicvt")
21121    (set_attr "mode" "SF")
21122    (set_attr "athlon_decode" "double,vector")])
21125 ;; MMX insns
21127 ;; MMX arithmetic
21129 (define_insn "addv8qi3"
21130   [(set (match_operand:V8QI 0 "register_operand" "=y")
21131         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21132                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21133   "TARGET_MMX"
21134   "paddb\t{%2, %0|%0, %2}"
21135   [(set_attr "type" "mmxadd")
21136    (set_attr "mode" "DI")])
21138 (define_insn "addv4hi3"
21139   [(set (match_operand:V4HI 0 "register_operand" "=y")
21140         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21141                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21142   "TARGET_MMX"
21143   "paddw\t{%2, %0|%0, %2}"
21144   [(set_attr "type" "mmxadd")
21145    (set_attr "mode" "DI")])
21147 (define_insn "addv2si3"
21148   [(set (match_operand:V2SI 0 "register_operand" "=y")
21149         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21150                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21151   "TARGET_MMX"
21152   "paddd\t{%2, %0|%0, %2}"
21153   [(set_attr "type" "mmxadd")
21154    (set_attr "mode" "DI")])
21156 (define_insn "mmx_adddi3"
21157   [(set (match_operand:DI 0 "register_operand" "=y")
21158         (unspec:DI
21159          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21160                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21161          UNSPEC_NOP))]
21162   "TARGET_MMX"
21163   "paddq\t{%2, %0|%0, %2}"
21164   [(set_attr "type" "mmxadd")
21165    (set_attr "mode" "DI")])
21167 (define_insn "ssaddv8qi3"
21168   [(set (match_operand:V8QI 0 "register_operand" "=y")
21169         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21170                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21171   "TARGET_MMX"
21172   "paddsb\t{%2, %0|%0, %2}"
21173   [(set_attr "type" "mmxadd")
21174    (set_attr "mode" "DI")])
21176 (define_insn "ssaddv4hi3"
21177   [(set (match_operand:V4HI 0 "register_operand" "=y")
21178         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21179                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21180   "TARGET_MMX"
21181   "paddsw\t{%2, %0|%0, %2}"
21182   [(set_attr "type" "mmxadd")
21183    (set_attr "mode" "DI")])
21185 (define_insn "usaddv8qi3"
21186   [(set (match_operand:V8QI 0 "register_operand" "=y")
21187         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21188                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21189   "TARGET_MMX"
21190   "paddusb\t{%2, %0|%0, %2}"
21191   [(set_attr "type" "mmxadd")
21192    (set_attr "mode" "DI")])
21194 (define_insn "usaddv4hi3"
21195   [(set (match_operand:V4HI 0 "register_operand" "=y")
21196         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21197                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21198   "TARGET_MMX"
21199   "paddusw\t{%2, %0|%0, %2}"
21200   [(set_attr "type" "mmxadd")
21201    (set_attr "mode" "DI")])
21203 (define_insn "subv8qi3"
21204   [(set (match_operand:V8QI 0 "register_operand" "=y")
21205         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21206                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21207   "TARGET_MMX"
21208   "psubb\t{%2, %0|%0, %2}"
21209   [(set_attr "type" "mmxadd")
21210    (set_attr "mode" "DI")])
21212 (define_insn "subv4hi3"
21213   [(set (match_operand:V4HI 0 "register_operand" "=y")
21214         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21215                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21216   "TARGET_MMX"
21217   "psubw\t{%2, %0|%0, %2}"
21218   [(set_attr "type" "mmxadd")
21219    (set_attr "mode" "DI")])
21221 (define_insn "subv2si3"
21222   [(set (match_operand:V2SI 0 "register_operand" "=y")
21223         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21224                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21225   "TARGET_MMX"
21226   "psubd\t{%2, %0|%0, %2}"
21227   [(set_attr "type" "mmxadd")
21228    (set_attr "mode" "DI")])
21230 (define_insn "mmx_subdi3"
21231   [(set (match_operand:DI 0 "register_operand" "=y")
21232         (unspec:DI
21233          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21234                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21235          UNSPEC_NOP))]
21236   "TARGET_MMX"
21237   "psubq\t{%2, %0|%0, %2}"
21238   [(set_attr "type" "mmxadd")
21239    (set_attr "mode" "DI")])
21241 (define_insn "sssubv8qi3"
21242   [(set (match_operand:V8QI 0 "register_operand" "=y")
21243         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21244                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21245   "TARGET_MMX"
21246   "psubsb\t{%2, %0|%0, %2}"
21247   [(set_attr "type" "mmxadd")
21248    (set_attr "mode" "DI")])
21250 (define_insn "sssubv4hi3"
21251   [(set (match_operand:V4HI 0 "register_operand" "=y")
21252         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21253                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21254   "TARGET_MMX"
21255   "psubsw\t{%2, %0|%0, %2}"
21256   [(set_attr "type" "mmxadd")
21257    (set_attr "mode" "DI")])
21259 (define_insn "ussubv8qi3"
21260   [(set (match_operand:V8QI 0 "register_operand" "=y")
21261         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21262                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21263   "TARGET_MMX"
21264   "psubusb\t{%2, %0|%0, %2}"
21265   [(set_attr "type" "mmxadd")
21266    (set_attr "mode" "DI")])
21268 (define_insn "ussubv4hi3"
21269   [(set (match_operand:V4HI 0 "register_operand" "=y")
21270         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21271                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21272   "TARGET_MMX"
21273   "psubusw\t{%2, %0|%0, %2}"
21274   [(set_attr "type" "mmxadd")
21275    (set_attr "mode" "DI")])
21277 (define_insn "mulv4hi3"
21278   [(set (match_operand:V4HI 0 "register_operand" "=y")
21279         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21280                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21281   "TARGET_MMX"
21282   "pmullw\t{%2, %0|%0, %2}"
21283   [(set_attr "type" "mmxmul")
21284    (set_attr "mode" "DI")])
21286 (define_insn "smulv4hi3_highpart"
21287   [(set (match_operand:V4HI 0 "register_operand" "=y")
21288         (truncate:V4HI
21289          (lshiftrt:V4SI
21290           (mult:V4SI (sign_extend:V4SI
21291                       (match_operand:V4HI 1 "register_operand" "0"))
21292                      (sign_extend:V4SI
21293                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21294           (const_int 16))))]
21295   "TARGET_MMX"
21296   "pmulhw\t{%2, %0|%0, %2}"
21297   [(set_attr "type" "mmxmul")
21298    (set_attr "mode" "DI")])
21300 (define_insn "umulv4hi3_highpart"
21301   [(set (match_operand:V4HI 0 "register_operand" "=y")
21302         (truncate:V4HI
21303          (lshiftrt:V4SI
21304           (mult:V4SI (zero_extend:V4SI
21305                       (match_operand:V4HI 1 "register_operand" "0"))
21306                      (zero_extend:V4SI
21307                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21308           (const_int 16))))]
21309   "TARGET_SSE || TARGET_3DNOW_A"
21310   "pmulhuw\t{%2, %0|%0, %2}"
21311   [(set_attr "type" "mmxmul")
21312    (set_attr "mode" "DI")])
21314 (define_insn "mmx_pmaddwd"
21315   [(set (match_operand:V2SI 0 "register_operand" "=y")
21316         (plus:V2SI
21317          (mult:V2SI
21318           (sign_extend:V2SI
21319            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21320                             (parallel [(const_int 0) (const_int 2)])))
21321           (sign_extend:V2SI
21322            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21323                             (parallel [(const_int 0) (const_int 2)]))))
21324          (mult:V2SI
21325           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21326                                              (parallel [(const_int 1)
21327                                                         (const_int 3)])))
21328           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21329                                              (parallel [(const_int 1)
21330                                                         (const_int 3)]))))))]
21331   "TARGET_MMX"
21332   "pmaddwd\t{%2, %0|%0, %2}"
21333   [(set_attr "type" "mmxmul")
21334    (set_attr "mode" "DI")])
21337 ;; MMX logical operations
21338 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21339 ;; normal code that also wants to use the FPU from getting broken.
21340 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21341 (define_insn "mmx_iordi3"
21342   [(set (match_operand:DI 0 "register_operand" "=y")
21343         (unspec:DI
21344          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21345                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21346          UNSPEC_NOP))]
21347   "TARGET_MMX"
21348   "por\t{%2, %0|%0, %2}"
21349   [(set_attr "type" "mmxadd")
21350    (set_attr "mode" "DI")])
21352 (define_insn "mmx_xordi3"
21353   [(set (match_operand:DI 0 "register_operand" "=y")
21354         (unspec:DI
21355          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21356                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21357          UNSPEC_NOP))]
21358   "TARGET_MMX"
21359   "pxor\t{%2, %0|%0, %2}"
21360   [(set_attr "type" "mmxadd")
21361    (set_attr "mode" "DI")
21362    (set_attr "memory" "none")])
21364 ;; Same as pxor, but don't show input operands so that we don't think
21365 ;; they are live.
21366 (define_insn "mmx_clrdi"
21367   [(set (match_operand:DI 0 "register_operand" "=y")
21368         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21369   "TARGET_MMX"
21370   "pxor\t{%0, %0|%0, %0}"
21371   [(set_attr "type" "mmxadd")
21372    (set_attr "mode" "DI")
21373    (set_attr "memory" "none")])
21375 (define_insn "mmx_anddi3"
21376   [(set (match_operand:DI 0 "register_operand" "=y")
21377         (unspec:DI
21378          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21379                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21380          UNSPEC_NOP))]
21381   "TARGET_MMX"
21382   "pand\t{%2, %0|%0, %2}"
21383   [(set_attr "type" "mmxadd")
21384    (set_attr "mode" "DI")])
21386 (define_insn "mmx_nanddi3"
21387   [(set (match_operand:DI 0 "register_operand" "=y")
21388         (unspec:DI
21389          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21390                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21391          UNSPEC_NOP))]
21392   "TARGET_MMX"
21393   "pandn\t{%2, %0|%0, %2}"
21394   [(set_attr "type" "mmxadd")
21395    (set_attr "mode" "DI")])
21398 ;; MMX unsigned averages/sum of absolute differences
21400 (define_insn "mmx_uavgv8qi3"
21401   [(set (match_operand:V8QI 0 "register_operand" "=y")
21402         (ashiftrt:V8QI
21403          (plus:V8QI (plus:V8QI
21404                      (match_operand:V8QI 1 "register_operand" "0")
21405                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21406                     (const_vector:V8QI [(const_int 1)
21407                                         (const_int 1)
21408                                         (const_int 1)
21409                                         (const_int 1)
21410                                         (const_int 1)
21411                                         (const_int 1)
21412                                         (const_int 1)
21413                                         (const_int 1)]))
21414          (const_int 1)))]
21415   "TARGET_SSE || TARGET_3DNOW_A"
21416   "pavgb\t{%2, %0|%0, %2}"
21417   [(set_attr "type" "mmxshft")
21418    (set_attr "mode" "DI")])
21420 (define_insn "mmx_uavgv4hi3"
21421   [(set (match_operand:V4HI 0 "register_operand" "=y")
21422         (ashiftrt:V4HI
21423          (plus:V4HI (plus:V4HI
21424                      (match_operand:V4HI 1 "register_operand" "0")
21425                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21426                     (const_vector:V4HI [(const_int 1)
21427                                         (const_int 1)
21428                                         (const_int 1)
21429                                         (const_int 1)]))
21430          (const_int 1)))]
21431   "TARGET_SSE || TARGET_3DNOW_A"
21432   "pavgw\t{%2, %0|%0, %2}"
21433   [(set_attr "type" "mmxshft")
21434    (set_attr "mode" "DI")])
21436 (define_insn "mmx_psadbw"
21437   [(set (match_operand:DI 0 "register_operand" "=y")
21438         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21439                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21440                    UNSPEC_PSADBW))]
21441   "TARGET_SSE || TARGET_3DNOW_A"
21442   "psadbw\t{%2, %0|%0, %2}"
21443   [(set_attr "type" "mmxshft")
21444    (set_attr "mode" "DI")])
21447 ;; MMX insert/extract/shuffle
21449 (define_expand "mmx_pinsrw"
21450   [(set (match_operand:V4HI 0 "register_operand" "")
21451         (vec_merge:V4HI
21452           (match_operand:V4HI 1 "register_operand" "")
21453           (vec_duplicate:V4HI
21454             (match_operand:SI 2 "nonimmediate_operand" ""))
21455           (match_operand:SI 3 "const_0_to_3_operand" "")))]
21456   "TARGET_SSE || TARGET_3DNOW_A"
21458   operands[2] = gen_lowpart (HImode, operands[2]);
21459   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
21462 (define_insn "*mmx_pinsrw"
21463   [(set (match_operand:V4HI 0 "register_operand" "=y")
21464         (vec_merge:V4HI
21465           (match_operand:V4HI 1 "register_operand" "0")
21466           (vec_duplicate:V4HI
21467             (match_operand:HI 2 "nonimmediate_operand" "rm"))
21468           (match_operand:SI 3 "const_pow2_1_to_8_operand" "N")))]
21469   "TARGET_SSE || TARGET_3DNOW_A"
21471   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
21472   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
21474   [(set_attr "type" "mmxcvt")
21475    (set_attr "mode" "DI")])
21477 (define_insn "mmx_pextrw"
21478   [(set (match_operand:SI 0 "register_operand" "=r")
21479         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21480                                        (parallel
21481                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21482   "TARGET_SSE || TARGET_3DNOW_A"
21483   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21484   [(set_attr "type" "mmxcvt")
21485    (set_attr "mode" "DI")])
21487 (define_insn "mmx_pshufw"
21488   [(set (match_operand:V4HI 0 "register_operand" "=y")
21489         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21490                       (match_operand:SI 2 "immediate_operand" "i")]
21491                      UNSPEC_SHUFFLE))]
21492   "TARGET_SSE || TARGET_3DNOW_A"
21493   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21494   [(set_attr "type" "mmxcvt")
21495    (set_attr "mode" "DI")])
21498 ;; MMX mask-generating comparisons
21500 (define_insn "eqv8qi3"
21501   [(set (match_operand:V8QI 0 "register_operand" "=y")
21502         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21503                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21504   "TARGET_MMX"
21505   "pcmpeqb\t{%2, %0|%0, %2}"
21506   [(set_attr "type" "mmxcmp")
21507    (set_attr "mode" "DI")])
21509 (define_insn "eqv4hi3"
21510   [(set (match_operand:V4HI 0 "register_operand" "=y")
21511         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21512                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21513   "TARGET_MMX"
21514   "pcmpeqw\t{%2, %0|%0, %2}"
21515   [(set_attr "type" "mmxcmp")
21516    (set_attr "mode" "DI")])
21518 (define_insn "eqv2si3"
21519   [(set (match_operand:V2SI 0 "register_operand" "=y")
21520         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21521                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21522   "TARGET_MMX"
21523   "pcmpeqd\t{%2, %0|%0, %2}"
21524   [(set_attr "type" "mmxcmp")
21525    (set_attr "mode" "DI")])
21527 (define_insn "gtv8qi3"
21528   [(set (match_operand:V8QI 0 "register_operand" "=y")
21529         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21530                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21531   "TARGET_MMX"
21532   "pcmpgtb\t{%2, %0|%0, %2}"
21533   [(set_attr "type" "mmxcmp")
21534    (set_attr "mode" "DI")])
21536 (define_insn "gtv4hi3"
21537   [(set (match_operand:V4HI 0 "register_operand" "=y")
21538         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21539                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21540   "TARGET_MMX"
21541   "pcmpgtw\t{%2, %0|%0, %2}"
21542   [(set_attr "type" "mmxcmp")
21543    (set_attr "mode" "DI")])
21545 (define_insn "gtv2si3"
21546   [(set (match_operand:V2SI 0 "register_operand" "=y")
21547         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21548                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21549   "TARGET_MMX"
21550   "pcmpgtd\t{%2, %0|%0, %2}"
21551   [(set_attr "type" "mmxcmp")
21552    (set_attr "mode" "DI")])
21555 ;; MMX max/min insns
21557 (define_insn "umaxv8qi3"
21558   [(set (match_operand:V8QI 0 "register_operand" "=y")
21559         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21560                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21561   "TARGET_SSE || TARGET_3DNOW_A"
21562   "pmaxub\t{%2, %0|%0, %2}"
21563   [(set_attr "type" "mmxadd")
21564    (set_attr "mode" "DI")])
21566 (define_insn "smaxv4hi3"
21567   [(set (match_operand:V4HI 0 "register_operand" "=y")
21568         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21569                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21570   "TARGET_SSE || TARGET_3DNOW_A"
21571   "pmaxsw\t{%2, %0|%0, %2}"
21572   [(set_attr "type" "mmxadd")
21573    (set_attr "mode" "DI")])
21575 (define_insn "uminv8qi3"
21576   [(set (match_operand:V8QI 0 "register_operand" "=y")
21577         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21578                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21579   "TARGET_SSE || TARGET_3DNOW_A"
21580   "pminub\t{%2, %0|%0, %2}"
21581   [(set_attr "type" "mmxadd")
21582    (set_attr "mode" "DI")])
21584 (define_insn "sminv4hi3"
21585   [(set (match_operand:V4HI 0 "register_operand" "=y")
21586         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21587                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21588   "TARGET_SSE || TARGET_3DNOW_A"
21589   "pminsw\t{%2, %0|%0, %2}"
21590   [(set_attr "type" "mmxadd")
21591    (set_attr "mode" "DI")])
21594 ;; MMX shifts
21596 (define_insn "ashrv4hi3"
21597   [(set (match_operand:V4HI 0 "register_operand" "=y")
21598         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21599                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21600   "TARGET_MMX"
21601   "psraw\t{%2, %0|%0, %2}"
21602   [(set_attr "type" "mmxshft")
21603    (set_attr "mode" "DI")])
21605 (define_insn "ashrv2si3"
21606   [(set (match_operand:V2SI 0 "register_operand" "=y")
21607         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21608                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21609   "TARGET_MMX"
21610   "psrad\t{%2, %0|%0, %2}"
21611   [(set_attr "type" "mmxshft")
21612    (set_attr "mode" "DI")])
21614 (define_insn "lshrv4hi3"
21615   [(set (match_operand:V4HI 0 "register_operand" "=y")
21616         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21617                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21618   "TARGET_MMX"
21619   "psrlw\t{%2, %0|%0, %2}"
21620   [(set_attr "type" "mmxshft")
21621    (set_attr "mode" "DI")])
21623 (define_insn "lshrv2si3"
21624   [(set (match_operand:V2SI 0 "register_operand" "=y")
21625         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21626                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21627   "TARGET_MMX"
21628   "psrld\t{%2, %0|%0, %2}"
21629   [(set_attr "type" "mmxshft")
21630    (set_attr "mode" "DI")])
21632 ;; See logical MMX insns.
21633 (define_insn "mmx_lshrdi3"
21634   [(set (match_operand:DI 0 "register_operand" "=y")
21635         (unspec:DI
21636           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21637                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21638           UNSPEC_NOP))]
21639   "TARGET_MMX"
21640   "psrlq\t{%2, %0|%0, %2}"
21641   [(set_attr "type" "mmxshft")
21642    (set_attr "mode" "DI")])
21644 (define_insn "ashlv4hi3"
21645   [(set (match_operand:V4HI 0 "register_operand" "=y")
21646         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21647                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21648   "TARGET_MMX"
21649   "psllw\t{%2, %0|%0, %2}"
21650   [(set_attr "type" "mmxshft")
21651    (set_attr "mode" "DI")])
21653 (define_insn "ashlv2si3"
21654   [(set (match_operand:V2SI 0 "register_operand" "=y")
21655         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21656                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21657   "TARGET_MMX"
21658   "pslld\t{%2, %0|%0, %2}"
21659   [(set_attr "type" "mmxshft")
21660    (set_attr "mode" "DI")])
21662 ;; See logical MMX insns.
21663 (define_insn "mmx_ashldi3"
21664   [(set (match_operand:DI 0 "register_operand" "=y")
21665         (unspec:DI
21666          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21667                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21668          UNSPEC_NOP))]
21669   "TARGET_MMX"
21670   "psllq\t{%2, %0|%0, %2}"
21671   [(set_attr "type" "mmxshft")
21672    (set_attr "mode" "DI")])
21675 ;; MMX pack/unpack insns.
21677 (define_insn "mmx_packsswb"
21678   [(set (match_operand:V8QI 0 "register_operand" "=y")
21679         (vec_concat:V8QI
21680          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21681          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21682   "TARGET_MMX"
21683   "packsswb\t{%2, %0|%0, %2}"
21684   [(set_attr "type" "mmxshft")
21685    (set_attr "mode" "DI")])
21687 (define_insn "mmx_packssdw"
21688   [(set (match_operand:V4HI 0 "register_operand" "=y")
21689         (vec_concat:V4HI
21690          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21691          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21692   "TARGET_MMX"
21693   "packssdw\t{%2, %0|%0, %2}"
21694   [(set_attr "type" "mmxshft")
21695    (set_attr "mode" "DI")])
21697 (define_insn "mmx_packuswb"
21698   [(set (match_operand:V8QI 0 "register_operand" "=y")
21699         (vec_concat:V8QI
21700          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21701          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21702   "TARGET_MMX"
21703   "packuswb\t{%2, %0|%0, %2}"
21704   [(set_attr "type" "mmxshft")
21705    (set_attr "mode" "DI")])
21707 (define_insn "mmx_punpckhbw"
21708   [(set (match_operand:V8QI 0 "register_operand" "=y")
21709         (vec_merge:V8QI
21710          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21711                           (parallel [(const_int 4)
21712                                      (const_int 0)
21713                                      (const_int 5)
21714                                      (const_int 1)
21715                                      (const_int 6)
21716                                      (const_int 2)
21717                                      (const_int 7)
21718                                      (const_int 3)]))
21719          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21720                           (parallel [(const_int 0)
21721                                      (const_int 4)
21722                                      (const_int 1)
21723                                      (const_int 5)
21724                                      (const_int 2)
21725                                      (const_int 6)
21726                                      (const_int 3)
21727                                      (const_int 7)]))
21728          (const_int 85)))]
21729   "TARGET_MMX"
21730   "punpckhbw\t{%2, %0|%0, %2}"
21731   [(set_attr "type" "mmxcvt")
21732    (set_attr "mode" "DI")])
21734 (define_insn "mmx_punpckhwd"
21735   [(set (match_operand:V4HI 0 "register_operand" "=y")
21736         (vec_merge:V4HI
21737          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21738                           (parallel [(const_int 0)
21739                                      (const_int 2)
21740                                      (const_int 1)
21741                                      (const_int 3)]))
21742          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21743                           (parallel [(const_int 2)
21744                                      (const_int 0)
21745                                      (const_int 3)
21746                                      (const_int 1)]))
21747          (const_int 5)))]
21748   "TARGET_MMX"
21749   "punpckhwd\t{%2, %0|%0, %2}"
21750   [(set_attr "type" "mmxcvt")
21751    (set_attr "mode" "DI")])
21753 (define_insn "mmx_punpckhdq"
21754   [(set (match_operand:V2SI 0 "register_operand" "=y")
21755         (vec_merge:V2SI
21756          (match_operand:V2SI 1 "register_operand" "0")
21757          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21758                           (parallel [(const_int 1)
21759                                      (const_int 0)]))
21760          (const_int 1)))]
21761   "TARGET_MMX"
21762   "punpckhdq\t{%2, %0|%0, %2}"
21763   [(set_attr "type" "mmxcvt")
21764    (set_attr "mode" "DI")])
21766 (define_insn "mmx_punpcklbw"
21767   [(set (match_operand:V8QI 0 "register_operand" "=y")
21768         (vec_merge:V8QI
21769          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21770                           (parallel [(const_int 0)
21771                                      (const_int 4)
21772                                      (const_int 1)
21773                                      (const_int 5)
21774                                      (const_int 2)
21775                                      (const_int 6)
21776                                      (const_int 3)
21777                                      (const_int 7)]))
21778          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21779                           (parallel [(const_int 4)
21780                                      (const_int 0)
21781                                      (const_int 5)
21782                                      (const_int 1)
21783                                      (const_int 6)
21784                                      (const_int 2)
21785                                      (const_int 7)
21786                                      (const_int 3)]))
21787          (const_int 85)))]
21788   "TARGET_MMX"
21789   "punpcklbw\t{%2, %0|%0, %2}"
21790   [(set_attr "type" "mmxcvt")
21791    (set_attr "mode" "DI")])
21793 (define_insn "mmx_punpcklwd"
21794   [(set (match_operand:V4HI 0 "register_operand" "=y")
21795         (vec_merge:V4HI
21796          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21797                           (parallel [(const_int 2)
21798                                      (const_int 0)
21799                                      (const_int 3)
21800                                      (const_int 1)]))
21801          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21802                           (parallel [(const_int 0)
21803                                      (const_int 2)
21804                                      (const_int 1)
21805                                      (const_int 3)]))
21806          (const_int 5)))]
21807   "TARGET_MMX"
21808   "punpcklwd\t{%2, %0|%0, %2}"
21809   [(set_attr "type" "mmxcvt")
21810    (set_attr "mode" "DI")])
21812 (define_insn "mmx_punpckldq"
21813   [(set (match_operand:V2SI 0 "register_operand" "=y")
21814         (vec_merge:V2SI
21815          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21816                            (parallel [(const_int 1)
21817                                       (const_int 0)]))
21818          (match_operand:V2SI 2 "register_operand" "y")
21819          (const_int 1)))]
21820   "TARGET_MMX"
21821   "punpckldq\t{%2, %0|%0, %2}"
21822   [(set_attr "type" "mmxcvt")
21823    (set_attr "mode" "DI")])
21826 ;; Miscellaneous stuff
21828 (define_insn "emms"
21829   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21830    (clobber (reg:XF 8))
21831    (clobber (reg:XF 9))
21832    (clobber (reg:XF 10))
21833    (clobber (reg:XF 11))
21834    (clobber (reg:XF 12))
21835    (clobber (reg:XF 13))
21836    (clobber (reg:XF 14))
21837    (clobber (reg:XF 15))
21838    (clobber (reg:DI 29))
21839    (clobber (reg:DI 30))
21840    (clobber (reg:DI 31))
21841    (clobber (reg:DI 32))
21842    (clobber (reg:DI 33))
21843    (clobber (reg:DI 34))
21844    (clobber (reg:DI 35))
21845    (clobber (reg:DI 36))]
21846   "TARGET_MMX"
21847   "emms"
21848   [(set_attr "type" "mmx")
21849    (set_attr "memory" "unknown")])
21851 (define_insn "ldmxcsr"
21852   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21853                     UNSPECV_LDMXCSR)]
21854   "TARGET_SSE"
21855   "ldmxcsr\t%0"
21856   [(set_attr "type" "sse")
21857    (set_attr "memory" "load")])
21859 (define_insn "stmxcsr"
21860   [(set (match_operand:SI 0 "memory_operand" "=m")
21861         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21862   "TARGET_SSE"
21863   "stmxcsr\t%0"
21864   [(set_attr "type" "sse")
21865    (set_attr "memory" "store")])
21867 (define_expand "sfence"
21868   [(set (match_dup 0)
21869         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21870   "TARGET_SSE || TARGET_3DNOW_A"
21872   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21873   MEM_VOLATILE_P (operands[0]) = 1;
21876 (define_insn "*sfence_insn"
21877   [(set (match_operand:BLK 0 "" "")
21878         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21879   "TARGET_SSE || TARGET_3DNOW_A"
21880   "sfence"
21881   [(set_attr "type" "sse")
21882    (set_attr "memory" "unknown")])
21884 (define_expand "sse_prologue_save"
21885   [(parallel [(set (match_operand:BLK 0 "" "")
21886                    (unspec:BLK [(reg:DI 21)
21887                                 (reg:DI 22)
21888                                 (reg:DI 23)
21889                                 (reg:DI 24)
21890                                 (reg:DI 25)
21891                                 (reg:DI 26)
21892                                 (reg:DI 27)
21893                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21894               (use (match_operand:DI 1 "register_operand" ""))
21895               (use (match_operand:DI 2 "immediate_operand" ""))
21896               (use (label_ref:DI (match_operand 3 "" "")))])]
21897   "TARGET_64BIT"
21898   "")
21900 (define_insn "*sse_prologue_save_insn"
21901   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21902                           (match_operand:DI 4 "const_int_operand" "n")))
21903         (unspec:BLK [(reg:DI 21)
21904                      (reg:DI 22)
21905                      (reg:DI 23)
21906                      (reg:DI 24)
21907                      (reg:DI 25)
21908                      (reg:DI 26)
21909                      (reg:DI 27)
21910                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21911    (use (match_operand:DI 1 "register_operand" "r"))
21912    (use (match_operand:DI 2 "const_int_operand" "i"))
21913    (use (label_ref:DI (match_operand 3 "" "X")))]
21914   "TARGET_64BIT
21915    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21916    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21917   "*
21919   int i;
21920   operands[0] = gen_rtx_MEM (Pmode,
21921                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21922   output_asm_insn (\"jmp\\t%A1\", operands);
21923   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21924     {
21925       operands[4] = adjust_address (operands[0], DImode, i*16);
21926       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21927       PUT_MODE (operands[4], TImode);
21928       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21929         output_asm_insn (\"rex\", operands);
21930       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21931     }
21932   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21933                              CODE_LABEL_NUMBER (operands[3]));
21934   RET;
21936   "
21937   [(set_attr "type" "other")
21938    (set_attr "length_immediate" "0")
21939    (set_attr "length_address" "0")
21940    (set_attr "length" "135")
21941    (set_attr "memory" "store")
21942    (set_attr "modrm" "0")
21943    (set_attr "mode" "DI")])
21945 ;; 3Dnow! instructions
21947 (define_insn "addv2sf3"
21948   [(set (match_operand:V2SF 0 "register_operand" "=y")
21949         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21950                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21951   "TARGET_3DNOW"
21952   "pfadd\\t{%2, %0|%0, %2}"
21953   [(set_attr "type" "mmxadd")
21954    (set_attr "mode" "V2SF")])
21956 (define_insn "subv2sf3"
21957   [(set (match_operand:V2SF 0 "register_operand" "=y")
21958         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21959                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21960   "TARGET_3DNOW"
21961   "pfsub\\t{%2, %0|%0, %2}"
21962   [(set_attr "type" "mmxadd")
21963    (set_attr "mode" "V2SF")])
21965 (define_insn "subrv2sf3"
21966   [(set (match_operand:V2SF 0 "register_operand" "=y")
21967         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21968                     (match_operand:V2SF 1 "register_operand" "0")))]
21969   "TARGET_3DNOW"
21970   "pfsubr\\t{%2, %0|%0, %2}"
21971   [(set_attr "type" "mmxadd")
21972    (set_attr "mode" "V2SF")])
21974 (define_insn "gtv2sf3"
21975   [(set (match_operand:V2SI 0 "register_operand" "=y")
21976         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21977                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21978   "TARGET_3DNOW"
21979   "pfcmpgt\\t{%2, %0|%0, %2}"
21980   [(set_attr "type" "mmxcmp")
21981    (set_attr "mode" "V2SF")])
21983 (define_insn "gev2sf3"
21984   [(set (match_operand:V2SI 0 "register_operand" "=y")
21985         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21986                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21987   "TARGET_3DNOW"
21988   "pfcmpge\\t{%2, %0|%0, %2}"
21989   [(set_attr "type" "mmxcmp")
21990    (set_attr "mode" "V2SF")])
21992 (define_insn "eqv2sf3"
21993   [(set (match_operand:V2SI 0 "register_operand" "=y")
21994         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21995                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21996   "TARGET_3DNOW"
21997   "pfcmpeq\\t{%2, %0|%0, %2}"
21998   [(set_attr "type" "mmxcmp")
21999    (set_attr "mode" "V2SF")])
22001 (define_insn "pfmaxv2sf3"
22002   [(set (match_operand:V2SF 0 "register_operand" "=y")
22003         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22004                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22005   "TARGET_3DNOW"
22006   "pfmax\\t{%2, %0|%0, %2}"
22007   [(set_attr "type" "mmxadd")
22008    (set_attr "mode" "V2SF")])
22010 (define_insn "pfminv2sf3"
22011   [(set (match_operand:V2SF 0 "register_operand" "=y")
22012         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22013                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22014   "TARGET_3DNOW"
22015   "pfmin\\t{%2, %0|%0, %2}"
22016   [(set_attr "type" "mmxadd")
22017    (set_attr "mode" "V2SF")])
22019 (define_insn "mulv2sf3"
22020   [(set (match_operand:V2SF 0 "register_operand" "=y")
22021         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22022                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22023   "TARGET_3DNOW"
22024   "pfmul\\t{%2, %0|%0, %2}"
22025   [(set_attr "type" "mmxmul")
22026    (set_attr "mode" "V2SF")])
22028 (define_insn "femms"
22029   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22030    (clobber (reg:XF 8))
22031    (clobber (reg:XF 9))
22032    (clobber (reg:XF 10))
22033    (clobber (reg:XF 11))
22034    (clobber (reg:XF 12))
22035    (clobber (reg:XF 13))
22036    (clobber (reg:XF 14))
22037    (clobber (reg:XF 15))
22038    (clobber (reg:DI 29))
22039    (clobber (reg:DI 30))
22040    (clobber (reg:DI 31))
22041    (clobber (reg:DI 32))
22042    (clobber (reg:DI 33))
22043    (clobber (reg:DI 34))
22044    (clobber (reg:DI 35))
22045    (clobber (reg:DI 36))]
22046   "TARGET_3DNOW"
22047   "femms"
22048   [(set_attr "type" "mmx")
22049    (set_attr "memory" "none")]) 
22051 (define_insn "pf2id"
22052   [(set (match_operand:V2SI 0 "register_operand" "=y")
22053         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22054   "TARGET_3DNOW"
22055   "pf2id\\t{%1, %0|%0, %1}"
22056   [(set_attr "type" "mmxcvt")
22057    (set_attr "mode" "V2SF")])
22059 (define_insn "pf2iw"
22060   [(set (match_operand:V2SI 0 "register_operand" "=y")
22061         (sign_extend:V2SI
22062            (ss_truncate:V2HI
22063               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22064   "TARGET_3DNOW_A"
22065   "pf2iw\\t{%1, %0|%0, %1}"
22066   [(set_attr "type" "mmxcvt")
22067    (set_attr "mode" "V2SF")])
22069 (define_insn "pfacc"
22070   [(set (match_operand:V2SF 0 "register_operand" "=y")
22071         (vec_concat:V2SF
22072            (plus:SF
22073               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22074                              (parallel [(const_int  0)]))
22075               (vec_select:SF (match_dup 1)
22076                              (parallel [(const_int 1)])))
22077            (plus:SF
22078               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22079                              (parallel [(const_int  0)]))
22080               (vec_select:SF (match_dup 2)
22081                              (parallel [(const_int 1)])))))]
22082   "TARGET_3DNOW"
22083   "pfacc\\t{%2, %0|%0, %2}"
22084   [(set_attr "type" "mmxadd")
22085    (set_attr "mode" "V2SF")])
22087 (define_insn "pfnacc"
22088   [(set (match_operand:V2SF 0 "register_operand" "=y")
22089         (vec_concat:V2SF
22090            (minus:SF
22091               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22092                              (parallel [(const_int 0)]))
22093               (vec_select:SF (match_dup 1)
22094                              (parallel [(const_int 1)])))
22095            (minus:SF
22096               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22097                              (parallel [(const_int  0)]))
22098               (vec_select:SF (match_dup 2)
22099                              (parallel [(const_int 1)])))))]
22100   "TARGET_3DNOW_A"
22101   "pfnacc\\t{%2, %0|%0, %2}"
22102   [(set_attr "type" "mmxadd")
22103    (set_attr "mode" "V2SF")])
22105 (define_insn "pfpnacc"
22106   [(set (match_operand:V2SF 0 "register_operand" "=y")
22107         (vec_concat:V2SF
22108            (minus:SF
22109               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22110                              (parallel [(const_int 0)]))
22111               (vec_select:SF (match_dup 1)
22112                              (parallel [(const_int 1)])))
22113            (plus:SF
22114               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22115                              (parallel [(const_int 0)]))
22116               (vec_select:SF (match_dup 2)
22117                              (parallel [(const_int 1)])))))]
22118   "TARGET_3DNOW_A"
22119   "pfpnacc\\t{%2, %0|%0, %2}"
22120   [(set_attr "type" "mmxadd")
22121    (set_attr "mode" "V2SF")])
22123 (define_insn "pi2fw"
22124   [(set (match_operand:V2SF 0 "register_operand" "=y")
22125         (float:V2SF
22126            (vec_concat:V2SI
22127               (sign_extend:SI
22128                  (truncate:HI
22129                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22130                                    (parallel [(const_int 0)]))))
22131               (sign_extend:SI
22132                  (truncate:HI
22133                     (vec_select:SI (match_dup 1)
22134                                    (parallel [(const_int  1)])))))))]
22135   "TARGET_3DNOW_A"
22136   "pi2fw\\t{%1, %0|%0, %1}"
22137   [(set_attr "type" "mmxcvt")
22138    (set_attr "mode" "V2SF")])
22140 (define_insn "floatv2si2"
22141   [(set (match_operand:V2SF 0 "register_operand" "=y")
22142         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22143   "TARGET_3DNOW"
22144   "pi2fd\\t{%1, %0|%0, %1}"
22145   [(set_attr "type" "mmxcvt")
22146    (set_attr "mode" "V2SF")])
22148 ;; This insn is identical to pavgb in operation, but the opcode is
22149 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22151 (define_insn "pavgusb"
22152  [(set (match_operand:V8QI 0 "register_operand" "=y")
22153        (unspec:V8QI
22154           [(match_operand:V8QI 1 "register_operand" "0")
22155            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22156           UNSPEC_PAVGUSB))]
22157   "TARGET_3DNOW"
22158   "pavgusb\\t{%2, %0|%0, %2}"
22159   [(set_attr "type" "mmxshft")
22160    (set_attr "mode" "TI")])
22162 ;; 3DNow reciprocal and sqrt
22164 (define_insn "pfrcpv2sf2"
22165   [(set (match_operand:V2SF 0 "register_operand" "=y")
22166         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22167         UNSPEC_PFRCP))]
22168   "TARGET_3DNOW"
22169   "pfrcp\\t{%1, %0|%0, %1}"
22170   [(set_attr "type" "mmx")
22171    (set_attr "mode" "TI")])
22173 (define_insn "pfrcpit1v2sf3"
22174   [(set (match_operand:V2SF 0 "register_operand" "=y")
22175         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22176                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22177                      UNSPEC_PFRCPIT1))]
22178   "TARGET_3DNOW"
22179   "pfrcpit1\\t{%2, %0|%0, %2}"
22180   [(set_attr "type" "mmx")
22181    (set_attr "mode" "TI")])
22183 (define_insn "pfrcpit2v2sf3"
22184   [(set (match_operand:V2SF 0 "register_operand" "=y")
22185         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22186                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22187                      UNSPEC_PFRCPIT2))]
22188   "TARGET_3DNOW"
22189   "pfrcpit2\\t{%2, %0|%0, %2}"
22190   [(set_attr "type" "mmx")
22191    (set_attr "mode" "TI")])
22193 (define_insn "pfrsqrtv2sf2"
22194   [(set (match_operand:V2SF 0 "register_operand" "=y")
22195         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22196                      UNSPEC_PFRSQRT))]
22197   "TARGET_3DNOW"
22198   "pfrsqrt\\t{%1, %0|%0, %1}"
22199   [(set_attr "type" "mmx")
22200    (set_attr "mode" "TI")])
22201                 
22202 (define_insn "pfrsqit1v2sf3"
22203   [(set (match_operand:V2SF 0 "register_operand" "=y")
22204         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22205                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22206                      UNSPEC_PFRSQIT1))]
22207   "TARGET_3DNOW"
22208   "pfrsqit1\\t{%2, %0|%0, %2}"
22209   [(set_attr "type" "mmx")
22210    (set_attr "mode" "TI")])
22212 (define_insn "pmulhrwv4hi3"
22213   [(set (match_operand:V4HI 0 "register_operand" "=y")
22214         (truncate:V4HI
22215            (lshiftrt:V4SI
22216               (plus:V4SI
22217                  (mult:V4SI
22218                     (sign_extend:V4SI
22219                        (match_operand:V4HI 1 "register_operand" "0"))
22220                     (sign_extend:V4SI
22221                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22222                  (const_vector:V4SI [(const_int 32768)
22223                                      (const_int 32768)
22224                                      (const_int 32768)
22225                                      (const_int 32768)]))
22226               (const_int 16))))]
22227   "TARGET_3DNOW"
22228   "pmulhrw\\t{%2, %0|%0, %2}"
22229   [(set_attr "type" "mmxmul")
22230    (set_attr "mode" "TI")])
22232 (define_insn "pswapdv2si2"
22233   [(set (match_operand:V2SI 0 "register_operand" "=y")
22234         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22235                          (parallel [(const_int 1) (const_int 0)])))]
22236   "TARGET_3DNOW_A"
22237   "pswapd\\t{%1, %0|%0, %1}"
22238   [(set_attr "type" "mmxcvt")
22239    (set_attr "mode" "TI")])
22241 (define_insn "pswapdv2sf2"
22242   [(set (match_operand:V2SF 0 "register_operand" "=y")
22243         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22244                          (parallel [(const_int 1) (const_int 0)])))]
22245   "TARGET_3DNOW_A"
22246   "pswapd\\t{%1, %0|%0, %1}"
22247   [(set_attr "type" "mmxcvt")
22248    (set_attr "mode" "TI")])
22250 (define_expand "prefetch"
22251   [(prefetch (match_operand 0 "address_operand" "")
22252              (match_operand:SI 1 "const_int_operand" "")
22253              (match_operand:SI 2 "const_int_operand" ""))]
22254   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22256   int rw = INTVAL (operands[1]);
22257   int locality = INTVAL (operands[2]);
22259   if (rw != 0 && rw != 1)
22260     abort ();
22261   if (locality < 0 || locality > 3)
22262     abort ();
22263   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22264     abort ();
22266   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22267      suported by SSE counterpart or the SSE prefetch is not available
22268      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22269      of locality.  */
22270   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22271     operands[2] = GEN_INT (3);
22272   else
22273     operands[1] = const0_rtx;
22276 (define_insn "*prefetch_sse"
22277   [(prefetch (match_operand:SI 0 "address_operand" "p")
22278              (const_int 0)
22279              (match_operand:SI 1 "const_int_operand" ""))]
22280   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22282   static const char * const patterns[4] = {
22283    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22284   };
22286   int locality = INTVAL (operands[1]);
22287   if (locality < 0 || locality > 3)
22288     abort ();
22290   return patterns[locality];  
22292   [(set_attr "type" "sse")
22293    (set_attr "memory" "none")])
22295 (define_insn "*prefetch_sse_rex"
22296   [(prefetch (match_operand:DI 0 "address_operand" "p")
22297              (const_int 0)
22298              (match_operand:SI 1 "const_int_operand" ""))]
22299   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22301   static const char * const patterns[4] = {
22302    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22303   };
22305   int locality = INTVAL (operands[1]);
22306   if (locality < 0 || locality > 3)
22307     abort ();
22309   return patterns[locality];  
22311   [(set_attr "type" "sse")
22312    (set_attr "memory" "none")])
22314 (define_insn "*prefetch_3dnow"
22315   [(prefetch (match_operand:SI 0 "address_operand" "p")
22316              (match_operand:SI 1 "const_int_operand" "n")
22317              (const_int 3))]
22318   "TARGET_3DNOW && !TARGET_64BIT"
22320   if (INTVAL (operands[1]) == 0)
22321     return "prefetch\t%a0";
22322   else
22323     return "prefetchw\t%a0";
22325   [(set_attr "type" "mmx")
22326    (set_attr "memory" "none")])
22328 (define_insn "*prefetch_3dnow_rex"
22329   [(prefetch (match_operand:DI 0 "address_operand" "p")
22330              (match_operand:SI 1 "const_int_operand" "n")
22331              (const_int 3))]
22332   "TARGET_3DNOW && TARGET_64BIT"
22334   if (INTVAL (operands[1]) == 0)
22335     return "prefetch\t%a0";
22336   else
22337     return "prefetchw\t%a0";
22339   [(set_attr "type" "mmx")
22340    (set_attr "memory" "none")])
22342 ;; SSE2 support
22344 (define_insn "addv2df3"
22345   [(set (match_operand:V2DF 0 "register_operand" "=x")
22346         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22347                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22348   "TARGET_SSE2"
22349   "addpd\t{%2, %0|%0, %2}"
22350   [(set_attr "type" "sseadd")
22351    (set_attr "mode" "V2DF")])
22353 (define_insn "vmaddv2df3"
22354   [(set (match_operand:V2DF 0 "register_operand" "=x")
22355         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22356                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22357                         (match_dup 1)
22358                         (const_int 1)))]
22359   "TARGET_SSE2"
22360   "addsd\t{%2, %0|%0, %2}"
22361   [(set_attr "type" "sseadd")
22362    (set_attr "mode" "DF")])
22364 (define_insn "subv2df3"
22365   [(set (match_operand:V2DF 0 "register_operand" "=x")
22366         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22367                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22368   "TARGET_SSE2"
22369   "subpd\t{%2, %0|%0, %2}"
22370   [(set_attr "type" "sseadd")
22371    (set_attr "mode" "V2DF")])
22373 (define_insn "vmsubv2df3"
22374   [(set (match_operand:V2DF 0 "register_operand" "=x")
22375         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22376                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22377                         (match_dup 1)
22378                         (const_int 1)))]
22379   "TARGET_SSE2"
22380   "subsd\t{%2, %0|%0, %2}"
22381   [(set_attr "type" "sseadd")
22382    (set_attr "mode" "DF")])
22384 (define_insn "mulv2df3"
22385   [(set (match_operand:V2DF 0 "register_operand" "=x")
22386         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22387                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22388   "TARGET_SSE2"
22389   "mulpd\t{%2, %0|%0, %2}"
22390   [(set_attr "type" "ssemul")
22391    (set_attr "mode" "V2DF")])
22393 (define_insn "vmmulv2df3"
22394   [(set (match_operand:V2DF 0 "register_operand" "=x")
22395         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22396                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22397                         (match_dup 1)
22398                         (const_int 1)))]
22399   "TARGET_SSE2"
22400   "mulsd\t{%2, %0|%0, %2}"
22401   [(set_attr "type" "ssemul")
22402    (set_attr "mode" "DF")])
22404 (define_insn "divv2df3"
22405   [(set (match_operand:V2DF 0 "register_operand" "=x")
22406         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22407                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22408   "TARGET_SSE2"
22409   "divpd\t{%2, %0|%0, %2}"
22410   [(set_attr "type" "ssediv")
22411    (set_attr "mode" "V2DF")])
22413 (define_insn "vmdivv2df3"
22414   [(set (match_operand:V2DF 0 "register_operand" "=x")
22415         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22416                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22417                         (match_dup 1)
22418                         (const_int 1)))]
22419   "TARGET_SSE2"
22420   "divsd\t{%2, %0|%0, %2}"
22421   [(set_attr "type" "ssediv")
22422    (set_attr "mode" "DF")])
22424 ;; SSE min/max
22426 (define_insn "smaxv2df3"
22427   [(set (match_operand:V2DF 0 "register_operand" "=x")
22428         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22429                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22430   "TARGET_SSE2"
22431   "maxpd\t{%2, %0|%0, %2}"
22432   [(set_attr "type" "sseadd")
22433    (set_attr "mode" "V2DF")])
22435 (define_insn "vmsmaxv2df3"
22436   [(set (match_operand:V2DF 0 "register_operand" "=x")
22437         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22438                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22439                         (match_dup 1)
22440                         (const_int 1)))]
22441   "TARGET_SSE2"
22442   "maxsd\t{%2, %0|%0, %2}"
22443   [(set_attr "type" "sseadd")
22444    (set_attr "mode" "DF")])
22446 (define_insn "sminv2df3"
22447   [(set (match_operand:V2DF 0 "register_operand" "=x")
22448         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22449                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22450   "TARGET_SSE2"
22451   "minpd\t{%2, %0|%0, %2}"
22452   [(set_attr "type" "sseadd")
22453    (set_attr "mode" "V2DF")])
22455 (define_insn "vmsminv2df3"
22456   [(set (match_operand:V2DF 0 "register_operand" "=x")
22457         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22458                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22459                         (match_dup 1)
22460                         (const_int 1)))]
22461   "TARGET_SSE2"
22462   "minsd\t{%2, %0|%0, %2}"
22463   [(set_attr "type" "sseadd")
22464    (set_attr "mode" "DF")])
22465 ;; SSE2 square root.  There doesn't appear to be an extension for the
22466 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22468 (define_insn "sqrtv2df2"
22469   [(set (match_operand:V2DF 0 "register_operand" "=x")
22470         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22471   "TARGET_SSE2"
22472   "sqrtpd\t{%1, %0|%0, %1}"
22473   [(set_attr "type" "sse")
22474    (set_attr "mode" "V2DF")])
22476 (define_insn "vmsqrtv2df2"
22477   [(set (match_operand:V2DF 0 "register_operand" "=x")
22478         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22479                         (match_operand:V2DF 2 "register_operand" "0")
22480                         (const_int 1)))]
22481   "TARGET_SSE2"
22482   "sqrtsd\t{%1, %0|%0, %1}"
22483   [(set_attr "type" "sse")
22484    (set_attr "mode" "SF")])
22486 ;; SSE mask-generating compares
22488 (define_insn "maskcmpv2df3"
22489   [(set (match_operand:V2DI 0 "register_operand" "=x")
22490         (match_operator:V2DI 3 "sse_comparison_operator"
22491                              [(match_operand:V2DF 1 "register_operand" "0")
22492                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22493   "TARGET_SSE2"
22494   "cmp%D3pd\t{%2, %0|%0, %2}"
22495   [(set_attr "type" "ssecmp")
22496    (set_attr "mode" "V2DF")])
22498 (define_insn "maskncmpv2df3"
22499   [(set (match_operand:V2DI 0 "register_operand" "=x")
22500         (not:V2DI
22501          (match_operator:V2DI 3 "sse_comparison_operator"
22502                               [(match_operand:V2DF 1 "register_operand" "0")
22503                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22504   "TARGET_SSE2"
22506   if (GET_CODE (operands[3]) == UNORDERED)
22507     return "cmpordps\t{%2, %0|%0, %2}";
22508   else
22509     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22511   [(set_attr "type" "ssecmp")
22512    (set_attr "mode" "V2DF")])
22514 (define_insn "vmmaskcmpv2df3"
22515   [(set (match_operand:V2DI 0 "register_operand" "=x")
22516         (vec_merge:V2DI
22517          (match_operator:V2DI 3 "sse_comparison_operator"
22518                               [(match_operand:V2DF 1 "register_operand" "0")
22519                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22520          (subreg:V2DI (match_dup 1) 0)
22521          (const_int 1)))]
22522   "TARGET_SSE2"
22523   "cmp%D3sd\t{%2, %0|%0, %2}"
22524   [(set_attr "type" "ssecmp")
22525    (set_attr "mode" "DF")])
22527 (define_insn "vmmaskncmpv2df3"
22528   [(set (match_operand:V2DI 0 "register_operand" "=x")
22529         (vec_merge:V2DI
22530          (not:V2DI
22531           (match_operator:V2DI 3 "sse_comparison_operator"
22532                                [(match_operand:V2DF 1 "register_operand" "0")
22533                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22534          (subreg:V2DI (match_dup 1) 0)
22535          (const_int 1)))]
22536   "TARGET_SSE2"
22538   if (GET_CODE (operands[3]) == UNORDERED)
22539     return "cmpordsd\t{%2, %0|%0, %2}";
22540   else
22541     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22543   [(set_attr "type" "ssecmp")
22544    (set_attr "mode" "DF")])
22546 (define_insn "sse2_comi"
22547   [(set (reg:CCFP FLAGS_REG)
22548         (compare:CCFP (vec_select:DF
22549                        (match_operand:V2DF 0 "register_operand" "x")
22550                        (parallel [(const_int 0)]))
22551                       (vec_select:DF
22552                        (match_operand:V2DF 1 "register_operand" "x")
22553                        (parallel [(const_int 0)]))))]
22554   "TARGET_SSE2"
22555   "comisd\t{%1, %0|%0, %1}"
22556   [(set_attr "type" "ssecomi")
22557    (set_attr "mode" "DF")])
22559 (define_insn "sse2_ucomi"
22560   [(set (reg:CCFPU FLAGS_REG)
22561         (compare:CCFPU (vec_select:DF
22562                          (match_operand:V2DF 0 "register_operand" "x")
22563                          (parallel [(const_int 0)]))
22564                         (vec_select:DF
22565                          (match_operand:V2DF 1 "register_operand" "x")
22566                          (parallel [(const_int 0)]))))]
22567   "TARGET_SSE2"
22568   "ucomisd\t{%1, %0|%0, %1}"
22569   [(set_attr "type" "ssecomi")
22570    (set_attr "mode" "DF")])
22572 ;; SSE Strange Moves.
22574 (define_insn "sse2_movmskpd"
22575   [(set (match_operand:SI 0 "register_operand" "=r")
22576         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22577                    UNSPEC_MOVMSK))]
22578   "TARGET_SSE2"
22579   "movmskpd\t{%1, %0|%0, %1}"
22580   [(set_attr "type" "ssecvt")
22581    (set_attr "mode" "V2DF")])
22583 (define_insn "sse2_pmovmskb"
22584   [(set (match_operand:SI 0 "register_operand" "=r")
22585         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22586                    UNSPEC_MOVMSK))]
22587   "TARGET_SSE2"
22588   "pmovmskb\t{%1, %0|%0, %1}"
22589   [(set_attr "type" "ssecvt")
22590    (set_attr "mode" "V2DF")])
22592 (define_insn "sse2_maskmovdqu"
22593   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22594         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22595                        (match_operand:V16QI 2 "register_operand" "x")]
22596                       UNSPEC_MASKMOV))]
22597   "TARGET_SSE2"
22598   ;; @@@ check ordering of operands in intel/nonintel syntax
22599   "maskmovdqu\t{%2, %1|%1, %2}"
22600   [(set_attr "type" "ssecvt")
22601    (set_attr "mode" "TI")])
22603 (define_insn "sse2_maskmovdqu_rex64"
22604   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22605         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22606                        (match_operand:V16QI 2 "register_operand" "x")]
22607                       UNSPEC_MASKMOV))]
22608   "TARGET_SSE2"
22609   ;; @@@ check ordering of operands in intel/nonintel syntax
22610   "maskmovdqu\t{%2, %1|%1, %2}"
22611   [(set_attr "type" "ssecvt")
22612    (set_attr "mode" "TI")])
22614 (define_insn "sse2_movntv2df"
22615   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22616         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22617                      UNSPEC_MOVNT))]
22618   "TARGET_SSE2"
22619   "movntpd\t{%1, %0|%0, %1}"
22620   [(set_attr "type" "ssecvt")
22621    (set_attr "mode" "V2DF")])
22623 (define_insn "sse2_movntv2di"
22624   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22625         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22626                      UNSPEC_MOVNT))]
22627   "TARGET_SSE2"
22628   "movntdq\t{%1, %0|%0, %1}"
22629   [(set_attr "type" "ssecvt")
22630    (set_attr "mode" "TI")])
22632 (define_insn "sse2_movntsi"
22633   [(set (match_operand:SI 0 "memory_operand" "=m")
22634         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22635                    UNSPEC_MOVNT))]
22636   "TARGET_SSE2"
22637   "movnti\t{%1, %0|%0, %1}"
22638   [(set_attr "type" "ssecvt")
22639    (set_attr "mode" "V2DF")])
22641 ;; SSE <-> integer/MMX conversions
22643 ;; Conversions between SI and SF
22645 (define_insn "cvtdq2ps"
22646   [(set (match_operand:V4SF 0 "register_operand" "=x")
22647         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22648   "TARGET_SSE2"
22649   "cvtdq2ps\t{%1, %0|%0, %1}"
22650   [(set_attr "type" "ssecvt")
22651    (set_attr "mode" "V2DF")])
22653 (define_insn "cvtps2dq"
22654   [(set (match_operand:V4SI 0 "register_operand" "=x")
22655         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22656   "TARGET_SSE2"
22657   "cvtps2dq\t{%1, %0|%0, %1}"
22658   [(set_attr "type" "ssecvt")
22659    (set_attr "mode" "TI")])
22661 (define_insn "cvttps2dq"
22662   [(set (match_operand:V4SI 0 "register_operand" "=x")
22663         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22664                      UNSPEC_FIX))]
22665   "TARGET_SSE2"
22666   "cvttps2dq\t{%1, %0|%0, %1}"
22667   [(set_attr "type" "ssecvt")
22668    (set_attr "mode" "TI")])
22670 ;; Conversions between SI and DF
22672 (define_insn "cvtdq2pd"
22673   [(set (match_operand:V2DF 0 "register_operand" "=x")
22674         (float:V2DF (vec_select:V2SI
22675                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22676                      (parallel
22677                       [(const_int 0)
22678                        (const_int 1)]))))]
22679   "TARGET_SSE2"
22680   "cvtdq2pd\t{%1, %0|%0, %1}"
22681   [(set_attr "type" "ssecvt")
22682    (set_attr "mode" "V2DF")])
22684 (define_insn "cvtpd2dq"
22685   [(set (match_operand:V4SI 0 "register_operand" "=x")
22686         (vec_concat:V4SI
22687          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22688          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22689   "TARGET_SSE2"
22690   "cvtpd2dq\t{%1, %0|%0, %1}"
22691   [(set_attr "type" "ssecvt")
22692    (set_attr "mode" "TI")])
22694 (define_insn "cvttpd2dq"
22695   [(set (match_operand:V4SI 0 "register_operand" "=x")
22696         (vec_concat:V4SI
22697          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22698                       UNSPEC_FIX)
22699          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22700   "TARGET_SSE2"
22701   "cvttpd2dq\t{%1, %0|%0, %1}"
22702   [(set_attr "type" "ssecvt")
22703    (set_attr "mode" "TI")])
22705 (define_insn "cvtpd2pi"
22706   [(set (match_operand:V2SI 0 "register_operand" "=y")
22707         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22708   "TARGET_SSE2"
22709   "cvtpd2pi\t{%1, %0|%0, %1}"
22710   [(set_attr "type" "ssecvt")
22711    (set_attr "mode" "TI")])
22713 (define_insn "cvttpd2pi"
22714   [(set (match_operand:V2SI 0 "register_operand" "=y")
22715         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22716                      UNSPEC_FIX))]
22717   "TARGET_SSE2"
22718   "cvttpd2pi\t{%1, %0|%0, %1}"
22719   [(set_attr "type" "ssecvt")
22720    (set_attr "mode" "TI")])
22722 (define_insn "cvtpi2pd"
22723   [(set (match_operand:V2DF 0 "register_operand" "=x")
22724         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22725   "TARGET_SSE2"
22726   "cvtpi2pd\t{%1, %0|%0, %1}"
22727   [(set_attr "type" "ssecvt")
22728    (set_attr "mode" "TI")])
22730 ;; Conversions between SI and DF
22732 (define_insn "cvtsd2si"
22733   [(set (match_operand:SI 0 "register_operand" "=r,r")
22734         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22735                                (parallel [(const_int 0)]))))]
22736   "TARGET_SSE2"
22737   "cvtsd2si\t{%1, %0|%0, %1}"
22738   [(set_attr "type" "sseicvt")
22739    (set_attr "athlon_decode" "double,vector")
22740    (set_attr "mode" "SI")])
22742 (define_insn "cvtsd2siq"
22743   [(set (match_operand:DI 0 "register_operand" "=r,r")
22744         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22745                                (parallel [(const_int 0)]))))]
22746   "TARGET_SSE2 && TARGET_64BIT"
22747   "cvtsd2siq\t{%1, %0|%0, %1}"
22748   [(set_attr "type" "sseicvt")
22749    (set_attr "athlon_decode" "double,vector")
22750    (set_attr "mode" "DI")])
22752 (define_insn "cvttsd2si"
22753   [(set (match_operand:SI 0 "register_operand" "=r,r")
22754         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22755                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22756   "TARGET_SSE2"
22757   "cvttsd2si\t{%1, %0|%0, %1}"
22758   [(set_attr "type" "sseicvt")
22759    (set_attr "mode" "SI")
22760    (set_attr "athlon_decode" "double,vector")])
22762 (define_insn "cvttsd2siq"
22763   [(set (match_operand:DI 0 "register_operand" "=r,r")
22764         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22765                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22766   "TARGET_SSE2 && TARGET_64BIT"
22767   "cvttsd2siq\t{%1, %0|%0, %1}"
22768   [(set_attr "type" "sseicvt")
22769    (set_attr "mode" "DI")
22770    (set_attr "athlon_decode" "double,vector")])
22772 (define_insn "cvtsi2sd"
22773   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22774         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22775                         (vec_duplicate:V2DF
22776                           (float:DF
22777                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22778                         (const_int 2)))]
22779   "TARGET_SSE2"
22780   "cvtsi2sd\t{%2, %0|%0, %2}"
22781   [(set_attr "type" "sseicvt")
22782    (set_attr "mode" "DF")
22783    (set_attr "athlon_decode" "double,direct")])
22785 (define_insn "cvtsi2sdq"
22786   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22787         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22788                         (vec_duplicate:V2DF
22789                           (float:DF
22790                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22791                         (const_int 2)))]
22792   "TARGET_SSE2 && TARGET_64BIT"
22793   "cvtsi2sdq\t{%2, %0|%0, %2}"
22794   [(set_attr "type" "sseicvt")
22795    (set_attr "mode" "DF")
22796    (set_attr "athlon_decode" "double,direct")])
22798 ;; Conversions between SF and DF
22800 (define_insn "cvtsd2ss"
22801   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22802         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22803                         (vec_duplicate:V4SF
22804                           (float_truncate:V2SF
22805                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22806                         (const_int 14)))]
22807   "TARGET_SSE2"
22808   "cvtsd2ss\t{%2, %0|%0, %2}"
22809   [(set_attr "type" "ssecvt")
22810    (set_attr "athlon_decode" "vector,double")
22811    (set_attr "mode" "SF")])
22813 (define_insn "cvtss2sd"
22814   [(set (match_operand:V2DF 0 "register_operand" "=x")
22815         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22816                         (float_extend:V2DF
22817                           (vec_select:V2SF
22818                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22819                             (parallel [(const_int 0)
22820                                        (const_int 1)])))
22821                         (const_int 2)))]
22822   "TARGET_SSE2"
22823   "cvtss2sd\t{%2, %0|%0, %2}"
22824   [(set_attr "type" "ssecvt")
22825    (set_attr "mode" "DF")])
22827 (define_insn "cvtpd2ps"
22828   [(set (match_operand:V4SF 0 "register_operand" "=x")
22829         (subreg:V4SF
22830           (vec_concat:V4SI
22831             (subreg:V2SI (float_truncate:V2SF
22832                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22833             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22834   "TARGET_SSE2"
22835   "cvtpd2ps\t{%1, %0|%0, %1}"
22836   [(set_attr "type" "ssecvt")
22837    (set_attr "mode" "V4SF")])
22839 (define_insn "cvtps2pd"
22840   [(set (match_operand:V2DF 0 "register_operand" "=x")
22841         (float_extend:V2DF
22842           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22843                            (parallel [(const_int 0)
22844                                       (const_int 1)]))))]
22845   "TARGET_SSE2"
22846   "cvtps2pd\t{%1, %0|%0, %1}"
22847   [(set_attr "type" "ssecvt")
22848    (set_attr "mode" "V2DF")])
22850 ;; SSE2 variants of MMX insns
22852 ;; MMX arithmetic
22854 (define_insn "addv16qi3"
22855   [(set (match_operand:V16QI 0 "register_operand" "=x")
22856         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22857                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22858   "TARGET_SSE2"
22859   "paddb\t{%2, %0|%0, %2}"
22860   [(set_attr "type" "sseiadd")
22861    (set_attr "mode" "TI")])
22863 (define_insn "addv8hi3"
22864   [(set (match_operand:V8HI 0 "register_operand" "=x")
22865         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22866                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22867   "TARGET_SSE2"
22868   "paddw\t{%2, %0|%0, %2}"
22869   [(set_attr "type" "sseiadd")
22870    (set_attr "mode" "TI")])
22872 (define_insn "addv4si3"
22873   [(set (match_operand:V4SI 0 "register_operand" "=x")
22874         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22875                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22876   "TARGET_SSE2"
22877   "paddd\t{%2, %0|%0, %2}"
22878   [(set_attr "type" "sseiadd")
22879    (set_attr "mode" "TI")])
22881 (define_insn "addv2di3"
22882   [(set (match_operand:V2DI 0 "register_operand" "=x")
22883         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22884                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22885   "TARGET_SSE2"
22886   "paddq\t{%2, %0|%0, %2}"
22887   [(set_attr "type" "sseiadd")
22888    (set_attr "mode" "TI")])
22890 (define_insn "ssaddv16qi3"
22891   [(set (match_operand:V16QI 0 "register_operand" "=x")
22892         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22893                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22894   "TARGET_SSE2"
22895   "paddsb\t{%2, %0|%0, %2}"
22896   [(set_attr "type" "sseiadd")
22897    (set_attr "mode" "TI")])
22899 (define_insn "ssaddv8hi3"
22900   [(set (match_operand:V8HI 0 "register_operand" "=x")
22901         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22902                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22903   "TARGET_SSE2"
22904   "paddsw\t{%2, %0|%0, %2}"
22905   [(set_attr "type" "sseiadd")
22906    (set_attr "mode" "TI")])
22908 (define_insn "usaddv16qi3"
22909   [(set (match_operand:V16QI 0 "register_operand" "=x")
22910         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22911                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22912   "TARGET_SSE2"
22913   "paddusb\t{%2, %0|%0, %2}"
22914   [(set_attr "type" "sseiadd")
22915    (set_attr "mode" "TI")])
22917 (define_insn "usaddv8hi3"
22918   [(set (match_operand:V8HI 0 "register_operand" "=x")
22919         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22920                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22921   "TARGET_SSE2"
22922   "paddusw\t{%2, %0|%0, %2}"
22923   [(set_attr "type" "sseiadd")
22924    (set_attr "mode" "TI")])
22926 (define_insn "subv16qi3"
22927   [(set (match_operand:V16QI 0 "register_operand" "=x")
22928         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22929                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22930   "TARGET_SSE2"
22931   "psubb\t{%2, %0|%0, %2}"
22932   [(set_attr "type" "sseiadd")
22933    (set_attr "mode" "TI")])
22935 (define_insn "subv8hi3"
22936   [(set (match_operand:V8HI 0 "register_operand" "=x")
22937         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22938                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22939   "TARGET_SSE2"
22940   "psubw\t{%2, %0|%0, %2}"
22941   [(set_attr "type" "sseiadd")
22942    (set_attr "mode" "TI")])
22944 (define_insn "subv4si3"
22945   [(set (match_operand:V4SI 0 "register_operand" "=x")
22946         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22947                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22948   "TARGET_SSE2"
22949   "psubd\t{%2, %0|%0, %2}"
22950   [(set_attr "type" "sseiadd")
22951    (set_attr "mode" "TI")])
22953 (define_insn "subv2di3"
22954   [(set (match_operand:V2DI 0 "register_operand" "=x")
22955         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22956                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22957   "TARGET_SSE2"
22958   "psubq\t{%2, %0|%0, %2}"
22959   [(set_attr "type" "sseiadd")
22960    (set_attr "mode" "TI")])
22962 (define_insn "sssubv16qi3"
22963   [(set (match_operand:V16QI 0 "register_operand" "=x")
22964         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22965                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22966   "TARGET_SSE2"
22967   "psubsb\t{%2, %0|%0, %2}"
22968   [(set_attr "type" "sseiadd")
22969    (set_attr "mode" "TI")])
22971 (define_insn "sssubv8hi3"
22972   [(set (match_operand:V8HI 0 "register_operand" "=x")
22973         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22974                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22975   "TARGET_SSE2"
22976   "psubsw\t{%2, %0|%0, %2}"
22977   [(set_attr "type" "sseiadd")
22978    (set_attr "mode" "TI")])
22980 (define_insn "ussubv16qi3"
22981   [(set (match_operand:V16QI 0 "register_operand" "=x")
22982         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22983                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22984   "TARGET_SSE2"
22985   "psubusb\t{%2, %0|%0, %2}"
22986   [(set_attr "type" "sseiadd")
22987    (set_attr "mode" "TI")])
22989 (define_insn "ussubv8hi3"
22990   [(set (match_operand:V8HI 0 "register_operand" "=x")
22991         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22992                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22993   "TARGET_SSE2"
22994   "psubusw\t{%2, %0|%0, %2}"
22995   [(set_attr "type" "sseiadd")
22996    (set_attr "mode" "TI")])
22998 (define_insn "mulv8hi3"
22999   [(set (match_operand:V8HI 0 "register_operand" "=x")
23000         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23001                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23002   "TARGET_SSE2"
23003   "pmullw\t{%2, %0|%0, %2}"
23004   [(set_attr "type" "sseimul")
23005    (set_attr "mode" "TI")])
23007 (define_insn "smulv8hi3_highpart"
23008   [(set (match_operand:V8HI 0 "register_operand" "=x")
23009         (truncate:V8HI
23010          (lshiftrt:V8SI
23011           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23012                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23013           (const_int 16))))]
23014   "TARGET_SSE2"
23015   "pmulhw\t{%2, %0|%0, %2}"
23016   [(set_attr "type" "sseimul")
23017    (set_attr "mode" "TI")])
23019 (define_insn "umulv8hi3_highpart"
23020   [(set (match_operand:V8HI 0 "register_operand" "=x")
23021         (truncate:V8HI
23022          (lshiftrt:V8SI
23023           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23024                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23025           (const_int 16))))]
23026   "TARGET_SSE2"
23027   "pmulhuw\t{%2, %0|%0, %2}"
23028   [(set_attr "type" "sseimul")
23029    (set_attr "mode" "TI")])
23031 (define_insn "sse2_umulsidi3"
23032   [(set (match_operand:DI 0 "register_operand" "=y")
23033         (mult:DI (zero_extend:DI (vec_select:SI
23034                                   (match_operand:V2SI 1 "register_operand" "0")
23035                                   (parallel [(const_int 0)])))
23036                  (zero_extend:DI (vec_select:SI
23037                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23038                                   (parallel [(const_int 0)])))))]
23039   "TARGET_SSE2"
23040   "pmuludq\t{%2, %0|%0, %2}"
23041   [(set_attr "type" "mmxmul")
23042    (set_attr "mode" "DI")])
23044 (define_insn "sse2_umulv2siv2di3"
23045   [(set (match_operand:V2DI 0 "register_operand" "=x")
23046         (mult:V2DI (zero_extend:V2DI
23047                      (vec_select:V2SI
23048                        (match_operand:V4SI 1 "register_operand" "0")
23049                        (parallel [(const_int 0) (const_int 2)])))
23050                    (zero_extend:V2DI
23051                      (vec_select:V2SI
23052                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23053                        (parallel [(const_int 0) (const_int 2)])))))]
23054   "TARGET_SSE2"
23055   "pmuludq\t{%2, %0|%0, %2}"
23056   [(set_attr "type" "sseimul")
23057    (set_attr "mode" "TI")])
23059 (define_insn "sse2_pmaddwd"
23060   [(set (match_operand:V4SI 0 "register_operand" "=x")
23061         (plus:V4SI
23062          (mult:V4SI
23063           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23064                                              (parallel [(const_int 0)
23065                                                         (const_int 2)
23066                                                         (const_int 4)
23067                                                         (const_int 6)])))
23068           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23069                                              (parallel [(const_int 0)
23070                                                         (const_int 2)
23071                                                         (const_int 4)
23072                                                         (const_int 6)]))))
23073          (mult:V4SI
23074           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23075                                              (parallel [(const_int 1)
23076                                                         (const_int 3)
23077                                                         (const_int 5)
23078                                                         (const_int 7)])))
23079           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23080                                              (parallel [(const_int 1)
23081                                                         (const_int 3)
23082                                                         (const_int 5)
23083                                                         (const_int 7)]))))))]
23084   "TARGET_SSE2"
23085   "pmaddwd\t{%2, %0|%0, %2}"
23086   [(set_attr "type" "sseiadd")
23087    (set_attr "mode" "TI")])
23089 ;; Same as pxor, but don't show input operands so that we don't think
23090 ;; they are live.
23091 (define_insn "sse2_clrti"
23092   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23093   "TARGET_SSE2"
23095   if (get_attr_mode (insn) == MODE_TI)
23096     return "pxor\t%0, %0";
23097   else
23098     return "xorps\t%0, %0";
23100   [(set_attr "type" "ssemov")
23101    (set_attr "memory" "none")
23102    (set (attr "mode")
23103               (if_then_else
23104                 (ne (symbol_ref "optimize_size")
23105                     (const_int 0))
23106                 (const_string "V4SF")
23107                 (const_string "TI")))])
23109 ;; MMX unsigned averages/sum of absolute differences
23111 (define_insn "sse2_uavgv16qi3"
23112   [(set (match_operand:V16QI 0 "register_operand" "=x")
23113         (ashiftrt:V16QI
23114          (plus:V16QI (plus:V16QI
23115                      (match_operand:V16QI 1 "register_operand" "0")
23116                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23117                      (const_vector:V16QI [(const_int 1) (const_int 1)
23118                                           (const_int 1) (const_int 1)
23119                                           (const_int 1) (const_int 1)
23120                                           (const_int 1) (const_int 1)
23121                                           (const_int 1) (const_int 1)
23122                                           (const_int 1) (const_int 1)
23123                                           (const_int 1) (const_int 1)
23124                                           (const_int 1) (const_int 1)]))
23125          (const_int 1)))]
23126   "TARGET_SSE2"
23127   "pavgb\t{%2, %0|%0, %2}"
23128   [(set_attr "type" "sseiadd")
23129    (set_attr "mode" "TI")])
23131 (define_insn "sse2_uavgv8hi3"
23132   [(set (match_operand:V8HI 0 "register_operand" "=x")
23133         (ashiftrt:V8HI
23134          (plus:V8HI (plus:V8HI
23135                      (match_operand:V8HI 1 "register_operand" "0")
23136                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23137                     (const_vector:V8HI [(const_int 1) (const_int 1)
23138                                         (const_int 1) (const_int 1)
23139                                         (const_int 1) (const_int 1)
23140                                         (const_int 1) (const_int 1)]))
23141          (const_int 1)))]
23142   "TARGET_SSE2"
23143   "pavgw\t{%2, %0|%0, %2}"
23144   [(set_attr "type" "sseiadd")
23145    (set_attr "mode" "TI")])
23147 ;; @@@ this isn't the right representation.
23148 (define_insn "sse2_psadbw"
23149   [(set (match_operand:V2DI 0 "register_operand" "=x")
23150         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23151                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23152                      UNSPEC_PSADBW))]
23153   "TARGET_SSE2"
23154   "psadbw\t{%2, %0|%0, %2}"
23155   [(set_attr "type" "sseiadd")
23156    (set_attr "mode" "TI")])
23159 ;; MMX insert/extract/shuffle
23161 (define_expand "sse2_pinsrw"
23162   [(set (match_operand:V8HI 0 "register_operand" "")
23163         (vec_merge:V8HI
23164           (match_operand:V8HI 1 "register_operand" "")
23165           (vec_duplicate:V8HI
23166             (match_operand:SI 2 "nonimmediate_operand" ""))
23167           (match_operand:SI 3 "const_0_to_7_operand" "")))]
23168   "TARGET_SSE2"
23170   operands[2] = gen_lowpart (HImode, operands[2]);
23171   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
23174 (define_insn "*sse2_pinsrw"
23175   [(set (match_operand:V8HI 0 "register_operand" "=x")
23176         (vec_merge:V8HI
23177           (match_operand:V8HI 1 "register_operand" "0")
23178           (vec_duplicate:V8HI
23179             (match_operand:HI 2 "nonimmediate_operand" "rm"))
23180           (match_operand:SI 3 "const_pow2_1_to_128_operand" "N")))]
23181   "TARGET_SSE2"
23183   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
23184   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
23186   [(set_attr "type" "ssecvt")
23187    (set_attr "mode" "TI")])
23189 (define_insn "sse2_pextrw"
23190   [(set (match_operand:SI 0 "register_operand" "=r")
23191         (zero_extend:SI
23192           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23193                          (parallel
23194                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23195   "TARGET_SSE2"
23196   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23197   [(set_attr "type" "ssecvt")
23198    (set_attr "mode" "TI")])
23200 (define_insn "sse2_pshufd"
23201   [(set (match_operand:V4SI 0 "register_operand" "=x")
23202         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23203                       (match_operand:SI 2 "immediate_operand" "i")]
23204                      UNSPEC_SHUFFLE))]
23205   "TARGET_SSE2"
23206   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23207   [(set_attr "type" "ssecvt")
23208    (set_attr "mode" "TI")])
23210 (define_insn "sse2_pshuflw"
23211   [(set (match_operand:V8HI 0 "register_operand" "=x")
23212         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23213                       (match_operand:SI 2 "immediate_operand" "i")]
23214                      UNSPEC_PSHUFLW))]
23215   "TARGET_SSE2"
23216   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23217   [(set_attr "type" "ssecvt")
23218    (set_attr "mode" "TI")])
23220 (define_insn "sse2_pshufhw"
23221   [(set (match_operand:V8HI 0 "register_operand" "=x")
23222         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23223                       (match_operand:SI 2 "immediate_operand" "i")]
23224                      UNSPEC_PSHUFHW))]
23225   "TARGET_SSE2"
23226   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23227   [(set_attr "type" "ssecvt")
23228    (set_attr "mode" "TI")])
23230 ;; MMX mask-generating comparisons
23232 (define_insn "eqv16qi3"
23233   [(set (match_operand:V16QI 0 "register_operand" "=x")
23234         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23235                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23236   "TARGET_SSE2"
23237   "pcmpeqb\t{%2, %0|%0, %2}"
23238   [(set_attr "type" "ssecmp")
23239    (set_attr "mode" "TI")])
23241 (define_insn "eqv8hi3"
23242   [(set (match_operand:V8HI 0 "register_operand" "=x")
23243         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23244                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23245   "TARGET_SSE2"
23246   "pcmpeqw\t{%2, %0|%0, %2}"
23247   [(set_attr "type" "ssecmp")
23248    (set_attr "mode" "TI")])
23250 (define_insn "eqv4si3"
23251   [(set (match_operand:V4SI 0 "register_operand" "=x")
23252         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23253                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23254   "TARGET_SSE2"
23255   "pcmpeqd\t{%2, %0|%0, %2}"
23256   [(set_attr "type" "ssecmp")
23257    (set_attr "mode" "TI")])
23259 (define_insn "gtv16qi3"
23260   [(set (match_operand:V16QI 0 "register_operand" "=x")
23261         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23262                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23263   "TARGET_SSE2"
23264   "pcmpgtb\t{%2, %0|%0, %2}"
23265   [(set_attr "type" "ssecmp")
23266    (set_attr "mode" "TI")])
23268 (define_insn "gtv8hi3"
23269   [(set (match_operand:V8HI 0 "register_operand" "=x")
23270         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23271                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23272   "TARGET_SSE2"
23273   "pcmpgtw\t{%2, %0|%0, %2}"
23274   [(set_attr "type" "ssecmp")
23275    (set_attr "mode" "TI")])
23277 (define_insn "gtv4si3"
23278   [(set (match_operand:V4SI 0 "register_operand" "=x")
23279         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23280                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23281   "TARGET_SSE2"
23282   "pcmpgtd\t{%2, %0|%0, %2}"
23283   [(set_attr "type" "ssecmp")
23284    (set_attr "mode" "TI")])
23287 ;; MMX max/min insns
23289 (define_insn "umaxv16qi3"
23290   [(set (match_operand:V16QI 0 "register_operand" "=x")
23291         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23292                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23293   "TARGET_SSE2"
23294   "pmaxub\t{%2, %0|%0, %2}"
23295   [(set_attr "type" "sseiadd")
23296    (set_attr "mode" "TI")])
23298 (define_insn "smaxv8hi3"
23299   [(set (match_operand:V8HI 0 "register_operand" "=x")
23300         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23301                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23302   "TARGET_SSE2"
23303   "pmaxsw\t{%2, %0|%0, %2}"
23304   [(set_attr "type" "sseiadd")
23305    (set_attr "mode" "TI")])
23307 (define_insn "uminv16qi3"
23308   [(set (match_operand:V16QI 0 "register_operand" "=x")
23309         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23310                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23311   "TARGET_SSE2"
23312   "pminub\t{%2, %0|%0, %2}"
23313   [(set_attr "type" "sseiadd")
23314    (set_attr "mode" "TI")])
23316 (define_insn "sminv8hi3"
23317   [(set (match_operand:V8HI 0 "register_operand" "=x")
23318         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23319                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23320   "TARGET_SSE2"
23321   "pminsw\t{%2, %0|%0, %2}"
23322   [(set_attr "type" "sseiadd")
23323    (set_attr "mode" "TI")])
23326 ;; MMX shifts
23328 (define_insn "ashrv8hi3"
23329   [(set (match_operand:V8HI 0 "register_operand" "=x")
23330         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23331                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23332   "TARGET_SSE2"
23333   "psraw\t{%2, %0|%0, %2}"
23334   [(set_attr "type" "sseishft")
23335    (set_attr "mode" "TI")])
23337 (define_insn "ashrv4si3"
23338   [(set (match_operand:V4SI 0 "register_operand" "=x")
23339         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23340                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23341   "TARGET_SSE2"
23342   "psrad\t{%2, %0|%0, %2}"
23343   [(set_attr "type" "sseishft")
23344    (set_attr "mode" "TI")])
23346 (define_insn "lshrv8hi3"
23347   [(set (match_operand:V8HI 0 "register_operand" "=x")
23348         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23349                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23350   "TARGET_SSE2"
23351   "psrlw\t{%2, %0|%0, %2}"
23352   [(set_attr "type" "sseishft")
23353    (set_attr "mode" "TI")])
23355 (define_insn "lshrv4si3"
23356   [(set (match_operand:V4SI 0 "register_operand" "=x")
23357         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23358                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23359   "TARGET_SSE2"
23360   "psrld\t{%2, %0|%0, %2}"
23361   [(set_attr "type" "sseishft")
23362    (set_attr "mode" "TI")])
23364 (define_insn "lshrv2di3"
23365   [(set (match_operand:V2DI 0 "register_operand" "=x")
23366         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23367                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23368   "TARGET_SSE2"
23369   "psrlq\t{%2, %0|%0, %2}"
23370   [(set_attr "type" "sseishft")
23371    (set_attr "mode" "TI")])
23373 (define_insn "ashlv8hi3"
23374   [(set (match_operand:V8HI 0 "register_operand" "=x")
23375         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23376                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23377   "TARGET_SSE2"
23378   "psllw\t{%2, %0|%0, %2}"
23379   [(set_attr "type" "sseishft")
23380    (set_attr "mode" "TI")])
23382 (define_insn "ashlv4si3"
23383   [(set (match_operand:V4SI 0 "register_operand" "=x")
23384         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23385                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23386   "TARGET_SSE2"
23387   "pslld\t{%2, %0|%0, %2}"
23388   [(set_attr "type" "sseishft")
23389    (set_attr "mode" "TI")])
23391 (define_insn "ashlv2di3"
23392   [(set (match_operand:V2DI 0 "register_operand" "=x")
23393         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23394                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23395   "TARGET_SSE2"
23396   "psllq\t{%2, %0|%0, %2}"
23397   [(set_attr "type" "sseishft")
23398    (set_attr "mode" "TI")])
23400 (define_insn "ashrv8hi3_ti"
23401   [(set (match_operand:V8HI 0 "register_operand" "=x")
23402         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23403                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23404   "TARGET_SSE2"
23405   "psraw\t{%2, %0|%0, %2}"
23406   [(set_attr "type" "sseishft")
23407    (set_attr "mode" "TI")])
23409 (define_insn "ashrv4si3_ti"
23410   [(set (match_operand:V4SI 0 "register_operand" "=x")
23411         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23412                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23413   "TARGET_SSE2"
23414   "psrad\t{%2, %0|%0, %2}"
23415   [(set_attr "type" "sseishft")
23416    (set_attr "mode" "TI")])
23418 (define_insn "lshrv8hi3_ti"
23419   [(set (match_operand:V8HI 0 "register_operand" "=x")
23420         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23421                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23422   "TARGET_SSE2"
23423   "psrlw\t{%2, %0|%0, %2}"
23424   [(set_attr "type" "sseishft")
23425    (set_attr "mode" "TI")])
23427 (define_insn "lshrv4si3_ti"
23428   [(set (match_operand:V4SI 0 "register_operand" "=x")
23429         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23430                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23431   "TARGET_SSE2"
23432   "psrld\t{%2, %0|%0, %2}"
23433   [(set_attr "type" "sseishft")
23434    (set_attr "mode" "TI")])
23436 (define_insn "lshrv2di3_ti"
23437   [(set (match_operand:V2DI 0 "register_operand" "=x")
23438         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23439                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23440   "TARGET_SSE2"
23441   "psrlq\t{%2, %0|%0, %2}"
23442   [(set_attr "type" "sseishft")
23443    (set_attr "mode" "TI")])
23445 (define_insn "ashlv8hi3_ti"
23446   [(set (match_operand:V8HI 0 "register_operand" "=x")
23447         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23448                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23449   "TARGET_SSE2"
23450   "psllw\t{%2, %0|%0, %2}"
23451   [(set_attr "type" "sseishft")
23452    (set_attr "mode" "TI")])
23454 (define_insn "ashlv4si3_ti"
23455   [(set (match_operand:V4SI 0 "register_operand" "=x")
23456         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23457                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23458   "TARGET_SSE2"
23459   "pslld\t{%2, %0|%0, %2}"
23460   [(set_attr "type" "sseishft")
23461    (set_attr "mode" "TI")])
23463 (define_insn "ashlv2di3_ti"
23464   [(set (match_operand:V2DI 0 "register_operand" "=x")
23465         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23466                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23467   "TARGET_SSE2"
23468   "psllq\t{%2, %0|%0, %2}"
23469   [(set_attr "type" "sseishft")
23470    (set_attr "mode" "TI")])
23472 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23473 ;; we wouldn't need here it since we never generate TImode arithmetic.
23475 ;; There has to be some kind of prize for the weirdest new instruction...
23476 (define_insn "sse2_ashlti3"
23477   [(set (match_operand:TI 0 "register_operand" "=x")
23478         (unspec:TI
23479          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23480                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23481                                (const_int 8)))] UNSPEC_NOP))]
23482   "TARGET_SSE2"
23483   "pslldq\t{%2, %0|%0, %2}"
23484   [(set_attr "type" "sseishft")
23485    (set_attr "mode" "TI")])
23487 (define_insn "sse2_lshrti3"
23488   [(set (match_operand:TI 0 "register_operand" "=x")
23489         (unspec:TI
23490          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23491                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23492                                 (const_int 8)))] UNSPEC_NOP))]
23493   "TARGET_SSE2"
23494   "psrldq\t{%2, %0|%0, %2}"
23495   [(set_attr "type" "sseishft")
23496    (set_attr "mode" "TI")])
23498 ;; SSE unpack
23500 (define_insn "sse2_unpckhpd"
23501   [(set (match_operand:V2DF 0 "register_operand" "=x")
23502         (vec_concat:V2DF
23503          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23504                         (parallel [(const_int 1)]))
23505          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23506                         (parallel [(const_int 1)]))))]
23507   "TARGET_SSE2"
23508   "unpckhpd\t{%2, %0|%0, %2}"
23509   [(set_attr "type" "ssecvt")
23510    (set_attr "mode" "V2DF")])
23512 (define_insn "sse2_unpcklpd"
23513   [(set (match_operand:V2DF 0 "register_operand" "=x")
23514         (vec_concat:V2DF
23515          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23516                         (parallel [(const_int 0)]))
23517          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23518                         (parallel [(const_int 0)]))))]
23519   "TARGET_SSE2"
23520   "unpcklpd\t{%2, %0|%0, %2}"
23521   [(set_attr "type" "ssecvt")
23522    (set_attr "mode" "V2DF")])
23524 ;; MMX pack/unpack insns.
23526 (define_insn "sse2_packsswb"
23527   [(set (match_operand:V16QI 0 "register_operand" "=x")
23528         (vec_concat:V16QI
23529          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23530          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23531   "TARGET_SSE2"
23532   "packsswb\t{%2, %0|%0, %2}"
23533   [(set_attr "type" "ssecvt")
23534    (set_attr "mode" "TI")])
23536 (define_insn "sse2_packssdw"
23537   [(set (match_operand:V8HI 0 "register_operand" "=x")
23538         (vec_concat:V8HI
23539          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23540          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23541   "TARGET_SSE2"
23542   "packssdw\t{%2, %0|%0, %2}"
23543   [(set_attr "type" "ssecvt")
23544    (set_attr "mode" "TI")])
23546 (define_insn "sse2_packuswb"
23547   [(set (match_operand:V16QI 0 "register_operand" "=x")
23548         (vec_concat:V16QI
23549          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23550          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23551   "TARGET_SSE2"
23552   "packuswb\t{%2, %0|%0, %2}"
23553   [(set_attr "type" "ssecvt")
23554    (set_attr "mode" "TI")])
23556 (define_insn "sse2_punpckhbw"
23557   [(set (match_operand:V16QI 0 "register_operand" "=x")
23558         (vec_merge:V16QI
23559          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23560                            (parallel [(const_int 8) (const_int 0)
23561                                       (const_int 9) (const_int 1)
23562                                       (const_int 10) (const_int 2)
23563                                       (const_int 11) (const_int 3)
23564                                       (const_int 12) (const_int 4)
23565                                       (const_int 13) (const_int 5)
23566                                       (const_int 14) (const_int 6)
23567                                       (const_int 15) (const_int 7)]))
23568          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23569                            (parallel [(const_int 0) (const_int 8)
23570                                       (const_int 1) (const_int 9)
23571                                       (const_int 2) (const_int 10)
23572                                       (const_int 3) (const_int 11)
23573                                       (const_int 4) (const_int 12)
23574                                       (const_int 5) (const_int 13)
23575                                       (const_int 6) (const_int 14)
23576                                       (const_int 7) (const_int 15)]))
23577          (const_int 21845)))]
23578   "TARGET_SSE2"
23579   "punpckhbw\t{%2, %0|%0, %2}"
23580   [(set_attr "type" "ssecvt")
23581    (set_attr "mode" "TI")])
23583 (define_insn "sse2_punpckhwd"
23584   [(set (match_operand:V8HI 0 "register_operand" "=x")
23585         (vec_merge:V8HI
23586          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23587                           (parallel [(const_int 4) (const_int 0)
23588                                      (const_int 5) (const_int 1)
23589                                      (const_int 6) (const_int 2)
23590                                      (const_int 7) (const_int 3)]))
23591          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23592                           (parallel [(const_int 0) (const_int 4)
23593                                      (const_int 1) (const_int 5)
23594                                      (const_int 2) (const_int 6)
23595                                      (const_int 3) (const_int 7)]))
23596          (const_int 85)))]
23597   "TARGET_SSE2"
23598   "punpckhwd\t{%2, %0|%0, %2}"
23599   [(set_attr "type" "ssecvt")
23600    (set_attr "mode" "TI")])
23602 (define_insn "sse2_punpckhdq"
23603   [(set (match_operand:V4SI 0 "register_operand" "=x")
23604         (vec_merge:V4SI
23605          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23606                           (parallel [(const_int 2) (const_int 0)
23607                                      (const_int 3) (const_int 1)]))
23608          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23609                           (parallel [(const_int 0) (const_int 2)
23610                                      (const_int 1) (const_int 3)]))
23611          (const_int 5)))]
23612   "TARGET_SSE2"
23613   "punpckhdq\t{%2, %0|%0, %2}"
23614   [(set_attr "type" "ssecvt")
23615    (set_attr "mode" "TI")])
23617 (define_insn "sse2_punpcklbw"
23618   [(set (match_operand:V16QI 0 "register_operand" "=x")
23619         (vec_merge:V16QI
23620          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23621                            (parallel [(const_int 0) (const_int 8)
23622                                       (const_int 1) (const_int 9)
23623                                       (const_int 2) (const_int 10)
23624                                       (const_int 3) (const_int 11)
23625                                       (const_int 4) (const_int 12)
23626                                       (const_int 5) (const_int 13)
23627                                       (const_int 6) (const_int 14)
23628                                       (const_int 7) (const_int 15)]))
23629          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23630                            (parallel [(const_int 8) (const_int 0)
23631                                       (const_int 9) (const_int 1)
23632                                       (const_int 10) (const_int 2)
23633                                       (const_int 11) (const_int 3)
23634                                       (const_int 12) (const_int 4)
23635                                       (const_int 13) (const_int 5)
23636                                       (const_int 14) (const_int 6)
23637                                       (const_int 15) (const_int 7)]))
23638          (const_int 21845)))]
23639   "TARGET_SSE2"
23640   "punpcklbw\t{%2, %0|%0, %2}"
23641   [(set_attr "type" "ssecvt")
23642    (set_attr "mode" "TI")])
23644 (define_insn "sse2_punpcklwd"
23645   [(set (match_operand:V8HI 0 "register_operand" "=x")
23646         (vec_merge:V8HI
23647          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23648                           (parallel [(const_int 0) (const_int 4)
23649                                      (const_int 1) (const_int 5)
23650                                      (const_int 2) (const_int 6)
23651                                      (const_int 3) (const_int 7)]))
23652          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23653                           (parallel [(const_int 4) (const_int 0)
23654                                      (const_int 5) (const_int 1)
23655                                      (const_int 6) (const_int 2)
23656                                      (const_int 7) (const_int 3)]))
23657          (const_int 85)))]
23658   "TARGET_SSE2"
23659   "punpcklwd\t{%2, %0|%0, %2}"
23660   [(set_attr "type" "ssecvt")
23661    (set_attr "mode" "TI")])
23663 (define_insn "sse2_punpckldq"
23664   [(set (match_operand:V4SI 0 "register_operand" "=x")
23665         (vec_merge:V4SI
23666          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23667                           (parallel [(const_int 0) (const_int 2)
23668                                      (const_int 1) (const_int 3)]))
23669          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23670                           (parallel [(const_int 2) (const_int 0)
23671                                      (const_int 3) (const_int 1)]))
23672          (const_int 5)))]
23673   "TARGET_SSE2"
23674   "punpckldq\t{%2, %0|%0, %2}"
23675   [(set_attr "type" "ssecvt")
23676    (set_attr "mode" "TI")])
23678 (define_insn "sse2_punpcklqdq"
23679   [(set (match_operand:V2DI 0 "register_operand" "=x")
23680         (vec_merge:V2DI
23681          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23682                           (parallel [(const_int 1)
23683                                      (const_int 0)]))
23684          (match_operand:V2DI 1 "register_operand" "0")
23685          (const_int 1)))]
23686   "TARGET_SSE2"
23687   "punpcklqdq\t{%2, %0|%0, %2}"
23688   [(set_attr "type" "ssecvt")
23689    (set_attr "mode" "TI")])
23691 (define_insn "sse2_punpckhqdq"
23692   [(set (match_operand:V2DI 0 "register_operand" "=x")
23693         (vec_merge:V2DI
23694          (match_operand:V2DI 1 "register_operand" "0")
23695          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23696                           (parallel [(const_int 1)
23697                                      (const_int 0)]))
23698          (const_int 1)))]
23699   "TARGET_SSE2"
23700   "punpckhqdq\t{%2, %0|%0, %2}"
23701   [(set_attr "type" "ssecvt")
23702    (set_attr "mode" "TI")])
23704 ;; SSE2 moves
23706 (define_insn "sse2_movapd"
23707   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23708         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23709                      UNSPEC_MOVA))]
23710   "TARGET_SSE2
23711    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23712   "movapd\t{%1, %0|%0, %1}"
23713   [(set_attr "type" "ssemov")
23714    (set_attr "mode" "V2DF")])
23716 (define_insn "sse2_movupd"
23717   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23718         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23719                      UNSPEC_MOVU))]
23720   "TARGET_SSE2
23721    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23722   "movupd\t{%1, %0|%0, %1}"
23723   [(set_attr "type" "ssecvt")
23724    (set_attr "mode" "V2DF")])
23726 (define_insn "sse2_movdqa"
23727   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23728         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23729                        UNSPEC_MOVA))]
23730   "TARGET_SSE2
23731    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23732   "movdqa\t{%1, %0|%0, %1}"
23733   [(set_attr "type" "ssemov")
23734    (set_attr "mode" "TI")])
23736 (define_insn "sse2_movdqu"
23737   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23738         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23739                        UNSPEC_MOVU))]
23740   "TARGET_SSE2
23741    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23742   "movdqu\t{%1, %0|%0, %1}"
23743   [(set_attr "type" "ssecvt")
23744    (set_attr "mode" "TI")])
23746 (define_insn "sse2_movdq2q"
23747   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23748         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23749                        (parallel [(const_int 0)])))]
23750   "TARGET_SSE2 && !TARGET_64BIT"
23751   "@
23752    movq\t{%1, %0|%0, %1}
23753    movdq2q\t{%1, %0|%0, %1}"
23754   [(set_attr "type" "ssecvt")
23755    (set_attr "mode" "TI")])
23757 (define_insn "sse2_movdq2q_rex64"
23758   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23759         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23760                        (parallel [(const_int 0)])))]
23761   "TARGET_SSE2 && TARGET_64BIT"
23762   "@
23763    movq\t{%1, %0|%0, %1}
23764    movdq2q\t{%1, %0|%0, %1}
23765    movd\t{%1, %0|%0, %1}"
23766   [(set_attr "type" "ssecvt")
23767    (set_attr "mode" "TI")])
23769 (define_insn "sse2_movq2dq"
23770   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23771         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23772                          (const_int 0)))]
23773   "TARGET_SSE2 && !TARGET_64BIT"
23774   "@
23775    movq\t{%1, %0|%0, %1}
23776    movq2dq\t{%1, %0|%0, %1}"
23777   [(set_attr "type" "ssecvt,ssemov")
23778    (set_attr "mode" "TI")])
23780 (define_insn "sse2_movq2dq_rex64"
23781   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23782         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23783                          (const_int 0)))]
23784   "TARGET_SSE2 && TARGET_64BIT"
23785   "@
23786    movq\t{%1, %0|%0, %1}
23787    movq2dq\t{%1, %0|%0, %1}
23788    movd\t{%1, %0|%0, %1}"
23789   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23790    (set_attr "mode" "TI")])
23792 (define_insn "sse2_movq"
23793   [(set (match_operand:V2DI 0 "register_operand" "=x")
23794         (vec_concat:V2DI (vec_select:DI
23795                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23796                           (parallel [(const_int 0)]))
23797                          (const_int 0)))]
23798   "TARGET_SSE2"
23799   "movq\t{%1, %0|%0, %1}"
23800   [(set_attr "type" "ssemov")
23801    (set_attr "mode" "TI")])
23803 (define_insn "sse2_loadd"
23804   [(set (match_operand:V4SI 0 "register_operand" "=x")
23805         (vec_merge:V4SI
23806          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23807          (const_vector:V4SI [(const_int 0)
23808                              (const_int 0)
23809                              (const_int 0)
23810                              (const_int 0)])
23811          (const_int 1)))]
23812   "TARGET_SSE2"
23813   "movd\t{%1, %0|%0, %1}"
23814   [(set_attr "type" "ssemov")
23815    (set_attr "mode" "TI")])
23817 (define_insn "sse2_stored"
23818   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23819         (vec_select:SI
23820          (match_operand:V4SI 1 "register_operand" "x")
23821          (parallel [(const_int 0)])))]
23822   "TARGET_SSE2"
23823   "movd\t{%1, %0|%0, %1}"
23824   [(set_attr "type" "ssemov")
23825    (set_attr "mode" "TI")])
23827 ;; Store the high double of the source vector into the double destination.
23828 (define_insn "sse2_storehpd"
23829   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,Y,Y")
23830         (vec_select:DF
23831           (match_operand:V2DF 1 "nonimmediate_operand" " Y,0,o")
23832           (parallel [(const_int 1)])))]
23833   "TARGET_SSE2"
23834   "@
23835    movhpd\t{%1, %0|%0, %1}
23836    unpckhpd\t%0, %0
23837    #"
23838   [(set_attr "type" "ssecvt")
23839    (set_attr "mode" "V2DF")])
23841 (define_split
23842   [(set (match_operand:DF 0 "register_operand" "")
23843         (vec_select:DF
23844           (match_operand:V2DF 1 "memory_operand" "")
23845           (parallel [(const_int 1)])))]
23846   "TARGET_SSE2 && reload_completed"
23847   [(const_int 0)]
23849   emit_move_insn (operands[0], adjust_address (operands[1], DFmode, 8));
23850   DONE;
23853 ;; Load the high double of the target vector from the source scalar.
23854 (define_insn "sse2_loadhpd"
23855   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=Y,Y,o")
23856         (vec_concat:V2DF
23857           (vec_select:DF
23858             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
23859             (parallel [(const_int 0)]))
23860           (match_operand:DF 2 "nonimmediate_operand"     " m,Y,Y")))]
23861   "TARGET_SSE2"
23862   "@
23863    movhpd\t{%2, %0|%0, %2}
23864    unpcklpd\t{%2, %0|%0, %2}
23865    #"
23866   [(set_attr "type" "ssecvt")
23867    (set_attr "mode" "V2DF")])
23869 (define_split
23870   [(set (match_operand:V2DF 0 "memory_operand" "")
23871         (vec_concat:V2DF
23872           (vec_select:DF (match_dup 0) (parallel [(const_int 0)]))
23873           (match_operand:DF 1 "register_operand" "")))]
23874   "TARGET_SSE2 && reload_completed"
23875   [(const_int 0)]
23877   emit_move_insn (adjust_address (operands[0], DFmode, 8), operands[1]);
23878   DONE;
23881 ;; Store the low double of the source vector into the double destination.
23882 (define_expand "sse2_storelpd"
23883   [(set (match_operand:DF 0 "nonimmediate_operand" "")
23884         (vec_select:DF
23885           (match_operand:V2DF 1 "nonimmediate_operand" "")
23886           (parallel [(const_int 1)])))]
23887   "TARGET_SSE2"
23889   operands[1] = gen_lowpart (DFmode, operands[1]);
23890   emit_move_insn (operands[0], operands[1]);
23891   DONE;
23894 ;; Load the load double of the target vector from the source scalar.
23895 (define_insn "sse2_loadlpd"
23896   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=Y,Y,m")
23897         (vec_concat:V2DF
23898           (match_operand:DF 2 "nonimmediate_operand"     " m,Y,Y")
23899           (vec_select:DF
23900             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
23901             (parallel [(const_int 1)]))))]
23902   "TARGET_SSE2"
23903   "@
23904    movlpd\t{%2, %0|%0, %2}
23905    movsd\t{%2, %0|%0, %2}
23906    movlpd\t{%2, %0|%0, %2}"
23907   [(set_attr "type" "ssecvt")
23908    (set_attr "mode" "V2DF")])
23910 ;; Merge the low part of the source vector into the low part of the target.
23911 (define_insn "sse2_movsd"
23912   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=Y,Y,m")
23913         (vec_merge:V2DF
23914          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23915          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,Y")
23916          (const_int 2)))]
23917   "TARGET_SSE2"
23918   "@movsd\t{%2, %0|%0, %2}
23919     movlpd\t{%2, %0|%0, %2}
23920     movlpd\t{%2, %0|%0, %2}"
23921   [(set_attr "type" "ssecvt")
23922    (set_attr "mode" "DF,V2DF,V2DF")])
23924 (define_expand "sse2_loadsd"
23925   [(match_operand:V2DF 0 "register_operand" "")
23926    (match_operand:DF 1 "memory_operand" "")]
23927   "TARGET_SSE2"
23929   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23930                                 CONST0_RTX (V2DFmode)));
23931   DONE;
23934 (define_insn "sse2_loadsd_1"
23935   [(set (match_operand:V2DF 0 "register_operand" "=x")
23936         (vec_merge:V2DF
23937          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23938          (match_operand:V2DF 2 "const0_operand" "X")
23939          (const_int 1)))]
23940   "TARGET_SSE2"
23941   "movsd\t{%1, %0|%0, %1}"
23942   [(set_attr "type" "ssecvt")
23943    (set_attr "mode" "DF")])
23945 (define_insn "sse2_storesd"
23946   [(set (match_operand:DF 0 "memory_operand" "=m")
23947         (vec_select:DF
23948          (match_operand:V2DF 1 "register_operand" "x")
23949          (parallel [(const_int 0)])))]
23950   "TARGET_SSE2"
23951   "movsd\t{%1, %0|%0, %1}"
23952   [(set_attr "type" "ssecvt")
23953    (set_attr "mode" "DF")])
23955 (define_insn "sse2_shufpd"
23956   [(set (match_operand:V2DF 0 "register_operand" "=x")
23957         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23958                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23959                       (match_operand:SI 3 "immediate_operand" "i")]
23960                      UNSPEC_SHUFFLE))]
23961   "TARGET_SSE2"
23962   ;; @@@ check operand order for intel/nonintel syntax
23963   "shufpd\t{%3, %2, %0|%0, %2, %3}"
23964   [(set_attr "type" "ssecvt")
23965    (set_attr "mode" "V2DF")])
23967 (define_insn "sse2_clflush"
23968   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23969                     UNSPECV_CLFLUSH)]
23970   "TARGET_SSE2"
23971   "clflush\t%a0"
23972   [(set_attr "type" "sse")
23973    (set_attr "memory" "unknown")])
23975 (define_expand "sse2_mfence"
23976   [(set (match_dup 0)
23977         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23978   "TARGET_SSE2"
23980   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23981   MEM_VOLATILE_P (operands[0]) = 1;
23984 (define_insn "*mfence_insn"
23985   [(set (match_operand:BLK 0 "" "")
23986         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23987   "TARGET_SSE2"
23988   "mfence"
23989   [(set_attr "type" "sse")
23990    (set_attr "memory" "unknown")])
23992 (define_expand "sse2_lfence"
23993   [(set (match_dup 0)
23994         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23995   "TARGET_SSE2"
23997   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23998   MEM_VOLATILE_P (operands[0]) = 1;
24001 (define_insn "*lfence_insn"
24002   [(set (match_operand:BLK 0 "" "")
24003         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24004   "TARGET_SSE2"
24005   "lfence"
24006   [(set_attr "type" "sse")
24007    (set_attr "memory" "unknown")])
24009 ;; SSE3
24011 (define_insn "mwait"
24012   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24013                      (match_operand:SI 1 "register_operand" "c")]
24014                     UNSPECV_MWAIT)]
24015   "TARGET_SSE3"
24016   "mwait\t%0, %1"
24017   [(set_attr "length" "3")])
24019 (define_insn "monitor"
24020   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24021                      (match_operand:SI 1 "register_operand" "c")
24022                      (match_operand:SI 2 "register_operand" "d")]
24023                     UNSPECV_MONITOR)]
24024   "TARGET_SSE3"
24025   "monitor\t%0, %1, %2"
24026   [(set_attr "length" "3")])
24028 ;; SSE3 arithmetic
24030 (define_insn "addsubv4sf3"
24031   [(set (match_operand:V4SF 0 "register_operand" "=x")
24032         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24033                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24034                      UNSPEC_ADDSUB))]
24035   "TARGET_SSE3"
24036   "addsubps\t{%2, %0|%0, %2}"
24037   [(set_attr "type" "sseadd")
24038    (set_attr "mode" "V4SF")])
24040 (define_insn "addsubv2df3"
24041   [(set (match_operand:V2DF 0 "register_operand" "=x")
24042         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24043                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24044                      UNSPEC_ADDSUB))]
24045   "TARGET_SSE3"
24046   "addsubpd\t{%2, %0|%0, %2}"
24047   [(set_attr "type" "sseadd")
24048    (set_attr "mode" "V2DF")])
24050 (define_insn "haddv4sf3"
24051   [(set (match_operand:V4SF 0 "register_operand" "=x")
24052         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24053                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24054                      UNSPEC_HADD))]
24055   "TARGET_SSE3"
24056   "haddps\t{%2, %0|%0, %2}"
24057   [(set_attr "type" "sseadd")
24058    (set_attr "mode" "V4SF")])
24060 (define_insn "haddv2df3"
24061   [(set (match_operand:V2DF 0 "register_operand" "=x")
24062         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24063                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24064                      UNSPEC_HADD))]
24065   "TARGET_SSE3"
24066   "haddpd\t{%2, %0|%0, %2}"
24067   [(set_attr "type" "sseadd")
24068    (set_attr "mode" "V2DF")])
24070 (define_insn "hsubv4sf3"
24071   [(set (match_operand:V4SF 0 "register_operand" "=x")
24072         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24073                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24074                      UNSPEC_HSUB))]
24075   "TARGET_SSE3"
24076   "hsubps\t{%2, %0|%0, %2}"
24077   [(set_attr "type" "sseadd")
24078    (set_attr "mode" "V4SF")])
24080 (define_insn "hsubv2df3"
24081   [(set (match_operand:V2DF 0 "register_operand" "=x")
24082         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24083                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24084                      UNSPEC_HSUB))]
24085   "TARGET_SSE3"
24086   "hsubpd\t{%2, %0|%0, %2}"
24087   [(set_attr "type" "sseadd")
24088    (set_attr "mode" "V2DF")])
24090 (define_insn "movshdup"
24091   [(set (match_operand:V4SF 0 "register_operand" "=x")
24092         (unspec:V4SF
24093          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24094   "TARGET_SSE3"
24095   "movshdup\t{%1, %0|%0, %1}"
24096   [(set_attr "type" "sse")
24097    (set_attr "mode" "V4SF")])
24099 (define_insn "movsldup"
24100   [(set (match_operand:V4SF 0 "register_operand" "=x")
24101         (unspec:V4SF
24102          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24103   "TARGET_SSE3"
24104   "movsldup\t{%1, %0|%0, %1}"
24105   [(set_attr "type" "sse")
24106    (set_attr "mode" "V4SF")])
24108 (define_insn "lddqu"
24109   [(set (match_operand:V16QI 0 "register_operand" "=x")
24110         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24111                        UNSPEC_LDQQU))]
24112   "TARGET_SSE3"
24113   "lddqu\t{%1, %0|%0, %1}"
24114   [(set_attr "type" "ssecvt")
24115    (set_attr "mode" "TI")])
24117 (define_insn "loadddup"
24118   [(set (match_operand:V2DF 0 "register_operand" "=x")
24119         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24120   "TARGET_SSE3"
24121   "movddup\t{%1, %0|%0, %1}"
24122   [(set_attr "type" "ssecvt")
24123    (set_attr "mode" "DF")])
24125 (define_insn "movddup"
24126   [(set (match_operand:V2DF 0 "register_operand" "=x")
24127         (vec_duplicate:V2DF
24128          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24129                         (parallel [(const_int 0)]))))]
24130   "TARGET_SSE3"
24131   "movddup\t{%1, %0|%0, %1}"
24132   [(set_attr "type" "ssecvt")
24133    (set_attr "mode" "DF")])