* config/i386/i386.c (ix86_prepare_fp_compare_args): Do not
[official-gcc.git] / gcc / config / i386 / i386.md
blobf08c85a4d44eee29023b3d6842924d1c37a024af
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"
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,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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 17)
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 (define_insn "*cmpfp_0_sf"
801   [(set (match_operand:HI 0 "register_operand" "=a")
802         (unspec:HI
803           [(compare:CCFP
804              (match_operand:SF 1 "register_operand" "f")
805              (match_operand:SF 2 "const0_operand" "X"))]
806         UNSPEC_FNSTSW))]
807   "TARGET_80387"
809   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
810     {
811       output_asm_insn ("ftst\;fnstsw\t%0", operands);
812       return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
813     }
814   else
815     return "ftst\;fnstsw\t%0";
817   [(set_attr "type" "multi")
818    (set_attr "mode" "SF")])
820 (define_insn "*cmpfp_0_df"
821   [(set (match_operand:HI 0 "register_operand" "=a")
822         (unspec:HI
823           [(compare:CCFP
824              (match_operand:DF 1 "register_operand" "f")
825              (match_operand:DF 2 "const0_operand" "X"))]
826         UNSPEC_FNSTSW))]
827   "TARGET_80387"
829   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
830     {
831       output_asm_insn ("ftst\;fnstsw\t%0", operands);
832       return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
833     }
834   else
835     return "ftst\;fnstsw\t%0";
837   [(set_attr "type" "multi")
838    (set_attr "mode" "DF")])
840 (define_insn "*cmpfp_0_xf"
841   [(set (match_operand:HI 0 "register_operand" "=a")
842         (unspec:HI
843           [(compare:CCFP
844              (match_operand:XF 1 "register_operand" "f")
845              (match_operand:XF 2 "const0_operand" "X"))]
846         UNSPEC_FNSTSW))]
847   "TARGET_80387"
849   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
850     {
851       output_asm_insn ("ftst\;fnstsw\t%0", operands);
852       return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
853     }
854   else
855     return "ftst\;fnstsw\t%0";
857   [(set_attr "type" "multi")
858    (set_attr "mode" "XF")])
860 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
861 ;; used to manage the reg stack popping would not be preserved.
863 (define_insn "*cmpfp_2_sf"
864   [(set (reg:CCFP FPSR_REG)
865         (compare:CCFP
866           (match_operand:SF 0 "register_operand" "f")
867           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
868   "TARGET_80387"
869   "* return output_fp_compare (insn, operands, 0, 0);"
870   [(set_attr "type" "fcmp")
871    (set_attr "mode" "SF")])
873 (define_insn "*cmpfp_2_sf_1"
874   [(set (match_operand:HI 0 "register_operand" "=a")
875         (unspec:HI
876           [(compare:CCFP
877              (match_operand:SF 1 "register_operand" "f")
878              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
879           UNSPEC_FNSTSW))]
880   "TARGET_80387"
881   "* return output_fp_compare (insn, operands, 2, 0);"
882   [(set_attr "type" "fcmp")
883    (set_attr "mode" "SF")])
885 (define_insn "*cmpfp_2_df"
886   [(set (reg:CCFP FPSR_REG)
887         (compare:CCFP
888           (match_operand:DF 0 "register_operand" "f")
889           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
890   "TARGET_80387"
891   "* return output_fp_compare (insn, operands, 0, 0);"
892   [(set_attr "type" "fcmp")
893    (set_attr "mode" "DF")])
895 (define_insn "*cmpfp_2_df_1"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand:DF 1 "register_operand" "f")
900              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
901           UNSPEC_FNSTSW))]
902   "TARGET_80387"
903   "* return output_fp_compare (insn, operands, 2, 0);"
904   [(set_attr "type" "multi")
905    (set_attr "mode" "DF")])
907 (define_insn "*cmpfp_2_xf"
908   [(set (reg:CCFP FPSR_REG)
909         (compare:CCFP
910           (match_operand:XF 0 "register_operand" "f")
911           (match_operand:XF 1 "register_operand" "f")))]
912   "TARGET_80387"
913   "* return output_fp_compare (insn, operands, 0, 0);"
914   [(set_attr "type" "fcmp")
915    (set_attr "mode" "XF")])
917 (define_insn "*cmpfp_2_xf_1"
918   [(set (match_operand:HI 0 "register_operand" "=a")
919         (unspec:HI
920           [(compare:CCFP
921              (match_operand:XF 1 "register_operand" "f")
922              (match_operand:XF 2 "register_operand" "f"))]
923           UNSPEC_FNSTSW))]
924   "TARGET_80387"
925   "* return output_fp_compare (insn, operands, 2, 0);"
926   [(set_attr "type" "multi")
927    (set_attr "mode" "XF")])
929 (define_insn "*cmpfp_2u"
930   [(set (reg:CCFPU FPSR_REG)
931         (compare:CCFPU
932           (match_operand 0 "register_operand" "f")
933           (match_operand 1 "register_operand" "f")))]
934   "TARGET_80387
935    && FLOAT_MODE_P (GET_MODE (operands[0]))
936    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
937   "* return output_fp_compare (insn, operands, 0, 1);"
938   [(set_attr "type" "fcmp")
939    (set (attr "mode")
940      (cond [(match_operand:SF 1 "" "")
941               (const_string "SF")
942             (match_operand:DF 1 "" "")
943               (const_string "DF")
944            ]
945            (const_string "XF")))])
947 (define_insn "*cmpfp_2u_1"
948   [(set (match_operand:HI 0 "register_operand" "=a")
949         (unspec:HI
950           [(compare:CCFPU
951              (match_operand 1 "register_operand" "f")
952              (match_operand 2 "register_operand" "f"))]
953           UNSPEC_FNSTSW))]
954   "TARGET_80387
955    && FLOAT_MODE_P (GET_MODE (operands[1]))
956    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
957   "* return output_fp_compare (insn, operands, 2, 1);"
958   [(set_attr "type" "multi")
959    (set (attr "mode")
960      (cond [(match_operand:SF 1 "" "")
961               (const_string "SF")
962             (match_operand:DF 1 "" "")
963               (const_string "DF")
964            ]
965            (const_string "XF")))])
967 ;; Patterns to match the SImode-in-memory ficom instructions.
969 ;; %%% Play games with accepting gp registers, as otherwise we have to
970 ;; force them to memory during rtl generation, which is no good.  We
971 ;; can get rid of this once we teach reload to do memory input reloads 
972 ;; via pushes.
974 (define_insn "*ficom_1"
975   [(set (reg:CCFP FPSR_REG)
976         (compare:CCFP
977           (match_operand 0 "register_operand" "f,f")
978           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
979   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
980    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
981   "#")
983 ;; Split the not-really-implemented gp register case into a
984 ;; push-op-pop sequence.
986 ;; %%% This is most efficient, but am I gonna get in trouble
987 ;; for separating cc0_setter and cc0_user?
989 (define_split
990   [(set (reg:CCFP FPSR_REG)
991         (compare:CCFP
992           (match_operand:SF 0 "register_operand" "")
993           (float (match_operand:SI 1 "register_operand" ""))))]
994   "0 && TARGET_80387 && reload_completed"
995   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 1))
996    (set (reg:CCFP FPSR_REG) (compare:CCFP (match_dup 0) (match_dup 2)))
997    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
998               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
999   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1000    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1002 ;; FP compares, step 2
1003 ;; Move the fpsw to ax.
1005 (define_insn "x86_fnstsw_1"
1006   [(set (match_operand:HI 0 "register_operand" "=a")
1007         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1008   "TARGET_80387"
1009   "fnstsw\t%0"
1010   [(set_attr "length" "2")
1011    (set_attr "mode" "SI")
1012    (set_attr "unit" "i387")])
1014 ;; FP compares, step 3
1015 ;; Get ax into flags, general case.
1017 (define_insn "x86_sahf_1"
1018   [(set (reg:CC FLAGS_REG)
1019         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
1020   "!TARGET_64BIT"
1021   "sahf"
1022   [(set_attr "length" "1")
1023    (set_attr "athlon_decode" "vector")
1024    (set_attr "mode" "SI")])
1026 ;; Pentium Pro can do steps 1 through 3 in one go.
1028 (define_insn "*cmpfp_i"
1029   [(set (reg:CCFP FLAGS_REG)
1030         (compare:CCFP (match_operand 0 "register_operand" "f")
1031                       (match_operand 1 "register_operand" "f")))]
1032   "TARGET_80387 && TARGET_CMOVE
1033    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1034    && FLOAT_MODE_P (GET_MODE (operands[0]))
1035    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1036   "* return output_fp_compare (insn, operands, 1, 0);"
1037   [(set_attr "type" "fcmp")
1038    (set (attr "mode")
1039      (cond [(match_operand:SF 1 "" "")
1040               (const_string "SF")
1041             (match_operand:DF 1 "" "")
1042               (const_string "DF")
1043            ]
1044            (const_string "XF")))
1045    (set_attr "athlon_decode" "vector")])
1047 (define_insn "*cmpfp_i_sse"
1048   [(set (reg:CCFP FLAGS_REG)
1049         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1050                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1051   "TARGET_80387
1052    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1053    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1054   "* return output_fp_compare (insn, operands, 1, 0);"
1055   [(set_attr "type" "fcmp,ssecomi")
1056    (set (attr "mode")
1057      (if_then_else (match_operand:SF 1 "" "")
1058         (const_string "SF")
1059         (const_string "DF")))
1060    (set_attr "athlon_decode" "vector")])
1062 (define_insn "*cmpfp_i_sse_only"
1063   [(set (reg:CCFP FLAGS_REG)
1064         (compare:CCFP (match_operand 0 "register_operand" "x")
1065                       (match_operand 1 "nonimmediate_operand" "xm")))]
1066   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1068   "* return output_fp_compare (insn, operands, 1, 0);"
1069   [(set_attr "type" "ssecomi")
1070    (set (attr "mode")
1071      (if_then_else (match_operand:SF 1 "" "")
1072         (const_string "SF")
1073         (const_string "DF")))
1074    (set_attr "athlon_decode" "vector")])
1076 (define_insn "*cmpfp_iu"
1077   [(set (reg:CCFPU FLAGS_REG)
1078         (compare:CCFPU (match_operand 0 "register_operand" "f")
1079                        (match_operand 1 "register_operand" "f")))]
1080   "TARGET_80387 && TARGET_CMOVE
1081    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1082    && FLOAT_MODE_P (GET_MODE (operands[0]))
1083    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1084   "* return output_fp_compare (insn, operands, 1, 1);"
1085   [(set_attr "type" "fcmp")
1086    (set (attr "mode")
1087      (cond [(match_operand:SF 1 "" "")
1088               (const_string "SF")
1089             (match_operand:DF 1 "" "")
1090               (const_string "DF")
1091            ]
1092            (const_string "XF")))
1093    (set_attr "athlon_decode" "vector")])
1095 (define_insn "*cmpfp_iu_sse"
1096   [(set (reg:CCFPU FLAGS_REG)
1097         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1098                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1099   "TARGET_80387
1100    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1101    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1102   "* return output_fp_compare (insn, operands, 1, 1);"
1103   [(set_attr "type" "fcmp,ssecomi")
1104    (set (attr "mode")
1105      (if_then_else (match_operand:SF 1 "" "")
1106         (const_string "SF")
1107         (const_string "DF")))
1108    (set_attr "athlon_decode" "vector")])
1110 (define_insn "*cmpfp_iu_sse_only"
1111   [(set (reg:CCFPU FLAGS_REG)
1112         (compare:CCFPU (match_operand 0 "register_operand" "x")
1113                        (match_operand 1 "nonimmediate_operand" "xm")))]
1114   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1115    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1116   "* return output_fp_compare (insn, operands, 1, 1);"
1117   [(set_attr "type" "ssecomi")
1118    (set (attr "mode")
1119      (if_then_else (match_operand:SF 1 "" "")
1120         (const_string "SF")
1121         (const_string "DF")))
1122    (set_attr "athlon_decode" "vector")])
1124 ;; Move instructions.
1126 ;; General case of fullword move.
1128 (define_expand "movsi"
1129   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1130         (match_operand:SI 1 "general_operand" ""))]
1131   ""
1132   "ix86_expand_move (SImode, operands); DONE;")
1134 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1135 ;; general_operand.
1137 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1138 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1139 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1140 ;; targets without our curiosities, and it is just as easy to represent
1141 ;; this differently.
1143 (define_insn "*pushsi2"
1144   [(set (match_operand:SI 0 "push_operand" "=<")
1145         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1146   "!TARGET_64BIT"
1147   "push{l}\t%1"
1148   [(set_attr "type" "push")
1149    (set_attr "mode" "SI")])
1151 ;; For 64BIT abi we always round up to 8 bytes.
1152 (define_insn "*pushsi2_rex64"
1153   [(set (match_operand:SI 0 "push_operand" "=X")
1154         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1155   "TARGET_64BIT"
1156   "push{q}\t%q1"
1157   [(set_attr "type" "push")
1158    (set_attr "mode" "SI")])
1160 (define_insn "*pushsi2_prologue"
1161   [(set (match_operand:SI 0 "push_operand" "=<")
1162         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1163    (clobber (mem:BLK (scratch)))]
1164   "!TARGET_64BIT"
1165   "push{l}\t%1"
1166   [(set_attr "type" "push")
1167    (set_attr "mode" "SI")])
1169 (define_insn "*popsi1_epilogue"
1170   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1171         (mem:SI (reg:SI SP_REG)))
1172    (set (reg:SI SP_REG)
1173         (plus:SI (reg:SI SP_REG) (const_int 4)))
1174    (clobber (mem:BLK (scratch)))]
1175   "!TARGET_64BIT"
1176   "pop{l}\t%0"
1177   [(set_attr "type" "pop")
1178    (set_attr "mode" "SI")])
1180 (define_insn "popsi1"
1181   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1182         (mem:SI (reg:SI SP_REG)))
1183    (set (reg:SI SP_REG)
1184         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1185   "!TARGET_64BIT"
1186   "pop{l}\t%0"
1187   [(set_attr "type" "pop")
1188    (set_attr "mode" "SI")])
1190 (define_insn "*movsi_xor"
1191   [(set (match_operand:SI 0 "register_operand" "=r")
1192         (match_operand:SI 1 "const0_operand" "i"))
1193    (clobber (reg:CC FLAGS_REG))]
1194   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1195   "xor{l}\t{%0, %0|%0, %0}"
1196   [(set_attr "type" "alu1")
1197    (set_attr "mode" "SI")
1198    (set_attr "length_immediate" "0")])
1200 (define_insn "*movsi_or"
1201   [(set (match_operand:SI 0 "register_operand" "=r")
1202         (match_operand:SI 1 "immediate_operand" "i"))
1203    (clobber (reg:CC FLAGS_REG))]
1204   "reload_completed
1205    && operands[1] == constm1_rtx
1206    && (TARGET_PENTIUM || optimize_size)"
1208   operands[1] = constm1_rtx;
1209   return "or{l}\t{%1, %0|%0, %1}";
1211   [(set_attr "type" "alu1")
1212    (set_attr "mode" "SI")
1213    (set_attr "length_immediate" "1")])
1215 (define_insn "*movsi_1"
1216   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1217         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1218   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1219    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1221   switch (get_attr_type (insn))
1222     {
1223     case TYPE_SSEMOV:
1224       if (get_attr_mode (insn) == MODE_TI)
1225         return "movdqa\t{%1, %0|%0, %1}";
1226       return "movd\t{%1, %0|%0, %1}";
1228     case TYPE_MMXMOV:
1229       if (get_attr_mode (insn) == MODE_DI)
1230         return "movq\t{%1, %0|%0, %1}";
1231       return "movd\t{%1, %0|%0, %1}";
1233     case TYPE_LEA:
1234       return "lea{l}\t{%1, %0|%0, %1}";
1236     default:
1237       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1238         abort();
1239       return "mov{l}\t{%1, %0|%0, %1}";
1240     }
1242   [(set (attr "type")
1243      (cond [(eq_attr "alternative" "2,3,4")
1244               (const_string "mmxmov")
1245             (eq_attr "alternative" "5,6,7")
1246               (const_string "ssemov")
1247             (and (ne (symbol_ref "flag_pic") (const_int 0))
1248                  (match_operand:SI 1 "symbolic_operand" ""))
1249               (const_string "lea")
1250            ]
1251            (const_string "imov")))
1252    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1254 (define_insn "*movsi_1_nointernunit"
1255   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1256         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1257   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1258    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1260   switch (get_attr_type (insn))
1261     {
1262     case TYPE_SSEMOV:
1263       if (get_attr_mode (insn) == MODE_TI)
1264         return "movdqa\t{%1, %0|%0, %1}";
1265       return "movd\t{%1, %0|%0, %1}";
1267     case TYPE_MMXMOV:
1268       if (get_attr_mode (insn) == MODE_DI)
1269         return "movq\t{%1, %0|%0, %1}";
1270       return "movd\t{%1, %0|%0, %1}";
1272     case TYPE_LEA:
1273       return "lea{l}\t{%1, %0|%0, %1}";
1275     default:
1276       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1277         abort();
1278       return "mov{l}\t{%1, %0|%0, %1}";
1279     }
1281   [(set (attr "type")
1282      (cond [(eq_attr "alternative" "2,3,4")
1283               (const_string "mmxmov")
1284             (eq_attr "alternative" "5,6,7")
1285               (const_string "ssemov")
1286             (and (ne (symbol_ref "flag_pic") (const_int 0))
1287                  (match_operand:SI 1 "symbolic_operand" ""))
1288               (const_string "lea")
1289            ]
1290            (const_string "imov")))
1291    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1293 ;; Stores and loads of ax to arbitrary constant address.
1294 ;; We fake an second form of instruction to force reload to load address
1295 ;; into register when rax is not available
1296 (define_insn "*movabssi_1_rex64"
1297   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1298         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1299   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1300   "@
1301    movabs{l}\t{%1, %P0|%P0, %1}
1302    mov{l}\t{%1, %a0|%a0, %1}"
1303   [(set_attr "type" "imov")
1304    (set_attr "modrm" "0,*")
1305    (set_attr "length_address" "8,0")
1306    (set_attr "length_immediate" "0,*")
1307    (set_attr "memory" "store")
1308    (set_attr "mode" "SI")])
1310 (define_insn "*movabssi_2_rex64"
1311   [(set (match_operand:SI 0 "register_operand" "=a,r")
1312         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1313   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1314   "@
1315    movabs{l}\t{%P1, %0|%0, %P1}
1316    mov{l}\t{%a1, %0|%0, %a1}"
1317   [(set_attr "type" "imov")
1318    (set_attr "modrm" "0,*")
1319    (set_attr "length_address" "8,0")
1320    (set_attr "length_immediate" "0")
1321    (set_attr "memory" "load")
1322    (set_attr "mode" "SI")])
1324 (define_insn "*swapsi"
1325   [(set (match_operand:SI 0 "register_operand" "+r")
1326         (match_operand:SI 1 "register_operand" "+r"))
1327    (set (match_dup 1)
1328         (match_dup 0))]
1329   ""
1330   "xchg{l}\t%1, %0"
1331   [(set_attr "type" "imov")
1332    (set_attr "pent_pair" "np")
1333    (set_attr "athlon_decode" "vector")
1334    (set_attr "mode" "SI")
1335    (set_attr "modrm" "0")])
1337 (define_expand "movhi"
1338   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1339         (match_operand:HI 1 "general_operand" ""))]
1340   ""
1341   "ix86_expand_move (HImode, operands); DONE;")
1343 (define_insn "*pushhi2"
1344   [(set (match_operand:HI 0 "push_operand" "=<,<")
1345         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1346   "!TARGET_64BIT"
1347   "@
1348    push{w}\t{|WORD PTR }%1
1349    push{w}\t%1"
1350   [(set_attr "type" "push")
1351    (set_attr "mode" "HI")])
1353 ;; For 64BIT abi we always round up to 8 bytes.
1354 (define_insn "*pushhi2_rex64"
1355   [(set (match_operand:HI 0 "push_operand" "=X")
1356         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1357   "TARGET_64BIT"
1358   "push{q}\t%q1"
1359   [(set_attr "type" "push")
1360    (set_attr "mode" "QI")])
1362 (define_insn "*movhi_1"
1363   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1364         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1365   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1367   switch (get_attr_type (insn))
1368     {
1369     case TYPE_IMOVX:
1370       /* movzwl is faster than movw on p2 due to partial word stalls,
1371          though not as fast as an aligned movl.  */
1372       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1373     default:
1374       if (get_attr_mode (insn) == MODE_SI)
1375         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1376       else
1377         return "mov{w}\t{%1, %0|%0, %1}";
1378     }
1380   [(set (attr "type")
1381      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1382               (const_string "imov")
1383             (and (eq_attr "alternative" "0")
1384                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1385                           (const_int 0))
1386                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1387                           (const_int 0))))
1388               (const_string "imov")
1389             (and (eq_attr "alternative" "1,2")
1390                  (match_operand:HI 1 "aligned_operand" ""))
1391               (const_string "imov")
1392             (and (ne (symbol_ref "TARGET_MOVX")
1393                      (const_int 0))
1394                  (eq_attr "alternative" "0,2"))
1395               (const_string "imovx")
1396            ]
1397            (const_string "imov")))
1398     (set (attr "mode")
1399       (cond [(eq_attr "type" "imovx")
1400                (const_string "SI")
1401              (and (eq_attr "alternative" "1,2")
1402                   (match_operand:HI 1 "aligned_operand" ""))
1403                (const_string "SI")
1404              (and (eq_attr "alternative" "0")
1405                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1406                            (const_int 0))
1407                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1408                            (const_int 0))))
1409                (const_string "SI")
1410             ]
1411             (const_string "HI")))])
1413 ;; Stores and loads of ax to arbitrary constant address.
1414 ;; We fake an second form of instruction to force reload to load address
1415 ;; into register when rax is not available
1416 (define_insn "*movabshi_1_rex64"
1417   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1418         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1419   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1420   "@
1421    movabs{w}\t{%1, %P0|%P0, %1}
1422    mov{w}\t{%1, %a0|%a0, %1}"
1423   [(set_attr "type" "imov")
1424    (set_attr "modrm" "0,*")
1425    (set_attr "length_address" "8,0")
1426    (set_attr "length_immediate" "0,*")
1427    (set_attr "memory" "store")
1428    (set_attr "mode" "HI")])
1430 (define_insn "*movabshi_2_rex64"
1431   [(set (match_operand:HI 0 "register_operand" "=a,r")
1432         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1433   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1434   "@
1435    movabs{w}\t{%P1, %0|%0, %P1}
1436    mov{w}\t{%a1, %0|%0, %a1}"
1437   [(set_attr "type" "imov")
1438    (set_attr "modrm" "0,*")
1439    (set_attr "length_address" "8,0")
1440    (set_attr "length_immediate" "0")
1441    (set_attr "memory" "load")
1442    (set_attr "mode" "HI")])
1444 (define_insn "*swaphi_1"
1445   [(set (match_operand:HI 0 "register_operand" "+r")
1446         (match_operand:HI 1 "register_operand" "+r"))
1447    (set (match_dup 1)
1448         (match_dup 0))]
1449   "TARGET_PARTIAL_REG_STALL"
1450   "xchg{w}\t%1, %0"
1451   [(set_attr "type" "imov")
1452    (set_attr "pent_pair" "np")
1453    (set_attr "mode" "HI")
1454    (set_attr "modrm" "0")])
1456 (define_insn "*swaphi_2"
1457   [(set (match_operand:HI 0 "register_operand" "+r")
1458         (match_operand:HI 1 "register_operand" "+r"))
1459    (set (match_dup 1)
1460         (match_dup 0))]
1461   "! TARGET_PARTIAL_REG_STALL"
1462   "xchg{l}\t%k1, %k0"
1463   [(set_attr "type" "imov")
1464    (set_attr "pent_pair" "np")
1465    (set_attr "mode" "SI")
1466    (set_attr "modrm" "0")])
1468 (define_expand "movstricthi"
1469   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1470         (match_operand:HI 1 "general_operand" ""))]
1471   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1473   /* Don't generate memory->memory moves, go through a register */
1474   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1475     operands[1] = force_reg (HImode, operands[1]);
1478 (define_insn "*movstricthi_1"
1479   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1480         (match_operand:HI 1 "general_operand" "rn,m"))]
1481   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1482    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1483   "mov{w}\t{%1, %0|%0, %1}"
1484   [(set_attr "type" "imov")
1485    (set_attr "mode" "HI")])
1487 (define_insn "*movstricthi_xor"
1488   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1489         (match_operand:HI 1 "const0_operand" "i"))
1490    (clobber (reg:CC FLAGS_REG))]
1491   "reload_completed
1492    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1493   "xor{w}\t{%0, %0|%0, %0}"
1494   [(set_attr "type" "alu1")
1495    (set_attr "mode" "HI")
1496    (set_attr "length_immediate" "0")])
1498 (define_expand "movqi"
1499   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1500         (match_operand:QI 1 "general_operand" ""))]
1501   ""
1502   "ix86_expand_move (QImode, operands); DONE;")
1504 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1505 ;; "push a byte".  But actually we use pushw, which has the effect
1506 ;; of rounding the amount pushed up to a halfword.
1508 (define_insn "*pushqi2"
1509   [(set (match_operand:QI 0 "push_operand" "=X,X")
1510         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1511   "!TARGET_64BIT"
1512   "@
1513    push{w}\t{|word ptr }%1
1514    push{w}\t%w1"
1515   [(set_attr "type" "push")
1516    (set_attr "mode" "HI")])
1518 ;; For 64BIT abi we always round up to 8 bytes.
1519 (define_insn "*pushqi2_rex64"
1520   [(set (match_operand:QI 0 "push_operand" "=X")
1521         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1522   "TARGET_64BIT"
1523   "push{q}\t%q1"
1524   [(set_attr "type" "push")
1525    (set_attr "mode" "QI")])
1527 ;; Situation is quite tricky about when to choose full sized (SImode) move
1528 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1529 ;; partial register dependency machines (such as AMD Athlon), where QImode
1530 ;; moves issue extra dependency and for partial register stalls machines
1531 ;; that don't use QImode patterns (and QImode move cause stall on the next
1532 ;; instruction).
1534 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1535 ;; register stall machines with, where we use QImode instructions, since
1536 ;; partial register stall can be caused there.  Then we use movzx.
1537 (define_insn "*movqi_1"
1538   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1539         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1540   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1542   switch (get_attr_type (insn))
1543     {
1544     case TYPE_IMOVX:
1545       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1546         abort ();
1547       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1548     default:
1549       if (get_attr_mode (insn) == MODE_SI)
1550         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1551       else
1552         return "mov{b}\t{%1, %0|%0, %1}";
1553     }
1555   [(set (attr "type")
1556      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1557               (const_string "imov")
1558             (and (eq_attr "alternative" "3")
1559                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1560                           (const_int 0))
1561                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1562                           (const_int 0))))
1563               (const_string "imov")
1564             (eq_attr "alternative" "3,5")
1565               (const_string "imovx")
1566             (and (ne (symbol_ref "TARGET_MOVX")
1567                      (const_int 0))
1568                  (eq_attr "alternative" "2"))
1569               (const_string "imovx")
1570            ]
1571            (const_string "imov")))
1572    (set (attr "mode")
1573       (cond [(eq_attr "alternative" "3,4,5")
1574                (const_string "SI")
1575              (eq_attr "alternative" "6")
1576                (const_string "QI")
1577              (eq_attr "type" "imovx")
1578                (const_string "SI")
1579              (and (eq_attr "type" "imov")
1580                   (and (eq_attr "alternative" "0,1,2")
1581                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1582                            (const_int 0))))
1583                (const_string "SI")
1584              ;; Avoid partial register stalls when not using QImode arithmetic
1585              (and (eq_attr "type" "imov")
1586                   (and (eq_attr "alternative" "0,1,2")
1587                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1588                                 (const_int 0))
1589                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1590                                 (const_int 0)))))
1591                (const_string "SI")
1592            ]
1593            (const_string "QI")))])
1595 (define_expand "reload_outqi"
1596   [(parallel [(match_operand:QI 0 "" "=m")
1597               (match_operand:QI 1 "register_operand" "r")
1598               (match_operand:QI 2 "register_operand" "=&q")])]
1599   ""
1601   rtx op0, op1, op2;
1602   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1604   if (reg_overlap_mentioned_p (op2, op0))
1605     abort ();
1606   if (! q_regs_operand (op1, QImode))
1607     {
1608       emit_insn (gen_movqi (op2, op1));
1609       op1 = op2;
1610     }
1611   emit_insn (gen_movqi (op0, op1));
1612   DONE;
1615 (define_insn "*swapqi"
1616   [(set (match_operand:QI 0 "register_operand" "+r")
1617         (match_operand:QI 1 "register_operand" "+r"))
1618    (set (match_dup 1)
1619         (match_dup 0))]
1620   ""
1621   "xchg{b}\t%1, %0"
1622   [(set_attr "type" "imov")
1623    (set_attr "pent_pair" "np")
1624    (set_attr "mode" "QI")
1625    (set_attr "modrm" "0")])
1627 (define_expand "movstrictqi"
1628   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1629         (match_operand:QI 1 "general_operand" ""))]
1630   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1632   /* Don't generate memory->memory moves, go through a register.  */
1633   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1634     operands[1] = force_reg (QImode, operands[1]);
1637 (define_insn "*movstrictqi_1"
1638   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1639         (match_operand:QI 1 "general_operand" "*qn,m"))]
1640   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1641    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1642   "mov{b}\t{%1, %0|%0, %1}"
1643   [(set_attr "type" "imov")
1644    (set_attr "mode" "QI")])
1646 (define_insn "*movstrictqi_xor"
1647   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1648         (match_operand:QI 1 "const0_operand" "i"))
1649    (clobber (reg:CC FLAGS_REG))]
1650   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1651   "xor{b}\t{%0, %0|%0, %0}"
1652   [(set_attr "type" "alu1")
1653    (set_attr "mode" "QI")
1654    (set_attr "length_immediate" "0")])
1656 (define_insn "*movsi_extv_1"
1657   [(set (match_operand:SI 0 "register_operand" "=R")
1658         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1659                          (const_int 8)
1660                          (const_int 8)))]
1661   ""
1662   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1663   [(set_attr "type" "imovx")
1664    (set_attr "mode" "SI")])
1666 (define_insn "*movhi_extv_1"
1667   [(set (match_operand:HI 0 "register_operand" "=R")
1668         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1669                          (const_int 8)
1670                          (const_int 8)))]
1671   ""
1672   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1673   [(set_attr "type" "imovx")
1674    (set_attr "mode" "SI")])
1676 (define_insn "*movqi_extv_1"
1677   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1678         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1679                          (const_int 8)
1680                          (const_int 8)))]
1681   "!TARGET_64BIT"
1683   switch (get_attr_type (insn))
1684     {
1685     case TYPE_IMOVX:
1686       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1687     default:
1688       return "mov{b}\t{%h1, %0|%0, %h1}";
1689     }
1691   [(set (attr "type")
1692      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1693                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1694                              (ne (symbol_ref "TARGET_MOVX")
1695                                  (const_int 0))))
1696         (const_string "imovx")
1697         (const_string "imov")))
1698    (set (attr "mode")
1699      (if_then_else (eq_attr "type" "imovx")
1700         (const_string "SI")
1701         (const_string "QI")))])
1703 (define_insn "*movqi_extv_1_rex64"
1704   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1705         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1706                          (const_int 8)
1707                          (const_int 8)))]
1708   "TARGET_64BIT"
1710   switch (get_attr_type (insn))
1711     {
1712     case TYPE_IMOVX:
1713       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1714     default:
1715       return "mov{b}\t{%h1, %0|%0, %h1}";
1716     }
1718   [(set (attr "type")
1719      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1720                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1721                              (ne (symbol_ref "TARGET_MOVX")
1722                                  (const_int 0))))
1723         (const_string "imovx")
1724         (const_string "imov")))
1725    (set (attr "mode")
1726      (if_then_else (eq_attr "type" "imovx")
1727         (const_string "SI")
1728         (const_string "QI")))])
1730 ;; Stores and loads of ax to arbitrary constant address.
1731 ;; We fake an second form of instruction to force reload to load address
1732 ;; into register when rax is not available
1733 (define_insn "*movabsqi_1_rex64"
1734   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1735         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1736   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1737   "@
1738    movabs{b}\t{%1, %P0|%P0, %1}
1739    mov{b}\t{%1, %a0|%a0, %1}"
1740   [(set_attr "type" "imov")
1741    (set_attr "modrm" "0,*")
1742    (set_attr "length_address" "8,0")
1743    (set_attr "length_immediate" "0,*")
1744    (set_attr "memory" "store")
1745    (set_attr "mode" "QI")])
1747 (define_insn "*movabsqi_2_rex64"
1748   [(set (match_operand:QI 0 "register_operand" "=a,r")
1749         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1750   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1751   "@
1752    movabs{b}\t{%P1, %0|%0, %P1}
1753    mov{b}\t{%a1, %0|%0, %a1}"
1754   [(set_attr "type" "imov")
1755    (set_attr "modrm" "0,*")
1756    (set_attr "length_address" "8,0")
1757    (set_attr "length_immediate" "0")
1758    (set_attr "memory" "load")
1759    (set_attr "mode" "QI")])
1761 (define_insn "*movsi_extzv_1"
1762   [(set (match_operand:SI 0 "register_operand" "=R")
1763         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1764                          (const_int 8)
1765                          (const_int 8)))]
1766   ""
1767   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1768   [(set_attr "type" "imovx")
1769    (set_attr "mode" "SI")])
1771 (define_insn "*movqi_extzv_2"
1772   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1773         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1774                                     (const_int 8)
1775                                     (const_int 8)) 0))]
1776   "!TARGET_64BIT"
1778   switch (get_attr_type (insn))
1779     {
1780     case TYPE_IMOVX:
1781       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1782     default:
1783       return "mov{b}\t{%h1, %0|%0, %h1}";
1784     }
1786   [(set (attr "type")
1787      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1788                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789                              (ne (symbol_ref "TARGET_MOVX")
1790                                  (const_int 0))))
1791         (const_string "imovx")
1792         (const_string "imov")))
1793    (set (attr "mode")
1794      (if_then_else (eq_attr "type" "imovx")
1795         (const_string "SI")
1796         (const_string "QI")))])
1798 (define_insn "*movqi_extzv_2_rex64"
1799   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1800         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1801                                     (const_int 8)
1802                                     (const_int 8)) 0))]
1803   "TARGET_64BIT"
1805   switch (get_attr_type (insn))
1806     {
1807     case TYPE_IMOVX:
1808       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1809     default:
1810       return "mov{b}\t{%h1, %0|%0, %h1}";
1811     }
1813   [(set (attr "type")
1814      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1815                         (ne (symbol_ref "TARGET_MOVX")
1816                             (const_int 0)))
1817         (const_string "imovx")
1818         (const_string "imov")))
1819    (set (attr "mode")
1820      (if_then_else (eq_attr "type" "imovx")
1821         (const_string "SI")
1822         (const_string "QI")))])
1824 (define_insn "movsi_insv_1"
1825   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1826                          (const_int 8)
1827                          (const_int 8))
1828         (match_operand:SI 1 "general_operand" "Qmn"))]
1829   "!TARGET_64BIT"
1830   "mov{b}\t{%b1, %h0|%h0, %b1}"
1831   [(set_attr "type" "imov")
1832    (set_attr "mode" "QI")])
1834 (define_insn "movdi_insv_1_rex64"
1835   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1836                          (const_int 8)
1837                          (const_int 8))
1838         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1839   "TARGET_64BIT"
1840   "mov{b}\t{%b1, %h0|%h0, %b1}"
1841   [(set_attr "type" "imov")
1842    (set_attr "mode" "QI")])
1844 (define_insn "*movqi_insv_2"
1845   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1846                          (const_int 8)
1847                          (const_int 8))
1848         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1849                      (const_int 8)))]
1850   ""
1851   "mov{b}\t{%h1, %h0|%h0, %h1}"
1852   [(set_attr "type" "imov")
1853    (set_attr "mode" "QI")])
1855 (define_expand "movdi"
1856   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1857         (match_operand:DI 1 "general_operand" ""))]
1858   ""
1859   "ix86_expand_move (DImode, operands); DONE;")
1861 (define_insn "*pushdi"
1862   [(set (match_operand:DI 0 "push_operand" "=<")
1863         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1864   "!TARGET_64BIT"
1865   "#")
1867 (define_insn "pushdi2_rex64"
1868   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1869         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1870   "TARGET_64BIT"
1871   "@
1872    push{q}\t%1
1873    #"
1874   [(set_attr "type" "push,multi")
1875    (set_attr "mode" "DI")])
1877 ;; Convert impossible pushes of immediate to existing instructions.
1878 ;; First try to get scratch register and go through it.  In case this
1879 ;; fails, push sign extended lower part first and then overwrite
1880 ;; upper part by 32bit move.
1881 (define_peephole2
1882   [(match_scratch:DI 2 "r")
1883    (set (match_operand:DI 0 "push_operand" "")
1884         (match_operand:DI 1 "immediate_operand" ""))]
1885   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1886    && !x86_64_immediate_operand (operands[1], DImode)"
1887   [(set (match_dup 2) (match_dup 1))
1888    (set (match_dup 0) (match_dup 2))]
1889   "")
1891 ;; We need to define this as both peepholer and splitter for case
1892 ;; peephole2 pass is not run.
1893 (define_peephole2
1894   [(set (match_operand:DI 0 "push_operand" "")
1895         (match_operand:DI 1 "immediate_operand" ""))]
1896   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1897    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1898   [(set (match_dup 0) (match_dup 1))
1899    (set (match_dup 2) (match_dup 3))]
1900   "split_di (operands + 1, 1, operands + 2, operands + 3);
1901    operands[1] = gen_lowpart (DImode, operands[2]);
1902    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1903                                                     GEN_INT (4)));
1904   ")
1906 (define_split
1907   [(set (match_operand:DI 0 "push_operand" "")
1908         (match_operand:DI 1 "immediate_operand" ""))]
1909   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1910    && !symbolic_operand (operands[1], DImode)
1911    && !x86_64_immediate_operand (operands[1], DImode)"
1912   [(set (match_dup 0) (match_dup 1))
1913    (set (match_dup 2) (match_dup 3))]
1914   "split_di (operands + 1, 1, operands + 2, operands + 3);
1915    operands[1] = gen_lowpart (DImode, operands[2]);
1916    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1917                                                     GEN_INT (4)));
1918   ")
1920 (define_insn "*pushdi2_prologue_rex64"
1921   [(set (match_operand:DI 0 "push_operand" "=<")
1922         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1923    (clobber (mem:BLK (scratch)))]
1924   "TARGET_64BIT"
1925   "push{q}\t%1"
1926   [(set_attr "type" "push")
1927    (set_attr "mode" "DI")])
1929 (define_insn "*popdi1_epilogue_rex64"
1930   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1931         (mem:DI (reg:DI SP_REG)))
1932    (set (reg:DI SP_REG)
1933         (plus:DI (reg:DI SP_REG) (const_int 8)))
1934    (clobber (mem:BLK (scratch)))]
1935   "TARGET_64BIT"
1936   "pop{q}\t%0"
1937   [(set_attr "type" "pop")
1938    (set_attr "mode" "DI")])
1940 (define_insn "popdi1"
1941   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1942         (mem:DI (reg:DI SP_REG)))
1943    (set (reg:DI SP_REG)
1944         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1945   "TARGET_64BIT"
1946   "pop{q}\t%0"
1947   [(set_attr "type" "pop")
1948    (set_attr "mode" "DI")])
1950 (define_insn "*movdi_xor_rex64"
1951   [(set (match_operand:DI 0 "register_operand" "=r")
1952         (match_operand:DI 1 "const0_operand" "i"))
1953    (clobber (reg:CC FLAGS_REG))]
1954   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1955    && reload_completed"
1956   "xor{l}\t{%k0, %k0|%k0, %k0}"
1957   [(set_attr "type" "alu1")
1958    (set_attr "mode" "SI")
1959    (set_attr "length_immediate" "0")])
1961 (define_insn "*movdi_or_rex64"
1962   [(set (match_operand:DI 0 "register_operand" "=r")
1963         (match_operand:DI 1 "const_int_operand" "i"))
1964    (clobber (reg:CC FLAGS_REG))]
1965   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1966    && reload_completed
1967    && operands[1] == constm1_rtx"
1969   operands[1] = constm1_rtx;
1970   return "or{q}\t{%1, %0|%0, %1}";
1972   [(set_attr "type" "alu1")
1973    (set_attr "mode" "DI")
1974    (set_attr "length_immediate" "1")])
1976 (define_insn "*movdi_2"
1977   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1978         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1979   "!TARGET_64BIT
1980    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1981   "@
1982    #
1983    #
1984    movq\t{%1, %0|%0, %1}
1985    movq\t{%1, %0|%0, %1}
1986    movq\t{%1, %0|%0, %1}
1987    movdqa\t{%1, %0|%0, %1}
1988    movq\t{%1, %0|%0, %1}"
1989   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1990    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1992 (define_split
1993   [(set (match_operand:DI 0 "push_operand" "")
1994         (match_operand:DI 1 "general_operand" ""))]
1995   "!TARGET_64BIT && reload_completed
1996    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1997   [(const_int 0)]
1998   "ix86_split_long_move (operands); DONE;")
2000 ;; %%% This multiword shite has got to go.
2001 (define_split
2002   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2003         (match_operand:DI 1 "general_operand" ""))]
2004   "!TARGET_64BIT && reload_completed
2005    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2006    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2007   [(const_int 0)]
2008   "ix86_split_long_move (operands); DONE;")
2010 (define_insn "*movdi_1_rex64"
2011   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
2012         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
2013   "TARGET_64BIT
2014    && (TARGET_INTER_UNIT_MOVES || optimize_size)
2015    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2017   switch (get_attr_type (insn))
2018     {
2019     case TYPE_SSECVT:
2020       if (which_alternative == 11)
2021         return "movq2dq\t{%1, %0|%0, %1}";
2022       else
2023         return "movdq2q\t{%1, %0|%0, %1}";
2024     case TYPE_SSEMOV:
2025       if (get_attr_mode (insn) == MODE_TI)
2026           return "movdqa\t{%1, %0|%0, %1}";
2027       /* FALLTHRU */
2028     case TYPE_MMXMOV:
2029       /* Moves from and into integer register is done using movd opcode with
2030          REX prefix.  */
2031       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2032           return "movd\t{%1, %0|%0, %1}";
2033       return "movq\t{%1, %0|%0, %1}";
2034     case TYPE_MULTI:
2035       return "#";
2036     case TYPE_LEA:
2037       return "lea{q}\t{%a1, %0|%0, %a1}";
2038     default:
2039       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2040         abort ();
2041       if (get_attr_mode (insn) == MODE_SI)
2042         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2043       else if (which_alternative == 2)
2044         return "movabs{q}\t{%1, %0|%0, %1}";
2045       else
2046         return "mov{q}\t{%1, %0|%0, %1}";
2047     }
2049   [(set (attr "type")
2050      (cond [(eq_attr "alternative" "5,6,7")
2051               (const_string "mmxmov")
2052             (eq_attr "alternative" "8,9,10")
2053               (const_string "ssemov")
2054             (eq_attr "alternative" "11,12")
2055               (const_string "ssecvt")
2056             (eq_attr "alternative" "4")
2057               (const_string "multi")
2058             (and (ne (symbol_ref "flag_pic") (const_int 0))
2059                  (match_operand:DI 1 "symbolic_operand" ""))
2060               (const_string "lea")
2061            ]
2062            (const_string "imov")))
2063    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
2064    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2065    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
2067 (define_insn "*movdi_1_rex64_nointerunit"
2068   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2069         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2070   "TARGET_64BIT
2071    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2072    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2074   switch (get_attr_type (insn))
2075     {
2076     case TYPE_SSEMOV:
2077       if (get_attr_mode (insn) == MODE_TI)
2078           return "movdqa\t{%1, %0|%0, %1}";
2079       /* FALLTHRU */
2080     case TYPE_MMXMOV:
2081       return "movq\t{%1, %0|%0, %1}";
2082     case TYPE_MULTI:
2083       return "#";
2084     case TYPE_LEA:
2085       return "lea{q}\t{%a1, %0|%0, %a1}";
2086     default:
2087       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2088         abort ();
2089       if (get_attr_mode (insn) == MODE_SI)
2090         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2091       else if (which_alternative == 2)
2092         return "movabs{q}\t{%1, %0|%0, %1}";
2093       else
2094         return "mov{q}\t{%1, %0|%0, %1}";
2095     }
2097   [(set (attr "type")
2098      (cond [(eq_attr "alternative" "5,6,7")
2099               (const_string "mmxmov")
2100             (eq_attr "alternative" "8,9,10")
2101               (const_string "ssemov")
2102             (eq_attr "alternative" "4")
2103               (const_string "multi")
2104             (and (ne (symbol_ref "flag_pic") (const_int 0))
2105                  (match_operand:DI 1 "symbolic_operand" ""))
2106               (const_string "lea")
2107            ]
2108            (const_string "imov")))
2109    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2110    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2111    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2113 ;; Stores and loads of ax to arbitrary constant address.
2114 ;; We fake an second form of instruction to force reload to load address
2115 ;; into register when rax is not available
2116 (define_insn "*movabsdi_1_rex64"
2117   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2118         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2119   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2120   "@
2121    movabs{q}\t{%1, %P0|%P0, %1}
2122    mov{q}\t{%1, %a0|%a0, %1}"
2123   [(set_attr "type" "imov")
2124    (set_attr "modrm" "0,*")
2125    (set_attr "length_address" "8,0")
2126    (set_attr "length_immediate" "0,*")
2127    (set_attr "memory" "store")
2128    (set_attr "mode" "DI")])
2130 (define_insn "*movabsdi_2_rex64"
2131   [(set (match_operand:DI 0 "register_operand" "=a,r")
2132         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2133   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2134   "@
2135    movabs{q}\t{%P1, %0|%0, %P1}
2136    mov{q}\t{%a1, %0|%0, %a1}"
2137   [(set_attr "type" "imov")
2138    (set_attr "modrm" "0,*")
2139    (set_attr "length_address" "8,0")
2140    (set_attr "length_immediate" "0")
2141    (set_attr "memory" "load")
2142    (set_attr "mode" "DI")])
2144 ;; Convert impossible stores of immediate to existing instructions.
2145 ;; First try to get scratch register and go through it.  In case this
2146 ;; fails, move by 32bit parts.
2147 (define_peephole2
2148   [(match_scratch:DI 2 "r")
2149    (set (match_operand:DI 0 "memory_operand" "")
2150         (match_operand:DI 1 "immediate_operand" ""))]
2151   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2152    && !x86_64_immediate_operand (operands[1], DImode)"
2153   [(set (match_dup 2) (match_dup 1))
2154    (set (match_dup 0) (match_dup 2))]
2155   "")
2157 ;; We need to define this as both peepholer and splitter for case
2158 ;; peephole2 pass is not run.
2159 (define_peephole2
2160   [(set (match_operand:DI 0 "memory_operand" "")
2161         (match_operand:DI 1 "immediate_operand" ""))]
2162   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2163    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2164   [(set (match_dup 2) (match_dup 3))
2165    (set (match_dup 4) (match_dup 5))]
2166   "split_di (operands, 2, operands + 2, operands + 4);")
2168 (define_split
2169   [(set (match_operand:DI 0 "memory_operand" "")
2170         (match_operand:DI 1 "immediate_operand" ""))]
2171   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2172    && !symbolic_operand (operands[1], DImode)
2173    && !x86_64_immediate_operand (operands[1], DImode)"
2174   [(set (match_dup 2) (match_dup 3))
2175    (set (match_dup 4) (match_dup 5))]
2176   "split_di (operands, 2, operands + 2, operands + 4);")
2178 (define_insn "*swapdi_rex64"
2179   [(set (match_operand:DI 0 "register_operand" "+r")
2180         (match_operand:DI 1 "register_operand" "+r"))
2181    (set (match_dup 1)
2182         (match_dup 0))]
2183   "TARGET_64BIT"
2184   "xchg{q}\t%1, %0"
2185   [(set_attr "type" "imov")
2186    (set_attr "pent_pair" "np")
2187    (set_attr "athlon_decode" "vector")
2188    (set_attr "mode" "DI")
2189    (set_attr "modrm" "0")])
2191   
2192 (define_expand "movsf"
2193   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2194         (match_operand:SF 1 "general_operand" ""))]
2195   ""
2196   "ix86_expand_move (SFmode, operands); DONE;")
2198 (define_insn "*pushsf"
2199   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2200         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2201   "!TARGET_64BIT"
2203   switch (which_alternative)
2204     {
2205     case 1:
2206       return "push{l}\t%1";
2208     default:
2209       /* This insn should be already split before reg-stack.  */
2210       abort ();
2211     }
2213   [(set_attr "type" "multi,push,multi")
2214    (set_attr "mode" "SF,SI,SF")])
2216 (define_insn "*pushsf_rex64"
2217   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2218         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2219   "TARGET_64BIT"
2221   switch (which_alternative)
2222     {
2223     case 1:
2224       return "push{q}\t%q1";
2226     default:
2227       /* This insn should be already split before reg-stack.  */
2228       abort ();
2229     }
2231   [(set_attr "type" "multi,push,multi")
2232    (set_attr "mode" "SF,DI,SF")])
2234 (define_split
2235   [(set (match_operand:SF 0 "push_operand" "")
2236         (match_operand:SF 1 "memory_operand" ""))]
2237   "reload_completed
2238    && GET_CODE (operands[1]) == MEM
2239    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2240    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2241   [(set (match_dup 0)
2242         (match_dup 1))]
2243   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2246 ;; %%% Kill this when call knows how to work this out.
2247 (define_split
2248   [(set (match_operand:SF 0 "push_operand" "")
2249         (match_operand:SF 1 "any_fp_register_operand" ""))]
2250   "!TARGET_64BIT"
2251   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2252    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2254 (define_split
2255   [(set (match_operand:SF 0 "push_operand" "")
2256         (match_operand:SF 1 "any_fp_register_operand" ""))]
2257   "TARGET_64BIT"
2258   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2259    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2261 (define_insn "*movsf_1"
2262   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2263         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2264   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2265    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2266    && (reload_in_progress || reload_completed
2267        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2268        || GET_CODE (operands[1]) != CONST_DOUBLE
2269        || memory_operand (operands[0], SFmode))" 
2271   switch (which_alternative)
2272     {
2273     case 0:
2274       return output_387_reg_move (insn, operands);
2276     case 1:
2277       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2278         return "fstp%z0\t%y0";
2279       else
2280         return "fst%z0\t%y0";
2282     case 2:
2283       return standard_80387_constant_opcode (operands[1]);
2285     case 3:
2286     case 4:
2287       return "mov{l}\t{%1, %0|%0, %1}";
2288     case 5:
2289       if (get_attr_mode (insn) == MODE_TI)
2290         return "pxor\t%0, %0";
2291       else
2292         return "xorps\t%0, %0";
2293     case 6:
2294       if (get_attr_mode (insn) == MODE_V4SF)
2295         return "movaps\t{%1, %0|%0, %1}";
2296       else
2297         return "movss\t{%1, %0|%0, %1}";
2298     case 7:
2299     case 8:
2300       return "movss\t{%1, %0|%0, %1}";
2302     case 9:
2303     case 10:
2304       return "movd\t{%1, %0|%0, %1}";
2306     case 11:
2307       return "movq\t{%1, %0|%0, %1}";
2309     default:
2310       abort();
2311     }
2313   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2314    (set (attr "mode")
2315         (cond [(eq_attr "alternative" "3,4,9,10")
2316                  (const_string "SI")
2317                (eq_attr "alternative" "5")
2318                  (if_then_else
2319                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2320                                  (const_int 0))
2321                              (ne (symbol_ref "TARGET_SSE2")
2322                                  (const_int 0)))
2323                         (eq (symbol_ref "optimize_size")
2324                             (const_int 0)))
2325                    (const_string "TI")
2326                    (const_string "V4SF"))
2327                /* For architectures resolving dependencies on
2328                   whole SSE registers use APS move to break dependency
2329                   chains, otherwise use short move to avoid extra work. 
2331                   Do the same for architectures resolving dependencies on
2332                   the parts.  While in DF mode it is better to always handle
2333                   just register parts, the SF mode is different due to lack
2334                   of instructions to load just part of the register.  It is
2335                   better to maintain the whole registers in single format
2336                   to avoid problems on using packed logical operations.  */
2337                (eq_attr "alternative" "6")
2338                  (if_then_else
2339                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2340                             (const_int 0))
2341                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2342                             (const_int 0)))
2343                    (const_string "V4SF")
2344                    (const_string "SF"))
2345                (eq_attr "alternative" "11")
2346                  (const_string "DI")]
2347                (const_string "SF")))])
2349 (define_insn "*movsf_1_nointerunit"
2350   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2351         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2352   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2353    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2354    && (reload_in_progress || reload_completed
2355        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2356        || GET_CODE (operands[1]) != CONST_DOUBLE
2357        || memory_operand (operands[0], SFmode))" 
2359   switch (which_alternative)
2360     {
2361     case 0:
2362       return output_387_reg_move (insn, operands);
2364     case 1:
2365       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2366         return "fstp%z0\t%y0";
2367       else
2368         return "fst%z0\t%y0";
2370     case 2:
2371       return standard_80387_constant_opcode (operands[1]);
2373     case 3:
2374     case 4:
2375       return "mov{l}\t{%1, %0|%0, %1}";
2376     case 5:
2377       if (get_attr_mode (insn) == MODE_TI)
2378         return "pxor\t%0, %0";
2379       else
2380         return "xorps\t%0, %0";
2381     case 6:
2382       if (get_attr_mode (insn) == MODE_V4SF)
2383         return "movaps\t{%1, %0|%0, %1}";
2384       else
2385         return "movss\t{%1, %0|%0, %1}";
2386     case 7:
2387     case 8:
2388       return "movss\t{%1, %0|%0, %1}";
2390     case 9:
2391     case 10:
2392       return "movd\t{%1, %0|%0, %1}";
2394     case 11:
2395       return "movq\t{%1, %0|%0, %1}";
2397     default:
2398       abort();
2399     }
2401   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2402    (set (attr "mode")
2403         (cond [(eq_attr "alternative" "3,4,9,10")
2404                  (const_string "SI")
2405                (eq_attr "alternative" "5")
2406                  (if_then_else
2407                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2408                                  (const_int 0))
2409                              (ne (symbol_ref "TARGET_SSE2")
2410                                  (const_int 0)))
2411                         (eq (symbol_ref "optimize_size")
2412                             (const_int 0)))
2413                    (const_string "TI")
2414                    (const_string "V4SF"))
2415                /* For architectures resolving dependencies on
2416                   whole SSE registers use APS move to break dependency
2417                   chains, otherwise use short move to avoid extra work. 
2419                   Do the same for architectures resolving dependencies on
2420                   the parts.  While in DF mode it is better to always handle
2421                   just register parts, the SF mode is different due to lack
2422                   of instructions to load just part of the register.  It is
2423                   better to maintain the whole registers in single format
2424                   to avoid problems on using packed logical operations.  */
2425                (eq_attr "alternative" "6")
2426                  (if_then_else
2427                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2428                             (const_int 0))
2429                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2430                             (const_int 0)))
2431                    (const_string "V4SF")
2432                    (const_string "SF"))
2433                (eq_attr "alternative" "11")
2434                  (const_string "DI")]
2435                (const_string "SF")))])
2437 (define_insn "*swapsf"
2438   [(set (match_operand:SF 0 "register_operand" "+f")
2439         (match_operand:SF 1 "register_operand" "+f"))
2440    (set (match_dup 1)
2441         (match_dup 0))]
2442   "reload_completed || !TARGET_SSE"
2444   if (STACK_TOP_P (operands[0]))
2445     return "fxch\t%1";
2446   else
2447     return "fxch\t%0";
2449   [(set_attr "type" "fxch")
2450    (set_attr "mode" "SF")])
2452 (define_expand "movdf"
2453   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2454         (match_operand:DF 1 "general_operand" ""))]
2455   ""
2456   "ix86_expand_move (DFmode, operands); DONE;")
2458 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2459 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2460 ;; On the average, pushdf using integers can be still shorter.  Allow this
2461 ;; pattern for optimize_size too.
2463 (define_insn "*pushdf_nointeger"
2464   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2465         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2466   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2468   /* This insn should be already split before reg-stack.  */
2469   abort ();
2471   [(set_attr "type" "multi")
2472    (set_attr "mode" "DF,SI,SI,DF")])
2474 (define_insn "*pushdf_integer"
2475   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2476         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2477   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2479   /* This insn should be already split before reg-stack.  */
2480   abort ();
2482   [(set_attr "type" "multi")
2483    (set_attr "mode" "DF,SI,DF")])
2485 ;; %%% Kill this when call knows how to work this out.
2486 (define_split
2487   [(set (match_operand:DF 0 "push_operand" "")
2488         (match_operand:DF 1 "any_fp_register_operand" ""))]
2489   "!TARGET_64BIT && reload_completed"
2490   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2491    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2492   "")
2494 (define_split
2495   [(set (match_operand:DF 0 "push_operand" "")
2496         (match_operand:DF 1 "any_fp_register_operand" ""))]
2497   "TARGET_64BIT && reload_completed"
2498   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2499    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2500   "")
2502 (define_split
2503   [(set (match_operand:DF 0 "push_operand" "")
2504         (match_operand:DF 1 "general_operand" ""))]
2505   "reload_completed"
2506   [(const_int 0)]
2507   "ix86_split_long_move (operands); DONE;")
2509 ;; Moving is usually shorter when only FP registers are used. This separate
2510 ;; movdf pattern avoids the use of integer registers for FP operations
2511 ;; when optimizing for size.
2513 (define_insn "*movdf_nointeger"
2514   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2515         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2516   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2517    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2518    && (reload_in_progress || reload_completed
2519        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2520        || GET_CODE (operands[1]) != CONST_DOUBLE
2521        || memory_operand (operands[0], DFmode))" 
2523   switch (which_alternative)
2524     {
2525     case 0:
2526       return output_387_reg_move (insn, operands);
2528     case 1:
2529       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2530         return "fstp%z0\t%y0";
2531       else
2532         return "fst%z0\t%y0";
2534     case 2:
2535       return standard_80387_constant_opcode (operands[1]);
2537     case 3:
2538     case 4:
2539       return "#";
2540     case 5:
2541       switch (get_attr_mode (insn))
2542         {
2543         case MODE_V4SF:
2544           return "xorps\t%0, %0";
2545         case MODE_V2DF:
2546           return "xorpd\t%0, %0";
2547         case MODE_TI:
2548           return "pxor\t%0, %0";
2549         default:
2550           abort ();
2551         }
2552     case 6:
2553       switch (get_attr_mode (insn))
2554         {
2555         case MODE_V4SF:
2556           return "movaps\t{%1, %0|%0, %1}";
2557         case MODE_V2DF:
2558           return "movapd\t{%1, %0|%0, %1}";
2559         case MODE_DF:
2560           return "movsd\t{%1, %0|%0, %1}";
2561         default:
2562           abort ();
2563         }
2564     case 7:
2565       if (get_attr_mode (insn) == MODE_V2DF)
2566         return "movlpd\t{%1, %0|%0, %1}";
2567       else
2568         return "movsd\t{%1, %0|%0, %1}";
2569     case 8:
2570       return "movsd\t{%1, %0|%0, %1}";
2572     default:
2573       abort();
2574     }
2576   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2577    (set (attr "mode")
2578         (cond [(eq_attr "alternative" "3,4")
2579                  (const_string "SI")
2580                /* xorps is one byte shorter.  */
2581                (eq_attr "alternative" "5")
2582                  (cond [(ne (symbol_ref "optimize_size")
2583                             (const_int 0))
2584                           (const_string "V4SF")
2585                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2586                             (const_int 0))
2587                           (const_string "TI")]
2588                        (const_string "V2DF"))
2589                /* For architectures resolving dependencies on
2590                   whole SSE registers use APD move to break dependency
2591                   chains, otherwise use short move to avoid extra work.
2593                   movaps encodes one byte shorter.  */
2594                (eq_attr "alternative" "6")
2595                  (cond
2596                   [(ne (symbol_ref "optimize_size")
2597                        (const_int 0))
2598                      (const_string "V4SF")
2599                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2600                        (const_int 0))
2601                      (const_string "V2DF")]
2602                    (const_string "DF"))
2603                /* For architectures resolving dependencies on register
2604                   parts we may avoid extra work to zero out upper part
2605                   of register.  */
2606                (eq_attr "alternative" "7")
2607                  (if_then_else
2608                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2609                        (const_int 0))
2610                    (const_string "V2DF")
2611                    (const_string "DF"))]
2612                (const_string "DF")))])
2614 (define_insn "*movdf_integer"
2615   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2616         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2618    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2619    && (reload_in_progress || reload_completed
2620        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2621        || GET_CODE (operands[1]) != CONST_DOUBLE
2622        || memory_operand (operands[0], DFmode))" 
2624   switch (which_alternative)
2625     {
2626     case 0:
2627       return output_387_reg_move (insn, operands);
2629     case 1:
2630       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2631         return "fstp%z0\t%y0";
2632       else
2633         return "fst%z0\t%y0";
2635     case 2:
2636       return standard_80387_constant_opcode (operands[1]);
2638     case 3:
2639     case 4:
2640       return "#";
2642     case 5:
2643       switch (get_attr_mode (insn))
2644         {
2645         case MODE_V4SF:
2646           return "xorps\t%0, %0";
2647         case MODE_V2DF:
2648           return "xorpd\t%0, %0";
2649         case MODE_TI:
2650           return "pxor\t%0, %0";
2651         default:
2652           abort ();
2653         }
2654     case 6:
2655       switch (get_attr_mode (insn))
2656         {
2657         case MODE_V4SF:
2658           return "movaps\t{%1, %0|%0, %1}";
2659         case MODE_V2DF:
2660           return "movapd\t{%1, %0|%0, %1}";
2661         case MODE_DF:
2662           return "movsd\t{%1, %0|%0, %1}";
2663         default:
2664           abort ();
2665         }
2666     case 7:
2667       if (get_attr_mode (insn) == MODE_V2DF)
2668         return "movlpd\t{%1, %0|%0, %1}";
2669       else
2670         return "movsd\t{%1, %0|%0, %1}";
2671     case 8:
2672       return "movsd\t{%1, %0|%0, %1}";
2674     default:
2675       abort();
2676     }
2678   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2679    (set (attr "mode")
2680         (cond [(eq_attr "alternative" "3,4")
2681                  (const_string "SI")
2682                /* xorps is one byte shorter.  */
2683                (eq_attr "alternative" "5")
2684                  (cond [(ne (symbol_ref "optimize_size")
2685                             (const_int 0))
2686                           (const_string "V4SF")
2687                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2688                             (const_int 0))
2689                           (const_string "TI")]
2690                        (const_string "V2DF"))
2691                /* For architectures resolving dependencies on
2692                   whole SSE registers use APD move to break dependency
2693                   chains, otherwise use short move to avoid extra work.  
2695                   movaps encodes one byte shorter.  */
2696                (eq_attr "alternative" "6")
2697                  (cond
2698                   [(ne (symbol_ref "optimize_size")
2699                        (const_int 0))
2700                      (const_string "V4SF")
2701                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2702                        (const_int 0))
2703                      (const_string "V2DF")]
2704                    (const_string "DF"))
2705                /* For architectures resolving dependencies on register
2706                   parts we may avoid extra work to zero out upper part
2707                   of register.  */
2708                (eq_attr "alternative" "7")
2709                  (if_then_else
2710                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2711                        (const_int 0))
2712                    (const_string "V2DF")
2713                    (const_string "DF"))]
2714                (const_string "DF")))])
2716 (define_split
2717   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2718         (match_operand:DF 1 "general_operand" ""))]
2719   "reload_completed
2720    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2721    && ! (ANY_FP_REG_P (operands[0]) || 
2722          (GET_CODE (operands[0]) == SUBREG
2723           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2724    && ! (ANY_FP_REG_P (operands[1]) || 
2725          (GET_CODE (operands[1]) == SUBREG
2726           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2727   [(const_int 0)]
2728   "ix86_split_long_move (operands); DONE;")
2730 (define_insn "*swapdf"
2731   [(set (match_operand:DF 0 "register_operand" "+f")
2732         (match_operand:DF 1 "register_operand" "+f"))
2733    (set (match_dup 1)
2734         (match_dup 0))]
2735   "reload_completed || !TARGET_SSE2"
2737   if (STACK_TOP_P (operands[0]))
2738     return "fxch\t%1";
2739   else
2740     return "fxch\t%0";
2742   [(set_attr "type" "fxch")
2743    (set_attr "mode" "DF")])
2745 (define_expand "movxf"
2746   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2747         (match_operand:XF 1 "general_operand" ""))]
2748   ""
2749   "ix86_expand_move (XFmode, operands); DONE;")
2751 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2752 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2753 ;; Pushing using integer instructions is longer except for constants
2754 ;; and direct memory references.
2755 ;; (assuming that any given constant is pushed only once, but this ought to be
2756 ;;  handled elsewhere).
2758 (define_insn "*pushxf_nointeger"
2759   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2760         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2761   "optimize_size"
2763   /* This insn should be already split before reg-stack.  */
2764   abort ();
2766   [(set_attr "type" "multi")
2767    (set_attr "mode" "XF,SI,SI")])
2769 (define_insn "*pushxf_integer"
2770   [(set (match_operand:XF 0 "push_operand" "=<,<")
2771         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2772   "!optimize_size"
2774   /* This insn should be already split before reg-stack.  */
2775   abort ();
2777   [(set_attr "type" "multi")
2778    (set_attr "mode" "XF,SI")])
2780 (define_split
2781   [(set (match_operand 0 "push_operand" "")
2782         (match_operand 1 "general_operand" ""))]
2783   "reload_completed
2784    && (GET_MODE (operands[0]) == XFmode
2785        || GET_MODE (operands[0]) == DFmode)
2786    && !ANY_FP_REG_P (operands[1])"
2787   [(const_int 0)]
2788   "ix86_split_long_move (operands); DONE;")
2790 (define_split
2791   [(set (match_operand:XF 0 "push_operand" "")
2792         (match_operand:XF 1 "any_fp_register_operand" ""))]
2793   "!TARGET_64BIT"
2794   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2795    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2796   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2798 (define_split
2799   [(set (match_operand:XF 0 "push_operand" "")
2800         (match_operand:XF 1 "any_fp_register_operand" ""))]
2801   "TARGET_64BIT"
2802   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2803    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2804   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2806 ;; Do not use integer registers when optimizing for size
2807 (define_insn "*movxf_nointeger"
2808   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2809         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2810   "optimize_size
2811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2812    && (reload_in_progress || reload_completed
2813        || GET_CODE (operands[1]) != CONST_DOUBLE
2814        || memory_operand (operands[0], XFmode))" 
2816   switch (which_alternative)
2817     {
2818     case 0:
2819       return output_387_reg_move (insn, operands);
2821     case 1:
2822       /* There is no non-popping store to memory for XFmode.  So if
2823          we need one, follow the store with a load.  */
2824       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2825         return "fstp%z0\t%y0\;fld%z0\t%y0";
2826       else
2827         return "fstp%z0\t%y0";
2829     case 2:
2830       return standard_80387_constant_opcode (operands[1]);
2832     case 3: case 4:
2833       return "#";
2834     }
2835   abort();
2837   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2838    (set_attr "mode" "XF,XF,XF,SI,SI")])
2840 (define_insn "*movxf_integer"
2841   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2842         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2843   "!optimize_size
2844    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2845    && (reload_in_progress || reload_completed
2846        || GET_CODE (operands[1]) != CONST_DOUBLE
2847        || memory_operand (operands[0], XFmode))" 
2849   switch (which_alternative)
2850     {
2851     case 0:
2852       return output_387_reg_move (insn, operands);
2854     case 1:
2855       /* There is no non-popping store to memory for XFmode.  So if
2856          we need one, follow the store with a load.  */
2857       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2858         return "fstp%z0\t%y0\;fld%z0\t%y0";
2859       else
2860         return "fstp%z0\t%y0";
2862     case 2:
2863       return standard_80387_constant_opcode (operands[1]);
2865     case 3: case 4:
2866       return "#";
2867     }
2868   abort();
2870   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2871    (set_attr "mode" "XF,XF,XF,SI,SI")])
2873 (define_split
2874   [(set (match_operand 0 "nonimmediate_operand" "")
2875         (match_operand 1 "general_operand" ""))]
2876   "reload_completed
2877    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2878    && GET_MODE (operands[0]) == XFmode
2879    && ! (ANY_FP_REG_P (operands[0]) || 
2880          (GET_CODE (operands[0]) == SUBREG
2881           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2882    && ! (ANY_FP_REG_P (operands[1]) || 
2883          (GET_CODE (operands[1]) == SUBREG
2884           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2885   [(const_int 0)]
2886   "ix86_split_long_move (operands); DONE;")
2888 (define_split
2889   [(set (match_operand 0 "register_operand" "")
2890         (match_operand 1 "memory_operand" ""))]
2891   "reload_completed
2892    && GET_CODE (operands[1]) == MEM
2893    && (GET_MODE (operands[0]) == XFmode
2894        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2895    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2896    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2897   [(set (match_dup 0) (match_dup 1))]
2899   rtx c = get_pool_constant (XEXP (operands[1], 0));
2900   rtx r = operands[0];
2902   if (GET_CODE (r) == SUBREG)
2903     r = SUBREG_REG (r);
2905   if (SSE_REG_P (r))
2906     {
2907       if (!standard_sse_constant_p (c))
2908         FAIL;
2909     }
2910   else if (FP_REG_P (r))
2911     {
2912       if (!standard_80387_constant_p (c))
2913         FAIL;
2914     }
2915   else if (MMX_REG_P (r))
2916     FAIL;
2918   operands[1] = c;
2921 (define_insn "swapxf"
2922   [(set (match_operand:XF 0 "register_operand" "+f")
2923         (match_operand:XF 1 "register_operand" "+f"))
2924    (set (match_dup 1)
2925         (match_dup 0))]
2926   ""
2928   if (STACK_TOP_P (operands[0]))
2929     return "fxch\t%1";
2930   else
2931     return "fxch\t%0";
2933   [(set_attr "type" "fxch")
2934    (set_attr "mode" "XF")])
2936 ;; Zero extension instructions
2938 (define_expand "zero_extendhisi2"
2939   [(set (match_operand:SI 0 "register_operand" "")
2940      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2941   ""
2943   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2944     {
2945       operands[1] = force_reg (HImode, operands[1]);
2946       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2947       DONE;
2948     }
2951 (define_insn "zero_extendhisi2_and"
2952   [(set (match_operand:SI 0 "register_operand" "=r")
2953      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2954    (clobber (reg:CC FLAGS_REG))]
2955   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2956   "#"
2957   [(set_attr "type" "alu1")
2958    (set_attr "mode" "SI")])
2960 (define_split
2961   [(set (match_operand:SI 0 "register_operand" "")
2962         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2963    (clobber (reg:CC FLAGS_REG))]
2964   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2965   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2966               (clobber (reg:CC FLAGS_REG))])]
2967   "")
2969 (define_insn "*zero_extendhisi2_movzwl"
2970   [(set (match_operand:SI 0 "register_operand" "=r")
2971      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2972   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2973   "movz{wl|x}\t{%1, %0|%0, %1}"
2974   [(set_attr "type" "imovx")
2975    (set_attr "mode" "SI")])
2977 (define_expand "zero_extendqihi2"
2978   [(parallel
2979     [(set (match_operand:HI 0 "register_operand" "")
2980        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2981      (clobber (reg:CC FLAGS_REG))])]
2982   ""
2983   "")
2985 (define_insn "*zero_extendqihi2_and"
2986   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2987      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2988    (clobber (reg:CC FLAGS_REG))]
2989   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2990   "#"
2991   [(set_attr "type" "alu1")
2992    (set_attr "mode" "HI")])
2994 (define_insn "*zero_extendqihi2_movzbw_and"
2995   [(set (match_operand:HI 0 "register_operand" "=r,r")
2996      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2997    (clobber (reg:CC FLAGS_REG))]
2998   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2999   "#"
3000   [(set_attr "type" "imovx,alu1")
3001    (set_attr "mode" "HI")])
3003 (define_insn "*zero_extendqihi2_movzbw"
3004   [(set (match_operand:HI 0 "register_operand" "=r")
3005      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3006   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3007   "movz{bw|x}\t{%1, %0|%0, %1}"
3008   [(set_attr "type" "imovx")
3009    (set_attr "mode" "HI")])
3011 ;; For the movzbw case strip only the clobber
3012 (define_split
3013   [(set (match_operand:HI 0 "register_operand" "")
3014         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3015    (clobber (reg:CC FLAGS_REG))]
3016   "reload_completed 
3017    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3018    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3019   [(set (match_operand:HI 0 "register_operand" "")
3020         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3022 ;; When source and destination does not overlap, clear destination
3023 ;; first and then do the movb
3024 (define_split
3025   [(set (match_operand:HI 0 "register_operand" "")
3026         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3027    (clobber (reg:CC FLAGS_REG))]
3028   "reload_completed
3029    && ANY_QI_REG_P (operands[0])
3030    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3031    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3032   [(set (match_dup 0) (const_int 0))
3033    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3034   "operands[2] = gen_lowpart (QImode, operands[0]);")
3036 ;; Rest is handled by single and.
3037 (define_split
3038   [(set (match_operand:HI 0 "register_operand" "")
3039         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3040    (clobber (reg:CC FLAGS_REG))]
3041   "reload_completed
3042    && true_regnum (operands[0]) == true_regnum (operands[1])"
3043   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3044               (clobber (reg:CC FLAGS_REG))])]
3045   "")
3047 (define_expand "zero_extendqisi2"
3048   [(parallel
3049     [(set (match_operand:SI 0 "register_operand" "")
3050        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3051      (clobber (reg:CC FLAGS_REG))])]
3052   ""
3053   "")
3055 (define_insn "*zero_extendqisi2_and"
3056   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3057      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3058    (clobber (reg:CC FLAGS_REG))]
3059   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3060   "#"
3061   [(set_attr "type" "alu1")
3062    (set_attr "mode" "SI")])
3064 (define_insn "*zero_extendqisi2_movzbw_and"
3065   [(set (match_operand:SI 0 "register_operand" "=r,r")
3066      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3067    (clobber (reg:CC FLAGS_REG))]
3068   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3069   "#"
3070   [(set_attr "type" "imovx,alu1")
3071    (set_attr "mode" "SI")])
3073 (define_insn "*zero_extendqisi2_movzbw"
3074   [(set (match_operand:SI 0 "register_operand" "=r")
3075      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3076   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3077   "movz{bl|x}\t{%1, %0|%0, %1}"
3078   [(set_attr "type" "imovx")
3079    (set_attr "mode" "SI")])
3081 ;; For the movzbl case strip only the clobber
3082 (define_split
3083   [(set (match_operand:SI 0 "register_operand" "")
3084         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3085    (clobber (reg:CC FLAGS_REG))]
3086   "reload_completed 
3087    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3088    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3089   [(set (match_dup 0)
3090         (zero_extend:SI (match_dup 1)))])
3092 ;; When source and destination does not overlap, clear destination
3093 ;; first and then do the movb
3094 (define_split
3095   [(set (match_operand:SI 0 "register_operand" "")
3096         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3097    (clobber (reg:CC FLAGS_REG))]
3098   "reload_completed
3099    && ANY_QI_REG_P (operands[0])
3100    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3101    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3102    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3103   [(set (match_dup 0) (const_int 0))
3104    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3105   "operands[2] = gen_lowpart (QImode, operands[0]);")
3107 ;; Rest is handled by single and.
3108 (define_split
3109   [(set (match_operand:SI 0 "register_operand" "")
3110         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3111    (clobber (reg:CC FLAGS_REG))]
3112   "reload_completed
3113    && true_regnum (operands[0]) == true_regnum (operands[1])"
3114   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3115               (clobber (reg:CC FLAGS_REG))])]
3116   "")
3118 ;; %%% Kill me once multi-word ops are sane.
3119 (define_expand "zero_extendsidi2"
3120   [(set (match_operand:DI 0 "register_operand" "=r")
3121      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3122   ""
3123   "if (!TARGET_64BIT)
3124      {
3125        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3126        DONE;
3127      }
3128   ")
3130 (define_insn "zero_extendsidi2_32"
3131   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3132         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3133    (clobber (reg:CC FLAGS_REG))]
3134   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3135   "@
3136    #
3137    #
3138    #
3139    movd\t{%1, %0|%0, %1}
3140    movd\t{%1, %0|%0, %1}"
3141   [(set_attr "mode" "SI,SI,SI,DI,TI")
3142    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3144 (define_insn "*zero_extendsidi2_32_1"
3145   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3146         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3147    (clobber (reg:CC FLAGS_REG))]
3148   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3149   "@
3150    #
3151    #
3152    #
3153    movd\t{%1, %0|%0, %1}
3154    movd\t{%1, %0|%0, %1}"
3155   [(set_attr "mode" "SI,SI,SI,DI,TI")
3156    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3158 (define_insn "zero_extendsidi2_rex64"
3159   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3160      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3161   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3162   "@
3163    mov\t{%k1, %k0|%k0, %k1}
3164    #
3165    movd\t{%1, %0|%0, %1}
3166    movd\t{%1, %0|%0, %1}"
3167   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3168    (set_attr "mode" "SI,DI,DI,TI")])
3170 (define_insn "*zero_extendsidi2_rex64_1"
3171   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3172      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3173   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3174   "@
3175    mov\t{%k1, %k0|%k0, %k1}
3176    #
3177    movd\t{%1, %0|%0, %1}
3178    movd\t{%1, %0|%0, %1}"
3179   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3180    (set_attr "mode" "SI,DI,SI,SI")])
3182 (define_split
3183   [(set (match_operand:DI 0 "memory_operand" "")
3184      (zero_extend:DI (match_dup 0)))]
3185   "TARGET_64BIT"
3186   [(set (match_dup 4) (const_int 0))]
3187   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3189 (define_split 
3190   [(set (match_operand:DI 0 "register_operand" "")
3191         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3192    (clobber (reg:CC FLAGS_REG))]
3193   "!TARGET_64BIT && reload_completed
3194    && true_regnum (operands[0]) == true_regnum (operands[1])"
3195   [(set (match_dup 4) (const_int 0))]
3196   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3198 (define_split 
3199   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3200         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3201    (clobber (reg:CC FLAGS_REG))]
3202   "!TARGET_64BIT && reload_completed
3203    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3204   [(set (match_dup 3) (match_dup 1))
3205    (set (match_dup 4) (const_int 0))]
3206   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3208 (define_insn "zero_extendhidi2"
3209   [(set (match_operand:DI 0 "register_operand" "=r,r")
3210      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3211   "TARGET_64BIT"
3212   "@
3213    movz{wl|x}\t{%1, %k0|%k0, %1}
3214    movz{wq|x}\t{%1, %0|%0, %1}"
3215   [(set_attr "type" "imovx")
3216    (set_attr "mode" "SI,DI")])
3218 (define_insn "zero_extendqidi2"
3219   [(set (match_operand:DI 0 "register_operand" "=r,r")
3220      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3221   "TARGET_64BIT"
3222   "@
3223    movz{bl|x}\t{%1, %k0|%k0, %1}
3224    movz{bq|x}\t{%1, %0|%0, %1}"
3225   [(set_attr "type" "imovx")
3226    (set_attr "mode" "SI,DI")])
3228 ;; Sign extension instructions
3230 (define_expand "extendsidi2"
3231   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3232                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3233               (clobber (reg:CC FLAGS_REG))
3234               (clobber (match_scratch:SI 2 ""))])]
3235   ""
3237   if (TARGET_64BIT)
3238     {
3239       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3240       DONE;
3241     }
3244 (define_insn "*extendsidi2_1"
3245   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3246         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3247    (clobber (reg:CC FLAGS_REG))
3248    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3249   "!TARGET_64BIT"
3250   "#")
3252 (define_insn "extendsidi2_rex64"
3253   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3254         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3255   "TARGET_64BIT"
3256   "@
3257    {cltq|cdqe}
3258    movs{lq|x}\t{%1,%0|%0, %1}"
3259   [(set_attr "type" "imovx")
3260    (set_attr "mode" "DI")
3261    (set_attr "prefix_0f" "0")
3262    (set_attr "modrm" "0,1")])
3264 (define_insn "extendhidi2"
3265   [(set (match_operand:DI 0 "register_operand" "=r")
3266         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3267   "TARGET_64BIT"
3268   "movs{wq|x}\t{%1,%0|%0, %1}"
3269   [(set_attr "type" "imovx")
3270    (set_attr "mode" "DI")])
3272 (define_insn "extendqidi2"
3273   [(set (match_operand:DI 0 "register_operand" "=r")
3274         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3275   "TARGET_64BIT"
3276   "movs{bq|x}\t{%1,%0|%0, %1}"
3277    [(set_attr "type" "imovx")
3278     (set_attr "mode" "DI")])
3280 ;; Extend to memory case when source register does die.
3281 (define_split 
3282   [(set (match_operand:DI 0 "memory_operand" "")
3283         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3284    (clobber (reg:CC FLAGS_REG))
3285    (clobber (match_operand:SI 2 "register_operand" ""))]
3286   "(reload_completed
3287     && dead_or_set_p (insn, operands[1])
3288     && !reg_mentioned_p (operands[1], operands[0]))"
3289   [(set (match_dup 3) (match_dup 1))
3290    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3291               (clobber (reg:CC FLAGS_REG))])
3292    (set (match_dup 4) (match_dup 1))]
3293   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3295 ;; Extend to memory case when source register does not die.
3296 (define_split 
3297   [(set (match_operand:DI 0 "memory_operand" "")
3298         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3299    (clobber (reg:CC FLAGS_REG))
3300    (clobber (match_operand:SI 2 "register_operand" ""))]
3301   "reload_completed"
3302   [(const_int 0)]
3304   split_di (&operands[0], 1, &operands[3], &operands[4]);
3306   emit_move_insn (operands[3], operands[1]);
3308   /* Generate a cltd if possible and doing so it profitable.  */
3309   if (true_regnum (operands[1]) == 0
3310       && true_regnum (operands[2]) == 1
3311       && (optimize_size || TARGET_USE_CLTD))
3312     {
3313       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3314     }
3315   else
3316     {
3317       emit_move_insn (operands[2], operands[1]);
3318       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3319     }
3320   emit_move_insn (operands[4], operands[2]);
3321   DONE;
3324 ;; Extend to register case.  Optimize case where source and destination
3325 ;; registers match and cases where we can use cltd.
3326 (define_split 
3327   [(set (match_operand:DI 0 "register_operand" "")
3328         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3329    (clobber (reg:CC FLAGS_REG))
3330    (clobber (match_scratch:SI 2 ""))]
3331   "reload_completed"
3332   [(const_int 0)]
3334   split_di (&operands[0], 1, &operands[3], &operands[4]);
3336   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3337     emit_move_insn (operands[3], operands[1]);
3339   /* Generate a cltd if possible and doing so it profitable.  */
3340   if (true_regnum (operands[3]) == 0
3341       && (optimize_size || TARGET_USE_CLTD))
3342     {
3343       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3344       DONE;
3345     }
3347   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3348     emit_move_insn (operands[4], operands[1]);
3350   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3351   DONE;
3354 (define_insn "extendhisi2"
3355   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3356         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3357   ""
3359   switch (get_attr_prefix_0f (insn))
3360     {
3361     case 0:
3362       return "{cwtl|cwde}";
3363     default:
3364       return "movs{wl|x}\t{%1,%0|%0, %1}";
3365     }
3367   [(set_attr "type" "imovx")
3368    (set_attr "mode" "SI")
3369    (set (attr "prefix_0f")
3370      ;; movsx is short decodable while cwtl is vector decoded.
3371      (if_then_else (and (eq_attr "cpu" "!k6")
3372                         (eq_attr "alternative" "0"))
3373         (const_string "0")
3374         (const_string "1")))
3375    (set (attr "modrm")
3376      (if_then_else (eq_attr "prefix_0f" "0")
3377         (const_string "0")
3378         (const_string "1")))])
3380 (define_insn "*extendhisi2_zext"
3381   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3382         (zero_extend:DI
3383           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3384   "TARGET_64BIT"
3386   switch (get_attr_prefix_0f (insn))
3387     {
3388     case 0:
3389       return "{cwtl|cwde}";
3390     default:
3391       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3392     }
3394   [(set_attr "type" "imovx")
3395    (set_attr "mode" "SI")
3396    (set (attr "prefix_0f")
3397      ;; movsx is short decodable while cwtl is vector decoded.
3398      (if_then_else (and (eq_attr "cpu" "!k6")
3399                         (eq_attr "alternative" "0"))
3400         (const_string "0")
3401         (const_string "1")))
3402    (set (attr "modrm")
3403      (if_then_else (eq_attr "prefix_0f" "0")
3404         (const_string "0")
3405         (const_string "1")))])
3407 (define_insn "extendqihi2"
3408   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3409         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3410   ""
3412   switch (get_attr_prefix_0f (insn))
3413     {
3414     case 0:
3415       return "{cbtw|cbw}";
3416     default:
3417       return "movs{bw|x}\t{%1,%0|%0, %1}";
3418     }
3420   [(set_attr "type" "imovx")
3421    (set_attr "mode" "HI")
3422    (set (attr "prefix_0f")
3423      ;; movsx is short decodable while cwtl is vector decoded.
3424      (if_then_else (and (eq_attr "cpu" "!k6")
3425                         (eq_attr "alternative" "0"))
3426         (const_string "0")
3427         (const_string "1")))
3428    (set (attr "modrm")
3429      (if_then_else (eq_attr "prefix_0f" "0")
3430         (const_string "0")
3431         (const_string "1")))])
3433 (define_insn "extendqisi2"
3434   [(set (match_operand:SI 0 "register_operand" "=r")
3435         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3436   ""
3437   "movs{bl|x}\t{%1,%0|%0, %1}"
3438    [(set_attr "type" "imovx")
3439     (set_attr "mode" "SI")])
3441 (define_insn "*extendqisi2_zext"
3442   [(set (match_operand:DI 0 "register_operand" "=r")
3443         (zero_extend:DI
3444           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3445   "TARGET_64BIT"
3446   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3447    [(set_attr "type" "imovx")
3448     (set_attr "mode" "SI")])
3450 ;; Conversions between float and double.
3452 ;; These are all no-ops in the model used for the 80387.  So just
3453 ;; emit moves.
3455 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3456 (define_insn "*dummy_extendsfdf2"
3457   [(set (match_operand:DF 0 "push_operand" "=<")
3458         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3459   "0"
3460   "#")
3462 (define_split
3463   [(set (match_operand:DF 0 "push_operand" "")
3464         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3465   "!TARGET_64BIT"
3466   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3467    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3469 (define_split
3470   [(set (match_operand:DF 0 "push_operand" "")
3471         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3472   "TARGET_64BIT"
3473   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3474    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3476 (define_insn "*dummy_extendsfxf2"
3477   [(set (match_operand:XF 0 "push_operand" "=<")
3478         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3479   "0"
3480   "#")
3482 (define_split
3483   [(set (match_operand:XF 0 "push_operand" "")
3484         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3485   ""
3486   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3487    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3488   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3490 (define_split
3491   [(set (match_operand:XF 0 "push_operand" "")
3492         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3493   "TARGET_64BIT"
3494   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3495    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3496   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3498 (define_split
3499   [(set (match_operand:XF 0 "push_operand" "")
3500         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3501   ""
3502   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3503    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3504   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3506 (define_split
3507   [(set (match_operand:XF 0 "push_operand" "")
3508         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3509   "TARGET_64BIT"
3510   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3511    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3512   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3514 (define_expand "extendsfdf2"
3515   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3516         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3517   "TARGET_80387 || TARGET_SSE2"
3519   /* ??? Needed for compress_float_constant since all fp constants
3520      are LEGITIMATE_CONSTANT_P.  */
3521   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3522     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3523   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3524     operands[1] = force_reg (SFmode, operands[1]);
3527 (define_insn "*extendsfdf2_1"
3528   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3529         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3530   "(TARGET_80387 || TARGET_SSE2)
3531    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3533   switch (which_alternative)
3534     {
3535     case 0:
3536       return output_387_reg_move (insn, operands);
3538     case 1:
3539       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3540         return "fstp%z0\t%y0";
3541       else
3542         return "fst%z0\t%y0";
3544     case 2:
3545       return "cvtss2sd\t{%1, %0|%0, %1}";
3547     default:
3548       abort ();
3549     }
3551   [(set_attr "type" "fmov,fmov,ssecvt")
3552    (set_attr "mode" "SF,XF,DF")])
3554 (define_insn "*extendsfdf2_1_sse_only"
3555   [(set (match_operand:DF 0 "register_operand" "=Y")
3556         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3557   "!TARGET_80387 && TARGET_SSE2
3558    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3559   "cvtss2sd\t{%1, %0|%0, %1}"
3560   [(set_attr "type" "ssecvt")
3561    (set_attr "mode" "DF")])
3563 (define_expand "extendsfxf2"
3564   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3565         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3566   "TARGET_80387"
3568   /* ??? Needed for compress_float_constant since all fp constants
3569      are LEGITIMATE_CONSTANT_P.  */
3570   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3571     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3572   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3573     operands[1] = force_reg (SFmode, operands[1]);
3576 (define_insn "*extendsfxf2_1"
3577   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3578         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3579   "TARGET_80387
3580    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3582   switch (which_alternative)
3583     {
3584     case 0:
3585       return output_387_reg_move (insn, operands);
3587     case 1:
3588       /* There is no non-popping store to memory for XFmode.  So if
3589          we need one, follow the store with a load.  */
3590       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3591         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3592       else
3593         return "fstp%z0\t%y0";
3595     default:
3596       abort ();
3597     }
3599   [(set_attr "type" "fmov")
3600    (set_attr "mode" "SF,XF")])
3602 (define_expand "extenddfxf2"
3603   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3604         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3605   "TARGET_80387"
3607   /* ??? Needed for compress_float_constant since all fp constants
3608      are LEGITIMATE_CONSTANT_P.  */
3609   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3610     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3611   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3612     operands[1] = force_reg (DFmode, operands[1]);
3615 (define_insn "*extenddfxf2_1"
3616   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3617         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3618   "TARGET_80387
3619    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3621   switch (which_alternative)
3622     {
3623     case 0:
3624       return output_387_reg_move (insn, operands);
3626     case 1:
3627       /* There is no non-popping store to memory for XFmode.  So if
3628          we need one, follow the store with a load.  */
3629       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3630         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3631       else
3632         return "fstp%z0\t%y0";
3634     default:
3635       abort ();
3636     }
3638   [(set_attr "type" "fmov")
3639    (set_attr "mode" "DF,XF")])
3641 ;; %%% This seems bad bad news.
3642 ;; This cannot output into an f-reg because there is no way to be sure
3643 ;; of truncating in that case.  Otherwise this is just like a simple move
3644 ;; insn.  So we pretend we can output to a reg in order to get better
3645 ;; register preferencing, but we really use a stack slot.
3647 (define_expand "truncdfsf2"
3648   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3649                    (float_truncate:SF
3650                     (match_operand:DF 1 "register_operand" "")))
3651               (clobber (match_dup 2))])]
3652   "TARGET_80387 || TARGET_SSE2"
3653   "
3654    if (!TARGET_80387)
3655      {
3656         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3657         DONE;
3658      }
3659    else if (flag_unsafe_math_optimizations)
3660      {
3661         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3662         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3663         if (reg != operands[0])
3664           emit_move_insn (operands[0], reg);
3665         DONE;
3666      }
3667    else
3668      operands[2] = assign_386_stack_local (SFmode, 0);
3671 (define_insn "truncdfsf2_noop"
3672   [(set (match_operand:SF 0 "register_operand" "=f")
3673         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3674   "TARGET_80387 && flag_unsafe_math_optimizations"
3676   return output_387_reg_move (insn, operands);
3678   [(set_attr "type" "fmov")
3679    (set_attr "mode" "SF")])
3681 (define_insn "*truncdfsf2_1"
3682   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3683         (float_truncate:SF
3684          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3685    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3686   "TARGET_80387 && !TARGET_SSE2"
3688   switch (which_alternative)
3689     {
3690     case 0:
3691       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3692         return "fstp%z0\t%y0";
3693       else
3694         return "fst%z0\t%y0";
3695     default:
3696       abort ();
3697     }
3699   [(set_attr "type" "fmov,multi,multi,multi")
3700    (set_attr "mode" "SF,SF,SF,SF")])
3702 (define_insn "*truncdfsf2_1_sse"
3703   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3704         (float_truncate:SF
3705          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3706    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3707   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3709   switch (which_alternative)
3710     {
3711     case 0:
3712       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3713         return "fstp%z0\t%y0";
3714       else
3715         return "fst%z0\t%y0";
3716     case 4:
3717       return "#";
3718     default:
3719       abort ();
3720     }
3722   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3723    (set_attr "mode" "SF,SF,SF,SF,DF")])
3725 (define_insn "*truncdfsf2_1_sse_nooverlap"
3726   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3727         (float_truncate:SF
3728          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3729    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3730   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3732   switch (which_alternative)
3733     {
3734     case 0:
3735       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3736         return "fstp%z0\t%y0";
3737       else
3738         return "fst%z0\t%y0";
3739     case 4:
3740       return "#";
3741     default:
3742       abort ();
3743     }
3745   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3746    (set_attr "mode" "SF,SF,SF,SF,DF")])
3748 (define_insn "*truncdfsf2_2"
3749   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3750         (float_truncate:SF
3751          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3752   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3753    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3755   switch (which_alternative)
3756     {
3757     case 0:
3758     case 1:
3759       return "cvtsd2ss\t{%1, %0|%0, %1}";
3760     case 2:
3761       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3762         return "fstp%z0\t%y0";
3763       else
3764         return "fst%z0\t%y0";
3765     default:
3766       abort ();
3767     }
3769   [(set_attr "type" "ssecvt,ssecvt,fmov")
3770    (set_attr "athlon_decode" "vector,double,*")
3771    (set_attr "mode" "SF,SF,SF")])
3773 (define_insn "*truncdfsf2_2_nooverlap"
3774   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3775         (float_truncate:SF
3776          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3777   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3778    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3780   switch (which_alternative)
3781     {
3782     case 0:
3783       return "#";
3784     case 1:
3785       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786         return "fstp%z0\t%y0";
3787       else
3788         return "fst%z0\t%y0";
3789     default:
3790       abort ();
3791     }
3793   [(set_attr "type" "ssecvt,fmov")
3794    (set_attr "mode" "DF,SF")])
3796 (define_insn "*truncdfsf2_3"
3797   [(set (match_operand:SF 0 "memory_operand" "=m")
3798         (float_truncate:SF
3799          (match_operand:DF 1 "register_operand" "f")))]
3800   "TARGET_80387"
3802   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3803     return "fstp%z0\t%y0";
3804   else
3805     return "fst%z0\t%y0";
3807   [(set_attr "type" "fmov")
3808    (set_attr "mode" "SF")])
3810 (define_insn "truncdfsf2_sse_only"
3811   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3812         (float_truncate:SF
3813          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3814   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3815   "cvtsd2ss\t{%1, %0|%0, %1}"
3816   [(set_attr "type" "ssecvt")
3817    (set_attr "athlon_decode" "vector,double")
3818    (set_attr "mode" "SF")])
3820 (define_insn "*truncdfsf2_sse_only_nooverlap"
3821   [(set (match_operand:SF 0 "register_operand" "=&Y")
3822         (float_truncate:SF
3823          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3824   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3825   "#"
3826   [(set_attr "type" "ssecvt")
3827    (set_attr "mode" "DF")])
3829 (define_split
3830   [(set (match_operand:SF 0 "memory_operand" "")
3831         (float_truncate:SF
3832          (match_operand:DF 1 "register_operand" "")))
3833    (clobber (match_operand:SF 2 "memory_operand" ""))]
3834   "TARGET_80387"
3835   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3836   "")
3838 ; Avoid possible reformatting penalty on the destination by first
3839 ; zeroing it out
3840 (define_split
3841   [(set (match_operand:SF 0 "register_operand" "")
3842         (float_truncate:SF
3843          (match_operand:DF 1 "nonimmediate_operand" "")))
3844    (clobber (match_operand 2 "" ""))]
3845   "TARGET_80387 && reload_completed
3846    && SSE_REG_P (operands[0])
3847    && !STACK_REG_P (operands[1])"
3848   [(const_int 0)]
3850   rtx src, dest;
3851   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3852     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3853   else
3854     {
3855       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3856       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3857       /* simplify_gen_subreg refuses to widen memory references.  */
3858       if (GET_CODE (src) == SUBREG)
3859         alter_subreg (&src);
3860       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3861         abort ();
3862       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3863       emit_insn (gen_cvtsd2ss (dest, dest, src));
3864     }
3865   DONE;
3868 (define_split
3869   [(set (match_operand:SF 0 "register_operand" "")
3870         (float_truncate:SF
3871          (match_operand:DF 1 "nonimmediate_operand" "")))]
3872   "TARGET_80387 && reload_completed
3873    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3874   [(const_int 0)]
3876   rtx src, dest;
3877   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3878   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3879   /* simplify_gen_subreg refuses to widen memory references.  */
3880   if (GET_CODE (src) == SUBREG)
3881     alter_subreg (&src);
3882   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3883     abort ();
3884   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3885   emit_insn (gen_cvtsd2ss (dest, dest, src));
3886   DONE;
3889 (define_split
3890   [(set (match_operand:SF 0 "register_operand" "")
3891         (float_truncate:SF
3892          (match_operand:DF 1 "fp_register_operand" "")))
3893    (clobber (match_operand:SF 2 "memory_operand" ""))]
3894   "TARGET_80387 && reload_completed"
3895   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3896    (set (match_dup 0) (match_dup 2))]
3897   "")
3899 (define_expand "truncxfsf2"
3900   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3901                    (float_truncate:SF
3902                     (match_operand:XF 1 "register_operand" "")))
3903               (clobber (match_dup 2))])]
3904   "TARGET_80387"
3905   "
3906   if (flag_unsafe_math_optimizations)
3907     {
3908       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3909       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3910       if (reg != operands[0])
3911         emit_move_insn (operands[0], reg);
3912       DONE;
3913     }
3914   else
3915     operands[2] = assign_386_stack_local (SFmode, 0);
3916   ")
3918 (define_insn "truncxfsf2_noop"
3919   [(set (match_operand:SF 0 "register_operand" "=f")
3920         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3921   "TARGET_80387 && flag_unsafe_math_optimizations"
3923   return output_387_reg_move (insn, operands);
3925   [(set_attr "type" "fmov")
3926    (set_attr "mode" "SF")])
3928 (define_insn "*truncxfsf2_1"
3929   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3930         (float_truncate:SF
3931          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3932    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3933   "TARGET_80387"
3935   switch (which_alternative)
3936     {
3937     case 0:
3938       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3939         return "fstp%z0\t%y0";
3940       else
3941         return "fst%z0\t%y0";
3942     default:
3943       abort();
3944     }
3946   [(set_attr "type" "fmov,multi,multi,multi")
3947    (set_attr "mode" "SF")])
3949 (define_insn "*truncxfsf2_2"
3950   [(set (match_operand:SF 0 "memory_operand" "=m")
3951         (float_truncate:SF
3952          (match_operand:XF 1 "register_operand" "f")))]
3953   "TARGET_80387"
3955   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3956     return "fstp%z0\t%y0";
3957   else
3958     return "fst%z0\t%y0";
3960   [(set_attr "type" "fmov")
3961    (set_attr "mode" "SF")])
3963 (define_split
3964   [(set (match_operand:SF 0 "memory_operand" "")
3965         (float_truncate:SF
3966          (match_operand:XF 1 "register_operand" "")))
3967    (clobber (match_operand:SF 2 "memory_operand" ""))]
3968   "TARGET_80387"
3969   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3970   "")
3972 (define_split
3973   [(set (match_operand:SF 0 "register_operand" "")
3974         (float_truncate:SF
3975          (match_operand:XF 1 "register_operand" "")))
3976    (clobber (match_operand:SF 2 "memory_operand" ""))]
3977   "TARGET_80387 && reload_completed"
3978   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3979    (set (match_dup 0) (match_dup 2))]
3980   "")
3982 (define_expand "truncxfdf2"
3983   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3984                    (float_truncate:DF
3985                     (match_operand:XF 1 "register_operand" "")))
3986               (clobber (match_dup 2))])]
3987   "TARGET_80387"
3988   "
3989   if (flag_unsafe_math_optimizations)
3990     {
3991       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3992       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3993       if (reg != operands[0])
3994         emit_move_insn (operands[0], reg);
3995       DONE;
3996     }
3997   else
3998     operands[2] = assign_386_stack_local (DFmode, 0);
3999   ")
4001 (define_insn "truncxfdf2_noop"
4002   [(set (match_operand:DF 0 "register_operand" "=f")
4003         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4004   "TARGET_80387 && flag_unsafe_math_optimizations"
4006   return output_387_reg_move (insn, operands);
4008   [(set_attr "type" "fmov")
4009    (set_attr "mode" "DF")])
4011 (define_insn "*truncxfdf2_1"
4012   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4013         (float_truncate:DF
4014          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4015    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4016   "TARGET_80387"
4018   switch (which_alternative)
4019     {
4020     case 0:
4021       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4022         return "fstp%z0\t%y0";
4023       else
4024         return "fst%z0\t%y0";
4025     default:
4026       abort();
4027     }
4028   abort ();
4030   [(set_attr "type" "fmov,multi,multi,multi")
4031    (set_attr "mode" "DF")])
4033 (define_insn "*truncxfdf2_2"
4034   [(set (match_operand:DF 0 "memory_operand" "=m")
4035         (float_truncate:DF
4036           (match_operand:XF 1 "register_operand" "f")))]
4037   "TARGET_80387"
4039   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4040     return "fstp%z0\t%y0";
4041   else
4042     return "fst%z0\t%y0";
4044   [(set_attr "type" "fmov")
4045    (set_attr "mode" "DF")])
4047 (define_split
4048   [(set (match_operand:DF 0 "memory_operand" "")
4049         (float_truncate:DF
4050          (match_operand:XF 1 "register_operand" "")))
4051    (clobber (match_operand:DF 2 "memory_operand" ""))]
4052   "TARGET_80387"
4053   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4054   "")
4056 (define_split
4057   [(set (match_operand:DF 0 "register_operand" "")
4058         (float_truncate:DF
4059          (match_operand:XF 1 "register_operand" "")))
4060    (clobber (match_operand:DF 2 "memory_operand" ""))]
4061   "TARGET_80387 && reload_completed"
4062   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4063    (set (match_dup 0) (match_dup 2))]
4064   "")
4067 ;; %%% Break up all these bad boys.
4069 ;; Signed conversion to DImode.
4071 (define_expand "fix_truncxfdi2"
4072   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4073                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4074               (clobber (reg:CC FLAGS_REG))])]
4075   "TARGET_80387"
4076   "")
4078 (define_expand "fix_truncdfdi2"
4079   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4081               (clobber (reg:CC FLAGS_REG))])]
4082   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4084   if (TARGET_64BIT && TARGET_SSE2)
4085    {
4086      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4087      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4088      if (out != operands[0])
4089         emit_move_insn (operands[0], out);
4090      DONE;
4091    }
4094 (define_expand "fix_truncsfdi2"
4095   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4096                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4097               (clobber (reg:CC FLAGS_REG))])] 
4098   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4100   if (TARGET_SSE && TARGET_64BIT)
4101    {
4102      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4103      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4104      if (out != operands[0])
4105         emit_move_insn (operands[0], out);
4106      DONE;
4107    }
4110 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4111 ;; of the machinery.
4112 (define_insn_and_split "*fix_truncdi_1"
4113   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4114         (fix:DI (match_operand 1 "register_operand" "f,f")))
4115    (clobber (reg:CC FLAGS_REG))]
4116   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4117    && !reload_completed && !reload_in_progress
4118    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4119   "#"
4120   "&& 1"
4121   [(const_int 0)]
4123   ix86_optimize_mode_switching = 1;
4124   operands[2] = assign_386_stack_local (HImode, 1);
4125   operands[3] = assign_386_stack_local (HImode, 2);
4126   if (memory_operand (operands[0], VOIDmode))
4127     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4128                                        operands[2], operands[3]));
4129   else
4130     {
4131       operands[4] = assign_386_stack_local (DImode, 0);
4132       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4133                                            operands[2], operands[3],
4134                                            operands[4]));
4135     }
4136   DONE;
4138   [(set_attr "type" "fistp")
4139    (set_attr "i387_cw" "trunc")
4140    (set_attr "mode" "DI")])
4142 (define_insn "fix_truncdi_nomemory"
4143   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4144         (fix:DI (match_operand 1 "register_operand" "f,f")))
4145    (use (match_operand:HI 2 "memory_operand" "m,m"))
4146    (use (match_operand:HI 3 "memory_operand" "m,m"))
4147    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4148    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4149   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4150    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4151   "#"
4152   [(set_attr "type" "fistp")
4153    (set_attr "i387_cw" "trunc")
4154    (set_attr "mode" "DI")])
4156 (define_insn "fix_truncdi_memory"
4157   [(set (match_operand:DI 0 "memory_operand" "=m")
4158         (fix:DI (match_operand 1 "register_operand" "f")))
4159    (use (match_operand:HI 2 "memory_operand" "m"))
4160    (use (match_operand:HI 3 "memory_operand" "m"))
4161    (clobber (match_scratch:DF 4 "=&1f"))]
4162   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4163    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4164   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4165   [(set_attr "type" "fistp")
4166    (set_attr "i387_cw" "trunc")
4167    (set_attr "mode" "DI")])
4169 (define_split 
4170   [(set (match_operand:DI 0 "register_operand" "")
4171         (fix:DI (match_operand 1 "register_operand" "")))
4172    (use (match_operand:HI 2 "memory_operand" ""))
4173    (use (match_operand:HI 3 "memory_operand" ""))
4174    (clobber (match_operand:DI 4 "memory_operand" ""))
4175    (clobber (match_scratch 5 ""))]
4176   "reload_completed"
4177   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4178               (use (match_dup 2))
4179               (use (match_dup 3))
4180               (clobber (match_dup 5))])
4181    (set (match_dup 0) (match_dup 4))]
4182   "")
4184 (define_split 
4185   [(set (match_operand:DI 0 "memory_operand" "")
4186         (fix:DI (match_operand 1 "register_operand" "")))
4187    (use (match_operand:HI 2 "memory_operand" ""))
4188    (use (match_operand:HI 3 "memory_operand" ""))
4189    (clobber (match_operand:DI 4 "memory_operand" ""))
4190    (clobber (match_scratch 5 ""))]
4191   "reload_completed"
4192   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4193               (use (match_dup 2))
4194               (use (match_dup 3))
4195               (clobber (match_dup 5))])]
4196   "")
4198 ;; When SSE available, it is always faster to use it!
4199 (define_insn "fix_truncsfdi_sse"
4200   [(set (match_operand:DI 0 "register_operand" "=r,r")
4201         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4202   "TARGET_64BIT && TARGET_SSE"
4203   "cvttss2si{q}\t{%1, %0|%0, %1}"
4204   [(set_attr "type" "sseicvt")
4205    (set_attr "mode" "SF")
4206    (set_attr "athlon_decode" "double,vector")])
4208 ;; Avoid vector decoded form of the instruction.
4209 (define_peephole2
4210   [(match_scratch:SF 2 "x")
4211    (set (match_operand:DI 0 "register_operand" "")
4212         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4213   "TARGET_K8 && !optimize_size"
4214   [(set (match_dup 2) (match_dup 1))
4215    (set (match_dup 0) (fix:DI (match_dup 2)))]
4216   "")
4218 (define_insn "fix_truncdfdi_sse"
4219   [(set (match_operand:DI 0 "register_operand" "=r,r")
4220         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4221   "TARGET_64BIT && TARGET_SSE2"
4222   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4223   [(set_attr "type" "sseicvt,sseicvt")
4224    (set_attr "mode" "DF")
4225    (set_attr "athlon_decode" "double,vector")])
4227 ;; Avoid vector decoded form of the instruction.
4228 (define_peephole2
4229   [(match_scratch:DF 2 "Y")
4230    (set (match_operand:DI 0 "register_operand" "")
4231         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4232   "TARGET_K8 && !optimize_size"
4233   [(set (match_dup 2) (match_dup 1))
4234    (set (match_dup 0) (fix:DI (match_dup 2)))]
4235   "")
4237 ;; Signed conversion to SImode.
4239 (define_expand "fix_truncxfsi2"
4240   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4241                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4242               (clobber (reg:CC FLAGS_REG))])]
4243   "TARGET_80387"
4244   "")
4246 (define_expand "fix_truncdfsi2"
4247   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4248                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4249               (clobber (reg:CC FLAGS_REG))])]
4250   "TARGET_80387 || TARGET_SSE2"
4252   if (TARGET_SSE2)
4253    {
4254      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4255      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4256      if (out != operands[0])
4257         emit_move_insn (operands[0], out);
4258      DONE;
4259    }
4262 (define_expand "fix_truncsfsi2"
4263   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4264                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4265               (clobber (reg:CC FLAGS_REG))])] 
4266   "TARGET_80387 || TARGET_SSE"
4268   if (TARGET_SSE)
4269    {
4270      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4271      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4272      if (out != operands[0])
4273         emit_move_insn (operands[0], out);
4274      DONE;
4275    }
4278 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4279 ;; of the machinery.
4280 (define_insn_and_split "*fix_truncsi_1"
4281   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4282         (fix:SI (match_operand 1 "register_operand" "f,f")))
4283    (clobber (reg:CC FLAGS_REG))]
4284   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4285    && !reload_completed && !reload_in_progress
4286    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4287   "#"
4288   "&& 1"
4289   [(const_int 0)]
4291   ix86_optimize_mode_switching = 1;
4292   operands[2] = assign_386_stack_local (HImode, 1);
4293   operands[3] = assign_386_stack_local (HImode, 2);
4294   if (memory_operand (operands[0], VOIDmode))
4295     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4296                                        operands[2], operands[3]));
4297   else
4298     {
4299       operands[4] = assign_386_stack_local (SImode, 0);
4300       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4301                                            operands[2], operands[3],
4302                                            operands[4]));
4303     }
4304   DONE;
4306   [(set_attr "type" "fistp")
4307    (set_attr "i387_cw" "trunc")
4308    (set_attr "mode" "SI")])
4310 (define_insn "fix_truncsi_nomemory"
4311   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4312         (fix:SI (match_operand 1 "register_operand" "f,f")))
4313    (use (match_operand:HI 2 "memory_operand" "m,m"))
4314    (use (match_operand:HI 3 "memory_operand" "m,m"))
4315    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4316   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4317    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4318   "#"
4319   [(set_attr "type" "fistp")
4320    (set_attr "i387_cw" "trunc")
4321    (set_attr "mode" "SI")])
4323 (define_insn "fix_truncsi_memory"
4324   [(set (match_operand:SI 0 "memory_operand" "=m")
4325         (fix:SI (match_operand 1 "register_operand" "f")))
4326    (use (match_operand:HI 2 "memory_operand" "m"))
4327    (use (match_operand:HI 3 "memory_operand" "m"))]
4328   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4329    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4330   "* return output_fix_trunc (insn, operands);"
4331   [(set_attr "type" "fistp")
4332    (set_attr "i387_cw" "trunc")
4333    (set_attr "mode" "SI")])
4335 ;; When SSE available, it is always faster to use it!
4336 (define_insn "fix_truncsfsi_sse"
4337   [(set (match_operand:SI 0 "register_operand" "=r,r")
4338         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4339   "TARGET_SSE"
4340   "cvttss2si\t{%1, %0|%0, %1}"
4341   [(set_attr "type" "sseicvt")
4342    (set_attr "mode" "DF")
4343    (set_attr "athlon_decode" "double,vector")])
4345 ;; Avoid vector decoded form of the instruction.
4346 (define_peephole2
4347   [(match_scratch:SF 2 "x")
4348    (set (match_operand:SI 0 "register_operand" "")
4349         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4350   "TARGET_K8 && !optimize_size"
4351   [(set (match_dup 2) (match_dup 1))
4352    (set (match_dup 0) (fix:SI (match_dup 2)))]
4353   "")
4355 (define_insn "fix_truncdfsi_sse"
4356   [(set (match_operand:SI 0 "register_operand" "=r,r")
4357         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4358   "TARGET_SSE2"
4359   "cvttsd2si\t{%1, %0|%0, %1}"
4360   [(set_attr "type" "sseicvt")
4361    (set_attr "mode" "DF")
4362    (set_attr "athlon_decode" "double,vector")])
4364 ;; Avoid vector decoded form of the instruction.
4365 (define_peephole2
4366   [(match_scratch:DF 2 "Y")
4367    (set (match_operand:SI 0 "register_operand" "")
4368         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4369   "TARGET_K8 && !optimize_size"
4370   [(set (match_dup 2) (match_dup 1))
4371    (set (match_dup 0) (fix:SI (match_dup 2)))]
4372   "")
4374 (define_split 
4375   [(set (match_operand:SI 0 "register_operand" "")
4376         (fix:SI (match_operand 1 "register_operand" "")))
4377    (use (match_operand:HI 2 "memory_operand" ""))
4378    (use (match_operand:HI 3 "memory_operand" ""))
4379    (clobber (match_operand:SI 4 "memory_operand" ""))]
4380   "reload_completed"
4381   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4382               (use (match_dup 2))
4383               (use (match_dup 3))])
4384    (set (match_dup 0) (match_dup 4))]
4385   "")
4387 (define_split 
4388   [(set (match_operand:SI 0 "memory_operand" "")
4389         (fix:SI (match_operand 1 "register_operand" "")))
4390    (use (match_operand:HI 2 "memory_operand" ""))
4391    (use (match_operand:HI 3 "memory_operand" ""))
4392    (clobber (match_operand:SI 4 "memory_operand" ""))]
4393   "reload_completed"
4394   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4395               (use (match_dup 2))
4396               (use (match_dup 3))])]
4397   "")
4399 ;; Signed conversion to HImode.
4401 (define_expand "fix_truncxfhi2"
4402   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4403                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4404               (clobber (reg:CC FLAGS_REG))])] 
4405   "TARGET_80387"
4406   "")
4408 (define_expand "fix_truncdfhi2"
4409   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4410                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4411               (clobber (reg:CC FLAGS_REG))])]
4412   "TARGET_80387 && !TARGET_SSE2"
4413   "")
4415 (define_expand "fix_truncsfhi2"
4416   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4417                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4418                (clobber (reg:CC FLAGS_REG))])]
4419   "TARGET_80387 && !TARGET_SSE"
4420   "")
4422 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4423 ;; of the machinery.
4424 (define_insn_and_split "*fix_trunchi_1"
4425   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4426         (fix:HI (match_operand 1 "register_operand" "f,f")))
4427    (clobber (reg:CC FLAGS_REG))]
4428   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4429    && !reload_completed && !reload_in_progress
4430    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4431   "#"
4432   ""
4433   [(const_int 0)]
4435   ix86_optimize_mode_switching = 1;
4436   operands[2] = assign_386_stack_local (HImode, 1);
4437   operands[3] = assign_386_stack_local (HImode, 2);
4438   if (memory_operand (operands[0], VOIDmode))
4439     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4440                                        operands[2], operands[3]));
4441   else
4442     {
4443       operands[4] = assign_386_stack_local (HImode, 0);
4444       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4445                                            operands[2], operands[3],
4446                                            operands[4]));
4447     }
4448   DONE;
4450   [(set_attr "type" "fistp")
4451    (set_attr "i387_cw" "trunc")
4452    (set_attr "mode" "HI")])
4454 (define_insn "fix_trunchi_nomemory"
4455   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4456         (fix:HI (match_operand 1 "register_operand" "f,f")))
4457    (use (match_operand:HI 2 "memory_operand" "m,m"))
4458    (use (match_operand:HI 3 "memory_operand" "m,m"))
4459    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4460   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4461    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4462   "#"
4463   [(set_attr "type" "fistp")
4464    (set_attr "i387_cw" "trunc")
4465    (set_attr "mode" "HI")])
4467 (define_insn "fix_trunchi_memory"
4468   [(set (match_operand:HI 0 "memory_operand" "=m")
4469         (fix:HI (match_operand 1 "register_operand" "f")))
4470    (use (match_operand:HI 2 "memory_operand" "m"))
4471    (use (match_operand:HI 3 "memory_operand" "m"))]
4472   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4473    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4474   "* return output_fix_trunc (insn, operands);"
4475   [(set_attr "type" "fistp")
4476    (set_attr "i387_cw" "trunc")
4477    (set_attr "mode" "HI")])
4479 (define_split 
4480   [(set (match_operand:HI 0 "memory_operand" "")
4481         (fix:HI (match_operand 1 "register_operand" "")))
4482    (use (match_operand:HI 2 "memory_operand" ""))
4483    (use (match_operand:HI 3 "memory_operand" ""))
4484    (clobber (match_operand:HI 4 "memory_operand" ""))]
4485   "reload_completed"
4486   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4487               (use (match_dup 2))
4488               (use (match_dup 3))])]
4489   "")
4491 (define_split 
4492   [(set (match_operand:HI 0 "register_operand" "")
4493         (fix:HI (match_operand 1 "register_operand" "")))
4494    (use (match_operand:HI 2 "memory_operand" ""))
4495    (use (match_operand:HI 3 "memory_operand" ""))
4496    (clobber (match_operand:HI 4 "memory_operand" ""))]
4497   "reload_completed"
4498   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4499               (use (match_dup 2))
4500               (use (match_dup 3))
4501               (clobber (match_dup 4))])
4502    (set (match_dup 0) (match_dup 4))]
4503   "")
4505 (define_insn "x86_fnstcw_1"
4506   [(set (match_operand:HI 0 "memory_operand" "=m")
4507         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4508   "TARGET_80387"
4509   "fnstcw\t%0"
4510   [(set_attr "length" "2")
4511    (set_attr "mode" "HI")
4512    (set_attr "unit" "i387")])
4514 (define_insn "x86_fldcw_1"
4515   [(set (reg:HI FPSR_REG)
4516         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4517   "TARGET_80387"
4518   "fldcw\t%0"
4519   [(set_attr "length" "2")
4520    (set_attr "mode" "HI")
4521    (set_attr "unit" "i387")
4522    (set_attr "athlon_decode" "vector")])
4524 ;; Conversion between fixed point and floating point.
4526 ;; Even though we only accept memory inputs, the backend _really_
4527 ;; wants to be able to do this between registers.
4529 (define_expand "floathisf2"
4530   [(set (match_operand:SF 0 "register_operand" "")
4531         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4532   "TARGET_SSE || TARGET_80387"
4534   if (TARGET_SSE && TARGET_SSE_MATH)
4535     {
4536       emit_insn (gen_floatsisf2 (operands[0],
4537                                  convert_to_mode (SImode, operands[1], 0)));
4538       DONE;
4539     }
4542 (define_insn "*floathisf2_1"
4543   [(set (match_operand:SF 0 "register_operand" "=f,f")
4544         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4545   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
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 "floatsisf2"
4554   [(set (match_operand:SF 0 "register_operand" "")
4555         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4556   "TARGET_SSE || TARGET_80387"
4557   "")
4559 (define_insn "*floatsisf2_i387"
4560   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4561         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4562   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4563   "@
4564    fild%z1\t%1
4565    #
4566    cvtsi2ss\t{%1, %0|%0, %1}
4567    cvtsi2ss\t{%1, %0|%0, %1}"
4568   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4569    (set_attr "mode" "SF")
4570    (set_attr "athlon_decode" "*,*,vector,double")
4571    (set_attr "fp_int_src" "true")])
4573 (define_insn "*floatsisf2_sse"
4574   [(set (match_operand:SF 0 "register_operand" "=x,x")
4575         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4576   "TARGET_SSE"
4577   "cvtsi2ss\t{%1, %0|%0, %1}"
4578   [(set_attr "type" "sseicvt")
4579    (set_attr "mode" "SF")
4580    (set_attr "athlon_decode" "vector,double")
4581    (set_attr "fp_int_src" "true")])
4583 ; Avoid possible reformatting penalty on the destination by first
4584 ; zeroing it out
4585 (define_split
4586   [(set (match_operand:SF 0 "register_operand" "")
4587         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4588   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4589    && SSE_REG_P (operands[0])"
4590   [(const_int 0)]
4592   rtx dest;
4593   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4594   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4595   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4596   DONE;
4599 (define_expand "floatdisf2"
4600   [(set (match_operand:SF 0 "register_operand" "")
4601         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4602   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4603   "")
4605 (define_insn "*floatdisf2_i387_only"
4606   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4607         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4608   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4609   "@
4610    fild%z1\t%1
4611    #"
4612   [(set_attr "type" "fmov,multi")
4613    (set_attr "mode" "SF")
4614    (set_attr "fp_int_src" "true")])
4616 (define_insn "*floatdisf2_i387"
4617   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4618         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4619   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4620   "@
4621    fild%z1\t%1
4622    #
4623    cvtsi2ss{q}\t{%1, %0|%0, %1}
4624    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4625   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4626    (set_attr "mode" "SF")
4627    (set_attr "athlon_decode" "*,*,vector,double")
4628    (set_attr "fp_int_src" "true")])
4630 (define_insn "*floatdisf2_sse"
4631   [(set (match_operand:SF 0 "register_operand" "=x,x")
4632         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4633   "TARGET_64BIT && TARGET_SSE"
4634   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4635   [(set_attr "type" "sseicvt")
4636    (set_attr "mode" "SF")
4637    (set_attr "athlon_decode" "vector,double")
4638    (set_attr "fp_int_src" "true")])
4640 ; Avoid possible reformatting penalty on the destination by first
4641 ; zeroing it out
4642 (define_split
4643   [(set (match_operand:SF 0 "register_operand" "")
4644         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4645   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4646    && SSE_REG_P (operands[0])"
4647   [(const_int 0)]
4649   rtx dest;
4650   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4651   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4652   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4653   DONE;
4656 (define_expand "floathidf2"
4657   [(set (match_operand:DF 0 "register_operand" "")
4658         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4659   "TARGET_SSE2 || TARGET_80387"
4661   if (TARGET_SSE && TARGET_SSE_MATH)
4662     {
4663       emit_insn (gen_floatsidf2 (operands[0],
4664                                  convert_to_mode (SImode, operands[1], 0)));
4665       DONE;
4666     }
4669 (define_insn "*floathidf2_1"
4670   [(set (match_operand:DF 0 "register_operand" "=f,f")
4671         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4672   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4673   "@
4674    fild%z1\t%1
4675    #"
4676   [(set_attr "type" "fmov,multi")
4677    (set_attr "mode" "DF")
4678    (set_attr "fp_int_src" "true")])
4680 (define_expand "floatsidf2"
4681   [(set (match_operand:DF 0 "register_operand" "")
4682         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4683   "TARGET_80387 || TARGET_SSE2"
4684   "")
4686 (define_insn "*floatsidf2_i387"
4687   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4688         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4689   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4690   "@
4691    fild%z1\t%1
4692    #
4693    cvtsi2sd\t{%1, %0|%0, %1}
4694    cvtsi2sd\t{%1, %0|%0, %1}"
4695   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4696    (set_attr "mode" "DF")
4697    (set_attr "athlon_decode" "*,*,double,direct")
4698    (set_attr "fp_int_src" "true")])
4700 (define_insn "*floatsidf2_sse"
4701   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4702         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4703   "TARGET_SSE2"
4704   "cvtsi2sd\t{%1, %0|%0, %1}"
4705   [(set_attr "type" "sseicvt")
4706    (set_attr "mode" "DF")
4707    (set_attr "athlon_decode" "double,direct")
4708    (set_attr "fp_int_src" "true")])
4710 (define_expand "floatdidf2"
4711   [(set (match_operand:DF 0 "register_operand" "")
4712         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4713   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4714   "")
4716 (define_insn "*floatdidf2_i387_only"
4717   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4718         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4719   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4720   "@
4721    fild%z1\t%1
4722    #"
4723   [(set_attr "type" "fmov,multi")
4724    (set_attr "mode" "DF")
4725    (set_attr "fp_int_src" "true")])
4727 (define_insn "*floatdidf2_i387"
4728   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4729         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4730   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4731   "@
4732    fild%z1\t%1
4733    #
4734    cvtsi2sd{q}\t{%1, %0|%0, %1}
4735    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4736   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4737    (set_attr "mode" "DF")
4738    (set_attr "athlon_decode" "*,*,double,direct")
4739    (set_attr "fp_int_src" "true")])
4741 (define_insn "*floatdidf2_sse"
4742   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4743         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4744   "TARGET_SSE2"
4745   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4746   [(set_attr "type" "sseicvt")
4747    (set_attr "mode" "DF")
4748    (set_attr "athlon_decode" "double,direct")
4749    (set_attr "fp_int_src" "true")])
4751 (define_insn "floathixf2"
4752   [(set (match_operand:XF 0 "register_operand" "=f,f")
4753         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4754   "TARGET_80387"
4755   "@
4756    fild%z1\t%1
4757    #"
4758   [(set_attr "type" "fmov,multi")
4759    (set_attr "mode" "XF")
4760    (set_attr "fp_int_src" "true")])
4762 (define_insn "floatsixf2"
4763   [(set (match_operand:XF 0 "register_operand" "=f,f")
4764         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4765   "TARGET_80387"
4766   "@
4767    fild%z1\t%1
4768    #"
4769   [(set_attr "type" "fmov,multi")
4770    (set_attr "mode" "XF")
4771    (set_attr "fp_int_src" "true")])
4773 (define_insn "floatdixf2"
4774   [(set (match_operand:XF 0 "register_operand" "=f,f")
4775         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4776   "TARGET_80387"
4777   "@
4778    fild%z1\t%1
4779    #"
4780   [(set_attr "type" "fmov,multi")
4781    (set_attr "mode" "XF")
4782    (set_attr "fp_int_src" "true")])
4784 ;; %%% Kill these when reload knows how to do it.
4785 (define_split
4786   [(set (match_operand 0 "fp_register_operand" "")
4787         (float (match_operand 1 "register_operand" "")))]
4788   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4789   [(const_int 0)]
4791   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4792   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4793   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4794   ix86_free_from_memory (GET_MODE (operands[1]));
4795   DONE;
4798 (define_expand "floatunssisf2"
4799   [(use (match_operand:SF 0 "register_operand" ""))
4800    (use (match_operand:SI 1 "register_operand" ""))]
4801   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4802   "x86_emit_floatuns (operands); DONE;")
4804 (define_expand "floatunsdisf2"
4805   [(use (match_operand:SF 0 "register_operand" ""))
4806    (use (match_operand:DI 1 "register_operand" ""))]
4807   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4808   "x86_emit_floatuns (operands); DONE;")
4810 (define_expand "floatunsdidf2"
4811   [(use (match_operand:DF 0 "register_operand" ""))
4812    (use (match_operand:DI 1 "register_operand" ""))]
4813   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4814   "x86_emit_floatuns (operands); DONE;")
4816 ;; SSE extract/set expanders
4818 (define_expand "vec_setv2df"
4819   [(match_operand:V2DF 0 "register_operand" "")
4820    (match_operand:DF 1 "register_operand" "")
4821    (match_operand 2 "const_int_operand" "")]
4822   "TARGET_SSE2"
4824   switch (INTVAL (operands[2]))
4825     {
4826     case 0:
4827       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4828                                  simplify_gen_subreg (V2DFmode, operands[1],
4829                                                       DFmode, 0)));
4830       break;
4831     case 1:
4832       {
4833         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4835         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4836       }
4837       break;
4838     default:
4839       abort ();
4840     }
4841   DONE;
4844 (define_expand "vec_extractv2df"
4845   [(match_operand:DF 0 "register_operand" "")
4846    (match_operand:V2DF 1 "register_operand" "")
4847    (match_operand 2 "const_int_operand" "")]
4848   "TARGET_SSE2"
4850   switch (INTVAL (operands[2]))
4851     {
4852     case 0:
4853       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4854       break;
4855     case 1:
4856       {
4857         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4859         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4860       }
4861       break;
4862     default:
4863       abort ();
4864     }
4865   DONE;
4868 (define_expand "vec_initv2df"
4869   [(match_operand:V2DF 0 "register_operand" "")
4870    (match_operand 1 "" "")]
4871   "TARGET_SSE2"
4873   ix86_expand_vector_init (operands[0], operands[1]);
4874   DONE;
4877 (define_expand "vec_setv4sf"
4878   [(match_operand:V4SF 0 "register_operand" "")
4879    (match_operand:SF 1 "register_operand" "")
4880    (match_operand 2 "const_int_operand" "")]
4881   "TARGET_SSE"
4883   switch (INTVAL (operands[2]))
4884     {
4885     case 0:
4886       emit_insn (gen_sse_movss (operands[0], operands[0],
4887                                 simplify_gen_subreg (V4SFmode, operands[1],
4888                                                      SFmode, 0)));
4889       break;
4890     case 1:
4891       {
4892         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4893         rtx tmp = gen_reg_rtx (V4SFmode);
4895         emit_move_insn (tmp, operands[0]);
4896         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4897         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4898         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4899                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4900       }
4901       break;
4902     case 2:
4903       {
4904         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4905         rtx tmp = gen_reg_rtx (V4SFmode);
4907         emit_move_insn (tmp, operands[0]);
4908         emit_insn (gen_sse_movss (tmp, tmp, op1));
4909         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4910                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4911       }
4912       break;
4913     case 3:
4914       {
4915         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4916         rtx tmp = gen_reg_rtx (V4SFmode);
4918         emit_move_insn (tmp, operands[0]);
4919         emit_insn (gen_sse_movss (tmp, tmp, op1));
4920         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4921                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4922       }
4923       break;
4924     default:
4925       abort ();
4926     }
4927   DONE;
4930 (define_expand "vec_extractv4sf"
4931   [(match_operand:SF 0 "register_operand" "")
4932    (match_operand:V4SF 1 "register_operand" "")
4933    (match_operand 2 "const_int_operand" "")]
4934   "TARGET_SSE"
4936   switch (INTVAL (operands[2]))
4937     {
4938     case 0:
4939       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4940       break;
4941     case 1:
4942       {
4943         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4944         rtx tmp = gen_reg_rtx (V4SFmode);
4946         emit_move_insn (tmp, operands[1]);
4947         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4948                                    const1_rtx));
4949       }
4950       break;
4951     case 2:
4952       {
4953         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4954         rtx tmp = gen_reg_rtx (V4SFmode);
4956         emit_move_insn (tmp, operands[1]);
4957         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4958       }
4959       break;
4960     case 3:
4961       {
4962         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4963         rtx tmp = gen_reg_rtx (V4SFmode);
4965         emit_move_insn (tmp, operands[1]);
4966         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4967                                    GEN_INT (3)));
4968       }
4969       break;
4970     default:
4971       abort ();
4972     }
4973   DONE;
4976 (define_expand "vec_initv4sf"
4977   [(match_operand:V4SF 0 "register_operand" "")
4978    (match_operand 1 "" "")]
4979   "TARGET_SSE"
4981   ix86_expand_vector_init (operands[0], operands[1]);
4982   DONE;
4985 ;; Add instructions
4987 ;; %%% splits for addsidi3
4988 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4989 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4990 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4992 (define_expand "adddi3"
4993   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4994         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4995                  (match_operand:DI 2 "x86_64_general_operand" "")))
4996    (clobber (reg:CC FLAGS_REG))]
4997   ""
4998   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5000 (define_insn "*adddi3_1"
5001   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5002         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5003                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5004    (clobber (reg:CC FLAGS_REG))]
5005   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5006   "#")
5008 (define_split
5009   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5010         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5011                  (match_operand:DI 2 "general_operand" "")))
5012    (clobber (reg:CC FLAGS_REG))]
5013   "!TARGET_64BIT && reload_completed"
5014   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5015                                           UNSPEC_ADD_CARRY))
5016               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5017    (parallel [(set (match_dup 3)
5018                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5019                                      (match_dup 4))
5020                             (match_dup 5)))
5021               (clobber (reg:CC FLAGS_REG))])]
5022   "split_di (operands+0, 1, operands+0, operands+3);
5023    split_di (operands+1, 1, operands+1, operands+4);
5024    split_di (operands+2, 1, operands+2, operands+5);")
5026 (define_insn "adddi3_carry_rex64"
5027   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5028           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5029                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5030                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5031    (clobber (reg:CC FLAGS_REG))]
5032   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5033   "adc{q}\t{%2, %0|%0, %2}"
5034   [(set_attr "type" "alu")
5035    (set_attr "pent_pair" "pu")
5036    (set_attr "mode" "DI")])
5038 (define_insn "*adddi3_cc_rex64"
5039   [(set (reg:CC FLAGS_REG)
5040         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5041                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5042                    UNSPEC_ADD_CARRY))
5043    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5044         (plus:DI (match_dup 1) (match_dup 2)))]
5045   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5046   "add{q}\t{%2, %0|%0, %2}"
5047   [(set_attr "type" "alu")
5048    (set_attr "mode" "DI")])
5050 (define_insn "addqi3_carry"
5051   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5052           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5053                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5054                    (match_operand:QI 2 "general_operand" "qi,qm")))
5055    (clobber (reg:CC FLAGS_REG))]
5056   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5057   "adc{b}\t{%2, %0|%0, %2}"
5058   [(set_attr "type" "alu")
5059    (set_attr "pent_pair" "pu")
5060    (set_attr "mode" "QI")])
5062 (define_insn "addhi3_carry"
5063   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5064           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5065                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5066                    (match_operand:HI 2 "general_operand" "ri,rm")))
5067    (clobber (reg:CC FLAGS_REG))]
5068   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5069   "adc{w}\t{%2, %0|%0, %2}"
5070   [(set_attr "type" "alu")
5071    (set_attr "pent_pair" "pu")
5072    (set_attr "mode" "HI")])
5074 (define_insn "addsi3_carry"
5075   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5076           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5077                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5078                    (match_operand:SI 2 "general_operand" "ri,rm")))
5079    (clobber (reg:CC FLAGS_REG))]
5080   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5081   "adc{l}\t{%2, %0|%0, %2}"
5082   [(set_attr "type" "alu")
5083    (set_attr "pent_pair" "pu")
5084    (set_attr "mode" "SI")])
5086 (define_insn "*addsi3_carry_zext"
5087   [(set (match_operand:DI 0 "register_operand" "=r")
5088           (zero_extend:DI 
5089             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5090                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5091                      (match_operand:SI 2 "general_operand" "rim"))))
5092    (clobber (reg:CC FLAGS_REG))]
5093   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5094   "adc{l}\t{%2, %k0|%k0, %2}"
5095   [(set_attr "type" "alu")
5096    (set_attr "pent_pair" "pu")
5097    (set_attr "mode" "SI")])
5099 (define_insn "*addsi3_cc"
5100   [(set (reg:CC FLAGS_REG)
5101         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5102                     (match_operand:SI 2 "general_operand" "ri,rm")]
5103                    UNSPEC_ADD_CARRY))
5104    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5105         (plus:SI (match_dup 1) (match_dup 2)))]
5106   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5107   "add{l}\t{%2, %0|%0, %2}"
5108   [(set_attr "type" "alu")
5109    (set_attr "mode" "SI")])
5111 (define_insn "addqi3_cc"
5112   [(set (reg:CC FLAGS_REG)
5113         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5114                     (match_operand:QI 2 "general_operand" "qi,qm")]
5115                    UNSPEC_ADD_CARRY))
5116    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5117         (plus:QI (match_dup 1) (match_dup 2)))]
5118   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5119   "add{b}\t{%2, %0|%0, %2}"
5120   [(set_attr "type" "alu")
5121    (set_attr "mode" "QI")])
5123 (define_expand "addsi3"
5124   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5125                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5126                             (match_operand:SI 2 "general_operand" "")))
5127               (clobber (reg:CC FLAGS_REG))])]
5128   ""
5129   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5131 (define_insn "*lea_1"
5132   [(set (match_operand:SI 0 "register_operand" "=r")
5133         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5134   "!TARGET_64BIT"
5135   "lea{l}\t{%a1, %0|%0, %a1}"
5136   [(set_attr "type" "lea")
5137    (set_attr "mode" "SI")])
5139 (define_insn "*lea_1_rex64"
5140   [(set (match_operand:SI 0 "register_operand" "=r")
5141         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5142   "TARGET_64BIT"
5143   "lea{l}\t{%a1, %0|%0, %a1}"
5144   [(set_attr "type" "lea")
5145    (set_attr "mode" "SI")])
5147 (define_insn "*lea_1_zext"
5148   [(set (match_operand:DI 0 "register_operand" "=r")
5149         (zero_extend:DI
5150          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5151   "TARGET_64BIT"
5152   "lea{l}\t{%a1, %k0|%k0, %a1}"
5153   [(set_attr "type" "lea")
5154    (set_attr "mode" "SI")])
5156 (define_insn "*lea_2_rex64"
5157   [(set (match_operand:DI 0 "register_operand" "=r")
5158         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5159   "TARGET_64BIT"
5160   "lea{q}\t{%a1, %0|%0, %a1}"
5161   [(set_attr "type" "lea")
5162    (set_attr "mode" "DI")])
5164 ;; The lea patterns for non-Pmodes needs to be matched by several
5165 ;; insns converted to real lea by splitters.
5167 (define_insn_and_split "*lea_general_1"
5168   [(set (match_operand 0 "register_operand" "=r")
5169         (plus (plus (match_operand 1 "index_register_operand" "r")
5170                     (match_operand 2 "register_operand" "r"))
5171               (match_operand 3 "immediate_operand" "i")))]
5172   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5173     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5174    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5175    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5176    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5177    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5178        || GET_MODE (operands[3]) == VOIDmode)"
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[2] = gen_lowpart (Pmode, operands[2]);
5187   operands[3] = gen_lowpart (Pmode, operands[3]);
5188   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5189                       operands[3]);
5190   if (Pmode != SImode)
5191     pat = gen_rtx_SUBREG (SImode, pat, 0);
5192   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5193   DONE;
5195   [(set_attr "type" "lea")
5196    (set_attr "mode" "SI")])
5198 (define_insn_and_split "*lea_general_1_zext"
5199   [(set (match_operand:DI 0 "register_operand" "=r")
5200         (zero_extend:DI
5201           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5202                             (match_operand:SI 2 "register_operand" "r"))
5203                    (match_operand:SI 3 "immediate_operand" "i"))))]
5204   "TARGET_64BIT"
5205   "#"
5206   "&& reload_completed"
5207   [(set (match_dup 0)
5208         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5209                                                      (match_dup 2))
5210                                             (match_dup 3)) 0)))]
5212   operands[1] = gen_lowpart (Pmode, operands[1]);
5213   operands[2] = gen_lowpart (Pmode, operands[2]);
5214   operands[3] = gen_lowpart (Pmode, operands[3]);
5216   [(set_attr "type" "lea")
5217    (set_attr "mode" "SI")])
5219 (define_insn_and_split "*lea_general_2"
5220   [(set (match_operand 0 "register_operand" "=r")
5221         (plus (mult (match_operand 1 "index_register_operand" "r")
5222                     (match_operand 2 "const248_operand" "i"))
5223               (match_operand 3 "nonmemory_operand" "ri")))]
5224   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5225     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5226    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5227    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5228    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5229        || GET_MODE (operands[3]) == VOIDmode)"
5230   "#"
5231   "&& reload_completed"
5232   [(const_int 0)]
5234   rtx pat;
5235   operands[0] = gen_lowpart (SImode, operands[0]);
5236   operands[1] = gen_lowpart (Pmode, operands[1]);
5237   operands[3] = gen_lowpart (Pmode, operands[3]);
5238   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5239                       operands[3]);
5240   if (Pmode != SImode)
5241     pat = gen_rtx_SUBREG (SImode, pat, 0);
5242   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5243   DONE;
5245   [(set_attr "type" "lea")
5246    (set_attr "mode" "SI")])
5248 (define_insn_and_split "*lea_general_2_zext"
5249   [(set (match_operand:DI 0 "register_operand" "=r")
5250         (zero_extend:DI
5251           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5252                             (match_operand:SI 2 "const248_operand" "n"))
5253                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5254   "TARGET_64BIT"
5255   "#"
5256   "&& reload_completed"
5257   [(set (match_dup 0)
5258         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5259                                                      (match_dup 2))
5260                                             (match_dup 3)) 0)))]
5262   operands[1] = gen_lowpart (Pmode, operands[1]);
5263   operands[3] = gen_lowpart (Pmode, operands[3]);
5265   [(set_attr "type" "lea")
5266    (set_attr "mode" "SI")])
5268 (define_insn_and_split "*lea_general_3"
5269   [(set (match_operand 0 "register_operand" "=r")
5270         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5271                           (match_operand 2 "const248_operand" "i"))
5272                     (match_operand 3 "register_operand" "r"))
5273               (match_operand 4 "immediate_operand" "i")))]
5274   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5275     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5276    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5277    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5278    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5279   "#"
5280   "&& reload_completed"
5281   [(const_int 0)]
5283   rtx pat;
5284   operands[0] = gen_lowpart (SImode, operands[0]);
5285   operands[1] = gen_lowpart (Pmode, operands[1]);
5286   operands[3] = gen_lowpart (Pmode, operands[3]);
5287   operands[4] = gen_lowpart (Pmode, operands[4]);
5288   pat = gen_rtx_PLUS (Pmode,
5289                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5290                                                          operands[2]),
5291                                     operands[3]),
5292                       operands[4]);
5293   if (Pmode != SImode)
5294     pat = gen_rtx_SUBREG (SImode, pat, 0);
5295   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5296   DONE;
5298   [(set_attr "type" "lea")
5299    (set_attr "mode" "SI")])
5301 (define_insn_and_split "*lea_general_3_zext"
5302   [(set (match_operand:DI 0 "register_operand" "=r")
5303         (zero_extend:DI
5304           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5305                                      (match_operand:SI 2 "const248_operand" "n"))
5306                             (match_operand:SI 3 "register_operand" "r"))
5307                    (match_operand:SI 4 "immediate_operand" "i"))))]
5308   "TARGET_64BIT"
5309   "#"
5310   "&& reload_completed"
5311   [(set (match_dup 0)
5312         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5313                                                               (match_dup 2))
5314                                                      (match_dup 3))
5315                                             (match_dup 4)) 0)))]
5317   operands[1] = gen_lowpart (Pmode, operands[1]);
5318   operands[3] = gen_lowpart (Pmode, operands[3]);
5319   operands[4] = gen_lowpart (Pmode, operands[4]);
5321   [(set_attr "type" "lea")
5322    (set_attr "mode" "SI")])
5324 (define_insn "*adddi_1_rex64"
5325   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5326         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5327                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5328    (clobber (reg:CC FLAGS_REG))]
5329   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5331   switch (get_attr_type (insn))
5332     {
5333     case TYPE_LEA:
5334       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5335       return "lea{q}\t{%a2, %0|%0, %a2}";
5337     case TYPE_INCDEC:
5338       if (! rtx_equal_p (operands[0], operands[1]))
5339         abort ();
5340       if (operands[2] == const1_rtx)
5341         return "inc{q}\t%0";
5342       else if (operands[2] == constm1_rtx)
5343         return "dec{q}\t%0";
5344       else
5345         abort ();
5347     default:
5348       if (! rtx_equal_p (operands[0], operands[1]))
5349         abort ();
5351       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5352          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5353       if (GET_CODE (operands[2]) == CONST_INT
5354           /* Avoid overflows.  */
5355           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5356           && (INTVAL (operands[2]) == 128
5357               || (INTVAL (operands[2]) < 0
5358                   && INTVAL (operands[2]) != -128)))
5359         {
5360           operands[2] = GEN_INT (-INTVAL (operands[2]));
5361           return "sub{q}\t{%2, %0|%0, %2}";
5362         }
5363       return "add{q}\t{%2, %0|%0, %2}";
5364     }
5366   [(set (attr "type")
5367      (cond [(eq_attr "alternative" "2")
5368               (const_string "lea")
5369             ; Current assemblers are broken and do not allow @GOTOFF in
5370             ; ought but a memory context.
5371             (match_operand:DI 2 "pic_symbolic_operand" "")
5372               (const_string "lea")
5373             (match_operand:DI 2 "incdec_operand" "")
5374               (const_string "incdec")
5375            ]
5376            (const_string "alu")))
5377    (set_attr "mode" "DI")])
5379 ;; Convert lea to the lea pattern to avoid flags dependency.
5380 (define_split
5381   [(set (match_operand:DI 0 "register_operand" "")
5382         (plus:DI (match_operand:DI 1 "register_operand" "")
5383                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5384    (clobber (reg:CC FLAGS_REG))]
5385   "TARGET_64BIT && reload_completed
5386    && true_regnum (operands[0]) != true_regnum (operands[1])"
5387   [(set (match_dup 0)
5388         (plus:DI (match_dup 1)
5389                  (match_dup 2)))]
5390   "")
5392 (define_insn "*adddi_2_rex64"
5393   [(set (reg 17)
5394         (compare
5395           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5396                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5397           (const_int 0)))                       
5398    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5399         (plus:DI (match_dup 1) (match_dup 2)))]
5400   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5401    && ix86_binary_operator_ok (PLUS, DImode, operands)
5402    /* Current assemblers are broken and do not allow @GOTOFF in
5403       ought but a memory context.  */
5404    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5406   switch (get_attr_type (insn))
5407     {
5408     case TYPE_INCDEC:
5409       if (! rtx_equal_p (operands[0], operands[1]))
5410         abort ();
5411       if (operands[2] == const1_rtx)
5412         return "inc{q}\t%0";
5413       else if (operands[2] == constm1_rtx)
5414         return "dec{q}\t%0";
5415       else
5416         abort ();
5418     default:
5419       if (! rtx_equal_p (operands[0], operands[1]))
5420         abort ();
5421       /* ???? We ought to handle there the 32bit case too
5422          - do we need new constraint?  */
5423       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5424          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5425       if (GET_CODE (operands[2]) == CONST_INT
5426           /* Avoid overflows.  */
5427           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5428           && (INTVAL (operands[2]) == 128
5429               || (INTVAL (operands[2]) < 0
5430                   && INTVAL (operands[2]) != -128)))
5431         {
5432           operands[2] = GEN_INT (-INTVAL (operands[2]));
5433           return "sub{q}\t{%2, %0|%0, %2}";
5434         }
5435       return "add{q}\t{%2, %0|%0, %2}";
5436     }
5438   [(set (attr "type")
5439      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5440         (const_string "incdec")
5441         (const_string "alu")))
5442    (set_attr "mode" "DI")])
5444 (define_insn "*adddi_3_rex64"
5445   [(set (reg 17)
5446         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5447                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5448    (clobber (match_scratch:DI 0 "=r"))]
5449   "TARGET_64BIT
5450    && ix86_match_ccmode (insn, CCZmode)
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       /* ???? We ought to handle there the 32bit case too
5472          - do we need new constraint?  */
5473       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5474          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5475       if (GET_CODE (operands[2]) == CONST_INT
5476           /* Avoid overflows.  */
5477           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5478           && (INTVAL (operands[2]) == 128
5479               || (INTVAL (operands[2]) < 0
5480                   && INTVAL (operands[2]) != -128)))
5481         {
5482           operands[2] = GEN_INT (-INTVAL (operands[2]));
5483           return "sub{q}\t{%2, %0|%0, %2}";
5484         }
5485       return "add{q}\t{%2, %0|%0, %2}";
5486     }
5488   [(set (attr "type")
5489      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5490         (const_string "incdec")
5491         (const_string "alu")))
5492    (set_attr "mode" "DI")])
5494 ; For comparisons against 1, -1 and 128, we may generate better code
5495 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5496 ; is matched then.  We can't accept general immediate, because for
5497 ; case of overflows,  the result is messed up.
5498 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5499 ; when negated.
5500 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5501 ; only for comparisons not depending on it.
5502 (define_insn "*adddi_4_rex64"
5503   [(set (reg 17)
5504         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5505                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5506    (clobber (match_scratch:DI 0 "=rm"))]
5507   "TARGET_64BIT
5508    &&  ix86_match_ccmode (insn, CCGCmode)"
5510   switch (get_attr_type (insn))
5511     {
5512     case TYPE_INCDEC:
5513       if (operands[2] == constm1_rtx)
5514         return "inc{q}\t%0";
5515       else if (operands[2] == const1_rtx)
5516         return "dec{q}\t%0";
5517       else
5518         abort();
5520     default:
5521       if (! rtx_equal_p (operands[0], operands[1]))
5522         abort ();
5523       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5524          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5525       if ((INTVAL (operands[2]) == -128
5526            || (INTVAL (operands[2]) > 0
5527                && INTVAL (operands[2]) != 128))
5528           /* Avoid overflows.  */
5529           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5530         return "sub{q}\t{%2, %0|%0, %2}";
5531       operands[2] = GEN_INT (-INTVAL (operands[2]));
5532       return "add{q}\t{%2, %0|%0, %2}";
5533     }
5535   [(set (attr "type")
5536      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5537         (const_string "incdec")
5538         (const_string "alu")))
5539    (set_attr "mode" "DI")])
5541 (define_insn "*adddi_5_rex64"
5542   [(set (reg 17)
5543         (compare
5544           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5545                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5546           (const_int 0)))                       
5547    (clobber (match_scratch:DI 0 "=r"))]
5548   "TARGET_64BIT
5549    && ix86_match_ccmode (insn, CCGOCmode)
5550    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5551    /* Current assemblers are broken and do not allow @GOTOFF in
5552       ought but a memory context.  */
5553    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555   switch (get_attr_type (insn))
5556     {
5557     case TYPE_INCDEC:
5558       if (! rtx_equal_p (operands[0], operands[1]))
5559         abort ();
5560       if (operands[2] == const1_rtx)
5561         return "inc{q}\t%0";
5562       else if (operands[2] == constm1_rtx)
5563         return "dec{q}\t%0";
5564       else
5565         abort();
5567     default:
5568       if (! rtx_equal_p (operands[0], operands[1]))
5569         abort ();
5570       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5571          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5572       if (GET_CODE (operands[2]) == CONST_INT
5573           /* Avoid overflows.  */
5574           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5575           && (INTVAL (operands[2]) == 128
5576               || (INTVAL (operands[2]) < 0
5577                   && INTVAL (operands[2]) != -128)))
5578         {
5579           operands[2] = GEN_INT (-INTVAL (operands[2]));
5580           return "sub{q}\t{%2, %0|%0, %2}";
5581         }
5582       return "add{q}\t{%2, %0|%0, %2}";
5583     }
5585   [(set (attr "type")
5586      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5587         (const_string "incdec")
5588         (const_string "alu")))
5589    (set_attr "mode" "DI")])
5592 (define_insn "*addsi_1"
5593   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5594         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5595                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5596    (clobber (reg:CC FLAGS_REG))]
5597   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5599   switch (get_attr_type (insn))
5600     {
5601     case TYPE_LEA:
5602       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5603       return "lea{l}\t{%a2, %0|%0, %a2}";
5605     case TYPE_INCDEC:
5606       if (! rtx_equal_p (operands[0], operands[1]))
5607         abort ();
5608       if (operands[2] == const1_rtx)
5609         return "inc{l}\t%0";
5610       else if (operands[2] == constm1_rtx)
5611         return "dec{l}\t%0";
5612       else
5613         abort();
5615     default:
5616       if (! rtx_equal_p (operands[0], operands[1]))
5617         abort ();
5619       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5620          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5621       if (GET_CODE (operands[2]) == CONST_INT
5622           && (INTVAL (operands[2]) == 128
5623               || (INTVAL (operands[2]) < 0
5624                   && INTVAL (operands[2]) != -128)))
5625         {
5626           operands[2] = GEN_INT (-INTVAL (operands[2]));
5627           return "sub{l}\t{%2, %0|%0, %2}";
5628         }
5629       return "add{l}\t{%2, %0|%0, %2}";
5630     }
5632   [(set (attr "type")
5633      (cond [(eq_attr "alternative" "2")
5634               (const_string "lea")
5635             ; Current assemblers are broken and do not allow @GOTOFF in
5636             ; ought but a memory context.
5637             (match_operand:SI 2 "pic_symbolic_operand" "")
5638               (const_string "lea")
5639             (match_operand:SI 2 "incdec_operand" "")
5640               (const_string "incdec")
5641            ]
5642            (const_string "alu")))
5643    (set_attr "mode" "SI")])
5645 ;; Convert lea to the lea pattern to avoid flags dependency.
5646 (define_split
5647   [(set (match_operand 0 "register_operand" "")
5648         (plus (match_operand 1 "register_operand" "")
5649               (match_operand 2 "nonmemory_operand" "")))
5650    (clobber (reg:CC FLAGS_REG))]
5651   "reload_completed
5652    && true_regnum (operands[0]) != true_regnum (operands[1])"
5653   [(const_int 0)]
5655   rtx pat;
5656   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5657      may confuse gen_lowpart.  */
5658   if (GET_MODE (operands[0]) != Pmode)
5659     {
5660       operands[1] = gen_lowpart (Pmode, operands[1]);
5661       operands[2] = gen_lowpart (Pmode, operands[2]);
5662     }
5663   operands[0] = gen_lowpart (SImode, operands[0]);
5664   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5665   if (Pmode != SImode)
5666     pat = gen_rtx_SUBREG (SImode, pat, 0);
5667   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5668   DONE;
5671 ;; It may seem that nonimmediate operand is proper one for operand 1.
5672 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5673 ;; we take care in ix86_binary_operator_ok to not allow two memory
5674 ;; operands so proper swapping will be done in reload.  This allow
5675 ;; patterns constructed from addsi_1 to match.
5676 (define_insn "addsi_1_zext"
5677   [(set (match_operand:DI 0 "register_operand" "=r,r")
5678         (zero_extend:DI
5679           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5680                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5681    (clobber (reg:CC FLAGS_REG))]
5682   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5684   switch (get_attr_type (insn))
5685     {
5686     case TYPE_LEA:
5687       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5688       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5690     case TYPE_INCDEC:
5691       if (operands[2] == const1_rtx)
5692         return "inc{l}\t%k0";
5693       else if (operands[2] == constm1_rtx)
5694         return "dec{l}\t%k0";
5695       else
5696         abort();
5698     default:
5699       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5700          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5701       if (GET_CODE (operands[2]) == CONST_INT
5702           && (INTVAL (operands[2]) == 128
5703               || (INTVAL (operands[2]) < 0
5704                   && INTVAL (operands[2]) != -128)))
5705         {
5706           operands[2] = GEN_INT (-INTVAL (operands[2]));
5707           return "sub{l}\t{%2, %k0|%k0, %2}";
5708         }
5709       return "add{l}\t{%2, %k0|%k0, %2}";
5710     }
5712   [(set (attr "type")
5713      (cond [(eq_attr "alternative" "1")
5714               (const_string "lea")
5715             ; Current assemblers are broken and do not allow @GOTOFF in
5716             ; ought but a memory context.
5717             (match_operand:SI 2 "pic_symbolic_operand" "")
5718               (const_string "lea")
5719             (match_operand:SI 2 "incdec_operand" "")
5720               (const_string "incdec")
5721            ]
5722            (const_string "alu")))
5723    (set_attr "mode" "SI")])
5725 ;; Convert lea to the lea pattern to avoid flags dependency.
5726 (define_split
5727   [(set (match_operand:DI 0 "register_operand" "")
5728         (zero_extend:DI
5729           (plus:SI (match_operand:SI 1 "register_operand" "")
5730                    (match_operand:SI 2 "nonmemory_operand" ""))))
5731    (clobber (reg:CC FLAGS_REG))]
5732   "TARGET_64BIT && reload_completed
5733    && true_regnum (operands[0]) != true_regnum (operands[1])"
5734   [(set (match_dup 0)
5735         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5737   operands[1] = gen_lowpart (Pmode, operands[1]);
5738   operands[2] = gen_lowpart (Pmode, operands[2]);
5741 (define_insn "*addsi_2"
5742   [(set (reg 17)
5743         (compare
5744           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5745                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5746           (const_int 0)))                       
5747    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5748         (plus:SI (match_dup 1) (match_dup 2)))]
5749   "ix86_match_ccmode (insn, CCGOCmode)
5750    && ix86_binary_operator_ok (PLUS, SImode, operands)
5751    /* Current assemblers are broken and do not allow @GOTOFF in
5752       ought but a memory context.  */
5753    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5755   switch (get_attr_type (insn))
5756     {
5757     case TYPE_INCDEC:
5758       if (! rtx_equal_p (operands[0], operands[1]))
5759         abort ();
5760       if (operands[2] == const1_rtx)
5761         return "inc{l}\t%0";
5762       else if (operands[2] == constm1_rtx)
5763         return "dec{l}\t%0";
5764       else
5765         abort();
5767     default:
5768       if (! rtx_equal_p (operands[0], operands[1]))
5769         abort ();
5770       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5771          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5772       if (GET_CODE (operands[2]) == CONST_INT
5773           && (INTVAL (operands[2]) == 128
5774               || (INTVAL (operands[2]) < 0
5775                   && INTVAL (operands[2]) != -128)))
5776         {
5777           operands[2] = GEN_INT (-INTVAL (operands[2]));
5778           return "sub{l}\t{%2, %0|%0, %2}";
5779         }
5780       return "add{l}\t{%2, %0|%0, %2}";
5781     }
5783   [(set (attr "type")
5784      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5785         (const_string "incdec")
5786         (const_string "alu")))
5787    (set_attr "mode" "SI")])
5789 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5790 (define_insn "*addsi_2_zext"
5791   [(set (reg 17)
5792         (compare
5793           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5794                    (match_operand:SI 2 "general_operand" "rmni"))
5795           (const_int 0)))                       
5796    (set (match_operand:DI 0 "register_operand" "=r")
5797         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5798   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5799    && ix86_binary_operator_ok (PLUS, SImode, operands)
5800    /* Current assemblers are broken and do not allow @GOTOFF in
5801       ought but a memory context.  */
5802    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5804   switch (get_attr_type (insn))
5805     {
5806     case TYPE_INCDEC:
5807       if (operands[2] == const1_rtx)
5808         return "inc{l}\t%k0";
5809       else if (operands[2] == constm1_rtx)
5810         return "dec{l}\t%k0";
5811       else
5812         abort();
5814     default:
5815       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5816          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5817       if (GET_CODE (operands[2]) == CONST_INT
5818           && (INTVAL (operands[2]) == 128
5819               || (INTVAL (operands[2]) < 0
5820                   && INTVAL (operands[2]) != -128)))
5821         {
5822           operands[2] = GEN_INT (-INTVAL (operands[2]));
5823           return "sub{l}\t{%2, %k0|%k0, %2}";
5824         }
5825       return "add{l}\t{%2, %k0|%k0, %2}";
5826     }
5828   [(set (attr "type")
5829      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5830         (const_string "incdec")
5831         (const_string "alu")))
5832    (set_attr "mode" "SI")])
5834 (define_insn "*addsi_3"
5835   [(set (reg 17)
5836         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5837                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5838    (clobber (match_scratch:SI 0 "=r"))]
5839   "ix86_match_ccmode (insn, CCZmode)
5840    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5841    /* Current assemblers are broken and do not allow @GOTOFF in
5842       ought but a memory context.  */
5843    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5845   switch (get_attr_type (insn))
5846     {
5847     case TYPE_INCDEC:
5848       if (! rtx_equal_p (operands[0], operands[1]))
5849         abort ();
5850       if (operands[2] == const1_rtx)
5851         return "inc{l}\t%0";
5852       else if (operands[2] == constm1_rtx)
5853         return "dec{l}\t%0";
5854       else
5855         abort();
5857     default:
5858       if (! rtx_equal_p (operands[0], operands[1]))
5859         abort ();
5860       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5861          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5862       if (GET_CODE (operands[2]) == CONST_INT
5863           && (INTVAL (operands[2]) == 128
5864               || (INTVAL (operands[2]) < 0
5865                   && INTVAL (operands[2]) != -128)))
5866         {
5867           operands[2] = GEN_INT (-INTVAL (operands[2]));
5868           return "sub{l}\t{%2, %0|%0, %2}";
5869         }
5870       return "add{l}\t{%2, %0|%0, %2}";
5871     }
5873   [(set (attr "type")
5874      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5875         (const_string "incdec")
5876         (const_string "alu")))
5877    (set_attr "mode" "SI")])
5879 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5880 (define_insn "*addsi_3_zext"
5881   [(set (reg 17)
5882         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5883                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5884    (set (match_operand:DI 0 "register_operand" "=r")
5885         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5886   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5887    && ix86_binary_operator_ok (PLUS, SImode, operands)
5888    /* Current assemblers are broken and do not allow @GOTOFF in
5889       ought but a memory context.  */
5890    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5892   switch (get_attr_type (insn))
5893     {
5894     case TYPE_INCDEC:
5895       if (operands[2] == const1_rtx)
5896         return "inc{l}\t%k0";
5897       else if (operands[2] == constm1_rtx)
5898         return "dec{l}\t%k0";
5899       else
5900         abort();
5902     default:
5903       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5904          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5905       if (GET_CODE (operands[2]) == CONST_INT
5906           && (INTVAL (operands[2]) == 128
5907               || (INTVAL (operands[2]) < 0
5908                   && INTVAL (operands[2]) != -128)))
5909         {
5910           operands[2] = GEN_INT (-INTVAL (operands[2]));
5911           return "sub{l}\t{%2, %k0|%k0, %2}";
5912         }
5913       return "add{l}\t{%2, %k0|%k0, %2}";
5914     }
5916   [(set (attr "type")
5917      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5918         (const_string "incdec")
5919         (const_string "alu")))
5920    (set_attr "mode" "SI")])
5922 ; For comparisons against 1, -1 and 128, we may generate better code
5923 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5924 ; is matched then.  We can't accept general immediate, because for
5925 ; case of overflows,  the result is messed up.
5926 ; This pattern also don't hold of 0x80000000, since the value overflows
5927 ; when negated.
5928 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5929 ; only for comparisons not depending on it.
5930 (define_insn "*addsi_4"
5931   [(set (reg 17)
5932         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5933                  (match_operand:SI 2 "const_int_operand" "n")))
5934    (clobber (match_scratch:SI 0 "=rm"))]
5935   "ix86_match_ccmode (insn, CCGCmode)
5936    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5938   switch (get_attr_type (insn))
5939     {
5940     case TYPE_INCDEC:
5941       if (operands[2] == constm1_rtx)
5942         return "inc{l}\t%0";
5943       else if (operands[2] == const1_rtx)
5944         return "dec{l}\t%0";
5945       else
5946         abort();
5948     default:
5949       if (! rtx_equal_p (operands[0], operands[1]))
5950         abort ();
5951       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5952          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5953       if ((INTVAL (operands[2]) == -128
5954            || (INTVAL (operands[2]) > 0
5955                && INTVAL (operands[2]) != 128)))
5956         return "sub{l}\t{%2, %0|%0, %2}";
5957       operands[2] = GEN_INT (-INTVAL (operands[2]));
5958       return "add{l}\t{%2, %0|%0, %2}";
5959     }
5961   [(set (attr "type")
5962      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5963         (const_string "incdec")
5964         (const_string "alu")))
5965    (set_attr "mode" "SI")])
5967 (define_insn "*addsi_5"
5968   [(set (reg 17)
5969         (compare
5970           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5971                    (match_operand:SI 2 "general_operand" "rmni"))
5972           (const_int 0)))                       
5973    (clobber (match_scratch:SI 0 "=r"))]
5974   "ix86_match_ccmode (insn, CCGOCmode)
5975    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5976    /* Current assemblers are broken and do not allow @GOTOFF in
5977       ought but a memory context.  */
5978    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5980   switch (get_attr_type (insn))
5981     {
5982     case TYPE_INCDEC:
5983       if (! rtx_equal_p (operands[0], operands[1]))
5984         abort ();
5985       if (operands[2] == const1_rtx)
5986         return "inc{l}\t%0";
5987       else if (operands[2] == constm1_rtx)
5988         return "dec{l}\t%0";
5989       else
5990         abort();
5992     default:
5993       if (! rtx_equal_p (operands[0], operands[1]))
5994         abort ();
5995       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5997       if (GET_CODE (operands[2]) == CONST_INT
5998           && (INTVAL (operands[2]) == 128
5999               || (INTVAL (operands[2]) < 0
6000                   && INTVAL (operands[2]) != -128)))
6001         {
6002           operands[2] = GEN_INT (-INTVAL (operands[2]));
6003           return "sub{l}\t{%2, %0|%0, %2}";
6004         }
6005       return "add{l}\t{%2, %0|%0, %2}";
6006     }
6008   [(set (attr "type")
6009      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6010         (const_string "incdec")
6011         (const_string "alu")))
6012    (set_attr "mode" "SI")])
6014 (define_expand "addhi3"
6015   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6016                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6017                             (match_operand:HI 2 "general_operand" "")))
6018               (clobber (reg:CC FLAGS_REG))])]
6019   "TARGET_HIMODE_MATH"
6020   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6022 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6023 ;; type optimizations enabled by define-splits.  This is not important
6024 ;; for PII, and in fact harmful because of partial register stalls.
6026 (define_insn "*addhi_1_lea"
6027   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6028         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6029                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6030    (clobber (reg:CC FLAGS_REG))]
6031   "!TARGET_PARTIAL_REG_STALL
6032    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6034   switch (get_attr_type (insn))
6035     {
6036     case TYPE_LEA:
6037       return "#";
6038     case TYPE_INCDEC:
6039       if (operands[2] == const1_rtx)
6040         return "inc{w}\t%0";
6041       else if (operands[2] == constm1_rtx)
6042         return "dec{w}\t%0";
6043       abort();
6045     default:
6046       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6047          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6048       if (GET_CODE (operands[2]) == CONST_INT
6049           && (INTVAL (operands[2]) == 128
6050               || (INTVAL (operands[2]) < 0
6051                   && INTVAL (operands[2]) != -128)))
6052         {
6053           operands[2] = GEN_INT (-INTVAL (operands[2]));
6054           return "sub{w}\t{%2, %0|%0, %2}";
6055         }
6056       return "add{w}\t{%2, %0|%0, %2}";
6057     }
6059   [(set (attr "type")
6060      (if_then_else (eq_attr "alternative" "2")
6061         (const_string "lea")
6062         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6063            (const_string "incdec")
6064            (const_string "alu"))))
6065    (set_attr "mode" "HI,HI,SI")])
6067 (define_insn "*addhi_1"
6068   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6069         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6070                  (match_operand:HI 2 "general_operand" "ri,rm")))
6071    (clobber (reg:CC FLAGS_REG))]
6072   "TARGET_PARTIAL_REG_STALL
6073    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6075   switch (get_attr_type (insn))
6076     {
6077     case TYPE_INCDEC:
6078       if (operands[2] == const1_rtx)
6079         return "inc{w}\t%0";
6080       else if (operands[2] == constm1_rtx)
6081         return "dec{w}\t%0";
6082       abort();
6084     default:
6085       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6087       if (GET_CODE (operands[2]) == CONST_INT
6088           && (INTVAL (operands[2]) == 128
6089               || (INTVAL (operands[2]) < 0
6090                   && INTVAL (operands[2]) != -128)))
6091         {
6092           operands[2] = GEN_INT (-INTVAL (operands[2]));
6093           return "sub{w}\t{%2, %0|%0, %2}";
6094         }
6095       return "add{w}\t{%2, %0|%0, %2}";
6096     }
6098   [(set (attr "type")
6099      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6100         (const_string "incdec")
6101         (const_string "alu")))
6102    (set_attr "mode" "HI")])
6104 (define_insn "*addhi_2"
6105   [(set (reg 17)
6106         (compare
6107           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6108                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6109           (const_int 0)))                       
6110    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6111         (plus:HI (match_dup 1) (match_dup 2)))]
6112   "ix86_match_ccmode (insn, CCGOCmode)
6113    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6115   switch (get_attr_type (insn))
6116     {
6117     case TYPE_INCDEC:
6118       if (operands[2] == const1_rtx)
6119         return "inc{w}\t%0";
6120       else if (operands[2] == constm1_rtx)
6121         return "dec{w}\t%0";
6122       abort();
6124     default:
6125       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6127       if (GET_CODE (operands[2]) == CONST_INT
6128           && (INTVAL (operands[2]) == 128
6129               || (INTVAL (operands[2]) < 0
6130                   && INTVAL (operands[2]) != -128)))
6131         {
6132           operands[2] = GEN_INT (-INTVAL (operands[2]));
6133           return "sub{w}\t{%2, %0|%0, %2}";
6134         }
6135       return "add{w}\t{%2, %0|%0, %2}";
6136     }
6138   [(set (attr "type")
6139      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6140         (const_string "incdec")
6141         (const_string "alu")))
6142    (set_attr "mode" "HI")])
6144 (define_insn "*addhi_3"
6145   [(set (reg 17)
6146         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6147                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6148    (clobber (match_scratch:HI 0 "=r"))]
6149   "ix86_match_ccmode (insn, CCZmode)
6150    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6152   switch (get_attr_type (insn))
6153     {
6154     case TYPE_INCDEC:
6155       if (operands[2] == const1_rtx)
6156         return "inc{w}\t%0";
6157       else if (operands[2] == constm1_rtx)
6158         return "dec{w}\t%0";
6159       abort();
6161     default:
6162       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6163          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6164       if (GET_CODE (operands[2]) == CONST_INT
6165           && (INTVAL (operands[2]) == 128
6166               || (INTVAL (operands[2]) < 0
6167                   && INTVAL (operands[2]) != -128)))
6168         {
6169           operands[2] = GEN_INT (-INTVAL (operands[2]));
6170           return "sub{w}\t{%2, %0|%0, %2}";
6171         }
6172       return "add{w}\t{%2, %0|%0, %2}";
6173     }
6175   [(set (attr "type")
6176      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6177         (const_string "incdec")
6178         (const_string "alu")))
6179    (set_attr "mode" "HI")])
6181 ; See comments above addsi_3_imm for details.
6182 (define_insn "*addhi_4"
6183   [(set (reg 17)
6184         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6185                  (match_operand:HI 2 "const_int_operand" "n")))
6186    (clobber (match_scratch:HI 0 "=rm"))]
6187   "ix86_match_ccmode (insn, CCGCmode)
6188    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6190   switch (get_attr_type (insn))
6191     {
6192     case TYPE_INCDEC:
6193       if (operands[2] == constm1_rtx)
6194         return "inc{w}\t%0";
6195       else if (operands[2] == const1_rtx)
6196         return "dec{w}\t%0";
6197       else
6198         abort();
6200     default:
6201       if (! rtx_equal_p (operands[0], operands[1]))
6202         abort ();
6203       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6204          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6205       if ((INTVAL (operands[2]) == -128
6206            || (INTVAL (operands[2]) > 0
6207                && INTVAL (operands[2]) != 128)))
6208         return "sub{w}\t{%2, %0|%0, %2}";
6209       operands[2] = GEN_INT (-INTVAL (operands[2]));
6210       return "add{w}\t{%2, %0|%0, %2}";
6211     }
6213   [(set (attr "type")
6214      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6215         (const_string "incdec")
6216         (const_string "alu")))
6217    (set_attr "mode" "SI")])
6220 (define_insn "*addhi_5"
6221   [(set (reg 17)
6222         (compare
6223           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6224                    (match_operand:HI 2 "general_operand" "rmni"))
6225           (const_int 0)))                       
6226    (clobber (match_scratch:HI 0 "=r"))]
6227   "ix86_match_ccmode (insn, CCGOCmode)
6228    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6230   switch (get_attr_type (insn))
6231     {
6232     case TYPE_INCDEC:
6233       if (operands[2] == const1_rtx)
6234         return "inc{w}\t%0";
6235       else if (operands[2] == constm1_rtx)
6236         return "dec{w}\t%0";
6237       abort();
6239     default:
6240       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6241          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6242       if (GET_CODE (operands[2]) == CONST_INT
6243           && (INTVAL (operands[2]) == 128
6244               || (INTVAL (operands[2]) < 0
6245                   && INTVAL (operands[2]) != -128)))
6246         {
6247           operands[2] = GEN_INT (-INTVAL (operands[2]));
6248           return "sub{w}\t{%2, %0|%0, %2}";
6249         }
6250       return "add{w}\t{%2, %0|%0, %2}";
6251     }
6253   [(set (attr "type")
6254      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6255         (const_string "incdec")
6256         (const_string "alu")))
6257    (set_attr "mode" "HI")])
6259 (define_expand "addqi3"
6260   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6261                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6262                             (match_operand:QI 2 "general_operand" "")))
6263               (clobber (reg:CC FLAGS_REG))])]
6264   "TARGET_QIMODE_MATH"
6265   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6267 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6268 (define_insn "*addqi_1_lea"
6269   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6270         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6271                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6272    (clobber (reg:CC FLAGS_REG))]
6273   "!TARGET_PARTIAL_REG_STALL
6274    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6276   int widen = (which_alternative == 2);
6277   switch (get_attr_type (insn))
6278     {
6279     case TYPE_LEA:
6280       return "#";
6281     case TYPE_INCDEC:
6282       if (operands[2] == const1_rtx)
6283         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6284       else if (operands[2] == constm1_rtx)
6285         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6286       abort();
6288     default:
6289       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6290          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6291       if (GET_CODE (operands[2]) == CONST_INT
6292           && (INTVAL (operands[2]) == 128
6293               || (INTVAL (operands[2]) < 0
6294                   && INTVAL (operands[2]) != -128)))
6295         {
6296           operands[2] = GEN_INT (-INTVAL (operands[2]));
6297           if (widen)
6298             return "sub{l}\t{%2, %k0|%k0, %2}";
6299           else
6300             return "sub{b}\t{%2, %0|%0, %2}";
6301         }
6302       if (widen)
6303         return "add{l}\t{%k2, %k0|%k0, %k2}";
6304       else
6305         return "add{b}\t{%2, %0|%0, %2}";
6306     }
6308   [(set (attr "type")
6309      (if_then_else (eq_attr "alternative" "3")
6310         (const_string "lea")
6311         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6312            (const_string "incdec")
6313            (const_string "alu"))))
6314    (set_attr "mode" "QI,QI,SI,SI")])
6316 (define_insn "*addqi_1"
6317   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6318         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6319                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6320    (clobber (reg:CC FLAGS_REG))]
6321   "TARGET_PARTIAL_REG_STALL
6322    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6324   int widen = (which_alternative == 2);
6325   switch (get_attr_type (insn))
6326     {
6327     case TYPE_INCDEC:
6328       if (operands[2] == const1_rtx)
6329         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6330       else if (operands[2] == constm1_rtx)
6331         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6332       abort();
6334     default:
6335       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6336          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6337       if (GET_CODE (operands[2]) == CONST_INT
6338           && (INTVAL (operands[2]) == 128
6339               || (INTVAL (operands[2]) < 0
6340                   && INTVAL (operands[2]) != -128)))
6341         {
6342           operands[2] = GEN_INT (-INTVAL (operands[2]));
6343           if (widen)
6344             return "sub{l}\t{%2, %k0|%k0, %2}";
6345           else
6346             return "sub{b}\t{%2, %0|%0, %2}";
6347         }
6348       if (widen)
6349         return "add{l}\t{%k2, %k0|%k0, %k2}";
6350       else
6351         return "add{b}\t{%2, %0|%0, %2}";
6352     }
6354   [(set (attr "type")
6355      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6356         (const_string "incdec")
6357         (const_string "alu")))
6358    (set_attr "mode" "QI,QI,SI")])
6360 (define_insn "*addqi_1_slp"
6361   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6362         (plus:QI (match_dup 0)
6363                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6364    (clobber (reg:CC FLAGS_REG))]
6365   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6366    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6368   switch (get_attr_type (insn))
6369     {
6370     case TYPE_INCDEC:
6371       if (operands[1] == const1_rtx)
6372         return "inc{b}\t%0";
6373       else if (operands[1] == constm1_rtx)
6374         return "dec{b}\t%0";
6375       abort();
6377     default:
6378       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6379       if (GET_CODE (operands[1]) == CONST_INT
6380           && INTVAL (operands[1]) < 0)
6381         {
6382           operands[1] = GEN_INT (-INTVAL (operands[1]));
6383           return "sub{b}\t{%1, %0|%0, %1}";
6384         }
6385       return "add{b}\t{%1, %0|%0, %1}";
6386     }
6388   [(set (attr "type")
6389      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6390         (const_string "incdec")
6391         (const_string "alu1")))
6392    (set_attr "mode" "QI")])
6394 (define_insn "*addqi_2"
6395   [(set (reg 17)
6396         (compare
6397           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6398                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6399           (const_int 0)))
6400    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6401         (plus:QI (match_dup 1) (match_dup 2)))]
6402   "ix86_match_ccmode (insn, CCGOCmode)
6403    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6405   switch (get_attr_type (insn))
6406     {
6407     case TYPE_INCDEC:
6408       if (operands[2] == const1_rtx)
6409         return "inc{b}\t%0";
6410       else if (operands[2] == constm1_rtx
6411                || (GET_CODE (operands[2]) == CONST_INT
6412                    && INTVAL (operands[2]) == 255))
6413         return "dec{b}\t%0";
6414       abort();
6416     default:
6417       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6418       if (GET_CODE (operands[2]) == CONST_INT
6419           && INTVAL (operands[2]) < 0)
6420         {
6421           operands[2] = GEN_INT (-INTVAL (operands[2]));
6422           return "sub{b}\t{%2, %0|%0, %2}";
6423         }
6424       return "add{b}\t{%2, %0|%0, %2}";
6425     }
6427   [(set (attr "type")
6428      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6429         (const_string "incdec")
6430         (const_string "alu")))
6431    (set_attr "mode" "QI")])
6433 (define_insn "*addqi_3"
6434   [(set (reg 17)
6435         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6436                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6437    (clobber (match_scratch:QI 0 "=q"))]
6438   "ix86_match_ccmode (insn, CCZmode)
6439    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6441   switch (get_attr_type (insn))
6442     {
6443     case TYPE_INCDEC:
6444       if (operands[2] == const1_rtx)
6445         return "inc{b}\t%0";
6446       else if (operands[2] == constm1_rtx
6447                || (GET_CODE (operands[2]) == CONST_INT
6448                    && INTVAL (operands[2]) == 255))
6449         return "dec{b}\t%0";
6450       abort();
6452     default:
6453       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6454       if (GET_CODE (operands[2]) == CONST_INT
6455           && INTVAL (operands[2]) < 0)
6456         {
6457           operands[2] = GEN_INT (-INTVAL (operands[2]));
6458           return "sub{b}\t{%2, %0|%0, %2}";
6459         }
6460       return "add{b}\t{%2, %0|%0, %2}";
6461     }
6463   [(set (attr "type")
6464      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6465         (const_string "incdec")
6466         (const_string "alu")))
6467    (set_attr "mode" "QI")])
6469 ; See comments above addsi_3_imm for details.
6470 (define_insn "*addqi_4"
6471   [(set (reg 17)
6472         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6473                  (match_operand:QI 2 "const_int_operand" "n")))
6474    (clobber (match_scratch:QI 0 "=qm"))]
6475   "ix86_match_ccmode (insn, CCGCmode)
6476    && (INTVAL (operands[2]) & 0xff) != 0x80"
6478   switch (get_attr_type (insn))
6479     {
6480     case TYPE_INCDEC:
6481       if (operands[2] == constm1_rtx
6482           || (GET_CODE (operands[2]) == CONST_INT
6483               && INTVAL (operands[2]) == 255))
6484         return "inc{b}\t%0";
6485       else if (operands[2] == const1_rtx)
6486         return "dec{b}\t%0";
6487       else
6488         abort();
6490     default:
6491       if (! rtx_equal_p (operands[0], operands[1]))
6492         abort ();
6493       if (INTVAL (operands[2]) < 0)
6494         {
6495           operands[2] = GEN_INT (-INTVAL (operands[2]));
6496           return "add{b}\t{%2, %0|%0, %2}";
6497         }
6498       return "sub{b}\t{%2, %0|%0, %2}";
6499     }
6501   [(set (attr "type")
6502      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6503         (const_string "incdec")
6504         (const_string "alu")))
6505    (set_attr "mode" "QI")])
6508 (define_insn "*addqi_5"
6509   [(set (reg 17)
6510         (compare
6511           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6512                    (match_operand:QI 2 "general_operand" "qmni"))
6513           (const_int 0)))
6514    (clobber (match_scratch:QI 0 "=q"))]
6515   "ix86_match_ccmode (insn, CCGOCmode)
6516    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6518   switch (get_attr_type (insn))
6519     {
6520     case TYPE_INCDEC:
6521       if (operands[2] == const1_rtx)
6522         return "inc{b}\t%0";
6523       else if (operands[2] == constm1_rtx
6524                || (GET_CODE (operands[2]) == CONST_INT
6525                    && INTVAL (operands[2]) == 255))
6526         return "dec{b}\t%0";
6527       abort();
6529     default:
6530       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6531       if (GET_CODE (operands[2]) == CONST_INT
6532           && INTVAL (operands[2]) < 0)
6533         {
6534           operands[2] = GEN_INT (-INTVAL (operands[2]));
6535           return "sub{b}\t{%2, %0|%0, %2}";
6536         }
6537       return "add{b}\t{%2, %0|%0, %2}";
6538     }
6540   [(set (attr "type")
6541      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6542         (const_string "incdec")
6543         (const_string "alu")))
6544    (set_attr "mode" "QI")])
6547 (define_insn "addqi_ext_1"
6548   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6549                          (const_int 8)
6550                          (const_int 8))
6551         (plus:SI
6552           (zero_extract:SI
6553             (match_operand 1 "ext_register_operand" "0")
6554             (const_int 8)
6555             (const_int 8))
6556           (match_operand:QI 2 "general_operand" "Qmn")))
6557    (clobber (reg:CC FLAGS_REG))]
6558   "!TARGET_64BIT"
6560   switch (get_attr_type (insn))
6561     {
6562     case TYPE_INCDEC:
6563       if (operands[2] == const1_rtx)
6564         return "inc{b}\t%h0";
6565       else if (operands[2] == constm1_rtx
6566                || (GET_CODE (operands[2]) == CONST_INT
6567                    && INTVAL (operands[2]) == 255))
6568         return "dec{b}\t%h0";
6569       abort();
6571     default:
6572       return "add{b}\t{%2, %h0|%h0, %2}";
6573     }
6575   [(set (attr "type")
6576      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6577         (const_string "incdec")
6578         (const_string "alu")))
6579    (set_attr "mode" "QI")])
6581 (define_insn "*addqi_ext_1_rex64"
6582   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6583                          (const_int 8)
6584                          (const_int 8))
6585         (plus:SI
6586           (zero_extract:SI
6587             (match_operand 1 "ext_register_operand" "0")
6588             (const_int 8)
6589             (const_int 8))
6590           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6591    (clobber (reg:CC FLAGS_REG))]
6592   "TARGET_64BIT"
6594   switch (get_attr_type (insn))
6595     {
6596     case TYPE_INCDEC:
6597       if (operands[2] == const1_rtx)
6598         return "inc{b}\t%h0";
6599       else if (operands[2] == constm1_rtx
6600                || (GET_CODE (operands[2]) == CONST_INT
6601                    && INTVAL (operands[2]) == 255))
6602         return "dec{b}\t%h0";
6603       abort();
6605     default:
6606       return "add{b}\t{%2, %h0|%h0, %2}";
6607     }
6609   [(set (attr "type")
6610      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6611         (const_string "incdec")
6612         (const_string "alu")))
6613    (set_attr "mode" "QI")])
6615 (define_insn "*addqi_ext_2"
6616   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6617                          (const_int 8)
6618                          (const_int 8))
6619         (plus:SI
6620           (zero_extract:SI
6621             (match_operand 1 "ext_register_operand" "%0")
6622             (const_int 8)
6623             (const_int 8))
6624           (zero_extract:SI
6625             (match_operand 2 "ext_register_operand" "Q")
6626             (const_int 8)
6627             (const_int 8))))
6628    (clobber (reg:CC FLAGS_REG))]
6629   ""
6630   "add{b}\t{%h2, %h0|%h0, %h2}"
6631   [(set_attr "type" "alu")
6632    (set_attr "mode" "QI")])
6634 ;; The patterns that match these are at the end of this file.
6636 (define_expand "addxf3"
6637   [(set (match_operand:XF 0 "register_operand" "")
6638         (plus:XF (match_operand:XF 1 "register_operand" "")
6639                  (match_operand:XF 2 "register_operand" "")))]
6640   "TARGET_80387"
6641   "")
6643 (define_expand "adddf3"
6644   [(set (match_operand:DF 0 "register_operand" "")
6645         (plus:DF (match_operand:DF 1 "register_operand" "")
6646                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6647   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6648   "")
6650 (define_expand "addsf3"
6651   [(set (match_operand:SF 0 "register_operand" "")
6652         (plus:SF (match_operand:SF 1 "register_operand" "")
6653                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6654   "TARGET_80387 || TARGET_SSE_MATH"
6655   "")
6657 ;; Subtract instructions
6659 ;; %%% splits for subsidi3
6661 (define_expand "subdi3"
6662   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6663                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6664                              (match_operand:DI 2 "x86_64_general_operand" "")))
6665               (clobber (reg:CC FLAGS_REG))])]
6666   ""
6667   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6669 (define_insn "*subdi3_1"
6670   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6671         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6672                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6673    (clobber (reg:CC FLAGS_REG))]
6674   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6675   "#")
6677 (define_split
6678   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6679         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6680                   (match_operand:DI 2 "general_operand" "")))
6681    (clobber (reg:CC FLAGS_REG))]
6682   "!TARGET_64BIT && reload_completed"
6683   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6684               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6685    (parallel [(set (match_dup 3)
6686                    (minus:SI (match_dup 4)
6687                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6688                                       (match_dup 5))))
6689               (clobber (reg:CC FLAGS_REG))])]
6690   "split_di (operands+0, 1, operands+0, operands+3);
6691    split_di (operands+1, 1, operands+1, operands+4);
6692    split_di (operands+2, 1, operands+2, operands+5);")
6694 (define_insn "subdi3_carry_rex64"
6695   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6696           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6697             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6698                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6699    (clobber (reg:CC FLAGS_REG))]
6700   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6701   "sbb{q}\t{%2, %0|%0, %2}"
6702   [(set_attr "type" "alu")
6703    (set_attr "pent_pair" "pu")
6704    (set_attr "mode" "DI")])
6706 (define_insn "*subdi_1_rex64"
6707   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6708         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6709                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6710    (clobber (reg:CC FLAGS_REG))]
6711   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6712   "sub{q}\t{%2, %0|%0, %2}"
6713   [(set_attr "type" "alu")
6714    (set_attr "mode" "DI")])
6716 (define_insn "*subdi_2_rex64"
6717   [(set (reg 17)
6718         (compare
6719           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6720                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6721           (const_int 0)))
6722    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6723         (minus:DI (match_dup 1) (match_dup 2)))]
6724   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6725    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6726   "sub{q}\t{%2, %0|%0, %2}"
6727   [(set_attr "type" "alu")
6728    (set_attr "mode" "DI")])
6730 (define_insn "*subdi_3_rex63"
6731   [(set (reg 17)
6732         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6733                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6734    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6735         (minus:DI (match_dup 1) (match_dup 2)))]
6736   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6737    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6738   "sub{q}\t{%2, %0|%0, %2}"
6739   [(set_attr "type" "alu")
6740    (set_attr "mode" "DI")])
6742 (define_insn "subqi3_carry"
6743   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6744           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6745             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6746                (match_operand:QI 2 "general_operand" "qi,qm"))))
6747    (clobber (reg:CC FLAGS_REG))]
6748   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6749   "sbb{b}\t{%2, %0|%0, %2}"
6750   [(set_attr "type" "alu")
6751    (set_attr "pent_pair" "pu")
6752    (set_attr "mode" "QI")])
6754 (define_insn "subhi3_carry"
6755   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6756           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6757             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6758                (match_operand:HI 2 "general_operand" "ri,rm"))))
6759    (clobber (reg:CC FLAGS_REG))]
6760   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6761   "sbb{w}\t{%2, %0|%0, %2}"
6762   [(set_attr "type" "alu")
6763    (set_attr "pent_pair" "pu")
6764    (set_attr "mode" "HI")])
6766 (define_insn "subsi3_carry"
6767   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6768           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6769             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6770                (match_operand:SI 2 "general_operand" "ri,rm"))))
6771    (clobber (reg:CC FLAGS_REG))]
6772   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6773   "sbb{l}\t{%2, %0|%0, %2}"
6774   [(set_attr "type" "alu")
6775    (set_attr "pent_pair" "pu")
6776    (set_attr "mode" "SI")])
6778 (define_insn "subsi3_carry_zext"
6779   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6780           (zero_extend:DI
6781             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6782               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6783                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6784    (clobber (reg:CC FLAGS_REG))]
6785   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6786   "sbb{l}\t{%2, %k0|%k0, %2}"
6787   [(set_attr "type" "alu")
6788    (set_attr "pent_pair" "pu")
6789    (set_attr "mode" "SI")])
6791 (define_expand "subsi3"
6792   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6793                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6794                              (match_operand:SI 2 "general_operand" "")))
6795               (clobber (reg:CC FLAGS_REG))])]
6796   ""
6797   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6799 (define_insn "*subsi_1"
6800   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6801         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6802                   (match_operand:SI 2 "general_operand" "ri,rm")))
6803    (clobber (reg:CC FLAGS_REG))]
6804   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6805   "sub{l}\t{%2, %0|%0, %2}"
6806   [(set_attr "type" "alu")
6807    (set_attr "mode" "SI")])
6809 (define_insn "*subsi_1_zext"
6810   [(set (match_operand:DI 0 "register_operand" "=r")
6811         (zero_extend:DI
6812           (minus:SI (match_operand:SI 1 "register_operand" "0")
6813                     (match_operand:SI 2 "general_operand" "rim"))))
6814    (clobber (reg:CC FLAGS_REG))]
6815   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6816   "sub{l}\t{%2, %k0|%k0, %2}"
6817   [(set_attr "type" "alu")
6818    (set_attr "mode" "SI")])
6820 (define_insn "*subsi_2"
6821   [(set (reg 17)
6822         (compare
6823           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6824                     (match_operand:SI 2 "general_operand" "ri,rm"))
6825           (const_int 0)))
6826    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6827         (minus:SI (match_dup 1) (match_dup 2)))]
6828   "ix86_match_ccmode (insn, CCGOCmode)
6829    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6830   "sub{l}\t{%2, %0|%0, %2}"
6831   [(set_attr "type" "alu")
6832    (set_attr "mode" "SI")])
6834 (define_insn "*subsi_2_zext"
6835   [(set (reg 17)
6836         (compare
6837           (minus:SI (match_operand:SI 1 "register_operand" "0")
6838                     (match_operand:SI 2 "general_operand" "rim"))
6839           (const_int 0)))
6840    (set (match_operand:DI 0 "register_operand" "=r")
6841         (zero_extend:DI
6842           (minus:SI (match_dup 1)
6843                     (match_dup 2))))]
6844   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6845    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6846   "sub{l}\t{%2, %k0|%k0, %2}"
6847   [(set_attr "type" "alu")
6848    (set_attr "mode" "SI")])
6850 (define_insn "*subsi_3"
6851   [(set (reg 17)
6852         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6853                  (match_operand:SI 2 "general_operand" "ri,rm")))
6854    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6855         (minus:SI (match_dup 1) (match_dup 2)))]
6856   "ix86_match_ccmode (insn, CCmode)
6857    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6858   "sub{l}\t{%2, %0|%0, %2}"
6859   [(set_attr "type" "alu")
6860    (set_attr "mode" "SI")])
6862 (define_insn "*subsi_3_zext"
6863   [(set (reg 17)
6864         (compare (match_operand:SI 1 "register_operand" "0")
6865                  (match_operand:SI 2 "general_operand" "rim")))
6866    (set (match_operand:DI 0 "register_operand" "=r")
6867         (zero_extend:DI
6868           (minus:SI (match_dup 1)
6869                     (match_dup 2))))]
6870   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6871    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6872   "sub{q}\t{%2, %0|%0, %2}"
6873   [(set_attr "type" "alu")
6874    (set_attr "mode" "DI")])
6876 (define_expand "subhi3"
6877   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6878                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6879                              (match_operand:HI 2 "general_operand" "")))
6880               (clobber (reg:CC FLAGS_REG))])]
6881   "TARGET_HIMODE_MATH"
6882   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6884 (define_insn "*subhi_1"
6885   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6886         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6887                   (match_operand:HI 2 "general_operand" "ri,rm")))
6888    (clobber (reg:CC FLAGS_REG))]
6889   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6890   "sub{w}\t{%2, %0|%0, %2}"
6891   [(set_attr "type" "alu")
6892    (set_attr "mode" "HI")])
6894 (define_insn "*subhi_2"
6895   [(set (reg 17)
6896         (compare
6897           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6898                     (match_operand:HI 2 "general_operand" "ri,rm"))
6899           (const_int 0)))
6900    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6901         (minus:HI (match_dup 1) (match_dup 2)))]
6902   "ix86_match_ccmode (insn, CCGOCmode)
6903    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6904   "sub{w}\t{%2, %0|%0, %2}"
6905   [(set_attr "type" "alu")
6906    (set_attr "mode" "HI")])
6908 (define_insn "*subhi_3"
6909   [(set (reg 17)
6910         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6911                  (match_operand:HI 2 "general_operand" "ri,rm")))
6912    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6913         (minus:HI (match_dup 1) (match_dup 2)))]
6914   "ix86_match_ccmode (insn, CCmode)
6915    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6916   "sub{w}\t{%2, %0|%0, %2}"
6917   [(set_attr "type" "alu")
6918    (set_attr "mode" "HI")])
6920 (define_expand "subqi3"
6921   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6922                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6923                              (match_operand:QI 2 "general_operand" "")))
6924               (clobber (reg:CC FLAGS_REG))])]
6925   "TARGET_QIMODE_MATH"
6926   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6928 (define_insn "*subqi_1"
6929   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6930         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6931                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6932    (clobber (reg:CC FLAGS_REG))]
6933   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6934   "sub{b}\t{%2, %0|%0, %2}"
6935   [(set_attr "type" "alu")
6936    (set_attr "mode" "QI")])
6938 (define_insn "*subqi_1_slp"
6939   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6940         (minus:QI (match_dup 0)
6941                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6942    (clobber (reg:CC FLAGS_REG))]
6943   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6944    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6945   "sub{b}\t{%1, %0|%0, %1}"
6946   [(set_attr "type" "alu1")
6947    (set_attr "mode" "QI")])
6949 (define_insn "*subqi_2"
6950   [(set (reg 17)
6951         (compare
6952           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6953                     (match_operand:QI 2 "general_operand" "qi,qm"))
6954           (const_int 0)))
6955    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6956         (minus:HI (match_dup 1) (match_dup 2)))]
6957   "ix86_match_ccmode (insn, CCGOCmode)
6958    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6959   "sub{b}\t{%2, %0|%0, %2}"
6960   [(set_attr "type" "alu")
6961    (set_attr "mode" "QI")])
6963 (define_insn "*subqi_3"
6964   [(set (reg 17)
6965         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6966                  (match_operand:QI 2 "general_operand" "qi,qm")))
6967    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6968         (minus:HI (match_dup 1) (match_dup 2)))]
6969   "ix86_match_ccmode (insn, CCmode)
6970    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6971   "sub{b}\t{%2, %0|%0, %2}"
6972   [(set_attr "type" "alu")
6973    (set_attr "mode" "QI")])
6975 ;; The patterns that match these are at the end of this file.
6977 (define_expand "subxf3"
6978   [(set (match_operand:XF 0 "register_operand" "")
6979         (minus:XF (match_operand:XF 1 "register_operand" "")
6980                   (match_operand:XF 2 "register_operand" "")))]
6981   "TARGET_80387"
6982   "")
6984 (define_expand "subdf3"
6985   [(set (match_operand:DF 0 "register_operand" "")
6986         (minus:DF (match_operand:DF 1 "register_operand" "")
6987                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6988   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6989   "")
6991 (define_expand "subsf3"
6992   [(set (match_operand:SF 0 "register_operand" "")
6993         (minus:SF (match_operand:SF 1 "register_operand" "")
6994                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6995   "TARGET_80387 || TARGET_SSE_MATH"
6996   "")
6998 ;; Multiply instructions
7000 (define_expand "muldi3"
7001   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7002                    (mult:DI (match_operand:DI 1 "register_operand" "")
7003                             (match_operand:DI 2 "x86_64_general_operand" "")))
7004               (clobber (reg:CC FLAGS_REG))])]
7005   "TARGET_64BIT"
7006   "")
7008 (define_insn "*muldi3_1_rex64"
7009   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7010         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7011                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7012    (clobber (reg:CC FLAGS_REG))]
7013   "TARGET_64BIT
7014    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7015   "@
7016    imul{q}\t{%2, %1, %0|%0, %1, %2}
7017    imul{q}\t{%2, %1, %0|%0, %1, %2}
7018    imul{q}\t{%2, %0|%0, %2}"
7019   [(set_attr "type" "imul")
7020    (set_attr "prefix_0f" "0,0,1")
7021    (set (attr "athlon_decode")
7022         (cond [(eq_attr "cpu" "athlon")
7023                   (const_string "vector")
7024                (eq_attr "alternative" "1")
7025                   (const_string "vector")
7026                (and (eq_attr "alternative" "2")
7027                     (match_operand 1 "memory_operand" ""))
7028                   (const_string "vector")]
7029               (const_string "direct")))
7030    (set_attr "mode" "DI")])
7032 (define_expand "mulsi3"
7033   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7034                    (mult:SI (match_operand:SI 1 "register_operand" "")
7035                             (match_operand:SI 2 "general_operand" "")))
7036               (clobber (reg:CC FLAGS_REG))])]
7037   ""
7038   "")
7040 (define_insn "*mulsi3_1"
7041   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7042         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7043                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7044    (clobber (reg:CC FLAGS_REG))]
7045   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7046   "@
7047    imul{l}\t{%2, %1, %0|%0, %1, %2}
7048    imul{l}\t{%2, %1, %0|%0, %1, %2}
7049    imul{l}\t{%2, %0|%0, %2}"
7050   [(set_attr "type" "imul")
7051    (set_attr "prefix_0f" "0,0,1")
7052    (set (attr "athlon_decode")
7053         (cond [(eq_attr "cpu" "athlon")
7054                   (const_string "vector")
7055                (eq_attr "alternative" "1")
7056                   (const_string "vector")
7057                (and (eq_attr "alternative" "2")
7058                     (match_operand 1 "memory_operand" ""))
7059                   (const_string "vector")]
7060               (const_string "direct")))
7061    (set_attr "mode" "SI")])
7063 (define_insn "*mulsi3_1_zext"
7064   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7065         (zero_extend:DI
7066           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7067                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7068    (clobber (reg:CC FLAGS_REG))]
7069   "TARGET_64BIT
7070    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7071   "@
7072    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7073    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7074    imul{l}\t{%2, %k0|%k0, %2}"
7075   [(set_attr "type" "imul")
7076    (set_attr "prefix_0f" "0,0,1")
7077    (set (attr "athlon_decode")
7078         (cond [(eq_attr "cpu" "athlon")
7079                   (const_string "vector")
7080                (eq_attr "alternative" "1")
7081                   (const_string "vector")
7082                (and (eq_attr "alternative" "2")
7083                     (match_operand 1 "memory_operand" ""))
7084                   (const_string "vector")]
7085               (const_string "direct")))
7086    (set_attr "mode" "SI")])
7088 (define_expand "mulhi3"
7089   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7090                    (mult:HI (match_operand:HI 1 "register_operand" "")
7091                             (match_operand:HI 2 "general_operand" "")))
7092               (clobber (reg:CC FLAGS_REG))])]
7093   "TARGET_HIMODE_MATH"
7094   "")
7096 (define_insn "*mulhi3_1"
7097   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7098         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7099                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7100    (clobber (reg:CC FLAGS_REG))]
7101   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7102   "@
7103    imul{w}\t{%2, %1, %0|%0, %1, %2}
7104    imul{w}\t{%2, %1, %0|%0, %1, %2}
7105    imul{w}\t{%2, %0|%0, %2}"
7106   [(set_attr "type" "imul")
7107    (set_attr "prefix_0f" "0,0,1")
7108    (set (attr "athlon_decode")
7109         (cond [(eq_attr "cpu" "athlon")
7110                   (const_string "vector")
7111                (eq_attr "alternative" "1,2")
7112                   (const_string "vector")]
7113               (const_string "direct")))
7114    (set_attr "mode" "HI")])
7116 (define_expand "mulqi3"
7117   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7118                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7119                             (match_operand:QI 2 "register_operand" "")))
7120               (clobber (reg:CC FLAGS_REG))])]
7121   "TARGET_QIMODE_MATH"
7122   "")
7124 (define_insn "*mulqi3_1"
7125   [(set (match_operand:QI 0 "register_operand" "=a")
7126         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7127                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7128    (clobber (reg:CC FLAGS_REG))]
7129   "TARGET_QIMODE_MATH
7130    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7131   "mul{b}\t%2"
7132   [(set_attr "type" "imul")
7133    (set_attr "length_immediate" "0")
7134    (set (attr "athlon_decode")
7135      (if_then_else (eq_attr "cpu" "athlon")
7136         (const_string "vector")
7137         (const_string "direct")))
7138    (set_attr "mode" "QI")])
7140 (define_expand "umulqihi3"
7141   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7142                    (mult:HI (zero_extend:HI
7143                               (match_operand:QI 1 "nonimmediate_operand" ""))
7144                             (zero_extend:HI
7145                               (match_operand:QI 2 "register_operand" ""))))
7146               (clobber (reg:CC FLAGS_REG))])]
7147   "TARGET_QIMODE_MATH"
7148   "")
7150 (define_insn "*umulqihi3_1"
7151   [(set (match_operand:HI 0 "register_operand" "=a")
7152         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7153                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7154    (clobber (reg:CC FLAGS_REG))]
7155   "TARGET_QIMODE_MATH
7156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7157   "mul{b}\t%2"
7158   [(set_attr "type" "imul")
7159    (set_attr "length_immediate" "0")
7160    (set (attr "athlon_decode")
7161      (if_then_else (eq_attr "cpu" "athlon")
7162         (const_string "vector")
7163         (const_string "direct")))
7164    (set_attr "mode" "QI")])
7166 (define_expand "mulqihi3"
7167   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7168                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7169                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7170               (clobber (reg:CC FLAGS_REG))])]
7171   "TARGET_QIMODE_MATH"
7172   "")
7174 (define_insn "*mulqihi3_insn"
7175   [(set (match_operand:HI 0 "register_operand" "=a")
7176         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7177                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7178    (clobber (reg:CC FLAGS_REG))]
7179   "TARGET_QIMODE_MATH
7180    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7181   "imul{b}\t%2"
7182   [(set_attr "type" "imul")
7183    (set_attr "length_immediate" "0")
7184    (set (attr "athlon_decode")
7185      (if_then_else (eq_attr "cpu" "athlon")
7186         (const_string "vector")
7187         (const_string "direct")))
7188    (set_attr "mode" "QI")])
7190 (define_expand "umulditi3"
7191   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7192                    (mult:TI (zero_extend:TI
7193                               (match_operand:DI 1 "nonimmediate_operand" ""))
7194                             (zero_extend:TI
7195                               (match_operand:DI 2 "register_operand" ""))))
7196               (clobber (reg:CC FLAGS_REG))])]
7197   "TARGET_64BIT"
7198   "")
7200 (define_insn "*umulditi3_insn"
7201   [(set (match_operand:TI 0 "register_operand" "=A")
7202         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7203                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7204    (clobber (reg:CC FLAGS_REG))]
7205   "TARGET_64BIT
7206    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7207   "mul{q}\t%2"
7208   [(set_attr "type" "imul")
7209    (set_attr "length_immediate" "0")
7210    (set (attr "athlon_decode")
7211      (if_then_else (eq_attr "cpu" "athlon")
7212         (const_string "vector")
7213         (const_string "double")))
7214    (set_attr "mode" "DI")])
7216 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7217 (define_expand "umulsidi3"
7218   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7219                    (mult:DI (zero_extend:DI
7220                               (match_operand:SI 1 "nonimmediate_operand" ""))
7221                             (zero_extend:DI
7222                               (match_operand:SI 2 "register_operand" ""))))
7223               (clobber (reg:CC FLAGS_REG))])]
7224   "!TARGET_64BIT"
7225   "")
7227 (define_insn "*umulsidi3_insn"
7228   [(set (match_operand:DI 0 "register_operand" "=A")
7229         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7230                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7231    (clobber (reg:CC FLAGS_REG))]
7232   "!TARGET_64BIT
7233    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7234   "mul{l}\t%2"
7235   [(set_attr "type" "imul")
7236    (set_attr "length_immediate" "0")
7237    (set (attr "athlon_decode")
7238      (if_then_else (eq_attr "cpu" "athlon")
7239         (const_string "vector")
7240         (const_string "double")))
7241    (set_attr "mode" "SI")])
7243 (define_expand "mulditi3"
7244   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7245                    (mult:TI (sign_extend:TI
7246                               (match_operand:DI 1 "nonimmediate_operand" ""))
7247                             (sign_extend:TI
7248                               (match_operand:DI 2 "register_operand" ""))))
7249               (clobber (reg:CC FLAGS_REG))])]
7250   "TARGET_64BIT"
7251   "")
7253 (define_insn "*mulditi3_insn"
7254   [(set (match_operand:TI 0 "register_operand" "=A")
7255         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7256                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7257    (clobber (reg:CC FLAGS_REG))]
7258   "TARGET_64BIT
7259    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7260   "imul{q}\t%2"
7261   [(set_attr "type" "imul")
7262    (set_attr "length_immediate" "0")
7263    (set (attr "athlon_decode")
7264      (if_then_else (eq_attr "cpu" "athlon")
7265         (const_string "vector")
7266         (const_string "double")))
7267    (set_attr "mode" "DI")])
7269 (define_expand "mulsidi3"
7270   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7271                    (mult:DI (sign_extend:DI
7272                               (match_operand:SI 1 "nonimmediate_operand" ""))
7273                             (sign_extend:DI
7274                               (match_operand:SI 2 "register_operand" ""))))
7275               (clobber (reg:CC FLAGS_REG))])]
7276   "!TARGET_64BIT"
7277   "")
7279 (define_insn "*mulsidi3_insn"
7280   [(set (match_operand:DI 0 "register_operand" "=A")
7281         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7282                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7283    (clobber (reg:CC FLAGS_REG))]
7284   "!TARGET_64BIT
7285    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7286   "imul{l}\t%2"
7287   [(set_attr "type" "imul")
7288    (set_attr "length_immediate" "0")
7289    (set (attr "athlon_decode")
7290      (if_then_else (eq_attr "cpu" "athlon")
7291         (const_string "vector")
7292         (const_string "double")))
7293    (set_attr "mode" "SI")])
7295 (define_expand "umuldi3_highpart"
7296   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7297                    (truncate:DI
7298                      (lshiftrt:TI
7299                        (mult:TI (zero_extend:TI
7300                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7301                                 (zero_extend:TI
7302                                   (match_operand:DI 2 "register_operand" "")))
7303                        (const_int 64))))
7304               (clobber (match_scratch:DI 3 ""))
7305               (clobber (reg:CC FLAGS_REG))])]
7306   "TARGET_64BIT"
7307   "")
7309 (define_insn "*umuldi3_highpart_rex64"
7310   [(set (match_operand:DI 0 "register_operand" "=d")
7311         (truncate:DI
7312           (lshiftrt:TI
7313             (mult:TI (zero_extend:TI
7314                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7315                      (zero_extend:TI
7316                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7317             (const_int 64))))
7318    (clobber (match_scratch:DI 3 "=1"))
7319    (clobber (reg:CC FLAGS_REG))]
7320   "TARGET_64BIT
7321    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7322   "mul{q}\t%2"
7323   [(set_attr "type" "imul")
7324    (set_attr "length_immediate" "0")
7325    (set (attr "athlon_decode")
7326      (if_then_else (eq_attr "cpu" "athlon")
7327         (const_string "vector")
7328         (const_string "double")))
7329    (set_attr "mode" "DI")])
7331 (define_expand "umulsi3_highpart"
7332   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7333                    (truncate:SI
7334                      (lshiftrt:DI
7335                        (mult:DI (zero_extend:DI
7336                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7337                                 (zero_extend:DI
7338                                   (match_operand:SI 2 "register_operand" "")))
7339                        (const_int 32))))
7340               (clobber (match_scratch:SI 3 ""))
7341               (clobber (reg:CC FLAGS_REG))])]
7342   ""
7343   "")
7345 (define_insn "*umulsi3_highpart_insn"
7346   [(set (match_operand:SI 0 "register_operand" "=d")
7347         (truncate:SI
7348           (lshiftrt:DI
7349             (mult:DI (zero_extend:DI
7350                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7351                      (zero_extend:DI
7352                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7353             (const_int 32))))
7354    (clobber (match_scratch:SI 3 "=1"))
7355    (clobber (reg:CC FLAGS_REG))]
7356   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7357   "mul{l}\t%2"
7358   [(set_attr "type" "imul")
7359    (set_attr "length_immediate" "0")
7360    (set (attr "athlon_decode")
7361      (if_then_else (eq_attr "cpu" "athlon")
7362         (const_string "vector")
7363         (const_string "double")))
7364    (set_attr "mode" "SI")])
7366 (define_insn "*umulsi3_highpart_zext"
7367   [(set (match_operand:DI 0 "register_operand" "=d")
7368         (zero_extend:DI (truncate:SI
7369           (lshiftrt:DI
7370             (mult:DI (zero_extend:DI
7371                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7372                      (zero_extend:DI
7373                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7374             (const_int 32)))))
7375    (clobber (match_scratch:SI 3 "=1"))
7376    (clobber (reg:CC FLAGS_REG))]
7377   "TARGET_64BIT
7378    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7379   "mul{l}\t%2"
7380   [(set_attr "type" "imul")
7381    (set_attr "length_immediate" "0")
7382    (set (attr "athlon_decode")
7383      (if_then_else (eq_attr "cpu" "athlon")
7384         (const_string "vector")
7385         (const_string "double")))
7386    (set_attr "mode" "SI")])
7388 (define_expand "smuldi3_highpart"
7389   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7390                    (truncate:DI
7391                      (lshiftrt:TI
7392                        (mult:TI (sign_extend:TI
7393                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7394                                 (sign_extend:TI
7395                                   (match_operand:DI 2 "register_operand" "")))
7396                        (const_int 64))))
7397               (clobber (match_scratch:DI 3 ""))
7398               (clobber (reg:CC FLAGS_REG))])]
7399   "TARGET_64BIT"
7400   "")
7402 (define_insn "*smuldi3_highpart_rex64"
7403   [(set (match_operand:DI 0 "register_operand" "=d")
7404         (truncate:DI
7405           (lshiftrt:TI
7406             (mult:TI (sign_extend:TI
7407                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7408                      (sign_extend:TI
7409                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7410             (const_int 64))))
7411    (clobber (match_scratch:DI 3 "=1"))
7412    (clobber (reg:CC FLAGS_REG))]
7413   "TARGET_64BIT
7414    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7415   "imul{q}\t%2"
7416   [(set_attr "type" "imul")
7417    (set (attr "athlon_decode")
7418      (if_then_else (eq_attr "cpu" "athlon")
7419         (const_string "vector")
7420         (const_string "double")))
7421    (set_attr "mode" "DI")])
7423 (define_expand "smulsi3_highpart"
7424   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7425                    (truncate:SI
7426                      (lshiftrt:DI
7427                        (mult:DI (sign_extend:DI
7428                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7429                                 (sign_extend:DI
7430                                   (match_operand:SI 2 "register_operand" "")))
7431                        (const_int 32))))
7432               (clobber (match_scratch:SI 3 ""))
7433               (clobber (reg:CC FLAGS_REG))])]
7434   ""
7435   "")
7437 (define_insn "*smulsi3_highpart_insn"
7438   [(set (match_operand:SI 0 "register_operand" "=d")
7439         (truncate:SI
7440           (lshiftrt:DI
7441             (mult:DI (sign_extend:DI
7442                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7443                      (sign_extend:DI
7444                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7445             (const_int 32))))
7446    (clobber (match_scratch:SI 3 "=1"))
7447    (clobber (reg:CC FLAGS_REG))]
7448   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7449   "imul{l}\t%2"
7450   [(set_attr "type" "imul")
7451    (set (attr "athlon_decode")
7452      (if_then_else (eq_attr "cpu" "athlon")
7453         (const_string "vector")
7454         (const_string "double")))
7455    (set_attr "mode" "SI")])
7457 (define_insn "*smulsi3_highpart_zext"
7458   [(set (match_operand:DI 0 "register_operand" "=d")
7459         (zero_extend:DI (truncate:SI
7460           (lshiftrt:DI
7461             (mult:DI (sign_extend:DI
7462                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7463                      (sign_extend:DI
7464                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7465             (const_int 32)))))
7466    (clobber (match_scratch:SI 3 "=1"))
7467    (clobber (reg:CC FLAGS_REG))]
7468   "TARGET_64BIT
7469    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7470   "imul{l}\t%2"
7471   [(set_attr "type" "imul")
7472    (set (attr "athlon_decode")
7473      (if_then_else (eq_attr "cpu" "athlon")
7474         (const_string "vector")
7475         (const_string "double")))
7476    (set_attr "mode" "SI")])
7478 ;; The patterns that match these are at the end of this file.
7480 (define_expand "mulxf3"
7481   [(set (match_operand:XF 0 "register_operand" "")
7482         (mult:XF (match_operand:XF 1 "register_operand" "")
7483                  (match_operand:XF 2 "register_operand" "")))]
7484   "TARGET_80387"
7485   "")
7487 (define_expand "muldf3"
7488   [(set (match_operand:DF 0 "register_operand" "")
7489         (mult:DF (match_operand:DF 1 "register_operand" "")
7490                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7491   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7492   "")
7494 (define_expand "mulsf3"
7495   [(set (match_operand:SF 0 "register_operand" "")
7496         (mult:SF (match_operand:SF 1 "register_operand" "")
7497                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7498   "TARGET_80387 || TARGET_SSE_MATH"
7499   "")
7501 ;; Divide instructions
7503 (define_insn "divqi3"
7504   [(set (match_operand:QI 0 "register_operand" "=a")
7505         (div:QI (match_operand:HI 1 "register_operand" "0")
7506                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7507    (clobber (reg:CC FLAGS_REG))]
7508   "TARGET_QIMODE_MATH"
7509   "idiv{b}\t%2"
7510   [(set_attr "type" "idiv")
7511    (set_attr "mode" "QI")])
7513 (define_insn "udivqi3"
7514   [(set (match_operand:QI 0 "register_operand" "=a")
7515         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7516                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7517    (clobber (reg:CC FLAGS_REG))]
7518   "TARGET_QIMODE_MATH"
7519   "div{b}\t%2"
7520   [(set_attr "type" "idiv")
7521    (set_attr "mode" "QI")])
7523 ;; The patterns that match these are at the end of this file.
7525 (define_expand "divxf3"
7526   [(set (match_operand:XF 0 "register_operand" "")
7527         (div:XF (match_operand:XF 1 "register_operand" "")
7528                 (match_operand:XF 2 "register_operand" "")))]
7529   "TARGET_80387"
7530   "")
7532 (define_expand "divdf3"
7533   [(set (match_operand:DF 0 "register_operand" "")
7534         (div:DF (match_operand:DF 1 "register_operand" "")
7535                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7536    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7537    "")
7539 (define_expand "divsf3"
7540   [(set (match_operand:SF 0 "register_operand" "")
7541         (div:SF (match_operand:SF 1 "register_operand" "")
7542                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7543   "TARGET_80387 || TARGET_SSE_MATH"
7544   "")
7546 ;; Remainder instructions.
7548 (define_expand "divmoddi4"
7549   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7550                    (div:DI (match_operand:DI 1 "register_operand" "")
7551                            (match_operand:DI 2 "nonimmediate_operand" "")))
7552               (set (match_operand:DI 3 "register_operand" "")
7553                    (mod:DI (match_dup 1) (match_dup 2)))
7554               (clobber (reg:CC FLAGS_REG))])]
7555   "TARGET_64BIT"
7556   "")
7558 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7559 ;; Penalize eax case slightly because it results in worse scheduling
7560 ;; of code.
7561 (define_insn "*divmoddi4_nocltd_rex64"
7562   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7563         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7564                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7565    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7566         (mod:DI (match_dup 2) (match_dup 3)))
7567    (clobber (reg:CC FLAGS_REG))]
7568   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7569   "#"
7570   [(set_attr "type" "multi")])
7572 (define_insn "*divmoddi4_cltd_rex64"
7573   [(set (match_operand:DI 0 "register_operand" "=a")
7574         (div:DI (match_operand:DI 2 "register_operand" "a")
7575                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7576    (set (match_operand:DI 1 "register_operand" "=&d")
7577         (mod:DI (match_dup 2) (match_dup 3)))
7578    (clobber (reg:CC FLAGS_REG))]
7579   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7580   "#"
7581   [(set_attr "type" "multi")])
7583 (define_insn "*divmoddi_noext_rex64"
7584   [(set (match_operand:DI 0 "register_operand" "=a")
7585         (div:DI (match_operand:DI 1 "register_operand" "0")
7586                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7587    (set (match_operand:DI 3 "register_operand" "=d")
7588         (mod:DI (match_dup 1) (match_dup 2)))
7589    (use (match_operand:DI 4 "register_operand" "3"))
7590    (clobber (reg:CC FLAGS_REG))]
7591   "TARGET_64BIT"
7592   "idiv{q}\t%2"
7593   [(set_attr "type" "idiv")
7594    (set_attr "mode" "DI")])
7596 (define_split
7597   [(set (match_operand:DI 0 "register_operand" "")
7598         (div:DI (match_operand:DI 1 "register_operand" "")
7599                 (match_operand:DI 2 "nonimmediate_operand" "")))
7600    (set (match_operand:DI 3 "register_operand" "")
7601         (mod:DI (match_dup 1) (match_dup 2)))
7602    (clobber (reg:CC FLAGS_REG))]
7603   "TARGET_64BIT && reload_completed"
7604   [(parallel [(set (match_dup 3)
7605                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7606               (clobber (reg:CC FLAGS_REG))])
7607    (parallel [(set (match_dup 0)
7608                    (div:DI (reg:DI 0) (match_dup 2)))
7609               (set (match_dup 3)
7610                    (mod:DI (reg:DI 0) (match_dup 2)))
7611               (use (match_dup 3))
7612               (clobber (reg:CC FLAGS_REG))])]
7614   /* Avoid use of cltd in favor of a mov+shift.  */
7615   if (!TARGET_USE_CLTD && !optimize_size)
7616     {
7617       if (true_regnum (operands[1]))
7618         emit_move_insn (operands[0], operands[1]);
7619       else
7620         emit_move_insn (operands[3], operands[1]);
7621       operands[4] = operands[3];
7622     }
7623   else
7624     {
7625       if (true_regnum (operands[1]))
7626         abort();
7627       operands[4] = operands[1];
7628     }
7632 (define_expand "divmodsi4"
7633   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7634                    (div:SI (match_operand:SI 1 "register_operand" "")
7635                            (match_operand:SI 2 "nonimmediate_operand" "")))
7636               (set (match_operand:SI 3 "register_operand" "")
7637                    (mod:SI (match_dup 1) (match_dup 2)))
7638               (clobber (reg:CC FLAGS_REG))])]
7639   ""
7640   "")
7642 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7643 ;; Penalize eax case slightly because it results in worse scheduling
7644 ;; of code.
7645 (define_insn "*divmodsi4_nocltd"
7646   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7647         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7648                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7649    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7650         (mod:SI (match_dup 2) (match_dup 3)))
7651    (clobber (reg:CC FLAGS_REG))]
7652   "!optimize_size && !TARGET_USE_CLTD"
7653   "#"
7654   [(set_attr "type" "multi")])
7656 (define_insn "*divmodsi4_cltd"
7657   [(set (match_operand:SI 0 "register_operand" "=a")
7658         (div:SI (match_operand:SI 2 "register_operand" "a")
7659                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7660    (set (match_operand:SI 1 "register_operand" "=&d")
7661         (mod:SI (match_dup 2) (match_dup 3)))
7662    (clobber (reg:CC FLAGS_REG))]
7663   "optimize_size || TARGET_USE_CLTD"
7664   "#"
7665   [(set_attr "type" "multi")])
7667 (define_insn "*divmodsi_noext"
7668   [(set (match_operand:SI 0 "register_operand" "=a")
7669         (div:SI (match_operand:SI 1 "register_operand" "0")
7670                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7671    (set (match_operand:SI 3 "register_operand" "=d")
7672         (mod:SI (match_dup 1) (match_dup 2)))
7673    (use (match_operand:SI 4 "register_operand" "3"))
7674    (clobber (reg:CC FLAGS_REG))]
7675   ""
7676   "idiv{l}\t%2"
7677   [(set_attr "type" "idiv")
7678    (set_attr "mode" "SI")])
7680 (define_split
7681   [(set (match_operand:SI 0 "register_operand" "")
7682         (div:SI (match_operand:SI 1 "register_operand" "")
7683                 (match_operand:SI 2 "nonimmediate_operand" "")))
7684    (set (match_operand:SI 3 "register_operand" "")
7685         (mod:SI (match_dup 1) (match_dup 2)))
7686    (clobber (reg:CC FLAGS_REG))]
7687   "reload_completed"
7688   [(parallel [(set (match_dup 3)
7689                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7690               (clobber (reg:CC FLAGS_REG))])
7691    (parallel [(set (match_dup 0)
7692                    (div:SI (reg:SI 0) (match_dup 2)))
7693               (set (match_dup 3)
7694                    (mod:SI (reg:SI 0) (match_dup 2)))
7695               (use (match_dup 3))
7696               (clobber (reg:CC FLAGS_REG))])]
7698   /* Avoid use of cltd in favor of a mov+shift.  */
7699   if (!TARGET_USE_CLTD && !optimize_size)
7700     {
7701       if (true_regnum (operands[1]))
7702         emit_move_insn (operands[0], operands[1]);
7703       else
7704         emit_move_insn (operands[3], operands[1]);
7705       operands[4] = operands[3];
7706     }
7707   else
7708     {
7709       if (true_regnum (operands[1]))
7710         abort();
7711       operands[4] = operands[1];
7712     }
7714 ;; %%% Split me.
7715 (define_insn "divmodhi4"
7716   [(set (match_operand:HI 0 "register_operand" "=a")
7717         (div:HI (match_operand:HI 1 "register_operand" "0")
7718                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7719    (set (match_operand:HI 3 "register_operand" "=&d")
7720         (mod:HI (match_dup 1) (match_dup 2)))
7721    (clobber (reg:CC FLAGS_REG))]
7722   "TARGET_HIMODE_MATH"
7723   "cwtd\;idiv{w}\t%2"
7724   [(set_attr "type" "multi")
7725    (set_attr "length_immediate" "0")
7726    (set_attr "mode" "SI")])
7728 (define_insn "udivmoddi4"
7729   [(set (match_operand:DI 0 "register_operand" "=a")
7730         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7731                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7732    (set (match_operand:DI 3 "register_operand" "=&d")
7733         (umod:DI (match_dup 1) (match_dup 2)))
7734    (clobber (reg:CC FLAGS_REG))]
7735   "TARGET_64BIT"
7736   "xor{q}\t%3, %3\;div{q}\t%2"
7737   [(set_attr "type" "multi")
7738    (set_attr "length_immediate" "0")
7739    (set_attr "mode" "DI")])
7741 (define_insn "*udivmoddi4_noext"
7742   [(set (match_operand:DI 0 "register_operand" "=a")
7743         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7744                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7745    (set (match_operand:DI 3 "register_operand" "=d")
7746         (umod:DI (match_dup 1) (match_dup 2)))
7747    (use (match_dup 3))
7748    (clobber (reg:CC FLAGS_REG))]
7749   "TARGET_64BIT"
7750   "div{q}\t%2"
7751   [(set_attr "type" "idiv")
7752    (set_attr "mode" "DI")])
7754 (define_split
7755   [(set (match_operand:DI 0 "register_operand" "")
7756         (udiv:DI (match_operand:DI 1 "register_operand" "")
7757                  (match_operand:DI 2 "nonimmediate_operand" "")))
7758    (set (match_operand:DI 3 "register_operand" "")
7759         (umod:DI (match_dup 1) (match_dup 2)))
7760    (clobber (reg:CC FLAGS_REG))]
7761   "TARGET_64BIT && reload_completed"
7762   [(set (match_dup 3) (const_int 0))
7763    (parallel [(set (match_dup 0)
7764                    (udiv:DI (match_dup 1) (match_dup 2)))
7765               (set (match_dup 3)
7766                    (umod:DI (match_dup 1) (match_dup 2)))
7767               (use (match_dup 3))
7768               (clobber (reg:CC FLAGS_REG))])]
7769   "")
7771 (define_insn "udivmodsi4"
7772   [(set (match_operand:SI 0 "register_operand" "=a")
7773         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7774                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7775    (set (match_operand:SI 3 "register_operand" "=&d")
7776         (umod:SI (match_dup 1) (match_dup 2)))
7777    (clobber (reg:CC FLAGS_REG))]
7778   ""
7779   "xor{l}\t%3, %3\;div{l}\t%2"
7780   [(set_attr "type" "multi")
7781    (set_attr "length_immediate" "0")
7782    (set_attr "mode" "SI")])
7784 (define_insn "*udivmodsi4_noext"
7785   [(set (match_operand:SI 0 "register_operand" "=a")
7786         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7787                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7788    (set (match_operand:SI 3 "register_operand" "=d")
7789         (umod:SI (match_dup 1) (match_dup 2)))
7790    (use (match_dup 3))
7791    (clobber (reg:CC FLAGS_REG))]
7792   ""
7793   "div{l}\t%2"
7794   [(set_attr "type" "idiv")
7795    (set_attr "mode" "SI")])
7797 (define_split
7798   [(set (match_operand:SI 0 "register_operand" "")
7799         (udiv:SI (match_operand:SI 1 "register_operand" "")
7800                  (match_operand:SI 2 "nonimmediate_operand" "")))
7801    (set (match_operand:SI 3 "register_operand" "")
7802         (umod:SI (match_dup 1) (match_dup 2)))
7803    (clobber (reg:CC FLAGS_REG))]
7804   "reload_completed"
7805   [(set (match_dup 3) (const_int 0))
7806    (parallel [(set (match_dup 0)
7807                    (udiv:SI (match_dup 1) (match_dup 2)))
7808               (set (match_dup 3)
7809                    (umod:SI (match_dup 1) (match_dup 2)))
7810               (use (match_dup 3))
7811               (clobber (reg:CC FLAGS_REG))])]
7812   "")
7814 (define_expand "udivmodhi4"
7815   [(set (match_dup 4) (const_int 0))
7816    (parallel [(set (match_operand:HI 0 "register_operand" "")
7817                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7818                             (match_operand:HI 2 "nonimmediate_operand" "")))
7819               (set (match_operand:HI 3 "register_operand" "")
7820                    (umod:HI (match_dup 1) (match_dup 2)))
7821               (use (match_dup 4))
7822               (clobber (reg:CC FLAGS_REG))])]
7823   "TARGET_HIMODE_MATH"
7824   "operands[4] = gen_reg_rtx (HImode);")
7826 (define_insn "*udivmodhi_noext"
7827   [(set (match_operand:HI 0 "register_operand" "=a")
7828         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7829                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7830    (set (match_operand:HI 3 "register_operand" "=d")
7831         (umod:HI (match_dup 1) (match_dup 2)))
7832    (use (match_operand:HI 4 "register_operand" "3"))
7833    (clobber (reg:CC FLAGS_REG))]
7834   ""
7835   "div{w}\t%2"
7836   [(set_attr "type" "idiv")
7837    (set_attr "mode" "HI")])
7839 ;; We cannot use div/idiv for double division, because it causes
7840 ;; "division by zero" on the overflow and that's not what we expect
7841 ;; from truncate.  Because true (non truncating) double division is
7842 ;; never generated, we can't create this insn anyway.
7844 ;(define_insn ""
7845 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7846 ;       (truncate:SI
7847 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7848 ;                  (zero_extend:DI
7849 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7850 ;   (set (match_operand:SI 3 "register_operand" "=d")
7851 ;       (truncate:SI
7852 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7853 ;   (clobber (reg:CC FLAGS_REG))]
7854 ;  ""
7855 ;  "div{l}\t{%2, %0|%0, %2}"
7856 ;  [(set_attr "type" "idiv")])
7858 ;;- Logical AND instructions
7860 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7861 ;; Note that this excludes ah.
7863 (define_insn "*testdi_1_rex64"
7864   [(set (reg 17)
7865         (compare
7866           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7867                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7868           (const_int 0)))]
7869   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7870    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7871   "@
7872    test{l}\t{%k1, %k0|%k0, %k1}
7873    test{l}\t{%k1, %k0|%k0, %k1}
7874    test{q}\t{%1, %0|%0, %1}
7875    test{q}\t{%1, %0|%0, %1}
7876    test{q}\t{%1, %0|%0, %1}"
7877   [(set_attr "type" "test")
7878    (set_attr "modrm" "0,1,0,1,1")
7879    (set_attr "mode" "SI,SI,DI,DI,DI")
7880    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7882 (define_insn "testsi_1"
7883   [(set (reg 17)
7884         (compare
7885           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7886                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7887           (const_int 0)))]
7888   "ix86_match_ccmode (insn, CCNOmode)
7889    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7890   "test{l}\t{%1, %0|%0, %1}"
7891   [(set_attr "type" "test")
7892    (set_attr "modrm" "0,1,1")
7893    (set_attr "mode" "SI")
7894    (set_attr "pent_pair" "uv,np,uv")])
7896 (define_expand "testsi_ccno_1"
7897   [(set (reg:CCNO FLAGS_REG)
7898         (compare:CCNO
7899           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7900                   (match_operand:SI 1 "nonmemory_operand" ""))
7901           (const_int 0)))]
7902   ""
7903   "")
7905 (define_insn "*testhi_1"
7906   [(set (reg 17)
7907         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7908                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7909                  (const_int 0)))]
7910   "ix86_match_ccmode (insn, CCNOmode)
7911    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7912   "test{w}\t{%1, %0|%0, %1}"
7913   [(set_attr "type" "test")
7914    (set_attr "modrm" "0,1,1")
7915    (set_attr "mode" "HI")
7916    (set_attr "pent_pair" "uv,np,uv")])
7918 (define_expand "testqi_ccz_1"
7919   [(set (reg:CCZ FLAGS_REG)
7920         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7921                              (match_operand:QI 1 "nonmemory_operand" ""))
7922                  (const_int 0)))]
7923   ""
7924   "")
7926 (define_insn "*testqi_1"
7927   [(set (reg 17)
7928         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7929                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7930                  (const_int 0)))]
7931   "ix86_match_ccmode (insn, CCNOmode)
7932    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7934   if (which_alternative == 3)
7935     {
7936       if (GET_CODE (operands[1]) == CONST_INT
7937           && (INTVAL (operands[1]) & 0xffffff00))
7938         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7939       return "test{l}\t{%1, %k0|%k0, %1}";
7940     }
7941   return "test{b}\t{%1, %0|%0, %1}";
7943   [(set_attr "type" "test")
7944    (set_attr "modrm" "0,1,1,1")
7945    (set_attr "mode" "QI,QI,QI,SI")
7946    (set_attr "pent_pair" "uv,np,uv,np")])
7948 (define_expand "testqi_ext_ccno_0"
7949   [(set (reg:CCNO FLAGS_REG)
7950         (compare:CCNO
7951           (and:SI
7952             (zero_extract:SI
7953               (match_operand 0 "ext_register_operand" "")
7954               (const_int 8)
7955               (const_int 8))
7956             (match_operand 1 "const_int_operand" ""))
7957           (const_int 0)))]
7958   ""
7959   "")
7961 (define_insn "*testqi_ext_0"
7962   [(set (reg 17)
7963         (compare
7964           (and:SI
7965             (zero_extract:SI
7966               (match_operand 0 "ext_register_operand" "Q")
7967               (const_int 8)
7968               (const_int 8))
7969             (match_operand 1 "const_int_operand" "n"))
7970           (const_int 0)))]
7971   "ix86_match_ccmode (insn, CCNOmode)"
7972   "test{b}\t{%1, %h0|%h0, %1}"
7973   [(set_attr "type" "test")
7974    (set_attr "mode" "QI")
7975    (set_attr "length_immediate" "1")
7976    (set_attr "pent_pair" "np")])
7978 (define_insn "*testqi_ext_1"
7979   [(set (reg 17)
7980         (compare
7981           (and:SI
7982             (zero_extract:SI
7983               (match_operand 0 "ext_register_operand" "Q")
7984               (const_int 8)
7985               (const_int 8))
7986             (zero_extend:SI
7987               (match_operand:QI 1 "general_operand" "Qm")))
7988           (const_int 0)))]
7989   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7990    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7991   "test{b}\t{%1, %h0|%h0, %1}"
7992   [(set_attr "type" "test")
7993    (set_attr "mode" "QI")])
7995 (define_insn "*testqi_ext_1_rex64"
7996   [(set (reg 17)
7997         (compare
7998           (and:SI
7999             (zero_extract:SI
8000               (match_operand 0 "ext_register_operand" "Q")
8001               (const_int 8)
8002               (const_int 8))
8003             (zero_extend:SI
8004               (match_operand:QI 1 "register_operand" "Q")))
8005           (const_int 0)))]
8006   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8007   "test{b}\t{%1, %h0|%h0, %1}"
8008   [(set_attr "type" "test")
8009    (set_attr "mode" "QI")])
8011 (define_insn "*testqi_ext_2"
8012   [(set (reg 17)
8013         (compare
8014           (and:SI
8015             (zero_extract:SI
8016               (match_operand 0 "ext_register_operand" "Q")
8017               (const_int 8)
8018               (const_int 8))
8019             (zero_extract:SI
8020               (match_operand 1 "ext_register_operand" "Q")
8021               (const_int 8)
8022               (const_int 8)))
8023           (const_int 0)))]
8024   "ix86_match_ccmode (insn, CCNOmode)"
8025   "test{b}\t{%h1, %h0|%h0, %h1}"
8026   [(set_attr "type" "test")
8027    (set_attr "mode" "QI")])
8029 ;; Combine likes to form bit extractions for some tests.  Humor it.
8030 (define_insn "*testqi_ext_3"
8031   [(set (reg 17)
8032         (compare (zero_extract:SI
8033                    (match_operand 0 "nonimmediate_operand" "rm")
8034                    (match_operand:SI 1 "const_int_operand" "")
8035                    (match_operand:SI 2 "const_int_operand" ""))
8036                  (const_int 0)))]
8037   "ix86_match_ccmode (insn, CCNOmode)
8038    && (GET_MODE (operands[0]) == SImode
8039        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8040        || GET_MODE (operands[0]) == HImode
8041        || GET_MODE (operands[0]) == QImode)"
8042   "#")
8044 (define_insn "*testqi_ext_3_rex64"
8045   [(set (reg 17)
8046         (compare (zero_extract:DI
8047                    (match_operand 0 "nonimmediate_operand" "rm")
8048                    (match_operand:DI 1 "const_int_operand" "")
8049                    (match_operand:DI 2 "const_int_operand" ""))
8050                  (const_int 0)))]
8051   "TARGET_64BIT
8052    && ix86_match_ccmode (insn, CCNOmode)
8053    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8054    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8055    /* Ensure that resulting mask is zero or sign extended operand.  */
8056    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8057        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8058            && INTVAL (operands[1]) > 32))
8059    && (GET_MODE (operands[0]) == SImode
8060        || GET_MODE (operands[0]) == DImode
8061        || GET_MODE (operands[0]) == HImode
8062        || GET_MODE (operands[0]) == QImode)"
8063   "#")
8065 (define_split
8066   [(set (reg 17)
8067         (compare (zero_extract
8068                    (match_operand 0 "nonimmediate_operand" "")
8069                    (match_operand 1 "const_int_operand" "")
8070                    (match_operand 2 "const_int_operand" ""))
8071                  (const_int 0)))]
8072   "ix86_match_ccmode (insn, CCNOmode)"
8073   [(set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
8075   HOST_WIDE_INT len = INTVAL (operands[1]);
8076   HOST_WIDE_INT pos = INTVAL (operands[2]);
8077   HOST_WIDE_INT mask;
8078   enum machine_mode mode, submode;
8080   mode = GET_MODE (operands[0]);
8081   if (GET_CODE (operands[0]) == MEM)
8082     {
8083       /* ??? Combine likes to put non-volatile mem extractions in QImode
8084          no matter the size of the test.  So find a mode that works.  */
8085       if (! MEM_VOLATILE_P (operands[0]))
8086         {
8087           mode = smallest_mode_for_size (pos + len, MODE_INT);
8088           operands[0] = adjust_address (operands[0], mode, 0);
8089         }
8090     }
8091   else if (GET_CODE (operands[0]) == SUBREG
8092            && (submode = GET_MODE (SUBREG_REG (operands[0])),
8093                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8094            && pos + len <= GET_MODE_BITSIZE (submode))
8095     {
8096       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8097       mode = submode;
8098       operands[0] = SUBREG_REG (operands[0]);
8099     }
8100   else if (mode == HImode && pos + len <= 8)
8101     {
8102       /* Small HImode tests can be converted to QImode.  */
8103       mode = QImode;
8104       operands[0] = gen_lowpart (QImode, operands[0]);
8105     }
8107   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8108   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8110   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8113 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8114 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8115 ;; this is relatively important trick.
8116 ;; Do the conversion only post-reload to avoid limiting of the register class
8117 ;; to QI regs.
8118 (define_split
8119   [(set (reg 17)
8120         (compare
8121           (and (match_operand 0 "register_operand" "")
8122                (match_operand 1 "const_int_operand" ""))
8123           (const_int 0)))]
8124    "reload_completed
8125     && QI_REG_P (operands[0])
8126     && ((ix86_match_ccmode (insn, CCZmode)
8127          && !(INTVAL (operands[1]) & ~(255 << 8)))
8128         || (ix86_match_ccmode (insn, CCNOmode)
8129             && !(INTVAL (operands[1]) & ~(127 << 8))))
8130     && GET_MODE (operands[0]) != QImode"
8131   [(set (reg:CCNO FLAGS_REG)
8132         (compare:CCNO
8133           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8134                   (match_dup 1))
8135           (const_int 0)))]
8136   "operands[0] = gen_lowpart (SImode, operands[0]);
8137    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8139 (define_split
8140   [(set (reg 17)
8141         (compare
8142           (and (match_operand 0 "nonimmediate_operand" "")
8143                (match_operand 1 "const_int_operand" ""))
8144           (const_int 0)))]
8145    "reload_completed
8146     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8147     && ((ix86_match_ccmode (insn, CCZmode)
8148          && !(INTVAL (operands[1]) & ~255))
8149         || (ix86_match_ccmode (insn, CCNOmode)
8150             && !(INTVAL (operands[1]) & ~127)))
8151     && GET_MODE (operands[0]) != QImode"
8152   [(set (reg:CCNO FLAGS_REG)
8153         (compare:CCNO
8154           (and:QI (match_dup 0)
8155                   (match_dup 1))
8156           (const_int 0)))]
8157   "operands[0] = gen_lowpart (QImode, operands[0]);
8158    operands[1] = gen_lowpart (QImode, operands[1]);")
8161 ;; %%% This used to optimize known byte-wide and operations to memory,
8162 ;; and sometimes to QImode registers.  If this is considered useful,
8163 ;; it should be done with splitters.
8165 (define_expand "anddi3"
8166   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8167         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8168                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8169    (clobber (reg:CC FLAGS_REG))]
8170   "TARGET_64BIT"
8171   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8173 (define_insn "*anddi_1_rex64"
8174   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8175         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8176                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8177    (clobber (reg:CC FLAGS_REG))]
8178   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8180   switch (get_attr_type (insn))
8181     {
8182     case TYPE_IMOVX:
8183       {
8184         enum machine_mode mode;
8186         if (GET_CODE (operands[2]) != CONST_INT)
8187           abort ();
8188         if (INTVAL (operands[2]) == 0xff)
8189           mode = QImode;
8190         else if (INTVAL (operands[2]) == 0xffff)
8191           mode = HImode;
8192         else
8193           abort ();
8194         
8195         operands[1] = gen_lowpart (mode, operands[1]);
8196         if (mode == QImode)
8197           return "movz{bq|x}\t{%1,%0|%0, %1}";
8198         else
8199           return "movz{wq|x}\t{%1,%0|%0, %1}";
8200       }
8202     default:
8203       if (! rtx_equal_p (operands[0], operands[1]))
8204         abort ();
8205       if (get_attr_mode (insn) == MODE_SI)
8206         return "and{l}\t{%k2, %k0|%k0, %k2}";
8207       else
8208         return "and{q}\t{%2, %0|%0, %2}";
8209     }
8211   [(set_attr "type" "alu,alu,alu,imovx")
8212    (set_attr "length_immediate" "*,*,*,0")
8213    (set_attr "mode" "SI,DI,DI,DI")])
8215 (define_insn "*anddi_2"
8216   [(set (reg 17)
8217         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8218                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8219                  (const_int 0)))
8220    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8221         (and:DI (match_dup 1) (match_dup 2)))]
8222   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8223    && ix86_binary_operator_ok (AND, DImode, operands)"
8224   "@
8225    and{l}\t{%k2, %k0|%k0, %k2}
8226    and{q}\t{%2, %0|%0, %2}
8227    and{q}\t{%2, %0|%0, %2}"
8228   [(set_attr "type" "alu")
8229    (set_attr "mode" "SI,DI,DI")])
8231 (define_expand "andsi3"
8232   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8233         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8234                 (match_operand:SI 2 "general_operand" "")))
8235    (clobber (reg:CC FLAGS_REG))]
8236   ""
8237   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8239 (define_insn "*andsi_1"
8240   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8241         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8242                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8243    (clobber (reg:CC FLAGS_REG))]
8244   "ix86_binary_operator_ok (AND, SImode, operands)"
8246   switch (get_attr_type (insn))
8247     {
8248     case TYPE_IMOVX:
8249       {
8250         enum machine_mode mode;
8252         if (GET_CODE (operands[2]) != CONST_INT)
8253           abort ();
8254         if (INTVAL (operands[2]) == 0xff)
8255           mode = QImode;
8256         else if (INTVAL (operands[2]) == 0xffff)
8257           mode = HImode;
8258         else
8259           abort ();
8260         
8261         operands[1] = gen_lowpart (mode, operands[1]);
8262         if (mode == QImode)
8263           return "movz{bl|x}\t{%1,%0|%0, %1}";
8264         else
8265           return "movz{wl|x}\t{%1,%0|%0, %1}";
8266       }
8268     default:
8269       if (! rtx_equal_p (operands[0], operands[1]))
8270         abort ();
8271       return "and{l}\t{%2, %0|%0, %2}";
8272     }
8274   [(set_attr "type" "alu,alu,imovx")
8275    (set_attr "length_immediate" "*,*,0")
8276    (set_attr "mode" "SI")])
8278 (define_split
8279   [(set (match_operand 0 "register_operand" "")
8280         (and (match_dup 0)
8281              (const_int -65536)))
8282    (clobber (reg:CC FLAGS_REG))]
8283   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8284   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8285   "operands[1] = gen_lowpart (HImode, operands[0]);")
8287 (define_split
8288   [(set (match_operand 0 "ext_register_operand" "")
8289         (and (match_dup 0)
8290              (const_int -256)))
8291    (clobber (reg:CC FLAGS_REG))]
8292   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8293   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8294   "operands[1] = gen_lowpart (QImode, operands[0]);")
8296 (define_split
8297   [(set (match_operand 0 "ext_register_operand" "")
8298         (and (match_dup 0)
8299              (const_int -65281)))
8300    (clobber (reg:CC FLAGS_REG))]
8301   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8302   [(parallel [(set (zero_extract:SI (match_dup 0)
8303                                     (const_int 8)
8304                                     (const_int 8))
8305                    (xor:SI 
8306                      (zero_extract:SI (match_dup 0)
8307                                       (const_int 8)
8308                                       (const_int 8))
8309                      (zero_extract:SI (match_dup 0)
8310                                       (const_int 8)
8311                                       (const_int 8))))
8312               (clobber (reg:CC FLAGS_REG))])]
8313   "operands[0] = gen_lowpart (SImode, operands[0]);")
8315 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8316 (define_insn "*andsi_1_zext"
8317   [(set (match_operand:DI 0 "register_operand" "=r")
8318         (zero_extend:DI
8319           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8320                   (match_operand:SI 2 "general_operand" "rim"))))
8321    (clobber (reg:CC FLAGS_REG))]
8322   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8323   "and{l}\t{%2, %k0|%k0, %2}"
8324   [(set_attr "type" "alu")
8325    (set_attr "mode" "SI")])
8327 (define_insn "*andsi_2"
8328   [(set (reg 17)
8329         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8330                          (match_operand:SI 2 "general_operand" "rim,ri"))
8331                  (const_int 0)))
8332    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8333         (and:SI (match_dup 1) (match_dup 2)))]
8334   "ix86_match_ccmode (insn, CCNOmode)
8335    && ix86_binary_operator_ok (AND, SImode, operands)"
8336   "and{l}\t{%2, %0|%0, %2}"
8337   [(set_attr "type" "alu")
8338    (set_attr "mode" "SI")])
8340 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8341 (define_insn "*andsi_2_zext"
8342   [(set (reg 17)
8343         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8344                          (match_operand:SI 2 "general_operand" "rim"))
8345                  (const_int 0)))
8346    (set (match_operand:DI 0 "register_operand" "=r")
8347         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8348   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8349    && ix86_binary_operator_ok (AND, SImode, operands)"
8350   "and{l}\t{%2, %k0|%k0, %2}"
8351   [(set_attr "type" "alu")
8352    (set_attr "mode" "SI")])
8354 (define_expand "andhi3"
8355   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8356         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8357                 (match_operand:HI 2 "general_operand" "")))
8358    (clobber (reg:CC FLAGS_REG))]
8359   "TARGET_HIMODE_MATH"
8360   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8362 (define_insn "*andhi_1"
8363   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8364         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8365                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8366    (clobber (reg:CC FLAGS_REG))]
8367   "ix86_binary_operator_ok (AND, HImode, operands)"
8369   switch (get_attr_type (insn))
8370     {
8371     case TYPE_IMOVX:
8372       if (GET_CODE (operands[2]) != CONST_INT)
8373         abort ();
8374       if (INTVAL (operands[2]) == 0xff)
8375         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8376       abort ();
8378     default:
8379       if (! rtx_equal_p (operands[0], operands[1]))
8380         abort ();
8382       return "and{w}\t{%2, %0|%0, %2}";
8383     }
8385   [(set_attr "type" "alu,alu,imovx")
8386    (set_attr "length_immediate" "*,*,0")
8387    (set_attr "mode" "HI,HI,SI")])
8389 (define_insn "*andhi_2"
8390   [(set (reg 17)
8391         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8392                          (match_operand:HI 2 "general_operand" "rim,ri"))
8393                  (const_int 0)))
8394    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8395         (and:HI (match_dup 1) (match_dup 2)))]
8396   "ix86_match_ccmode (insn, CCNOmode)
8397    && ix86_binary_operator_ok (AND, HImode, operands)"
8398   "and{w}\t{%2, %0|%0, %2}"
8399   [(set_attr "type" "alu")
8400    (set_attr "mode" "HI")])
8402 (define_expand "andqi3"
8403   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8404         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8405                 (match_operand:QI 2 "general_operand" "")))
8406    (clobber (reg:CC FLAGS_REG))]
8407   "TARGET_QIMODE_MATH"
8408   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8410 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8411 (define_insn "*andqi_1"
8412   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8413         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8414                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8415    (clobber (reg:CC FLAGS_REG))]
8416   "ix86_binary_operator_ok (AND, QImode, operands)"
8417   "@
8418    and{b}\t{%2, %0|%0, %2}
8419    and{b}\t{%2, %0|%0, %2}
8420    and{l}\t{%k2, %k0|%k0, %k2}"
8421   [(set_attr "type" "alu")
8422    (set_attr "mode" "QI,QI,SI")])
8424 (define_insn "*andqi_1_slp"
8425   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8426         (and:QI (match_dup 0)
8427                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8428    (clobber (reg:CC FLAGS_REG))]
8429   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8430    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8431   "and{b}\t{%1, %0|%0, %1}"
8432   [(set_attr "type" "alu1")
8433    (set_attr "mode" "QI")])
8435 (define_insn "*andqi_2"
8436   [(set (reg 17)
8437         (compare (and:QI
8438                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8439                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8440                  (const_int 0)))
8441    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8442         (and:QI (match_dup 1) (match_dup 2)))]
8443   "ix86_match_ccmode (insn, CCNOmode)
8444    && ix86_binary_operator_ok (AND, QImode, operands)"
8446   if (which_alternative == 2)
8447     {
8448       if (GET_CODE (operands[2]) == CONST_INT
8449           && (INTVAL (operands[2]) & 0xffffff00))
8450         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8451       return "and{l}\t{%2, %k0|%k0, %2}";
8452     }
8453   return "and{b}\t{%2, %0|%0, %2}";
8455   [(set_attr "type" "alu")
8456    (set_attr "mode" "QI,QI,SI")])
8458 (define_insn "*andqi_2_slp"
8459   [(set (reg 17)
8460         (compare (and:QI
8461                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8462                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8463                  (const_int 0)))
8464    (set (strict_low_part (match_dup 0))
8465         (and:QI (match_dup 0) (match_dup 1)))]
8466   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8467    && ix86_match_ccmode (insn, CCNOmode)
8468    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8469   "and{b}\t{%1, %0|%0, %1}"
8470   [(set_attr "type" "alu1")
8471    (set_attr "mode" "QI")])
8473 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8474 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8475 ;; for a QImode operand, which of course failed.
8477 (define_insn "andqi_ext_0"
8478   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8479                          (const_int 8)
8480                          (const_int 8))
8481         (and:SI 
8482           (zero_extract:SI
8483             (match_operand 1 "ext_register_operand" "0")
8484             (const_int 8)
8485             (const_int 8))
8486           (match_operand 2 "const_int_operand" "n")))
8487    (clobber (reg:CC FLAGS_REG))]
8488   ""
8489   "and{b}\t{%2, %h0|%h0, %2}"
8490   [(set_attr "type" "alu")
8491    (set_attr "length_immediate" "1")
8492    (set_attr "mode" "QI")])
8494 ;; Generated by peephole translating test to and.  This shows up
8495 ;; often in fp comparisons.
8497 (define_insn "*andqi_ext_0_cc"
8498   [(set (reg 17)
8499         (compare
8500           (and:SI
8501             (zero_extract:SI
8502               (match_operand 1 "ext_register_operand" "0")
8503               (const_int 8)
8504               (const_int 8))
8505             (match_operand 2 "const_int_operand" "n"))
8506           (const_int 0)))
8507    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8508                          (const_int 8)
8509                          (const_int 8))
8510         (and:SI 
8511           (zero_extract:SI
8512             (match_dup 1)
8513             (const_int 8)
8514             (const_int 8))
8515           (match_dup 2)))]
8516   "ix86_match_ccmode (insn, CCNOmode)"
8517   "and{b}\t{%2, %h0|%h0, %2}"
8518   [(set_attr "type" "alu")
8519    (set_attr "length_immediate" "1")
8520    (set_attr "mode" "QI")])
8522 (define_insn "*andqi_ext_1"
8523   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8524                          (const_int 8)
8525                          (const_int 8))
8526         (and:SI 
8527           (zero_extract:SI
8528             (match_operand 1 "ext_register_operand" "0")
8529             (const_int 8)
8530             (const_int 8))
8531           (zero_extend:SI
8532             (match_operand:QI 2 "general_operand" "Qm"))))
8533    (clobber (reg:CC FLAGS_REG))]
8534   "!TARGET_64BIT"
8535   "and{b}\t{%2, %h0|%h0, %2}"
8536   [(set_attr "type" "alu")
8537    (set_attr "length_immediate" "0")
8538    (set_attr "mode" "QI")])
8540 (define_insn "*andqi_ext_1_rex64"
8541   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8542                          (const_int 8)
8543                          (const_int 8))
8544         (and:SI 
8545           (zero_extract:SI
8546             (match_operand 1 "ext_register_operand" "0")
8547             (const_int 8)
8548             (const_int 8))
8549           (zero_extend:SI
8550             (match_operand 2 "ext_register_operand" "Q"))))
8551    (clobber (reg:CC FLAGS_REG))]
8552   "TARGET_64BIT"
8553   "and{b}\t{%2, %h0|%h0, %2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "length_immediate" "0")
8556    (set_attr "mode" "QI")])
8558 (define_insn "*andqi_ext_2"
8559   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8560                          (const_int 8)
8561                          (const_int 8))
8562         (and:SI
8563           (zero_extract:SI
8564             (match_operand 1 "ext_register_operand" "%0")
8565             (const_int 8)
8566             (const_int 8))
8567           (zero_extract:SI
8568             (match_operand 2 "ext_register_operand" "Q")
8569             (const_int 8)
8570             (const_int 8))))
8571    (clobber (reg:CC FLAGS_REG))]
8572   ""
8573   "and{b}\t{%h2, %h0|%h0, %h2}"
8574   [(set_attr "type" "alu")
8575    (set_attr "length_immediate" "0")
8576    (set_attr "mode" "QI")])
8578 ;; Convert wide AND instructions with immediate operand to shorter QImode
8579 ;; equivalents when possible.
8580 ;; Don't do the splitting with memory operands, since it introduces risk
8581 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8582 ;; for size, but that can (should?) be handled by generic code instead.
8583 (define_split
8584   [(set (match_operand 0 "register_operand" "")
8585         (and (match_operand 1 "register_operand" "")
8586              (match_operand 2 "const_int_operand" "")))
8587    (clobber (reg:CC FLAGS_REG))]
8588    "reload_completed
8589     && QI_REG_P (operands[0])
8590     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8591     && !(~INTVAL (operands[2]) & ~(255 << 8))
8592     && GET_MODE (operands[0]) != QImode"
8593   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8594                    (and:SI (zero_extract:SI (match_dup 1)
8595                                             (const_int 8) (const_int 8))
8596                            (match_dup 2)))
8597               (clobber (reg:CC FLAGS_REG))])]
8598   "operands[0] = gen_lowpart (SImode, operands[0]);
8599    operands[1] = gen_lowpart (SImode, operands[1]);
8600    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8602 ;; Since AND can be encoded with sign extended immediate, this is only
8603 ;; profitable when 7th bit is not set.
8604 (define_split
8605   [(set (match_operand 0 "register_operand" "")
8606         (and (match_operand 1 "general_operand" "")
8607              (match_operand 2 "const_int_operand" "")))
8608    (clobber (reg:CC FLAGS_REG))]
8609    "reload_completed
8610     && ANY_QI_REG_P (operands[0])
8611     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8612     && !(~INTVAL (operands[2]) & ~255)
8613     && !(INTVAL (operands[2]) & 128)
8614     && GET_MODE (operands[0]) != QImode"
8615   [(parallel [(set (strict_low_part (match_dup 0))
8616                    (and:QI (match_dup 1)
8617                            (match_dup 2)))
8618               (clobber (reg:CC FLAGS_REG))])]
8619   "operands[0] = gen_lowpart (QImode, operands[0]);
8620    operands[1] = gen_lowpart (QImode, operands[1]);
8621    operands[2] = gen_lowpart (QImode, operands[2]);")
8623 ;; Logical inclusive OR instructions
8625 ;; %%% This used to optimize known byte-wide and operations to memory.
8626 ;; If this is considered useful, it should be done with splitters.
8628 (define_expand "iordi3"
8629   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8630         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8631                 (match_operand:DI 2 "x86_64_general_operand" "")))
8632    (clobber (reg:CC FLAGS_REG))]
8633   "TARGET_64BIT"
8634   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8636 (define_insn "*iordi_1_rex64"
8637   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8638         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8639                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8640    (clobber (reg:CC FLAGS_REG))]
8641   "TARGET_64BIT
8642    && ix86_binary_operator_ok (IOR, DImode, operands)"
8643   "or{q}\t{%2, %0|%0, %2}"
8644   [(set_attr "type" "alu")
8645    (set_attr "mode" "DI")])
8647 (define_insn "*iordi_2_rex64"
8648   [(set (reg 17)
8649         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8650                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8651                  (const_int 0)))
8652    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8653         (ior:DI (match_dup 1) (match_dup 2)))]
8654   "TARGET_64BIT
8655    && ix86_match_ccmode (insn, CCNOmode)
8656    && ix86_binary_operator_ok (IOR, DImode, operands)"
8657   "or{q}\t{%2, %0|%0, %2}"
8658   [(set_attr "type" "alu")
8659    (set_attr "mode" "DI")])
8661 (define_insn "*iordi_3_rex64"
8662   [(set (reg 17)
8663         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8664                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8665                  (const_int 0)))
8666    (clobber (match_scratch:DI 0 "=r"))]
8667   "TARGET_64BIT
8668    && ix86_match_ccmode (insn, CCNOmode)
8669    && ix86_binary_operator_ok (IOR, DImode, operands)"
8670   "or{q}\t{%2, %0|%0, %2}"
8671   [(set_attr "type" "alu")
8672    (set_attr "mode" "DI")])
8675 (define_expand "iorsi3"
8676   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8677         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8678                 (match_operand:SI 2 "general_operand" "")))
8679    (clobber (reg:CC FLAGS_REG))]
8680   ""
8681   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8683 (define_insn "*iorsi_1"
8684   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8685         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8686                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8687    (clobber (reg:CC FLAGS_REG))]
8688   "ix86_binary_operator_ok (IOR, SImode, operands)"
8689   "or{l}\t{%2, %0|%0, %2}"
8690   [(set_attr "type" "alu")
8691    (set_attr "mode" "SI")])
8693 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8694 (define_insn "*iorsi_1_zext"
8695   [(set (match_operand:DI 0 "register_operand" "=rm")
8696         (zero_extend:DI
8697           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8698                   (match_operand:SI 2 "general_operand" "rim"))))
8699    (clobber (reg:CC FLAGS_REG))]
8700   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8701   "or{l}\t{%2, %k0|%k0, %2}"
8702   [(set_attr "type" "alu")
8703    (set_attr "mode" "SI")])
8705 (define_insn "*iorsi_1_zext_imm"
8706   [(set (match_operand:DI 0 "register_operand" "=rm")
8707         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8708                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8709    (clobber (reg:CC FLAGS_REG))]
8710   "TARGET_64BIT"
8711   "or{l}\t{%2, %k0|%k0, %2}"
8712   [(set_attr "type" "alu")
8713    (set_attr "mode" "SI")])
8715 (define_insn "*iorsi_2"
8716   [(set (reg 17)
8717         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8718                          (match_operand:SI 2 "general_operand" "rim,ri"))
8719                  (const_int 0)))
8720    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8721         (ior:SI (match_dup 1) (match_dup 2)))]
8722   "ix86_match_ccmode (insn, CCNOmode)
8723    && ix86_binary_operator_ok (IOR, SImode, operands)"
8724   "or{l}\t{%2, %0|%0, %2}"
8725   [(set_attr "type" "alu")
8726    (set_attr "mode" "SI")])
8728 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8729 ;; ??? Special case for immediate operand is missing - it is tricky.
8730 (define_insn "*iorsi_2_zext"
8731   [(set (reg 17)
8732         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8733                          (match_operand:SI 2 "general_operand" "rim"))
8734                  (const_int 0)))
8735    (set (match_operand:DI 0 "register_operand" "=r")
8736         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8737   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8738    && ix86_binary_operator_ok (IOR, SImode, operands)"
8739   "or{l}\t{%2, %k0|%k0, %2}"
8740   [(set_attr "type" "alu")
8741    (set_attr "mode" "SI")])
8743 (define_insn "*iorsi_2_zext_imm"
8744   [(set (reg 17)
8745         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8746                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8747                  (const_int 0)))
8748    (set (match_operand:DI 0 "register_operand" "=r")
8749         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8750   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8751    && ix86_binary_operator_ok (IOR, SImode, operands)"
8752   "or{l}\t{%2, %k0|%k0, %2}"
8753   [(set_attr "type" "alu")
8754    (set_attr "mode" "SI")])
8756 (define_insn "*iorsi_3"
8757   [(set (reg 17)
8758         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8759                          (match_operand:SI 2 "general_operand" "rim"))
8760                  (const_int 0)))
8761    (clobber (match_scratch:SI 0 "=r"))]
8762   "ix86_match_ccmode (insn, CCNOmode)
8763    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8764   "or{l}\t{%2, %0|%0, %2}"
8765   [(set_attr "type" "alu")
8766    (set_attr "mode" "SI")])
8768 (define_expand "iorhi3"
8769   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8770         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8771                 (match_operand:HI 2 "general_operand" "")))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "TARGET_HIMODE_MATH"
8774   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8776 (define_insn "*iorhi_1"
8777   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8778         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8779                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8780    (clobber (reg:CC FLAGS_REG))]
8781   "ix86_binary_operator_ok (IOR, HImode, operands)"
8782   "or{w}\t{%2, %0|%0, %2}"
8783   [(set_attr "type" "alu")
8784    (set_attr "mode" "HI")])
8786 (define_insn "*iorhi_2"
8787   [(set (reg 17)
8788         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8789                          (match_operand:HI 2 "general_operand" "rim,ri"))
8790                  (const_int 0)))
8791    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8792         (ior:HI (match_dup 1) (match_dup 2)))]
8793   "ix86_match_ccmode (insn, CCNOmode)
8794    && ix86_binary_operator_ok (IOR, HImode, operands)"
8795   "or{w}\t{%2, %0|%0, %2}"
8796   [(set_attr "type" "alu")
8797    (set_attr "mode" "HI")])
8799 (define_insn "*iorhi_3"
8800   [(set (reg 17)
8801         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8802                          (match_operand:HI 2 "general_operand" "rim"))
8803                  (const_int 0)))
8804    (clobber (match_scratch:HI 0 "=r"))]
8805   "ix86_match_ccmode (insn, CCNOmode)
8806    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8807   "or{w}\t{%2, %0|%0, %2}"
8808   [(set_attr "type" "alu")
8809    (set_attr "mode" "HI")])
8811 (define_expand "iorqi3"
8812   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8813         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8814                 (match_operand:QI 2 "general_operand" "")))
8815    (clobber (reg:CC FLAGS_REG))]
8816   "TARGET_QIMODE_MATH"
8817   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8819 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8820 (define_insn "*iorqi_1"
8821   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8822         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8823                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8824    (clobber (reg:CC FLAGS_REG))]
8825   "ix86_binary_operator_ok (IOR, QImode, operands)"
8826   "@
8827    or{b}\t{%2, %0|%0, %2}
8828    or{b}\t{%2, %0|%0, %2}
8829    or{l}\t{%k2, %k0|%k0, %k2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "mode" "QI,QI,SI")])
8833 (define_insn "*iorqi_1_slp"
8834   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8835         (ior:QI (match_dup 0)
8836                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8837    (clobber (reg:CC FLAGS_REG))]
8838   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8839    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8840   "or{b}\t{%1, %0|%0, %1}"
8841   [(set_attr "type" "alu1")
8842    (set_attr "mode" "QI")])
8844 (define_insn "*iorqi_2"
8845   [(set (reg 17)
8846         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8847                          (match_operand:QI 2 "general_operand" "qim,qi"))
8848                  (const_int 0)))
8849    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8850         (ior:QI (match_dup 1) (match_dup 2)))]
8851   "ix86_match_ccmode (insn, CCNOmode)
8852    && ix86_binary_operator_ok (IOR, QImode, operands)"
8853   "or{b}\t{%2, %0|%0, %2}"
8854   [(set_attr "type" "alu")
8855    (set_attr "mode" "QI")])
8857 (define_insn "*iorqi_2_slp"
8858   [(set (reg 17)
8859         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8860                          (match_operand:QI 1 "general_operand" "qim,qi"))
8861                  (const_int 0)))
8862    (set (strict_low_part (match_dup 0))
8863         (ior:QI (match_dup 0) (match_dup 1)))]
8864   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8865    && ix86_match_ccmode (insn, CCNOmode)
8866    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8867   "or{b}\t{%1, %0|%0, %1}"
8868   [(set_attr "type" "alu1")
8869    (set_attr "mode" "QI")])
8871 (define_insn "*iorqi_3"
8872   [(set (reg 17)
8873         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8874                          (match_operand:QI 2 "general_operand" "qim"))
8875                  (const_int 0)))
8876    (clobber (match_scratch:QI 0 "=q"))]
8877   "ix86_match_ccmode (insn, CCNOmode)
8878    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8879   "or{b}\t{%2, %0|%0, %2}"
8880   [(set_attr "type" "alu")
8881    (set_attr "mode" "QI")])
8883 (define_insn "iorqi_ext_0"
8884   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8885                          (const_int 8)
8886                          (const_int 8))
8887         (ior:SI 
8888           (zero_extract:SI
8889             (match_operand 1 "ext_register_operand" "0")
8890             (const_int 8)
8891             (const_int 8))
8892           (match_operand 2 "const_int_operand" "n")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8895   "or{b}\t{%2, %h0|%h0, %2}"
8896   [(set_attr "type" "alu")
8897    (set_attr "length_immediate" "1")
8898    (set_attr "mode" "QI")])
8900 (define_insn "*iorqi_ext_1"
8901   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8902                          (const_int 8)
8903                          (const_int 8))
8904         (ior:SI 
8905           (zero_extract:SI
8906             (match_operand 1 "ext_register_operand" "0")
8907             (const_int 8)
8908             (const_int 8))
8909           (zero_extend:SI
8910             (match_operand:QI 2 "general_operand" "Qm"))))
8911    (clobber (reg:CC FLAGS_REG))]
8912   "!TARGET_64BIT
8913    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8914   "or{b}\t{%2, %h0|%h0, %2}"
8915   [(set_attr "type" "alu")
8916    (set_attr "length_immediate" "0")
8917    (set_attr "mode" "QI")])
8919 (define_insn "*iorqi_ext_1_rex64"
8920   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8921                          (const_int 8)
8922                          (const_int 8))
8923         (ior:SI 
8924           (zero_extract:SI
8925             (match_operand 1 "ext_register_operand" "0")
8926             (const_int 8)
8927             (const_int 8))
8928           (zero_extend:SI
8929             (match_operand 2 "ext_register_operand" "Q"))))
8930    (clobber (reg:CC FLAGS_REG))]
8931   "TARGET_64BIT
8932    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8933   "or{b}\t{%2, %h0|%h0, %2}"
8934   [(set_attr "type" "alu")
8935    (set_attr "length_immediate" "0")
8936    (set_attr "mode" "QI")])
8938 (define_insn "*iorqi_ext_2"
8939   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8940                          (const_int 8)
8941                          (const_int 8))
8942         (ior:SI 
8943           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8944                            (const_int 8)
8945                            (const_int 8))
8946           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8947                            (const_int 8)
8948                            (const_int 8))))
8949    (clobber (reg:CC FLAGS_REG))]
8950   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8951   "ior{b}\t{%h2, %h0|%h0, %h2}"
8952   [(set_attr "type" "alu")
8953    (set_attr "length_immediate" "0")
8954    (set_attr "mode" "QI")])
8956 (define_split
8957   [(set (match_operand 0 "register_operand" "")
8958         (ior (match_operand 1 "register_operand" "")
8959              (match_operand 2 "const_int_operand" "")))
8960    (clobber (reg:CC FLAGS_REG))]
8961    "reload_completed
8962     && QI_REG_P (operands[0])
8963     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8964     && !(INTVAL (operands[2]) & ~(255 << 8))
8965     && GET_MODE (operands[0]) != QImode"
8966   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8967                    (ior:SI (zero_extract:SI (match_dup 1)
8968                                             (const_int 8) (const_int 8))
8969                            (match_dup 2)))
8970               (clobber (reg:CC FLAGS_REG))])]
8971   "operands[0] = gen_lowpart (SImode, operands[0]);
8972    operands[1] = gen_lowpart (SImode, operands[1]);
8973    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8975 ;; Since OR can be encoded with sign extended immediate, this is only
8976 ;; profitable when 7th bit is set.
8977 (define_split
8978   [(set (match_operand 0 "register_operand" "")
8979         (ior (match_operand 1 "general_operand" "")
8980              (match_operand 2 "const_int_operand" "")))
8981    (clobber (reg:CC FLAGS_REG))]
8982    "reload_completed
8983     && ANY_QI_REG_P (operands[0])
8984     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8985     && !(INTVAL (operands[2]) & ~255)
8986     && (INTVAL (operands[2]) & 128)
8987     && GET_MODE (operands[0]) != QImode"
8988   [(parallel [(set (strict_low_part (match_dup 0))
8989                    (ior:QI (match_dup 1)
8990                            (match_dup 2)))
8991               (clobber (reg:CC FLAGS_REG))])]
8992   "operands[0] = gen_lowpart (QImode, operands[0]);
8993    operands[1] = gen_lowpart (QImode, operands[1]);
8994    operands[2] = gen_lowpart (QImode, operands[2]);")
8996 ;; Logical XOR instructions
8998 ;; %%% This used to optimize known byte-wide and operations to memory.
8999 ;; If this is considered useful, it should be done with splitters.
9001 (define_expand "xordi3"
9002   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9003         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9004                 (match_operand:DI 2 "x86_64_general_operand" "")))
9005    (clobber (reg:CC FLAGS_REG))]
9006   "TARGET_64BIT"
9007   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9009 (define_insn "*xordi_1_rex64"
9010   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9011         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9012                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9013    (clobber (reg:CC FLAGS_REG))]
9014   "TARGET_64BIT
9015    && ix86_binary_operator_ok (XOR, DImode, operands)"
9016   "@
9017    xor{q}\t{%2, %0|%0, %2}
9018    xor{q}\t{%2, %0|%0, %2}"
9019   [(set_attr "type" "alu")
9020    (set_attr "mode" "DI,DI")])
9022 (define_insn "*xordi_2_rex64"
9023   [(set (reg 17)
9024         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9025                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9026                  (const_int 0)))
9027    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9028         (xor:DI (match_dup 1) (match_dup 2)))]
9029   "TARGET_64BIT
9030    && ix86_match_ccmode (insn, CCNOmode)
9031    && ix86_binary_operator_ok (XOR, DImode, operands)"
9032   "@
9033    xor{q}\t{%2, %0|%0, %2}
9034    xor{q}\t{%2, %0|%0, %2}"
9035   [(set_attr "type" "alu")
9036    (set_attr "mode" "DI,DI")])
9038 (define_insn "*xordi_3_rex64"
9039   [(set (reg 17)
9040         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9041                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9042                  (const_int 0)))
9043    (clobber (match_scratch:DI 0 "=r"))]
9044   "TARGET_64BIT
9045    && ix86_match_ccmode (insn, CCNOmode)
9046    && ix86_binary_operator_ok (XOR, DImode, operands)"
9047   "xor{q}\t{%2, %0|%0, %2}"
9048   [(set_attr "type" "alu")
9049    (set_attr "mode" "DI")])
9051 (define_expand "xorsi3"
9052   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9053         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9054                 (match_operand:SI 2 "general_operand" "")))
9055    (clobber (reg:CC FLAGS_REG))]
9056   ""
9057   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9059 (define_insn "*xorsi_1"
9060   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9061         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9062                 (match_operand:SI 2 "general_operand" "ri,rm")))
9063    (clobber (reg:CC FLAGS_REG))]
9064   "ix86_binary_operator_ok (XOR, SImode, operands)"
9065   "xor{l}\t{%2, %0|%0, %2}"
9066   [(set_attr "type" "alu")
9067    (set_attr "mode" "SI")])
9069 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9070 ;; Add speccase for immediates
9071 (define_insn "*xorsi_1_zext"
9072   [(set (match_operand:DI 0 "register_operand" "=r")
9073         (zero_extend:DI
9074           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9075                   (match_operand:SI 2 "general_operand" "rim"))))
9076    (clobber (reg:CC FLAGS_REG))]
9077   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9078   "xor{l}\t{%2, %k0|%k0, %2}"
9079   [(set_attr "type" "alu")
9080    (set_attr "mode" "SI")])
9082 (define_insn "*xorsi_1_zext_imm"
9083   [(set (match_operand:DI 0 "register_operand" "=r")
9084         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9085                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9086    (clobber (reg:CC FLAGS_REG))]
9087   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9088   "xor{l}\t{%2, %k0|%k0, %2}"
9089   [(set_attr "type" "alu")
9090    (set_attr "mode" "SI")])
9092 (define_insn "*xorsi_2"
9093   [(set (reg 17)
9094         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9095                          (match_operand:SI 2 "general_operand" "rim,ri"))
9096                  (const_int 0)))
9097    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9098         (xor:SI (match_dup 1) (match_dup 2)))]
9099   "ix86_match_ccmode (insn, CCNOmode)
9100    && ix86_binary_operator_ok (XOR, SImode, operands)"
9101   "xor{l}\t{%2, %0|%0, %2}"
9102   [(set_attr "type" "alu")
9103    (set_attr "mode" "SI")])
9105 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9106 ;; ??? Special case for immediate operand is missing - it is tricky.
9107 (define_insn "*xorsi_2_zext"
9108   [(set (reg 17)
9109         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9110                          (match_operand:SI 2 "general_operand" "rim"))
9111                  (const_int 0)))
9112    (set (match_operand:DI 0 "register_operand" "=r")
9113         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9114   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9115    && ix86_binary_operator_ok (XOR, SImode, operands)"
9116   "xor{l}\t{%2, %k0|%k0, %2}"
9117   [(set_attr "type" "alu")
9118    (set_attr "mode" "SI")])
9120 (define_insn "*xorsi_2_zext_imm"
9121   [(set (reg 17)
9122         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9123                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9124                  (const_int 0)))
9125    (set (match_operand:DI 0 "register_operand" "=r")
9126         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9127   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9128    && ix86_binary_operator_ok (XOR, SImode, operands)"
9129   "xor{l}\t{%2, %k0|%k0, %2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "mode" "SI")])
9133 (define_insn "*xorsi_3"
9134   [(set (reg 17)
9135         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9136                          (match_operand:SI 2 "general_operand" "rim"))
9137                  (const_int 0)))
9138    (clobber (match_scratch:SI 0 "=r"))]
9139   "ix86_match_ccmode (insn, CCNOmode)
9140    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9141   "xor{l}\t{%2, %0|%0, %2}"
9142   [(set_attr "type" "alu")
9143    (set_attr "mode" "SI")])
9145 (define_expand "xorhi3"
9146   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9147         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9148                 (match_operand:HI 2 "general_operand" "")))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "TARGET_HIMODE_MATH"
9151   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9153 (define_insn "*xorhi_1"
9154   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9155         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9156                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9157    (clobber (reg:CC FLAGS_REG))]
9158   "ix86_binary_operator_ok (XOR, HImode, operands)"
9159   "xor{w}\t{%2, %0|%0, %2}"
9160   [(set_attr "type" "alu")
9161    (set_attr "mode" "HI")])
9163 (define_insn "*xorhi_2"
9164   [(set (reg 17)
9165         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9166                          (match_operand:HI 2 "general_operand" "rim,ri"))
9167                  (const_int 0)))
9168    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9169         (xor:HI (match_dup 1) (match_dup 2)))]
9170   "ix86_match_ccmode (insn, CCNOmode)
9171    && ix86_binary_operator_ok (XOR, HImode, operands)"
9172   "xor{w}\t{%2, %0|%0, %2}"
9173   [(set_attr "type" "alu")
9174    (set_attr "mode" "HI")])
9176 (define_insn "*xorhi_3"
9177   [(set (reg 17)
9178         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9179                          (match_operand:HI 2 "general_operand" "rim"))
9180                  (const_int 0)))
9181    (clobber (match_scratch:HI 0 "=r"))]
9182   "ix86_match_ccmode (insn, CCNOmode)
9183    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9184   "xor{w}\t{%2, %0|%0, %2}"
9185   [(set_attr "type" "alu")
9186    (set_attr "mode" "HI")])
9188 (define_expand "xorqi3"
9189   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9190         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9191                 (match_operand:QI 2 "general_operand" "")))
9192    (clobber (reg:CC FLAGS_REG))]
9193   "TARGET_QIMODE_MATH"
9194   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9196 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9197 (define_insn "*xorqi_1"
9198   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9199         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9200                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9201    (clobber (reg:CC FLAGS_REG))]
9202   "ix86_binary_operator_ok (XOR, QImode, operands)"
9203   "@
9204    xor{b}\t{%2, %0|%0, %2}
9205    xor{b}\t{%2, %0|%0, %2}
9206    xor{l}\t{%k2, %k0|%k0, %k2}"
9207   [(set_attr "type" "alu")
9208    (set_attr "mode" "QI,QI,SI")])
9210 (define_insn "*xorqi_1_slp"
9211   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9212         (xor:QI (match_dup 0)
9213                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9214    (clobber (reg:CC FLAGS_REG))]
9215   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9216    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9217   "xor{b}\t{%1, %0|%0, %1}"
9218   [(set_attr "type" "alu1")
9219    (set_attr "mode" "QI")])
9221 (define_insn "xorqi_ext_0"
9222   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9223                          (const_int 8)
9224                          (const_int 8))
9225         (xor:SI 
9226           (zero_extract:SI
9227             (match_operand 1 "ext_register_operand" "0")
9228             (const_int 8)
9229             (const_int 8))
9230           (match_operand 2 "const_int_operand" "n")))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9233   "xor{b}\t{%2, %h0|%h0, %2}"
9234   [(set_attr "type" "alu")
9235    (set_attr "length_immediate" "1")
9236    (set_attr "mode" "QI")])
9238 (define_insn "*xorqi_ext_1"
9239   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9240                          (const_int 8)
9241                          (const_int 8))
9242         (xor:SI 
9243           (zero_extract:SI
9244             (match_operand 1 "ext_register_operand" "0")
9245             (const_int 8)
9246             (const_int 8))
9247           (zero_extend:SI
9248             (match_operand:QI 2 "general_operand" "Qm"))))
9249    (clobber (reg:CC FLAGS_REG))]
9250   "!TARGET_64BIT
9251    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9252   "xor{b}\t{%2, %h0|%h0, %2}"
9253   [(set_attr "type" "alu")
9254    (set_attr "length_immediate" "0")
9255    (set_attr "mode" "QI")])
9257 (define_insn "*xorqi_ext_1_rex64"
9258   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9259                          (const_int 8)
9260                          (const_int 8))
9261         (xor:SI 
9262           (zero_extract:SI
9263             (match_operand 1 "ext_register_operand" "0")
9264             (const_int 8)
9265             (const_int 8))
9266           (zero_extend:SI
9267             (match_operand 2 "ext_register_operand" "Q"))))
9268    (clobber (reg:CC FLAGS_REG))]
9269   "TARGET_64BIT
9270    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9271   "xor{b}\t{%2, %h0|%h0, %2}"
9272   [(set_attr "type" "alu")
9273    (set_attr "length_immediate" "0")
9274    (set_attr "mode" "QI")])
9276 (define_insn "*xorqi_ext_2"
9277   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9278                          (const_int 8)
9279                          (const_int 8))
9280         (xor:SI 
9281           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9282                            (const_int 8)
9283                            (const_int 8))
9284           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9285                            (const_int 8)
9286                            (const_int 8))))
9287    (clobber (reg:CC FLAGS_REG))]
9288   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9289   "xor{b}\t{%h2, %h0|%h0, %h2}"
9290   [(set_attr "type" "alu")
9291    (set_attr "length_immediate" "0")
9292    (set_attr "mode" "QI")])
9294 (define_insn "*xorqi_cc_1"
9295   [(set (reg 17)
9296         (compare
9297           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9298                   (match_operand:QI 2 "general_operand" "qim,qi"))
9299           (const_int 0)))
9300    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9301         (xor:QI (match_dup 1) (match_dup 2)))]
9302   "ix86_match_ccmode (insn, CCNOmode)
9303    && ix86_binary_operator_ok (XOR, QImode, operands)"
9304   "xor{b}\t{%2, %0|%0, %2}"
9305   [(set_attr "type" "alu")
9306    (set_attr "mode" "QI")])
9308 (define_insn "*xorqi_2_slp"
9309   [(set (reg 17)
9310         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9311                          (match_operand:QI 1 "general_operand" "qim,qi"))
9312                  (const_int 0)))
9313    (set (strict_low_part (match_dup 0))
9314         (xor:QI (match_dup 0) (match_dup 1)))]
9315   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9316    && ix86_match_ccmode (insn, CCNOmode)
9317    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9318   "xor{b}\t{%1, %0|%0, %1}"
9319   [(set_attr "type" "alu1")
9320    (set_attr "mode" "QI")])
9322 (define_insn "*xorqi_cc_2"
9323   [(set (reg 17)
9324         (compare
9325           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9326                   (match_operand:QI 2 "general_operand" "qim"))
9327           (const_int 0)))
9328    (clobber (match_scratch:QI 0 "=q"))]
9329   "ix86_match_ccmode (insn, CCNOmode)
9330    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9331   "xor{b}\t{%2, %0|%0, %2}"
9332   [(set_attr "type" "alu")
9333    (set_attr "mode" "QI")])
9335 (define_insn "*xorqi_cc_ext_1"
9336   [(set (reg 17)
9337         (compare
9338           (xor:SI
9339             (zero_extract:SI
9340               (match_operand 1 "ext_register_operand" "0")
9341               (const_int 8)
9342               (const_int 8))
9343             (match_operand:QI 2 "general_operand" "qmn"))
9344           (const_int 0)))
9345    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9346                          (const_int 8)
9347                          (const_int 8))
9348         (xor:SI 
9349           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9350           (match_dup 2)))]
9351   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9352   "xor{b}\t{%2, %h0|%h0, %2}"
9353   [(set_attr "type" "alu")
9354    (set_attr "mode" "QI")])
9356 (define_insn "*xorqi_cc_ext_1_rex64"
9357   [(set (reg 17)
9358         (compare
9359           (xor:SI
9360             (zero_extract:SI
9361               (match_operand 1 "ext_register_operand" "0")
9362               (const_int 8)
9363               (const_int 8))
9364             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9365           (const_int 0)))
9366    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9367                          (const_int 8)
9368                          (const_int 8))
9369         (xor:SI 
9370           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9371           (match_dup 2)))]
9372   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9373   "xor{b}\t{%2, %h0|%h0, %2}"
9374   [(set_attr "type" "alu")
9375    (set_attr "mode" "QI")])
9377 (define_expand "xorqi_cc_ext_1"
9378   [(parallel [
9379      (set (reg:CCNO FLAGS_REG)
9380           (compare:CCNO
9381             (xor:SI
9382               (zero_extract:SI
9383                 (match_operand 1 "ext_register_operand" "")
9384                 (const_int 8)
9385                 (const_int 8))
9386               (match_operand:QI 2 "general_operand" ""))
9387             (const_int 0)))
9388      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9389                            (const_int 8)
9390                            (const_int 8))
9391           (xor:SI 
9392             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9393             (match_dup 2)))])]
9394   ""
9395   "")
9397 (define_split
9398   [(set (match_operand 0 "register_operand" "")
9399         (xor (match_operand 1 "register_operand" "")
9400              (match_operand 2 "const_int_operand" "")))
9401    (clobber (reg:CC FLAGS_REG))]
9402    "reload_completed
9403     && QI_REG_P (operands[0])
9404     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9405     && !(INTVAL (operands[2]) & ~(255 << 8))
9406     && GET_MODE (operands[0]) != QImode"
9407   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9408                    (xor:SI (zero_extract:SI (match_dup 1)
9409                                             (const_int 8) (const_int 8))
9410                            (match_dup 2)))
9411               (clobber (reg:CC FLAGS_REG))])]
9412   "operands[0] = gen_lowpart (SImode, operands[0]);
9413    operands[1] = gen_lowpart (SImode, operands[1]);
9414    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9416 ;; Since XOR can be encoded with sign extended immediate, this is only
9417 ;; profitable when 7th bit is set.
9418 (define_split
9419   [(set (match_operand 0 "register_operand" "")
9420         (xor (match_operand 1 "general_operand" "")
9421              (match_operand 2 "const_int_operand" "")))
9422    (clobber (reg:CC FLAGS_REG))]
9423    "reload_completed
9424     && ANY_QI_REG_P (operands[0])
9425     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9426     && !(INTVAL (operands[2]) & ~255)
9427     && (INTVAL (operands[2]) & 128)
9428     && GET_MODE (operands[0]) != QImode"
9429   [(parallel [(set (strict_low_part (match_dup 0))
9430                    (xor:QI (match_dup 1)
9431                            (match_dup 2)))
9432               (clobber (reg:CC FLAGS_REG))])]
9433   "operands[0] = gen_lowpart (QImode, operands[0]);
9434    operands[1] = gen_lowpart (QImode, operands[1]);
9435    operands[2] = gen_lowpart (QImode, operands[2]);")
9437 ;; Negation instructions
9439 (define_expand "negdi2"
9440   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9441                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9442               (clobber (reg:CC FLAGS_REG))])]
9443   ""
9444   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9446 (define_insn "*negdi2_1"
9447   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9448         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9449    (clobber (reg:CC FLAGS_REG))]
9450   "!TARGET_64BIT
9451    && ix86_unary_operator_ok (NEG, DImode, operands)"
9452   "#")
9454 (define_split
9455   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9456         (neg:DI (match_operand:DI 1 "general_operand" "")))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "!TARGET_64BIT && reload_completed"
9459   [(parallel
9460     [(set (reg:CCZ FLAGS_REG)
9461           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9462      (set (match_dup 0) (neg:SI (match_dup 2)))])
9463    (parallel
9464     [(set (match_dup 1)
9465           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9466                             (match_dup 3))
9467                    (const_int 0)))
9468      (clobber (reg:CC FLAGS_REG))])
9469    (parallel
9470     [(set (match_dup 1)
9471           (neg:SI (match_dup 1)))
9472      (clobber (reg:CC FLAGS_REG))])]
9473   "split_di (operands+1, 1, operands+2, operands+3);
9474    split_di (operands+0, 1, operands+0, operands+1);")
9476 (define_insn "*negdi2_1_rex64"
9477   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9478         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9479    (clobber (reg:CC FLAGS_REG))]
9480   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9481   "neg{q}\t%0"
9482   [(set_attr "type" "negnot")
9483    (set_attr "mode" "DI")])
9485 ;; The problem with neg is that it does not perform (compare x 0),
9486 ;; it really performs (compare 0 x), which leaves us with the zero
9487 ;; flag being the only useful item.
9489 (define_insn "*negdi2_cmpz_rex64"
9490   [(set (reg:CCZ FLAGS_REG)
9491         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9492                      (const_int 0)))
9493    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9494         (neg:DI (match_dup 1)))]
9495   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9496   "neg{q}\t%0"
9497   [(set_attr "type" "negnot")
9498    (set_attr "mode" "DI")])
9501 (define_expand "negsi2"
9502   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9503                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9504               (clobber (reg:CC FLAGS_REG))])]
9505   ""
9506   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9508 (define_insn "*negsi2_1"
9509   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9510         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9511    (clobber (reg:CC FLAGS_REG))]
9512   "ix86_unary_operator_ok (NEG, SImode, operands)"
9513   "neg{l}\t%0"
9514   [(set_attr "type" "negnot")
9515    (set_attr "mode" "SI")])
9517 ;; Combine is quite creative about this pattern.
9518 (define_insn "*negsi2_1_zext"
9519   [(set (match_operand:DI 0 "register_operand" "=r")
9520         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9521                                         (const_int 32)))
9522                      (const_int 32)))
9523    (clobber (reg:CC FLAGS_REG))]
9524   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9525   "neg{l}\t%k0"
9526   [(set_attr "type" "negnot")
9527    (set_attr "mode" "SI")])
9529 ;; The problem with neg is that it does not perform (compare x 0),
9530 ;; it really performs (compare 0 x), which leaves us with the zero
9531 ;; flag being the only useful item.
9533 (define_insn "*negsi2_cmpz"
9534   [(set (reg:CCZ FLAGS_REG)
9535         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9536                      (const_int 0)))
9537    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9538         (neg:SI (match_dup 1)))]
9539   "ix86_unary_operator_ok (NEG, SImode, operands)"
9540   "neg{l}\t%0"
9541   [(set_attr "type" "negnot")
9542    (set_attr "mode" "SI")])
9544 (define_insn "*negsi2_cmpz_zext"
9545   [(set (reg:CCZ FLAGS_REG)
9546         (compare:CCZ (lshiftrt:DI
9547                        (neg:DI (ashift:DI
9548                                  (match_operand:DI 1 "register_operand" "0")
9549                                  (const_int 32)))
9550                        (const_int 32))
9551                      (const_int 0)))
9552    (set (match_operand:DI 0 "register_operand" "=r")
9553         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9554                                         (const_int 32)))
9555                      (const_int 32)))]
9556   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9557   "neg{l}\t%k0"
9558   [(set_attr "type" "negnot")
9559    (set_attr "mode" "SI")])
9561 (define_expand "neghi2"
9562   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9563                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9564               (clobber (reg:CC FLAGS_REG))])]
9565   "TARGET_HIMODE_MATH"
9566   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9568 (define_insn "*neghi2_1"
9569   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9570         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9571    (clobber (reg:CC FLAGS_REG))]
9572   "ix86_unary_operator_ok (NEG, HImode, operands)"
9573   "neg{w}\t%0"
9574   [(set_attr "type" "negnot")
9575    (set_attr "mode" "HI")])
9577 (define_insn "*neghi2_cmpz"
9578   [(set (reg:CCZ FLAGS_REG)
9579         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9580                      (const_int 0)))
9581    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9582         (neg:HI (match_dup 1)))]
9583   "ix86_unary_operator_ok (NEG, HImode, operands)"
9584   "neg{w}\t%0"
9585   [(set_attr "type" "negnot")
9586    (set_attr "mode" "HI")])
9588 (define_expand "negqi2"
9589   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9590                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9591               (clobber (reg:CC FLAGS_REG))])]
9592   "TARGET_QIMODE_MATH"
9593   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9595 (define_insn "*negqi2_1"
9596   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9597         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9598    (clobber (reg:CC FLAGS_REG))]
9599   "ix86_unary_operator_ok (NEG, QImode, operands)"
9600   "neg{b}\t%0"
9601   [(set_attr "type" "negnot")
9602    (set_attr "mode" "QI")])
9604 (define_insn "*negqi2_cmpz"
9605   [(set (reg:CCZ FLAGS_REG)
9606         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9607                      (const_int 0)))
9608    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9609         (neg:QI (match_dup 1)))]
9610   "ix86_unary_operator_ok (NEG, QImode, operands)"
9611   "neg{b}\t%0"
9612   [(set_attr "type" "negnot")
9613    (set_attr "mode" "QI")])
9615 ;; Changing of sign for FP values is doable using integer unit too.
9617 (define_expand "negsf2"
9618   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9619                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9620               (clobber (reg:CC FLAGS_REG))])]
9621   "TARGET_80387"
9622   "if (TARGET_SSE)
9623      {
9624        /* In case operand is in memory,  we will not use SSE.  */
9625        if (memory_operand (operands[0], VOIDmode)
9626            && rtx_equal_p (operands[0], operands[1]))
9627          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9628        else
9629         {
9630           /* Using SSE is tricky, since we need bitwise negation of -0
9631              in register.  */
9632           rtx reg = gen_reg_rtx (SFmode);
9633           rtx dest = operands[0];
9634           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9636           operands[1] = force_reg (SFmode, operands[1]);
9637           operands[0] = force_reg (SFmode, operands[0]);
9638           reg = force_reg (V4SFmode,
9639                            gen_rtx_CONST_VECTOR (V4SFmode,
9640                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9641                                         CONST0_RTX (SFmode),
9642                                         CONST0_RTX (SFmode))));
9643           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9644           if (dest != operands[0])
9645             emit_move_insn (dest, operands[0]);
9646         }
9647        DONE;
9648      }
9649    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9651 (define_insn "negsf2_memory"
9652   [(set (match_operand:SF 0 "memory_operand" "=m")
9653         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9654    (clobber (reg:CC FLAGS_REG))]
9655   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9656   "#")
9658 (define_insn "negsf2_ifs"
9659   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9660         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9661    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9662    (clobber (reg:CC FLAGS_REG))]
9663   "TARGET_SSE
9664    && (reload_in_progress || reload_completed
9665        || (register_operand (operands[0], VOIDmode)
9666            && register_operand (operands[1], VOIDmode)))"
9667   "#")
9669 (define_split
9670   [(set (match_operand:SF 0 "memory_operand" "")
9671         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9672    (use (match_operand:SF 2 "" ""))
9673    (clobber (reg:CC FLAGS_REG))]
9674   ""
9675   [(parallel [(set (match_dup 0)
9676                    (neg:SF (match_dup 1)))
9677               (clobber (reg:CC FLAGS_REG))])])
9679 (define_split
9680   [(set (match_operand:SF 0 "register_operand" "")
9681         (neg:SF (match_operand:SF 1 "register_operand" "")))
9682    (use (match_operand:V4SF 2 "" ""))
9683    (clobber (reg:CC FLAGS_REG))]
9684   "reload_completed && !SSE_REG_P (operands[0])"
9685   [(parallel [(set (match_dup 0)
9686                    (neg:SF (match_dup 1)))
9687               (clobber (reg:CC FLAGS_REG))])])
9689 (define_split
9690   [(set (match_operand:SF 0 "register_operand" "")
9691         (neg:SF (match_operand:SF 1 "register_operand" "")))
9692    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9693    (clobber (reg:CC FLAGS_REG))]
9694   "reload_completed && SSE_REG_P (operands[0])"
9695   [(set (match_dup 0)
9696         (xor:V4SF (match_dup 1)
9697                   (match_dup 2)))]
9699   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9700   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9701   if (operands_match_p (operands[0], operands[2]))
9702     {
9703       rtx tmp;
9704       tmp = operands[1];
9705       operands[1] = operands[2];
9706       operands[2] = tmp;
9707     }
9711 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9712 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9713 ;; to itself.
9714 (define_insn "*negsf2_if"
9715   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9716         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9717    (clobber (reg:CC FLAGS_REG))]
9718   "TARGET_80387 && !TARGET_SSE
9719    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9720   "#")
9722 (define_split
9723   [(set (match_operand:SF 0 "fp_register_operand" "")
9724         (neg:SF (match_operand:SF 1 "register_operand" "")))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "TARGET_80387 && reload_completed"
9727   [(set (match_dup 0)
9728         (neg:SF (match_dup 1)))]
9729   "")
9731 (define_split
9732   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9733         (neg:SF (match_operand:SF 1 "register_operand" "")))
9734    (clobber (reg:CC FLAGS_REG))]
9735   "TARGET_80387 && reload_completed"
9736   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9737               (clobber (reg:CC FLAGS_REG))])]
9738   "operands[1] = gen_int_mode (0x80000000, SImode);
9739    operands[0] = gen_lowpart (SImode, operands[0]);")
9741 (define_split
9742   [(set (match_operand 0 "memory_operand" "")
9743         (neg (match_operand 1 "memory_operand" "")))
9744    (clobber (reg:CC FLAGS_REG))]
9745   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9746   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9747               (clobber (reg:CC FLAGS_REG))])]
9749   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9751   if (GET_MODE (operands[1]) == XFmode)
9752     size = 10;
9753   operands[0] = adjust_address (operands[0], QImode, size - 1);
9754   operands[1] = gen_int_mode (0x80, QImode);
9757 (define_expand "negdf2"
9758   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9759                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9760               (clobber (reg:CC FLAGS_REG))])]
9761   "TARGET_80387"
9762   "if (TARGET_SSE2)
9763      {
9764        /* In case operand is in memory,  we will not use SSE.  */
9765        if (memory_operand (operands[0], VOIDmode)
9766            && rtx_equal_p (operands[0], operands[1]))
9767          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9768        else
9769         {
9770           /* Using SSE is tricky, since we need bitwise negation of -0
9771              in register.  */
9772           rtx reg;
9773 #if HOST_BITS_PER_WIDE_INT >= 64
9774           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9775 #else
9776           rtx imm = immed_double_const (0, 0x80000000, DImode);
9777 #endif
9778           rtx dest = operands[0];
9780           operands[1] = force_reg (DFmode, operands[1]);
9781           operands[0] = force_reg (DFmode, operands[0]);
9782           imm = gen_lowpart (DFmode, imm);
9783           reg = force_reg (V2DFmode,
9784                            gen_rtx_CONST_VECTOR (V2DFmode,
9785                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9786           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9787           if (dest != operands[0])
9788             emit_move_insn (dest, operands[0]);
9789         }
9790        DONE;
9791      }
9792    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9794 (define_insn "negdf2_memory"
9795   [(set (match_operand:DF 0 "memory_operand" "=m")
9796         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9799   "#")
9801 (define_insn "negdf2_ifs"
9802   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9803         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9804    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9805    (clobber (reg:CC FLAGS_REG))]
9806   "!TARGET_64BIT && TARGET_SSE2
9807    && (reload_in_progress || reload_completed
9808        || (register_operand (operands[0], VOIDmode)
9809            && register_operand (operands[1], VOIDmode)))"
9810   "#")
9812 (define_insn "*negdf2_ifs_rex64"
9813   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9814         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9815    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9816    (clobber (reg:CC FLAGS_REG))]
9817   "TARGET_64BIT && TARGET_SSE2
9818    && (reload_in_progress || reload_completed
9819        || (register_operand (operands[0], VOIDmode)
9820            && register_operand (operands[1], VOIDmode)))"
9821   "#")
9823 (define_split
9824   [(set (match_operand:DF 0 "memory_operand" "")
9825         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9826    (use (match_operand:V2DF 2 "" ""))
9827    (clobber (reg:CC FLAGS_REG))]
9828   ""
9829   [(parallel [(set (match_dup 0)
9830                    (neg:DF (match_dup 1)))
9831               (clobber (reg:CC FLAGS_REG))])])
9833 (define_split
9834   [(set (match_operand:DF 0 "register_operand" "")
9835         (neg:DF (match_operand:DF 1 "register_operand" "")))
9836    (use (match_operand:V2DF 2 "" ""))
9837    (clobber (reg:CC FLAGS_REG))]
9838   "reload_completed && !SSE_REG_P (operands[0])
9839    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9840   [(parallel [(set (match_dup 0)
9841                    (neg:DF (match_dup 1)))
9842               (clobber (reg:CC FLAGS_REG))])])
9844 (define_split
9845   [(set (match_operand:DF 0 "register_operand" "")
9846         (neg:DF (match_operand:DF 1 "register_operand" "")))
9847    (use (match_operand:V2DF 2 "" ""))
9848    (clobber (reg:CC FLAGS_REG))]
9849   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9850   [(parallel [(set (match_dup 0)
9851                    (xor:DI (match_dup 1) (match_dup 2)))
9852               (clobber (reg:CC FLAGS_REG))])]
9853    "operands[0] = gen_lowpart (DImode, operands[0]);
9854     operands[1] = gen_lowpart (DImode, operands[1]);
9855     operands[2] = gen_lowpart (DImode, operands[2]);")
9857 (define_split
9858   [(set (match_operand:DF 0 "register_operand" "")
9859         (neg:DF (match_operand:DF 1 "register_operand" "")))
9860    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "reload_completed && SSE_REG_P (operands[0])"
9863   [(set (match_dup 0)
9864         (xor:V2DF (match_dup 1)
9865                   (match_dup 2)))]
9867   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9868   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9869   /* Avoid possible reformatting on the operands.  */
9870   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9871     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9872   if (operands_match_p (operands[0], operands[2]))
9873     {
9874       rtx tmp;
9875       tmp = operands[1];
9876       operands[1] = operands[2];
9877       operands[2] = tmp;
9878     }
9881 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9882 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9883 ;; to itself.
9884 (define_insn "*negdf2_if"
9885   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9886         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9887    (clobber (reg:CC FLAGS_REG))]
9888   "!TARGET_64BIT && TARGET_80387
9889    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9890   "#")
9892 ;; FIXME: We should to allow integer registers here.  Problem is that
9893 ;; we need another scratch register to get constant from.
9894 ;; Forcing constant to mem if no register available in peep2 should be
9895 ;; safe even for PIC mode, because of RIP relative addressing.
9896 (define_insn "*negdf2_if_rex64"
9897   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9898         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9899    (clobber (reg:CC FLAGS_REG))]
9900   "TARGET_64BIT && TARGET_80387
9901    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9902   "#")
9904 (define_split
9905   [(set (match_operand:DF 0 "fp_register_operand" "")
9906         (neg:DF (match_operand:DF 1 "register_operand" "")))
9907    (clobber (reg:CC FLAGS_REG))]
9908   "TARGET_80387 && reload_completed"
9909   [(set (match_dup 0)
9910         (neg:DF (match_dup 1)))]
9911   "")
9913 (define_split
9914   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9915         (neg:DF (match_operand:DF 1 "register_operand" "")))
9916    (clobber (reg:CC FLAGS_REG))]
9917   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9918   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9919               (clobber (reg:CC FLAGS_REG))])]
9920   "operands[4] = gen_int_mode (0x80000000, SImode);
9921    split_di (operands+0, 1, operands+2, operands+3);")
9923 (define_expand "negxf2"
9924   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9925                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9926               (clobber (reg:CC FLAGS_REG))])]
9927   "TARGET_80387"
9928   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9930 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9931 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9932 ;; to itself.
9933 (define_insn "*negxf2_if"
9934   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9935         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9936    (clobber (reg:CC FLAGS_REG))]
9937   "TARGET_80387
9938    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9939   "#")
9941 (define_split
9942   [(set (match_operand:XF 0 "fp_register_operand" "")
9943         (neg:XF (match_operand:XF 1 "register_operand" "")))
9944    (clobber (reg:CC FLAGS_REG))]
9945   "TARGET_80387 && reload_completed"
9946   [(set (match_dup 0)
9947         (neg:XF (match_dup 1)))]
9948   "")
9950 (define_split
9951   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9952         (neg:XF (match_operand:XF 1 "register_operand" "")))
9953    (clobber (reg:CC FLAGS_REG))]
9954   "TARGET_80387 && reload_completed"
9955   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9956               (clobber (reg:CC FLAGS_REG))])]
9957   "operands[1] = GEN_INT (0x8000);
9958    operands[0] = gen_rtx_REG (SImode,
9959                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9961 ;; Conditionalize these after reload. If they matches before reload, we 
9962 ;; lose the clobber and ability to use integer instructions.
9964 (define_insn "*negsf2_1"
9965   [(set (match_operand:SF 0 "register_operand" "=f")
9966         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9967   "TARGET_80387 && reload_completed"
9968   "fchs"
9969   [(set_attr "type" "fsgn")
9970    (set_attr "mode" "SF")])
9972 (define_insn "*negdf2_1"
9973   [(set (match_operand:DF 0 "register_operand" "=f")
9974         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9975   "TARGET_80387 && reload_completed"
9976   "fchs"
9977   [(set_attr "type" "fsgn")
9978    (set_attr "mode" "DF")])
9980 (define_insn "*negextendsfdf2"
9981   [(set (match_operand:DF 0 "register_operand" "=f")
9982         (neg:DF (float_extend:DF
9983                   (match_operand:SF 1 "register_operand" "0"))))]
9984   "TARGET_80387"
9985   "fchs"
9986   [(set_attr "type" "fsgn")
9987    (set_attr "mode" "DF")])
9989 (define_insn "*negxf2_1"
9990   [(set (match_operand:XF 0 "register_operand" "=f")
9991         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9992   "TARGET_80387 && reload_completed"
9993   "fchs"
9994   [(set_attr "type" "fsgn")
9995    (set_attr "mode" "XF")])
9997 (define_insn "*negextenddfxf2"
9998   [(set (match_operand:XF 0 "register_operand" "=f")
9999         (neg:XF (float_extend:XF
10000                   (match_operand:DF 1 "register_operand" "0"))))]
10001   "TARGET_80387"
10002   "fchs"
10003   [(set_attr "type" "fsgn")
10004    (set_attr "mode" "XF")])
10006 (define_insn "*negextendsfxf2"
10007   [(set (match_operand:XF 0 "register_operand" "=f")
10008         (neg:XF (float_extend:XF
10009                   (match_operand:SF 1 "register_operand" "0"))))]
10010   "TARGET_80387"
10011   "fchs"
10012   [(set_attr "type" "fsgn")
10013    (set_attr "mode" "XF")])
10015 ;; Absolute value instructions
10017 (define_expand "abssf2"
10018   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10019                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10020               (clobber (reg:CC FLAGS_REG))])]
10021   "TARGET_80387"
10022   "if (TARGET_SSE)
10023      {
10024        /* In case operand is in memory,  we will not use SSE.  */
10025        if (memory_operand (operands[0], VOIDmode)
10026            && rtx_equal_p (operands[0], operands[1]))
10027          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10028        else
10029         {
10030           /* Using SSE is tricky, since we need bitwise negation of -0
10031              in register.  */
10032           rtx reg = gen_reg_rtx (V4SFmode);
10033           rtx dest = operands[0];
10034           rtx imm;
10036           operands[1] = force_reg (SFmode, operands[1]);
10037           operands[0] = force_reg (SFmode, operands[0]);
10038           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10039           reg = force_reg (V4SFmode,
10040                            gen_rtx_CONST_VECTOR (V4SFmode,
10041                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
10042                                       CONST0_RTX (SFmode),
10043                                       CONST0_RTX (SFmode))));
10044           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10045           if (dest != operands[0])
10046             emit_move_insn (dest, operands[0]);
10047         }
10048        DONE;
10049      }
10050    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10052 (define_insn "abssf2_memory"
10053   [(set (match_operand:SF 0 "memory_operand" "=m")
10054         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10055    (clobber (reg:CC FLAGS_REG))]
10056   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10057   "#")
10059 (define_insn "abssf2_ifs"
10060   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10061         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10062    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10063    (clobber (reg:CC FLAGS_REG))]
10064   "TARGET_SSE
10065    && (reload_in_progress || reload_completed
10066        || (register_operand (operands[0], VOIDmode)
10067             && register_operand (operands[1], VOIDmode)))"
10068   "#")
10070 (define_split
10071   [(set (match_operand:SF 0 "memory_operand" "")
10072         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10073    (use (match_operand:V4SF 2 "" ""))
10074    (clobber (reg:CC FLAGS_REG))]
10075   ""
10076   [(parallel [(set (match_dup 0)
10077                    (abs:SF (match_dup 1)))
10078               (clobber (reg:CC FLAGS_REG))])])
10080 (define_split
10081   [(set (match_operand:SF 0 "register_operand" "")
10082         (abs:SF (match_operand:SF 1 "register_operand" "")))
10083    (use (match_operand:V4SF 2 "" ""))
10084    (clobber (reg:CC FLAGS_REG))]
10085   "reload_completed && !SSE_REG_P (operands[0])"
10086   [(parallel [(set (match_dup 0)
10087                    (abs:SF (match_dup 1)))
10088               (clobber (reg:CC FLAGS_REG))])])
10090 (define_split
10091   [(set (match_operand:SF 0 "register_operand" "")
10092         (abs:SF (match_operand:SF 1 "register_operand" "")))
10093    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10094    (clobber (reg:CC FLAGS_REG))]
10095   "reload_completed && SSE_REG_P (operands[0])"
10096   [(set (match_dup 0)
10097         (and:V4SF (match_dup 1)
10098                   (match_dup 2)))]
10100   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10101   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10102   if (operands_match_p (operands[0], operands[2]))
10103     {
10104       rtx tmp;
10105       tmp = operands[1];
10106       operands[1] = operands[2];
10107       operands[2] = tmp;
10108     }
10111 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10112 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10113 ;; to itself.
10114 (define_insn "*abssf2_if"
10115   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10116         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10117    (clobber (reg:CC FLAGS_REG))]
10118   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10119   "#")
10121 (define_split
10122   [(set (match_operand:SF 0 "fp_register_operand" "")
10123         (abs:SF (match_operand:SF 1 "register_operand" "")))
10124    (clobber (reg:CC FLAGS_REG))]
10125   "TARGET_80387 && reload_completed"
10126   [(set (match_dup 0)
10127         (abs:SF (match_dup 1)))]
10128   "")
10130 (define_split
10131   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10132         (abs:SF (match_operand:SF 1 "register_operand" "")))
10133    (clobber (reg:CC FLAGS_REG))]
10134   "TARGET_80387 && reload_completed"
10135   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10136               (clobber (reg:CC FLAGS_REG))])]
10137   "operands[1] = gen_int_mode (~0x80000000, SImode);
10138    operands[0] = gen_lowpart (SImode, operands[0]);")
10140 (define_split
10141   [(set (match_operand 0 "memory_operand" "")
10142         (abs (match_operand 1 "memory_operand" "")))
10143    (clobber (reg:CC FLAGS_REG))]
10144   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10145   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10146               (clobber (reg:CC FLAGS_REG))])]
10148   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10150   if (GET_MODE (operands[1]) == XFmode)
10151     size = 10;
10152   operands[0] = adjust_address (operands[0], QImode, size - 1);
10153   operands[1] = gen_int_mode (~0x80, QImode);
10156 (define_expand "absdf2"
10157   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10158                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10159               (clobber (reg:CC FLAGS_REG))])]
10160   "TARGET_80387"
10161   "if (TARGET_SSE2)
10162      {
10163        /* In case operand is in memory,  we will not use SSE.  */
10164        if (memory_operand (operands[0], VOIDmode)
10165            && rtx_equal_p (operands[0], operands[1]))
10166          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10167        else
10168         {
10169           /* Using SSE is tricky, since we need bitwise negation of -0
10170              in register.  */
10171           rtx reg = gen_reg_rtx (V2DFmode);
10172 #if HOST_BITS_PER_WIDE_INT >= 64
10173           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10174 #else
10175           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10176 #endif
10177           rtx dest = operands[0];
10179           operands[1] = force_reg (DFmode, operands[1]);
10180           operands[0] = force_reg (DFmode, operands[0]);
10182           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10183           imm = gen_lowpart (DFmode, imm);
10184           reg = force_reg (V2DFmode,
10185                            gen_rtx_CONST_VECTOR (V2DFmode,
10186                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10187           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10188           if (dest != operands[0])
10189             emit_move_insn (dest, operands[0]);
10190         }
10191        DONE;
10192      }
10193    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10195 (define_insn "absdf2_memory"
10196   [(set (match_operand:DF 0 "memory_operand" "=m")
10197         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10198    (clobber (reg:CC FLAGS_REG))]
10199   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10200   "#")
10202 (define_insn "absdf2_ifs"
10203   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10204         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10205    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10206    (clobber (reg:CC FLAGS_REG))]
10207   "!TARGET_64BIT && TARGET_SSE2
10208    && (reload_in_progress || reload_completed
10209        || (register_operand (operands[0], VOIDmode)
10210            && register_operand (operands[1], VOIDmode)))"
10211   "#")
10213 (define_insn "*absdf2_ifs_rex64"
10214   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10215         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10216    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10217    (clobber (reg:CC FLAGS_REG))]
10218   "TARGET_64BIT && TARGET_SSE2
10219    && (reload_in_progress || reload_completed
10220        || (register_operand (operands[0], VOIDmode)
10221            && register_operand (operands[1], VOIDmode)))"
10222   "#")
10224 (define_split
10225   [(set (match_operand:DF 0 "memory_operand" "")
10226         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10227    (use (match_operand:V2DF 2 "" ""))
10228    (clobber (reg:CC FLAGS_REG))]
10229   ""
10230   [(parallel [(set (match_dup 0)
10231                    (abs:DF (match_dup 1)))
10232               (clobber (reg:CC FLAGS_REG))])])
10234 (define_split
10235   [(set (match_operand:DF 0 "register_operand" "")
10236         (abs:DF (match_operand:DF 1 "register_operand" "")))
10237    (use (match_operand:V2DF 2 "" ""))
10238    (clobber (reg:CC FLAGS_REG))]
10239   "reload_completed && !SSE_REG_P (operands[0])"
10240   [(parallel [(set (match_dup 0)
10241                    (abs:DF (match_dup 1)))
10242               (clobber (reg:CC FLAGS_REG))])])
10244 (define_split
10245   [(set (match_operand:DF 0 "register_operand" "")
10246         (abs:DF (match_operand:DF 1 "register_operand" "")))
10247    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10248    (clobber (reg:CC FLAGS_REG))]
10249   "reload_completed && SSE_REG_P (operands[0])"
10250   [(set (match_dup 0)
10251         (and:V2DF (match_dup 1)
10252                   (match_dup 2)))]
10254   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10255   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10256   /* Avoid possible reformatting on the operands.  */
10257   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10258     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10259   if (operands_match_p (operands[0], operands[2]))
10260     {
10261       rtx tmp;
10262       tmp = operands[1];
10263       operands[1] = operands[2];
10264       operands[2] = tmp;
10265     }
10269 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10270 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10271 ;; to itself.
10272 (define_insn "*absdf2_if"
10273   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10274         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10275    (clobber (reg:CC FLAGS_REG))]
10276   "!TARGET_64BIT && TARGET_80387
10277    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10278   "#")
10280 ;; FIXME: We should to allow integer registers here.  Problem is that
10281 ;; we need another scratch register to get constant from.
10282 ;; Forcing constant to mem if no register available in peep2 should be
10283 ;; safe even for PIC mode, because of RIP relative addressing.
10284 (define_insn "*absdf2_if_rex64"
10285   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10286         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10287    (clobber (reg:CC FLAGS_REG))]
10288   "TARGET_64BIT && TARGET_80387
10289    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10290   "#")
10292 (define_split
10293   [(set (match_operand:DF 0 "fp_register_operand" "")
10294         (abs:DF (match_operand:DF 1 "register_operand" "")))
10295    (clobber (reg:CC FLAGS_REG))]
10296   "TARGET_80387 && reload_completed"
10297   [(set (match_dup 0)
10298         (abs:DF (match_dup 1)))]
10299   "")
10301 (define_split
10302   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10303         (abs:DF (match_operand:DF 1 "register_operand" "")))
10304    (clobber (reg:CC FLAGS_REG))]
10305   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10306   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10307               (clobber (reg:CC FLAGS_REG))])]
10308   "operands[4] = gen_int_mode (~0x80000000, SImode);
10309    split_di (operands+0, 1, operands+2, operands+3);")
10311 (define_expand "absxf2"
10312   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10313                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10314               (clobber (reg:CC FLAGS_REG))])]
10315   "TARGET_80387"
10316   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10318 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10319 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10320 ;; to itself.
10321 (define_insn "*absxf2_if"
10322   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10323         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10324    (clobber (reg:CC FLAGS_REG))]
10325   "TARGET_80387
10326    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10327   "#")
10329 (define_split
10330   [(set (match_operand:XF 0 "fp_register_operand" "")
10331         (abs:XF (match_operand:XF 1 "register_operand" "")))
10332    (clobber (reg:CC FLAGS_REG))]
10333   "TARGET_80387 && reload_completed"
10334   [(set (match_dup 0)
10335         (abs:XF (match_dup 1)))]
10336   "")
10338 (define_split
10339   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10340         (abs:XF (match_operand:XF 1 "register_operand" "")))
10341    (clobber (reg:CC FLAGS_REG))]
10342   "TARGET_80387 && reload_completed"
10343   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10344               (clobber (reg:CC FLAGS_REG))])]
10345   "operands[1] = GEN_INT (~0x8000);
10346    operands[0] = gen_rtx_REG (SImode,
10347                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10349 (define_insn "*abssf2_1"
10350   [(set (match_operand:SF 0 "register_operand" "=f")
10351         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10352   "TARGET_80387 && reload_completed"
10353   "fabs"
10354   [(set_attr "type" "fsgn")
10355    (set_attr "mode" "SF")])
10357 (define_insn "*absdf2_1"
10358   [(set (match_operand:DF 0 "register_operand" "=f")
10359         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10360   "TARGET_80387 && reload_completed"
10361   "fabs"
10362   [(set_attr "type" "fsgn")
10363    (set_attr "mode" "DF")])
10365 (define_insn "*absextendsfdf2"
10366   [(set (match_operand:DF 0 "register_operand" "=f")
10367         (abs:DF (float_extend:DF
10368                   (match_operand:SF 1 "register_operand" "0"))))]
10369   "TARGET_80387"
10370   "fabs"
10371   [(set_attr "type" "fsgn")
10372    (set_attr "mode" "DF")])
10374 (define_insn "*absxf2_1"
10375   [(set (match_operand:XF 0 "register_operand" "=f")
10376         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10377   "TARGET_80387 && reload_completed"
10378   "fabs"
10379   [(set_attr "type" "fsgn")
10380    (set_attr "mode" "DF")])
10382 (define_insn "*absextenddfxf2"
10383   [(set (match_operand:XF 0 "register_operand" "=f")
10384         (abs:XF (float_extend:XF
10385           (match_operand:DF 1 "register_operand" "0"))))]
10386   "TARGET_80387"
10387   "fabs"
10388   [(set_attr "type" "fsgn")
10389    (set_attr "mode" "XF")])
10391 (define_insn "*absextendsfxf2"
10392   [(set (match_operand:XF 0 "register_operand" "=f")
10393         (abs:XF (float_extend:XF
10394           (match_operand:SF 1 "register_operand" "0"))))]
10395   "TARGET_80387"
10396   "fabs"
10397   [(set_attr "type" "fsgn")
10398    (set_attr "mode" "XF")])
10400 ;; One complement instructions
10402 (define_expand "one_cmpldi2"
10403   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10404         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10405   "TARGET_64BIT"
10406   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10408 (define_insn "*one_cmpldi2_1_rex64"
10409   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10410         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10411   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10412   "not{q}\t%0"
10413   [(set_attr "type" "negnot")
10414    (set_attr "mode" "DI")])
10416 (define_insn "*one_cmpldi2_2_rex64"
10417   [(set (reg 17)
10418         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10419                  (const_int 0)))
10420    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10421         (not:DI (match_dup 1)))]
10422   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10423    && ix86_unary_operator_ok (NOT, DImode, operands)"
10424   "#"
10425   [(set_attr "type" "alu1")
10426    (set_attr "mode" "DI")])
10428 (define_split
10429   [(set (reg 17)
10430         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10431                  (const_int 0)))
10432    (set (match_operand:DI 0 "nonimmediate_operand" "")
10433         (not:DI (match_dup 1)))]
10434   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10435   [(parallel [(set (reg:CCNO FLAGS_REG)
10436                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10437                                  (const_int 0)))
10438               (set (match_dup 0)
10439                    (xor:DI (match_dup 1) (const_int -1)))])]
10440   "")
10442 (define_expand "one_cmplsi2"
10443   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10444         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10445   ""
10446   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10448 (define_insn "*one_cmplsi2_1"
10449   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10450         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10451   "ix86_unary_operator_ok (NOT, SImode, operands)"
10452   "not{l}\t%0"
10453   [(set_attr "type" "negnot")
10454    (set_attr "mode" "SI")])
10456 ;; ??? Currently never generated - xor is used instead.
10457 (define_insn "*one_cmplsi2_1_zext"
10458   [(set (match_operand:DI 0 "register_operand" "=r")
10459         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10460   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10461   "not{l}\t%k0"
10462   [(set_attr "type" "negnot")
10463    (set_attr "mode" "SI")])
10465 (define_insn "*one_cmplsi2_2"
10466   [(set (reg 17)
10467         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10468                  (const_int 0)))
10469    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10470         (not:SI (match_dup 1)))]
10471   "ix86_match_ccmode (insn, CCNOmode)
10472    && ix86_unary_operator_ok (NOT, SImode, operands)"
10473   "#"
10474   [(set_attr "type" "alu1")
10475    (set_attr "mode" "SI")])
10477 (define_split
10478   [(set (reg 17)
10479         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10480                  (const_int 0)))
10481    (set (match_operand:SI 0 "nonimmediate_operand" "")
10482         (not:SI (match_dup 1)))]
10483   "ix86_match_ccmode (insn, CCNOmode)"
10484   [(parallel [(set (reg:CCNO FLAGS_REG)
10485                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10486                                  (const_int 0)))
10487               (set (match_dup 0)
10488                    (xor:SI (match_dup 1) (const_int -1)))])]
10489   "")
10491 ;; ??? Currently never generated - xor is used instead.
10492 (define_insn "*one_cmplsi2_2_zext"
10493   [(set (reg 17)
10494         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10495                  (const_int 0)))
10496    (set (match_operand:DI 0 "register_operand" "=r")
10497         (zero_extend:DI (not:SI (match_dup 1))))]
10498   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10499    && ix86_unary_operator_ok (NOT, SImode, operands)"
10500   "#"
10501   [(set_attr "type" "alu1")
10502    (set_attr "mode" "SI")])
10504 (define_split
10505   [(set (reg 17)
10506         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10507                  (const_int 0)))
10508    (set (match_operand:DI 0 "register_operand" "")
10509         (zero_extend:DI (not:SI (match_dup 1))))]
10510   "ix86_match_ccmode (insn, CCNOmode)"
10511   [(parallel [(set (reg:CCNO FLAGS_REG)
10512                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10513                                  (const_int 0)))
10514               (set (match_dup 0)
10515                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10516   "")
10518 (define_expand "one_cmplhi2"
10519   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10520         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10521   "TARGET_HIMODE_MATH"
10522   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10524 (define_insn "*one_cmplhi2_1"
10525   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10526         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10527   "ix86_unary_operator_ok (NOT, HImode, operands)"
10528   "not{w}\t%0"
10529   [(set_attr "type" "negnot")
10530    (set_attr "mode" "HI")])
10532 (define_insn "*one_cmplhi2_2"
10533   [(set (reg 17)
10534         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10535                  (const_int 0)))
10536    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10537         (not:HI (match_dup 1)))]
10538   "ix86_match_ccmode (insn, CCNOmode)
10539    && ix86_unary_operator_ok (NEG, HImode, operands)"
10540   "#"
10541   [(set_attr "type" "alu1")
10542    (set_attr "mode" "HI")])
10544 (define_split
10545   [(set (reg 17)
10546         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10547                  (const_int 0)))
10548    (set (match_operand:HI 0 "nonimmediate_operand" "")
10549         (not:HI (match_dup 1)))]
10550   "ix86_match_ccmode (insn, CCNOmode)"
10551   [(parallel [(set (reg:CCNO FLAGS_REG)
10552                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10553                                  (const_int 0)))
10554               (set (match_dup 0)
10555                    (xor:HI (match_dup 1) (const_int -1)))])]
10556   "")
10558 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10559 (define_expand "one_cmplqi2"
10560   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10561         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10562   "TARGET_QIMODE_MATH"
10563   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10565 (define_insn "*one_cmplqi2_1"
10566   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10567         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10568   "ix86_unary_operator_ok (NOT, QImode, operands)"
10569   "@
10570    not{b}\t%0
10571    not{l}\t%k0"
10572   [(set_attr "type" "negnot")
10573    (set_attr "mode" "QI,SI")])
10575 (define_insn "*one_cmplqi2_2"
10576   [(set (reg 17)
10577         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10578                  (const_int 0)))
10579    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10580         (not:QI (match_dup 1)))]
10581   "ix86_match_ccmode (insn, CCNOmode)
10582    && ix86_unary_operator_ok (NOT, QImode, operands)"
10583   "#"
10584   [(set_attr "type" "alu1")
10585    (set_attr "mode" "QI")])
10587 (define_split
10588   [(set (reg 17)
10589         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10590                  (const_int 0)))
10591    (set (match_operand:QI 0 "nonimmediate_operand" "")
10592         (not:QI (match_dup 1)))]
10593   "ix86_match_ccmode (insn, CCNOmode)"
10594   [(parallel [(set (reg:CCNO FLAGS_REG)
10595                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10596                                  (const_int 0)))
10597               (set (match_dup 0)
10598                    (xor:QI (match_dup 1) (const_int -1)))])]
10599   "")
10601 ;; Arithmetic shift instructions
10603 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10604 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10605 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10606 ;; from the assembler input.
10608 ;; This instruction shifts the target reg/mem as usual, but instead of
10609 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10610 ;; is a left shift double, bits are taken from the high order bits of
10611 ;; reg, else if the insn is a shift right double, bits are taken from the
10612 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10613 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10615 ;; Since sh[lr]d does not change the `reg' operand, that is done
10616 ;; separately, making all shifts emit pairs of shift double and normal
10617 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10618 ;; support a 63 bit shift, each shift where the count is in a reg expands
10619 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10621 ;; If the shift count is a constant, we need never emit more than one
10622 ;; shift pair, instead using moves and sign extension for counts greater
10623 ;; than 31.
10625 (define_expand "ashldi3"
10626   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10627                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10628                               (match_operand:QI 2 "nonmemory_operand" "")))
10629               (clobber (reg:CC FLAGS_REG))])]
10630   ""
10632   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10633     {
10634       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10635       DONE;
10636     }
10637   ix86_expand_binary_operator (ASHIFT, DImode, operands);
10638   DONE;
10641 (define_insn "*ashldi3_1_rex64"
10642   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10643         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10644                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10645    (clobber (reg:CC FLAGS_REG))]
10646   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10648   switch (get_attr_type (insn))
10649     {
10650     case TYPE_ALU:
10651       if (operands[2] != const1_rtx)
10652         abort ();
10653       if (!rtx_equal_p (operands[0], operands[1]))
10654         abort ();
10655       return "add{q}\t{%0, %0|%0, %0}";
10657     case TYPE_LEA:
10658       if (GET_CODE (operands[2]) != CONST_INT
10659           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10660         abort ();
10661       operands[1] = gen_rtx_MULT (DImode, operands[1],
10662                                   GEN_INT (1 << INTVAL (operands[2])));
10663       return "lea{q}\t{%a1, %0|%0, %a1}";
10665     default:
10666       if (REG_P (operands[2]))
10667         return "sal{q}\t{%b2, %0|%0, %b2}";
10668       else if (operands[2] == const1_rtx
10669                && (TARGET_SHIFT1 || optimize_size))
10670         return "sal{q}\t%0";
10671       else
10672         return "sal{q}\t{%2, %0|%0, %2}";
10673     }
10675   [(set (attr "type")
10676      (cond [(eq_attr "alternative" "1")
10677               (const_string "lea")
10678             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10679                           (const_int 0))
10680                       (match_operand 0 "register_operand" ""))
10681                  (match_operand 2 "const1_operand" ""))
10682               (const_string "alu")
10683            ]
10684            (const_string "ishift")))
10685    (set_attr "mode" "DI")])
10687 ;; Convert lea to the lea pattern to avoid flags dependency.
10688 (define_split
10689   [(set (match_operand:DI 0 "register_operand" "")
10690         (ashift:DI (match_operand:DI 1 "register_operand" "")
10691                    (match_operand:QI 2 "immediate_operand" "")))
10692    (clobber (reg:CC FLAGS_REG))]
10693   "TARGET_64BIT && reload_completed
10694    && true_regnum (operands[0]) != true_regnum (operands[1])"
10695   [(set (match_dup 0)
10696         (mult:DI (match_dup 1)
10697                  (match_dup 2)))]
10698   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10700 ;; This pattern can't accept a variable shift count, since shifts by
10701 ;; zero don't affect the flags.  We assume that shifts by constant
10702 ;; zero are optimized away.
10703 (define_insn "*ashldi3_cmp_rex64"
10704   [(set (reg 17)
10705         (compare
10706           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10707                      (match_operand:QI 2 "immediate_operand" "e"))
10708           (const_int 0)))
10709    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10710         (ashift:DI (match_dup 1) (match_dup 2)))]
10711   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10712    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10714   switch (get_attr_type (insn))
10715     {
10716     case TYPE_ALU:
10717       if (operands[2] != const1_rtx)
10718         abort ();
10719       return "add{q}\t{%0, %0|%0, %0}";
10721     default:
10722       if (REG_P (operands[2]))
10723         return "sal{q}\t{%b2, %0|%0, %b2}";
10724       else if (operands[2] == const1_rtx
10725                && (TARGET_SHIFT1 || optimize_size))
10726         return "sal{q}\t%0";
10727       else
10728         return "sal{q}\t{%2, %0|%0, %2}";
10729     }
10731   [(set (attr "type")
10732      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10733                           (const_int 0))
10734                       (match_operand 0 "register_operand" ""))
10735                  (match_operand 2 "const1_operand" ""))
10736               (const_string "alu")
10737            ]
10738            (const_string "ishift")))
10739    (set_attr "mode" "DI")])
10741 (define_insn "ashldi3_1"
10742   [(set (match_operand:DI 0 "register_operand" "=r")
10743         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10744                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10745    (clobber (match_scratch:SI 3 "=&r"))
10746    (clobber (reg:CC FLAGS_REG))]
10747   "!TARGET_64BIT && TARGET_CMOVE"
10748   "#"
10749   [(set_attr "type" "multi")])
10751 (define_insn "*ashldi3_2"
10752   [(set (match_operand:DI 0 "register_operand" "=r")
10753         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10754                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10755    (clobber (reg:CC FLAGS_REG))]
10756   "!TARGET_64BIT"
10757   "#"
10758   [(set_attr "type" "multi")])
10760 (define_split
10761   [(set (match_operand:DI 0 "register_operand" "")
10762         (ashift:DI (match_operand:DI 1 "register_operand" "")
10763                    (match_operand:QI 2 "nonmemory_operand" "")))
10764    (clobber (match_scratch:SI 3 ""))
10765    (clobber (reg:CC FLAGS_REG))]
10766   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10767   [(const_int 0)]
10768   "ix86_split_ashldi (operands, operands[3]); DONE;")
10770 (define_split
10771   [(set (match_operand:DI 0 "register_operand" "")
10772         (ashift:DI (match_operand:DI 1 "register_operand" "")
10773                    (match_operand:QI 2 "nonmemory_operand" "")))
10774    (clobber (reg:CC FLAGS_REG))]
10775   "!TARGET_64BIT && reload_completed"
10776   [(const_int 0)]
10777   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10779 (define_insn "x86_shld_1"
10780   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10781         (ior:SI (ashift:SI (match_dup 0)
10782                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10783                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10784                   (minus:QI (const_int 32) (match_dup 2)))))
10785    (clobber (reg:CC FLAGS_REG))]
10786   ""
10787   "@
10788    shld{l}\t{%2, %1, %0|%0, %1, %2}
10789    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10790   [(set_attr "type" "ishift")
10791    (set_attr "prefix_0f" "1")
10792    (set_attr "mode" "SI")
10793    (set_attr "pent_pair" "np")
10794    (set_attr "athlon_decode" "vector")])
10796 (define_expand "x86_shift_adj_1"
10797   [(set (reg:CCZ FLAGS_REG)
10798         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10799                              (const_int 32))
10800                      (const_int 0)))
10801    (set (match_operand:SI 0 "register_operand" "")
10802         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10803                          (match_operand:SI 1 "register_operand" "")
10804                          (match_dup 0)))
10805    (set (match_dup 1)
10806         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10807                          (match_operand:SI 3 "register_operand" "r")
10808                          (match_dup 1)))]
10809   "TARGET_CMOVE"
10810   "")
10812 (define_expand "x86_shift_adj_2"
10813   [(use (match_operand:SI 0 "register_operand" ""))
10814    (use (match_operand:SI 1 "register_operand" ""))
10815    (use (match_operand:QI 2 "register_operand" ""))]
10816   ""
10818   rtx label = gen_label_rtx ();
10819   rtx tmp;
10821   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10823   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10824   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10825   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10826                               gen_rtx_LABEL_REF (VOIDmode, label),
10827                               pc_rtx);
10828   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10829   JUMP_LABEL (tmp) = label;
10831   emit_move_insn (operands[0], operands[1]);
10832   emit_move_insn (operands[1], const0_rtx);
10834   emit_label (label);
10835   LABEL_NUSES (label) = 1;
10837   DONE;
10840 (define_expand "ashlsi3"
10841   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10842         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10843                    (match_operand:QI 2 "nonmemory_operand" "")))
10844    (clobber (reg:CC FLAGS_REG))]
10845   ""
10846   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10848 (define_insn "*ashlsi3_1"
10849   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10850         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10851                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10852    (clobber (reg:CC FLAGS_REG))]
10853   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10855   switch (get_attr_type (insn))
10856     {
10857     case TYPE_ALU:
10858       if (operands[2] != const1_rtx)
10859         abort ();
10860       if (!rtx_equal_p (operands[0], operands[1]))
10861         abort ();
10862       return "add{l}\t{%0, %0|%0, %0}";
10864     case TYPE_LEA:
10865       return "#";
10867     default:
10868       if (REG_P (operands[2]))
10869         return "sal{l}\t{%b2, %0|%0, %b2}";
10870       else if (operands[2] == const1_rtx
10871                && (TARGET_SHIFT1 || optimize_size))
10872         return "sal{l}\t%0";
10873       else
10874         return "sal{l}\t{%2, %0|%0, %2}";
10875     }
10877   [(set (attr "type")
10878      (cond [(eq_attr "alternative" "1")
10879               (const_string "lea")
10880             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10881                           (const_int 0))
10882                       (match_operand 0 "register_operand" ""))
10883                  (match_operand 2 "const1_operand" ""))
10884               (const_string "alu")
10885            ]
10886            (const_string "ishift")))
10887    (set_attr "mode" "SI")])
10889 ;; Convert lea to the lea pattern to avoid flags dependency.
10890 (define_split
10891   [(set (match_operand 0 "register_operand" "")
10892         (ashift (match_operand 1 "index_register_operand" "")
10893                 (match_operand:QI 2 "const_int_operand" "")))
10894    (clobber (reg:CC FLAGS_REG))]
10895   "reload_completed
10896    && true_regnum (operands[0]) != true_regnum (operands[1])"
10897   [(const_int 0)]
10899   rtx pat;
10900   operands[0] = gen_lowpart (SImode, operands[0]);
10901   operands[1] = gen_lowpart (Pmode, operands[1]);
10902   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10903   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10904   if (Pmode != SImode)
10905     pat = gen_rtx_SUBREG (SImode, pat, 0);
10906   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10907   DONE;
10910 ;; Rare case of shifting RSP is handled by generating move and shift
10911 (define_split
10912   [(set (match_operand 0 "register_operand" "")
10913         (ashift (match_operand 1 "register_operand" "")
10914                 (match_operand:QI 2 "const_int_operand" "")))
10915    (clobber (reg:CC FLAGS_REG))]
10916   "reload_completed
10917    && true_regnum (operands[0]) != true_regnum (operands[1])"
10918   [(const_int 0)]
10920   rtx pat, clob;
10921   emit_move_insn (operands[1], operands[0]);
10922   pat = gen_rtx_SET (VOIDmode, operands[0],
10923                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10924                                      operands[0], operands[2]));
10925   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10926   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10927   DONE;
10930 (define_insn "*ashlsi3_1_zext"
10931   [(set (match_operand:DI 0 "register_operand" "=r,r")
10932         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10933                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10934    (clobber (reg:CC FLAGS_REG))]
10935   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10937   switch (get_attr_type (insn))
10938     {
10939     case TYPE_ALU:
10940       if (operands[2] != const1_rtx)
10941         abort ();
10942       return "add{l}\t{%k0, %k0|%k0, %k0}";
10944     case TYPE_LEA:
10945       return "#";
10947     default:
10948       if (REG_P (operands[2]))
10949         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10950       else if (operands[2] == const1_rtx
10951                && (TARGET_SHIFT1 || optimize_size))
10952         return "sal{l}\t%k0";
10953       else
10954         return "sal{l}\t{%2, %k0|%k0, %2}";
10955     }
10957   [(set (attr "type")
10958      (cond [(eq_attr "alternative" "1")
10959               (const_string "lea")
10960             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10961                      (const_int 0))
10962                  (match_operand 2 "const1_operand" ""))
10963               (const_string "alu")
10964            ]
10965            (const_string "ishift")))
10966    (set_attr "mode" "SI")])
10968 ;; Convert lea to the lea pattern to avoid flags dependency.
10969 (define_split
10970   [(set (match_operand:DI 0 "register_operand" "")
10971         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10972                                 (match_operand:QI 2 "const_int_operand" ""))))
10973    (clobber (reg:CC FLAGS_REG))]
10974   "TARGET_64BIT && reload_completed
10975    && true_regnum (operands[0]) != true_regnum (operands[1])"
10976   [(set (match_dup 0) (zero_extend:DI
10977                         (subreg:SI (mult:SI (match_dup 1)
10978                                             (match_dup 2)) 0)))]
10980   operands[1] = gen_lowpart (Pmode, operands[1]);
10981   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10984 ;; This pattern can't accept a variable shift count, since shifts by
10985 ;; zero don't affect the flags.  We assume that shifts by constant
10986 ;; zero are optimized away.
10987 (define_insn "*ashlsi3_cmp"
10988   [(set (reg 17)
10989         (compare
10990           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10991                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10992           (const_int 0)))
10993    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10994         (ashift:SI (match_dup 1) (match_dup 2)))]
10995   "ix86_match_ccmode (insn, CCGOCmode)
10996    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10998   switch (get_attr_type (insn))
10999     {
11000     case TYPE_ALU:
11001       if (operands[2] != const1_rtx)
11002         abort ();
11003       return "add{l}\t{%0, %0|%0, %0}";
11005     default:
11006       if (REG_P (operands[2]))
11007         return "sal{l}\t{%b2, %0|%0, %b2}";
11008       else if (operands[2] == const1_rtx
11009                && (TARGET_SHIFT1 || optimize_size))
11010         return "sal{l}\t%0";
11011       else
11012         return "sal{l}\t{%2, %0|%0, %2}";
11013     }
11015   [(set (attr "type")
11016      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11017                           (const_int 0))
11018                       (match_operand 0 "register_operand" ""))
11019                  (match_operand 2 "const1_operand" ""))
11020               (const_string "alu")
11021            ]
11022            (const_string "ishift")))
11023    (set_attr "mode" "SI")])
11025 (define_insn "*ashlsi3_cmp_zext"
11026   [(set (reg 17)
11027         (compare
11028           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11029                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11030           (const_int 0)))
11031    (set (match_operand:DI 0 "register_operand" "=r")
11032         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11033   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11034    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11036   switch (get_attr_type (insn))
11037     {
11038     case TYPE_ALU:
11039       if (operands[2] != const1_rtx)
11040         abort ();
11041       return "add{l}\t{%k0, %k0|%k0, %k0}";
11043     default:
11044       if (REG_P (operands[2]))
11045         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11046       else if (operands[2] == const1_rtx
11047                && (TARGET_SHIFT1 || optimize_size))
11048         return "sal{l}\t%k0";
11049       else
11050         return "sal{l}\t{%2, %k0|%k0, %2}";
11051     }
11053   [(set (attr "type")
11054      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11055                      (const_int 0))
11056                  (match_operand 2 "const1_operand" ""))
11057               (const_string "alu")
11058            ]
11059            (const_string "ishift")))
11060    (set_attr "mode" "SI")])
11062 (define_expand "ashlhi3"
11063   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11064         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11065                    (match_operand:QI 2 "nonmemory_operand" "")))
11066    (clobber (reg:CC FLAGS_REG))]
11067   "TARGET_HIMODE_MATH"
11068   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11070 (define_insn "*ashlhi3_1_lea"
11071   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11072         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11073                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11074    (clobber (reg:CC FLAGS_REG))]
11075   "!TARGET_PARTIAL_REG_STALL
11076    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11078   switch (get_attr_type (insn))
11079     {
11080     case TYPE_LEA:
11081       return "#";
11082     case TYPE_ALU:
11083       if (operands[2] != const1_rtx)
11084         abort ();
11085       return "add{w}\t{%0, %0|%0, %0}";
11087     default:
11088       if (REG_P (operands[2]))
11089         return "sal{w}\t{%b2, %0|%0, %b2}";
11090       else if (operands[2] == const1_rtx
11091                && (TARGET_SHIFT1 || optimize_size))
11092         return "sal{w}\t%0";
11093       else
11094         return "sal{w}\t{%2, %0|%0, %2}";
11095     }
11097   [(set (attr "type")
11098      (cond [(eq_attr "alternative" "1")
11099               (const_string "lea")
11100             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11101                           (const_int 0))
11102                       (match_operand 0 "register_operand" ""))
11103                  (match_operand 2 "const1_operand" ""))
11104               (const_string "alu")
11105            ]
11106            (const_string "ishift")))
11107    (set_attr "mode" "HI,SI")])
11109 (define_insn "*ashlhi3_1"
11110   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11111         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11112                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11113    (clobber (reg:CC FLAGS_REG))]
11114   "TARGET_PARTIAL_REG_STALL
11115    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11117   switch (get_attr_type (insn))
11118     {
11119     case TYPE_ALU:
11120       if (operands[2] != const1_rtx)
11121         abort ();
11122       return "add{w}\t{%0, %0|%0, %0}";
11124     default:
11125       if (REG_P (operands[2]))
11126         return "sal{w}\t{%b2, %0|%0, %b2}";
11127       else if (operands[2] == const1_rtx
11128                && (TARGET_SHIFT1 || optimize_size))
11129         return "sal{w}\t%0";
11130       else
11131         return "sal{w}\t{%2, %0|%0, %2}";
11132     }
11134   [(set (attr "type")
11135      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11136                           (const_int 0))
11137                       (match_operand 0 "register_operand" ""))
11138                  (match_operand 2 "const1_operand" ""))
11139               (const_string "alu")
11140            ]
11141            (const_string "ishift")))
11142    (set_attr "mode" "HI")])
11144 ;; This pattern can't accept a variable shift count, since shifts by
11145 ;; zero don't affect the flags.  We assume that shifts by constant
11146 ;; zero are optimized away.
11147 (define_insn "*ashlhi3_cmp"
11148   [(set (reg 17)
11149         (compare
11150           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11151                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11152           (const_int 0)))
11153    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11154         (ashift:HI (match_dup 1) (match_dup 2)))]
11155   "ix86_match_ccmode (insn, CCGOCmode)
11156    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11158   switch (get_attr_type (insn))
11159     {
11160     case TYPE_ALU:
11161       if (operands[2] != const1_rtx)
11162         abort ();
11163       return "add{w}\t{%0, %0|%0, %0}";
11165     default:
11166       if (REG_P (operands[2]))
11167         return "sal{w}\t{%b2, %0|%0, %b2}";
11168       else if (operands[2] == const1_rtx
11169                && (TARGET_SHIFT1 || optimize_size))
11170         return "sal{w}\t%0";
11171       else
11172         return "sal{w}\t{%2, %0|%0, %2}";
11173     }
11175   [(set (attr "type")
11176      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11177                           (const_int 0))
11178                       (match_operand 0 "register_operand" ""))
11179                  (match_operand 2 "const1_operand" ""))
11180               (const_string "alu")
11181            ]
11182            (const_string "ishift")))
11183    (set_attr "mode" "HI")])
11185 (define_expand "ashlqi3"
11186   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11187         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11188                    (match_operand:QI 2 "nonmemory_operand" "")))
11189    (clobber (reg:CC FLAGS_REG))]
11190   "TARGET_QIMODE_MATH"
11191   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11193 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11195 (define_insn "*ashlqi3_1_lea"
11196   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11197         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11198                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11199    (clobber (reg:CC FLAGS_REG))]
11200   "!TARGET_PARTIAL_REG_STALL
11201    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11203   switch (get_attr_type (insn))
11204     {
11205     case TYPE_LEA:
11206       return "#";
11207     case TYPE_ALU:
11208       if (operands[2] != const1_rtx)
11209         abort ();
11210       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11211         return "add{l}\t{%k0, %k0|%k0, %k0}";
11212       else
11213         return "add{b}\t{%0, %0|%0, %0}";
11215     default:
11216       if (REG_P (operands[2]))
11217         {
11218           if (get_attr_mode (insn) == MODE_SI)
11219             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11220           else
11221             return "sal{b}\t{%b2, %0|%0, %b2}";
11222         }
11223       else if (operands[2] == const1_rtx
11224                && (TARGET_SHIFT1 || optimize_size))
11225         {
11226           if (get_attr_mode (insn) == MODE_SI)
11227             return "sal{l}\t%0";
11228           else
11229             return "sal{b}\t%0";
11230         }
11231       else
11232         {
11233           if (get_attr_mode (insn) == MODE_SI)
11234             return "sal{l}\t{%2, %k0|%k0, %2}";
11235           else
11236             return "sal{b}\t{%2, %0|%0, %2}";
11237         }
11238     }
11240   [(set (attr "type")
11241      (cond [(eq_attr "alternative" "2")
11242               (const_string "lea")
11243             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11244                           (const_int 0))
11245                       (match_operand 0 "register_operand" ""))
11246                  (match_operand 2 "const1_operand" ""))
11247               (const_string "alu")
11248            ]
11249            (const_string "ishift")))
11250    (set_attr "mode" "QI,SI,SI")])
11252 (define_insn "*ashlqi3_1"
11253   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11254         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11255                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11256    (clobber (reg:CC FLAGS_REG))]
11257   "TARGET_PARTIAL_REG_STALL
11258    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11260   switch (get_attr_type (insn))
11261     {
11262     case TYPE_ALU:
11263       if (operands[2] != const1_rtx)
11264         abort ();
11265       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11266         return "add{l}\t{%k0, %k0|%k0, %k0}";
11267       else
11268         return "add{b}\t{%0, %0|%0, %0}";
11270     default:
11271       if (REG_P (operands[2]))
11272         {
11273           if (get_attr_mode (insn) == MODE_SI)
11274             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11275           else
11276             return "sal{b}\t{%b2, %0|%0, %b2}";
11277         }
11278       else if (operands[2] == const1_rtx
11279                && (TARGET_SHIFT1 || optimize_size))
11280         {
11281           if (get_attr_mode (insn) == MODE_SI)
11282             return "sal{l}\t%0";
11283           else
11284             return "sal{b}\t%0";
11285         }
11286       else
11287         {
11288           if (get_attr_mode (insn) == MODE_SI)
11289             return "sal{l}\t{%2, %k0|%k0, %2}";
11290           else
11291             return "sal{b}\t{%2, %0|%0, %2}";
11292         }
11293     }
11295   [(set (attr "type")
11296      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11297                           (const_int 0))
11298                       (match_operand 0 "register_operand" ""))
11299                  (match_operand 2 "const1_operand" ""))
11300               (const_string "alu")
11301            ]
11302            (const_string "ishift")))
11303    (set_attr "mode" "QI,SI")])
11305 ;; This pattern can't accept a variable shift count, since shifts by
11306 ;; zero don't affect the flags.  We assume that shifts by constant
11307 ;; zero are optimized away.
11308 (define_insn "*ashlqi3_cmp"
11309   [(set (reg 17)
11310         (compare
11311           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11312                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11313           (const_int 0)))
11314    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11315         (ashift:QI (match_dup 1) (match_dup 2)))]
11316   "ix86_match_ccmode (insn, CCGOCmode)
11317    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11319   switch (get_attr_type (insn))
11320     {
11321     case TYPE_ALU:
11322       if (operands[2] != const1_rtx)
11323         abort ();
11324       return "add{b}\t{%0, %0|%0, %0}";
11326     default:
11327       if (REG_P (operands[2]))
11328         return "sal{b}\t{%b2, %0|%0, %b2}";
11329       else if (operands[2] == const1_rtx
11330                && (TARGET_SHIFT1 || optimize_size))
11331         return "sal{b}\t%0";
11332       else
11333         return "sal{b}\t{%2, %0|%0, %2}";
11334     }
11336   [(set (attr "type")
11337      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11338                           (const_int 0))
11339                       (match_operand 0 "register_operand" ""))
11340                  (match_operand 2 "const1_operand" ""))
11341               (const_string "alu")
11342            ]
11343            (const_string "ishift")))
11344    (set_attr "mode" "QI")])
11346 ;; See comment above `ashldi3' about how this works.
11348 (define_expand "ashrdi3"
11349   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11350                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11351                                 (match_operand:QI 2 "nonmemory_operand" "")))
11352               (clobber (reg:CC FLAGS_REG))])]
11353   ""
11355   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11356     {
11357       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11358       DONE;
11359     }
11360   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11361   DONE;
11364 (define_insn "ashrdi3_63_rex64"
11365   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11366         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11367                      (match_operand:DI 2 "const_int_operand" "i,i")))
11368    (clobber (reg:CC FLAGS_REG))]
11369   "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11370    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11371   "@
11372    {cqto|cqo}
11373    sar{q}\t{%2, %0|%0, %2}"
11374   [(set_attr "type" "imovx,ishift")
11375    (set_attr "prefix_0f" "0,*")
11376    (set_attr "length_immediate" "0,*")
11377    (set_attr "modrm" "0,1")
11378    (set_attr "mode" "DI")])
11380 (define_insn "*ashrdi3_1_one_bit_rex64"
11381   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11382         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11383                      (match_operand:QI 2 "const1_operand" "")))
11384    (clobber (reg:CC FLAGS_REG))]
11385   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11386    && (TARGET_SHIFT1 || optimize_size)"
11387   "sar{q}\t%0"
11388   [(set_attr "type" "ishift")
11389    (set (attr "length") 
11390      (if_then_else (match_operand:DI 0 "register_operand" "") 
11391         (const_string "2")
11392         (const_string "*")))])
11394 (define_insn "*ashrdi3_1_rex64"
11395   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11396         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11397                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11398    (clobber (reg:CC FLAGS_REG))]
11399   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11400   "@
11401    sar{q}\t{%2, %0|%0, %2}
11402    sar{q}\t{%b2, %0|%0, %b2}"
11403   [(set_attr "type" "ishift")
11404    (set_attr "mode" "DI")])
11406 ;; This pattern can't accept a variable shift count, since shifts by
11407 ;; zero don't affect the flags.  We assume that shifts by constant
11408 ;; zero are optimized away.
11409 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11410   [(set (reg 17)
11411         (compare
11412           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11413                        (match_operand:QI 2 "const1_operand" ""))
11414           (const_int 0)))
11415    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11416         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11417   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11418    && (TARGET_SHIFT1 || optimize_size)
11419    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11420   "sar{q}\t%0"
11421   [(set_attr "type" "ishift")
11422    (set (attr "length") 
11423      (if_then_else (match_operand:DI 0 "register_operand" "") 
11424         (const_string "2")
11425         (const_string "*")))])
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags.  We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*ashrdi3_cmp_rex64"
11431   [(set (reg 17)
11432         (compare
11433           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434                        (match_operand:QI 2 "const_int_operand" "n"))
11435           (const_int 0)))
11436    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11437         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11438   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11440   "sar{q}\t{%2, %0|%0, %2}"
11441   [(set_attr "type" "ishift")
11442    (set_attr "mode" "DI")])
11445 (define_insn "ashrdi3_1"
11446   [(set (match_operand:DI 0 "register_operand" "=r")
11447         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11448                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11449    (clobber (match_scratch:SI 3 "=&r"))
11450    (clobber (reg:CC FLAGS_REG))]
11451   "!TARGET_64BIT && TARGET_CMOVE"
11452   "#"
11453   [(set_attr "type" "multi")])
11455 (define_insn "*ashrdi3_2"
11456   [(set (match_operand:DI 0 "register_operand" "=r")
11457         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11458                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11459    (clobber (reg:CC FLAGS_REG))]
11460   "!TARGET_64BIT"
11461   "#"
11462   [(set_attr "type" "multi")])
11464 (define_split
11465   [(set (match_operand:DI 0 "register_operand" "")
11466         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11467                      (match_operand:QI 2 "nonmemory_operand" "")))
11468    (clobber (match_scratch:SI 3 ""))
11469    (clobber (reg:CC FLAGS_REG))]
11470   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11471   [(const_int 0)]
11472   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11474 (define_split
11475   [(set (match_operand:DI 0 "register_operand" "")
11476         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11477                      (match_operand:QI 2 "nonmemory_operand" "")))
11478    (clobber (reg:CC FLAGS_REG))]
11479   "!TARGET_64BIT && reload_completed"
11480   [(const_int 0)]
11481   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11483 (define_insn "x86_shrd_1"
11484   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11485         (ior:SI (ashiftrt:SI (match_dup 0)
11486                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11487                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11488                   (minus:QI (const_int 32) (match_dup 2)))))
11489    (clobber (reg:CC FLAGS_REG))]
11490   ""
11491   "@
11492    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11493    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11494   [(set_attr "type" "ishift")
11495    (set_attr "prefix_0f" "1")
11496    (set_attr "pent_pair" "np")
11497    (set_attr "mode" "SI")])
11499 (define_expand "x86_shift_adj_3"
11500   [(use (match_operand:SI 0 "register_operand" ""))
11501    (use (match_operand:SI 1 "register_operand" ""))
11502    (use (match_operand:QI 2 "register_operand" ""))]
11503   ""
11505   rtx label = gen_label_rtx ();
11506   rtx tmp;
11508   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11510   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11511   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11512   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11513                               gen_rtx_LABEL_REF (VOIDmode, label),
11514                               pc_rtx);
11515   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11516   JUMP_LABEL (tmp) = label;
11518   emit_move_insn (operands[0], operands[1]);
11519   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11521   emit_label (label);
11522   LABEL_NUSES (label) = 1;
11524   DONE;
11527 (define_insn "ashrsi3_31"
11528   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11529         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11530                      (match_operand:SI 2 "const_int_operand" "i,i")))
11531    (clobber (reg:CC FLAGS_REG))]
11532   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11533    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11534   "@
11535    {cltd|cdq}
11536    sar{l}\t{%2, %0|%0, %2}"
11537   [(set_attr "type" "imovx,ishift")
11538    (set_attr "prefix_0f" "0,*")
11539    (set_attr "length_immediate" "0,*")
11540    (set_attr "modrm" "0,1")
11541    (set_attr "mode" "SI")])
11543 (define_insn "*ashrsi3_31_zext"
11544   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11545         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11546                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11547    (clobber (reg:CC FLAGS_REG))]
11548   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11549    && INTVAL (operands[2]) == 31
11550    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11551   "@
11552    {cltd|cdq}
11553    sar{l}\t{%2, %k0|%k0, %2}"
11554   [(set_attr "type" "imovx,ishift")
11555    (set_attr "prefix_0f" "0,*")
11556    (set_attr "length_immediate" "0,*")
11557    (set_attr "modrm" "0,1")
11558    (set_attr "mode" "SI")])
11560 (define_expand "ashrsi3"
11561   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11562         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11563                      (match_operand:QI 2 "nonmemory_operand" "")))
11564    (clobber (reg:CC FLAGS_REG))]
11565   ""
11566   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11568 (define_insn "*ashrsi3_1_one_bit"
11569   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11570         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11571                      (match_operand:QI 2 "const1_operand" "")))
11572    (clobber (reg:CC FLAGS_REG))]
11573   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11574    && (TARGET_SHIFT1 || optimize_size)"
11575   "sar{l}\t%0"
11576   [(set_attr "type" "ishift")
11577    (set (attr "length") 
11578      (if_then_else (match_operand:SI 0 "register_operand" "") 
11579         (const_string "2")
11580         (const_string "*")))])
11582 (define_insn "*ashrsi3_1_one_bit_zext"
11583   [(set (match_operand:DI 0 "register_operand" "=r")
11584         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11585                                      (match_operand:QI 2 "const1_operand" ""))))
11586    (clobber (reg:CC FLAGS_REG))]
11587   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11588    && (TARGET_SHIFT1 || optimize_size)"
11589   "sar{l}\t%k0"
11590   [(set_attr "type" "ishift")
11591    (set_attr "length" "2")])
11593 (define_insn "*ashrsi3_1"
11594   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11595         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11596                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11597    (clobber (reg:CC FLAGS_REG))]
11598   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11599   "@
11600    sar{l}\t{%2, %0|%0, %2}
11601    sar{l}\t{%b2, %0|%0, %b2}"
11602   [(set_attr "type" "ishift")
11603    (set_attr "mode" "SI")])
11605 (define_insn "*ashrsi3_1_zext"
11606   [(set (match_operand:DI 0 "register_operand" "=r,r")
11607         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11608                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11609    (clobber (reg:CC FLAGS_REG))]
11610   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11611   "@
11612    sar{l}\t{%2, %k0|%k0, %2}
11613    sar{l}\t{%b2, %k0|%k0, %b2}"
11614   [(set_attr "type" "ishift")
11615    (set_attr "mode" "SI")])
11617 ;; This pattern can't accept a variable shift count, since shifts by
11618 ;; zero don't affect the flags.  We assume that shifts by constant
11619 ;; zero are optimized away.
11620 (define_insn "*ashrsi3_one_bit_cmp"
11621   [(set (reg 17)
11622         (compare
11623           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11624                        (match_operand:QI 2 "const1_operand" ""))
11625           (const_int 0)))
11626    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11627         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11628   "ix86_match_ccmode (insn, CCGOCmode)
11629    && (TARGET_SHIFT1 || optimize_size)
11630    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11631   "sar{l}\t%0"
11632   [(set_attr "type" "ishift")
11633    (set (attr "length") 
11634      (if_then_else (match_operand:SI 0 "register_operand" "") 
11635         (const_string "2")
11636         (const_string "*")))])
11638 (define_insn "*ashrsi3_one_bit_cmp_zext"
11639   [(set (reg 17)
11640         (compare
11641           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11642                        (match_operand:QI 2 "const1_operand" ""))
11643           (const_int 0)))
11644    (set (match_operand:DI 0 "register_operand" "=r")
11645         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11646   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11647    && (TARGET_SHIFT1 || optimize_size)
11648    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11649   "sar{l}\t%k0"
11650   [(set_attr "type" "ishift")
11651    (set_attr "length" "2")])
11653 ;; This pattern can't accept a variable shift count, since shifts by
11654 ;; zero don't affect the flags.  We assume that shifts by constant
11655 ;; zero are optimized away.
11656 (define_insn "*ashrsi3_cmp"
11657   [(set (reg 17)
11658         (compare
11659           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11660                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11661           (const_int 0)))
11662    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11663         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11664   "ix86_match_ccmode (insn, CCGOCmode)
11665    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11666   "sar{l}\t{%2, %0|%0, %2}"
11667   [(set_attr "type" "ishift")
11668    (set_attr "mode" "SI")])
11670 (define_insn "*ashrsi3_cmp_zext"
11671   [(set (reg 17)
11672         (compare
11673           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11674                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11675           (const_int 0)))
11676    (set (match_operand:DI 0 "register_operand" "=r")
11677         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11678   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11679    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11680   "sar{l}\t{%2, %k0|%k0, %2}"
11681   [(set_attr "type" "ishift")
11682    (set_attr "mode" "SI")])
11684 (define_expand "ashrhi3"
11685   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11686         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11687                      (match_operand:QI 2 "nonmemory_operand" "")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "TARGET_HIMODE_MATH"
11690   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11692 (define_insn "*ashrhi3_1_one_bit"
11693   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11694         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11695                      (match_operand:QI 2 "const1_operand" "")))
11696    (clobber (reg:CC FLAGS_REG))]
11697   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11698    && (TARGET_SHIFT1 || optimize_size)"
11699   "sar{w}\t%0"
11700   [(set_attr "type" "ishift")
11701    (set (attr "length") 
11702      (if_then_else (match_operand 0 "register_operand" "") 
11703         (const_string "2")
11704         (const_string "*")))])
11706 (define_insn "*ashrhi3_1"
11707   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11708         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11709                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11710    (clobber (reg:CC FLAGS_REG))]
11711   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11712   "@
11713    sar{w}\t{%2, %0|%0, %2}
11714    sar{w}\t{%b2, %0|%0, %b2}"
11715   [(set_attr "type" "ishift")
11716    (set_attr "mode" "HI")])
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 "*ashrhi3_one_bit_cmp"
11722   [(set (reg 17)
11723         (compare
11724           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11725                        (match_operand:QI 2 "const1_operand" ""))
11726           (const_int 0)))
11727    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11728         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11729   "ix86_match_ccmode (insn, CCGOCmode)
11730    && (TARGET_SHIFT1 || optimize_size)
11731    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11732   "sar{w}\t%0"
11733   [(set_attr "type" "ishift")
11734    (set (attr "length") 
11735      (if_then_else (match_operand 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 "*ashrhi3_cmp"
11743   [(set (reg 17)
11744         (compare
11745           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11746                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11747           (const_int 0)))
11748    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11749         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11750   "ix86_match_ccmode (insn, CCGOCmode)
11751    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11752   "sar{w}\t{%2, %0|%0, %2}"
11753   [(set_attr "type" "ishift")
11754    (set_attr "mode" "HI")])
11756 (define_expand "ashrqi3"
11757   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11758         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11759                      (match_operand:QI 2 "nonmemory_operand" "")))
11760    (clobber (reg:CC FLAGS_REG))]
11761   "TARGET_QIMODE_MATH"
11762   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11764 (define_insn "*ashrqi3_1_one_bit"
11765   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11766         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11767                      (match_operand:QI 2 "const1_operand" "")))
11768    (clobber (reg:CC FLAGS_REG))]
11769   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11770    && (TARGET_SHIFT1 || optimize_size)"
11771   "sar{b}\t%0"
11772   [(set_attr "type" "ishift")
11773    (set (attr "length") 
11774      (if_then_else (match_operand 0 "register_operand" "") 
11775         (const_string "2")
11776         (const_string "*")))])
11778 (define_insn "*ashrqi3_1_one_bit_slp"
11779   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11780         (ashiftrt:QI (match_dup 0)
11781                      (match_operand:QI 1 "const1_operand" "")))
11782    (clobber (reg:CC FLAGS_REG))]
11783   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11784    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11785    && (TARGET_SHIFT1 || optimize_size)"
11786   "sar{b}\t%0"
11787   [(set_attr "type" "ishift1")
11788    (set (attr "length") 
11789      (if_then_else (match_operand 0 "register_operand" "") 
11790         (const_string "2")
11791         (const_string "*")))])
11793 (define_insn "*ashrqi3_1"
11794   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11795         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11796                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11797    (clobber (reg:CC FLAGS_REG))]
11798   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11799   "@
11800    sar{b}\t{%2, %0|%0, %2}
11801    sar{b}\t{%b2, %0|%0, %b2}"
11802   [(set_attr "type" "ishift")
11803    (set_attr "mode" "QI")])
11805 (define_insn "*ashrqi3_1_slp"
11806   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11807         (ashiftrt:QI (match_dup 0)
11808                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11809    (clobber (reg:CC FLAGS_REG))]
11810   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11812   "@
11813    sar{b}\t{%1, %0|%0, %1}
11814    sar{b}\t{%b1, %0|%0, %b1}"
11815   [(set_attr "type" "ishift1")
11816    (set_attr "mode" "QI")])
11818 ;; This pattern can't accept a variable shift count, since shifts by
11819 ;; zero don't affect the flags.  We assume that shifts by constant
11820 ;; zero are optimized away.
11821 (define_insn "*ashrqi3_one_bit_cmp"
11822   [(set (reg 17)
11823         (compare
11824           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11825                        (match_operand:QI 2 "const1_operand" "I"))
11826           (const_int 0)))
11827    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11828         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11829   "ix86_match_ccmode (insn, CCGOCmode)
11830    && (TARGET_SHIFT1 || optimize_size)
11831    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11832   "sar{b}\t%0"
11833   [(set_attr "type" "ishift")
11834    (set (attr "length") 
11835      (if_then_else (match_operand 0 "register_operand" "") 
11836         (const_string "2")
11837         (const_string "*")))])
11839 ;; This pattern can't accept a variable shift count, since shifts by
11840 ;; zero don't affect the flags.  We assume that shifts by constant
11841 ;; zero are optimized away.
11842 (define_insn "*ashrqi3_cmp"
11843   [(set (reg 17)
11844         (compare
11845           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11846                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11847           (const_int 0)))
11848    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11849         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11850   "ix86_match_ccmode (insn, CCGOCmode)
11851    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11852   "sar{b}\t{%2, %0|%0, %2}"
11853   [(set_attr "type" "ishift")
11854    (set_attr "mode" "QI")])
11856 ;; Logical shift instructions
11858 ;; See comment above `ashldi3' about how this works.
11860 (define_expand "lshrdi3"
11861   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11862                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11863                                 (match_operand:QI 2 "nonmemory_operand" "")))
11864               (clobber (reg:CC FLAGS_REG))])]
11865   ""
11867   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11868     {
11869       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11870       DONE;
11871     }
11872   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11873   DONE;
11876 (define_insn "*lshrdi3_1_one_bit_rex64"
11877   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11878         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11879                      (match_operand:QI 2 "const1_operand" "")))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11882    && (TARGET_SHIFT1 || optimize_size)"
11883   "shr{q}\t%0"
11884   [(set_attr "type" "ishift")
11885    (set (attr "length") 
11886      (if_then_else (match_operand:DI 0 "register_operand" "") 
11887         (const_string "2")
11888         (const_string "*")))])
11890 (define_insn "*lshrdi3_1_rex64"
11891   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11892         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11893                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11894    (clobber (reg:CC FLAGS_REG))]
11895   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11896   "@
11897    shr{q}\t{%2, %0|%0, %2}
11898    shr{q}\t{%b2, %0|%0, %b2}"
11899   [(set_attr "type" "ishift")
11900    (set_attr "mode" "DI")])
11902 ;; This pattern can't accept a variable shift count, since shifts by
11903 ;; zero don't affect the flags.  We assume that shifts by constant
11904 ;; zero are optimized away.
11905 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11906   [(set (reg 17)
11907         (compare
11908           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11909                        (match_operand:QI 2 "const1_operand" ""))
11910           (const_int 0)))
11911    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11912         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11913   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11914    && (TARGET_SHIFT1 || optimize_size)
11915    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11916   "shr{q}\t%0"
11917   [(set_attr "type" "ishift")
11918    (set (attr "length") 
11919      (if_then_else (match_operand:DI 0 "register_operand" "") 
11920         (const_string "2")
11921         (const_string "*")))])
11923 ;; This pattern can't accept a variable shift count, since shifts by
11924 ;; zero don't affect the flags.  We assume that shifts by constant
11925 ;; zero are optimized away.
11926 (define_insn "*lshrdi3_cmp_rex64"
11927   [(set (reg 17)
11928         (compare
11929           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11930                        (match_operand:QI 2 "const_int_operand" "e"))
11931           (const_int 0)))
11932    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11933         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11934   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11935    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11936   "shr{q}\t{%2, %0|%0, %2}"
11937   [(set_attr "type" "ishift")
11938    (set_attr "mode" "DI")])
11940 (define_insn "lshrdi3_1"
11941   [(set (match_operand:DI 0 "register_operand" "=r")
11942         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11943                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11944    (clobber (match_scratch:SI 3 "=&r"))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "!TARGET_64BIT && TARGET_CMOVE"
11947   "#"
11948   [(set_attr "type" "multi")])
11950 (define_insn "*lshrdi3_2"
11951   [(set (match_operand:DI 0 "register_operand" "=r")
11952         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11953                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11954    (clobber (reg:CC FLAGS_REG))]
11955   "!TARGET_64BIT"
11956   "#"
11957   [(set_attr "type" "multi")])
11959 (define_split 
11960   [(set (match_operand:DI 0 "register_operand" "")
11961         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11962                      (match_operand:QI 2 "nonmemory_operand" "")))
11963    (clobber (match_scratch:SI 3 ""))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11966   [(const_int 0)]
11967   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11969 (define_split 
11970   [(set (match_operand:DI 0 "register_operand" "")
11971         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11972                      (match_operand:QI 2 "nonmemory_operand" "")))
11973    (clobber (reg:CC FLAGS_REG))]
11974   "!TARGET_64BIT && reload_completed"
11975   [(const_int 0)]
11976   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11978 (define_expand "lshrsi3"
11979   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11980         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11981                      (match_operand:QI 2 "nonmemory_operand" "")))
11982    (clobber (reg:CC FLAGS_REG))]
11983   ""
11984   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11986 (define_insn "*lshrsi3_1_one_bit"
11987   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11988         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11989                      (match_operand:QI 2 "const1_operand" "")))
11990    (clobber (reg:CC FLAGS_REG))]
11991   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11992    && (TARGET_SHIFT1 || optimize_size)"
11993   "shr{l}\t%0"
11994   [(set_attr "type" "ishift")
11995    (set (attr "length") 
11996      (if_then_else (match_operand:SI 0 "register_operand" "") 
11997         (const_string "2")
11998         (const_string "*")))])
12000 (define_insn "*lshrsi3_1_one_bit_zext"
12001   [(set (match_operand:DI 0 "register_operand" "=r")
12002         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12003                      (match_operand:QI 2 "const1_operand" "")))
12004    (clobber (reg:CC FLAGS_REG))]
12005   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12006    && (TARGET_SHIFT1 || optimize_size)"
12007   "shr{l}\t%k0"
12008   [(set_attr "type" "ishift")
12009    (set_attr "length" "2")])
12011 (define_insn "*lshrsi3_1"
12012   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12013         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12014                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12015    (clobber (reg:CC FLAGS_REG))]
12016   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12017   "@
12018    shr{l}\t{%2, %0|%0, %2}
12019    shr{l}\t{%b2, %0|%0, %b2}"
12020   [(set_attr "type" "ishift")
12021    (set_attr "mode" "SI")])
12023 (define_insn "*lshrsi3_1_zext"
12024   [(set (match_operand:DI 0 "register_operand" "=r,r")
12025         (zero_extend:DI
12026           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12027                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12028    (clobber (reg:CC FLAGS_REG))]
12029   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12030   "@
12031    shr{l}\t{%2, %k0|%k0, %2}
12032    shr{l}\t{%b2, %k0|%k0, %b2}"
12033   [(set_attr "type" "ishift")
12034    (set_attr "mode" "SI")])
12036 ;; This pattern can't accept a variable shift count, since shifts by
12037 ;; zero don't affect the flags.  We assume that shifts by constant
12038 ;; zero are optimized away.
12039 (define_insn "*lshrsi3_one_bit_cmp"
12040   [(set (reg 17)
12041         (compare
12042           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12043                        (match_operand:QI 2 "const1_operand" ""))
12044           (const_int 0)))
12045    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12046         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12047   "ix86_match_ccmode (insn, CCGOCmode)
12048    && (TARGET_SHIFT1 || optimize_size)
12049    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12050   "shr{l}\t%0"
12051   [(set_attr "type" "ishift")
12052    (set (attr "length") 
12053      (if_then_else (match_operand:SI 0 "register_operand" "") 
12054         (const_string "2")
12055         (const_string "*")))])
12057 (define_insn "*lshrsi3_cmp_one_bit_zext"
12058   [(set (reg 17)
12059         (compare
12060           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12061                        (match_operand:QI 2 "const1_operand" ""))
12062           (const_int 0)))
12063    (set (match_operand:DI 0 "register_operand" "=r")
12064         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12065   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12066    && (TARGET_SHIFT1 || optimize_size)
12067    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12068   "shr{l}\t%k0"
12069   [(set_attr "type" "ishift")
12070    (set_attr "length" "2")])
12072 ;; This pattern can't accept a variable shift count, since shifts by
12073 ;; zero don't affect the flags.  We assume that shifts by constant
12074 ;; zero are optimized away.
12075 (define_insn "*lshrsi3_cmp"
12076   [(set (reg 17)
12077         (compare
12078           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12079                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12080           (const_int 0)))
12081    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12082         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12083   "ix86_match_ccmode (insn, CCGOCmode)
12084    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12085   "shr{l}\t{%2, %0|%0, %2}"
12086   [(set_attr "type" "ishift")
12087    (set_attr "mode" "SI")])
12089 (define_insn "*lshrsi3_cmp_zext"
12090   [(set (reg 17)
12091         (compare
12092           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12093                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12094           (const_int 0)))
12095    (set (match_operand:DI 0 "register_operand" "=r")
12096         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12097   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12098    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12099   "shr{l}\t{%2, %k0|%k0, %2}"
12100   [(set_attr "type" "ishift")
12101    (set_attr "mode" "SI")])
12103 (define_expand "lshrhi3"
12104   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12105         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12106                      (match_operand:QI 2 "nonmemory_operand" "")))
12107    (clobber (reg:CC FLAGS_REG))]
12108   "TARGET_HIMODE_MATH"
12109   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12111 (define_insn "*lshrhi3_1_one_bit"
12112   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12113         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12114                      (match_operand:QI 2 "const1_operand" "")))
12115    (clobber (reg:CC FLAGS_REG))]
12116   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12117    && (TARGET_SHIFT1 || optimize_size)"
12118   "shr{w}\t%0"
12119   [(set_attr "type" "ishift")
12120    (set (attr "length") 
12121      (if_then_else (match_operand 0 "register_operand" "") 
12122         (const_string "2")
12123         (const_string "*")))])
12125 (define_insn "*lshrhi3_1"
12126   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12127         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12128                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12131   "@
12132    shr{w}\t{%2, %0|%0, %2}
12133    shr{w}\t{%b2, %0|%0, %b2}"
12134   [(set_attr "type" "ishift")
12135    (set_attr "mode" "HI")])
12137 ;; This pattern can't accept a variable shift count, since shifts by
12138 ;; zero don't affect the flags.  We assume that shifts by constant
12139 ;; zero are optimized away.
12140 (define_insn "*lshrhi3_one_bit_cmp"
12141   [(set (reg 17)
12142         (compare
12143           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12144                        (match_operand:QI 2 "const1_operand" ""))
12145           (const_int 0)))
12146    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12147         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12148   "ix86_match_ccmode (insn, CCGOCmode)
12149    && (TARGET_SHIFT1 || optimize_size)
12150    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12151   "shr{w}\t%0"
12152   [(set_attr "type" "ishift")
12153    (set (attr "length") 
12154      (if_then_else (match_operand:SI 0 "register_operand" "") 
12155         (const_string "2")
12156         (const_string "*")))])
12158 ;; This pattern can't accept a variable shift count, since shifts by
12159 ;; zero don't affect the flags.  We assume that shifts by constant
12160 ;; zero are optimized away.
12161 (define_insn "*lshrhi3_cmp"
12162   [(set (reg 17)
12163         (compare
12164           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12165                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12166           (const_int 0)))
12167    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12168         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12169   "ix86_match_ccmode (insn, CCGOCmode)
12170    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12171   "shr{w}\t{%2, %0|%0, %2}"
12172   [(set_attr "type" "ishift")
12173    (set_attr "mode" "HI")])
12175 (define_expand "lshrqi3"
12176   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12177         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12178                      (match_operand:QI 2 "nonmemory_operand" "")))
12179    (clobber (reg:CC FLAGS_REG))]
12180   "TARGET_QIMODE_MATH"
12181   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12183 (define_insn "*lshrqi3_1_one_bit"
12184   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12185         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12186                      (match_operand:QI 2 "const1_operand" "")))
12187    (clobber (reg:CC FLAGS_REG))]
12188   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12189    && (TARGET_SHIFT1 || optimize_size)"
12190   "shr{b}\t%0"
12191   [(set_attr "type" "ishift")
12192    (set (attr "length") 
12193      (if_then_else (match_operand 0 "register_operand" "") 
12194         (const_string "2")
12195         (const_string "*")))])
12197 (define_insn "*lshrqi3_1_one_bit_slp"
12198   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12199         (lshiftrt:QI (match_dup 0)
12200                      (match_operand:QI 1 "const1_operand" "")))
12201    (clobber (reg:CC FLAGS_REG))]
12202   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12203    && (TARGET_SHIFT1 || optimize_size)"
12204   "shr{b}\t%0"
12205   [(set_attr "type" "ishift1")
12206    (set (attr "length") 
12207      (if_then_else (match_operand 0 "register_operand" "") 
12208         (const_string "2")
12209         (const_string "*")))])
12211 (define_insn "*lshrqi3_1"
12212   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12213         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12214                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12215    (clobber (reg:CC FLAGS_REG))]
12216   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12217   "@
12218    shr{b}\t{%2, %0|%0, %2}
12219    shr{b}\t{%b2, %0|%0, %b2}"
12220   [(set_attr "type" "ishift")
12221    (set_attr "mode" "QI")])
12223 (define_insn "*lshrqi3_1_slp"
12224   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12225         (lshiftrt:QI (match_dup 0)
12226                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12227    (clobber (reg:CC FLAGS_REG))]
12228   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12229    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12230   "@
12231    shr{b}\t{%1, %0|%0, %1}
12232    shr{b}\t{%b1, %0|%0, %b1}"
12233   [(set_attr "type" "ishift1")
12234    (set_attr "mode" "QI")])
12236 ;; This pattern can't accept a variable shift count, since shifts by
12237 ;; zero don't affect the flags.  We assume that shifts by constant
12238 ;; zero are optimized away.
12239 (define_insn "*lshrqi2_one_bit_cmp"
12240   [(set (reg 17)
12241         (compare
12242           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12243                        (match_operand:QI 2 "const1_operand" ""))
12244           (const_int 0)))
12245    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12246         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12247   "ix86_match_ccmode (insn, CCGOCmode)
12248    && (TARGET_SHIFT1 || optimize_size)
12249    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12250   "shr{b}\t%0"
12251   [(set_attr "type" "ishift")
12252    (set (attr "length") 
12253      (if_then_else (match_operand:SI 0 "register_operand" "") 
12254         (const_string "2")
12255         (const_string "*")))])
12257 ;; This pattern can't accept a variable shift count, since shifts by
12258 ;; zero don't affect the flags.  We assume that shifts by constant
12259 ;; zero are optimized away.
12260 (define_insn "*lshrqi2_cmp"
12261   [(set (reg 17)
12262         (compare
12263           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12264                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12265           (const_int 0)))
12266    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12267         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12268   "ix86_match_ccmode (insn, CCGOCmode)
12269    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12270   "shr{b}\t{%2, %0|%0, %2}"
12271   [(set_attr "type" "ishift")
12272    (set_attr "mode" "QI")])
12274 ;; Rotate instructions
12276 (define_expand "rotldi3"
12277   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12278         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12279                    (match_operand:QI 2 "nonmemory_operand" "")))
12280    (clobber (reg:CC FLAGS_REG))]
12281   "TARGET_64BIT"
12282   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12284 (define_insn "*rotlsi3_1_one_bit_rex64"
12285   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12286         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12287                    (match_operand:QI 2 "const1_operand" "")))
12288    (clobber (reg:CC FLAGS_REG))]
12289   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12290    && (TARGET_SHIFT1 || optimize_size)"
12291   "rol{q}\t%0"
12292   [(set_attr "type" "rotate")
12293    (set (attr "length") 
12294      (if_then_else (match_operand:DI 0 "register_operand" "") 
12295         (const_string "2")
12296         (const_string "*")))])
12298 (define_insn "*rotldi3_1_rex64"
12299   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12300         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12301                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12302    (clobber (reg:CC FLAGS_REG))]
12303   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12304   "@
12305    rol{q}\t{%2, %0|%0, %2}
12306    rol{q}\t{%b2, %0|%0, %b2}"
12307   [(set_attr "type" "rotate")
12308    (set_attr "mode" "DI")])
12310 (define_expand "rotlsi3"
12311   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12312         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12313                    (match_operand:QI 2 "nonmemory_operand" "")))
12314    (clobber (reg:CC FLAGS_REG))]
12315   ""
12316   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12318 (define_insn "*rotlsi3_1_one_bit"
12319   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12320         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12321                    (match_operand:QI 2 "const1_operand" "")))
12322    (clobber (reg:CC FLAGS_REG))]
12323   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12324    && (TARGET_SHIFT1 || optimize_size)"
12325   "rol{l}\t%0"
12326   [(set_attr "type" "rotate")
12327    (set (attr "length") 
12328      (if_then_else (match_operand:SI 0 "register_operand" "") 
12329         (const_string "2")
12330         (const_string "*")))])
12332 (define_insn "*rotlsi3_1_one_bit_zext"
12333   [(set (match_operand:DI 0 "register_operand" "=r")
12334         (zero_extend:DI
12335           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12336                      (match_operand:QI 2 "const1_operand" ""))))
12337    (clobber (reg:CC FLAGS_REG))]
12338   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12339    && (TARGET_SHIFT1 || optimize_size)"
12340   "rol{l}\t%k0"
12341   [(set_attr "type" "rotate")
12342    (set_attr "length" "2")])
12344 (define_insn "*rotlsi3_1"
12345   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12346         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12347                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12350   "@
12351    rol{l}\t{%2, %0|%0, %2}
12352    rol{l}\t{%b2, %0|%0, %b2}"
12353   [(set_attr "type" "rotate")
12354    (set_attr "mode" "SI")])
12356 (define_insn "*rotlsi3_1_zext"
12357   [(set (match_operand:DI 0 "register_operand" "=r,r")
12358         (zero_extend:DI
12359           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12360                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12361    (clobber (reg:CC FLAGS_REG))]
12362   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12363   "@
12364    rol{l}\t{%2, %k0|%k0, %2}
12365    rol{l}\t{%b2, %k0|%k0, %b2}"
12366   [(set_attr "type" "rotate")
12367    (set_attr "mode" "SI")])
12369 (define_expand "rotlhi3"
12370   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12371         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12372                    (match_operand:QI 2 "nonmemory_operand" "")))
12373    (clobber (reg:CC FLAGS_REG))]
12374   "TARGET_HIMODE_MATH"
12375   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12377 (define_insn "*rotlhi3_1_one_bit"
12378   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12379         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12380                    (match_operand:QI 2 "const1_operand" "")))
12381    (clobber (reg:CC FLAGS_REG))]
12382   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12383    && (TARGET_SHIFT1 || optimize_size)"
12384   "rol{w}\t%0"
12385   [(set_attr "type" "rotate")
12386    (set (attr "length") 
12387      (if_then_else (match_operand 0 "register_operand" "") 
12388         (const_string "2")
12389         (const_string "*")))])
12391 (define_insn "*rotlhi3_1"
12392   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12393         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12394                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12395    (clobber (reg:CC FLAGS_REG))]
12396   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12397   "@
12398    rol{w}\t{%2, %0|%0, %2}
12399    rol{w}\t{%b2, %0|%0, %b2}"
12400   [(set_attr "type" "rotate")
12401    (set_attr "mode" "HI")])
12403 (define_expand "rotlqi3"
12404   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12405         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12406                    (match_operand:QI 2 "nonmemory_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "TARGET_QIMODE_MATH"
12409   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12411 (define_insn "*rotlqi3_1_one_bit_slp"
12412   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12413         (rotate:QI (match_dup 0)
12414                    (match_operand:QI 1 "const1_operand" "")))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12417    && (TARGET_SHIFT1 || optimize_size)"
12418   "rol{b}\t%0"
12419   [(set_attr "type" "rotate1")
12420    (set (attr "length") 
12421      (if_then_else (match_operand 0 "register_operand" "") 
12422         (const_string "2")
12423         (const_string "*")))])
12425 (define_insn "*rotlqi3_1_one_bit"
12426   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12427         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12428                    (match_operand:QI 2 "const1_operand" "")))
12429    (clobber (reg:CC FLAGS_REG))]
12430   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12431    && (TARGET_SHIFT1 || optimize_size)"
12432   "rol{b}\t%0"
12433   [(set_attr "type" "rotate")
12434    (set (attr "length") 
12435      (if_then_else (match_operand 0 "register_operand" "") 
12436         (const_string "2")
12437         (const_string "*")))])
12439 (define_insn "*rotlqi3_1_slp"
12440   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12441         (rotate:QI (match_dup 0)
12442                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12445    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12446   "@
12447    rol{b}\t{%1, %0|%0, %1}
12448    rol{b}\t{%b1, %0|%0, %b1}"
12449   [(set_attr "type" "rotate1")
12450    (set_attr "mode" "QI")])
12452 (define_insn "*rotlqi3_1"
12453   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12454         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12455                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12456    (clobber (reg:CC FLAGS_REG))]
12457   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12458   "@
12459    rol{b}\t{%2, %0|%0, %2}
12460    rol{b}\t{%b2, %0|%0, %b2}"
12461   [(set_attr "type" "rotate")
12462    (set_attr "mode" "QI")])
12464 (define_expand "rotrdi3"
12465   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12466         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12467                      (match_operand:QI 2 "nonmemory_operand" "")))
12468    (clobber (reg:CC FLAGS_REG))]
12469   "TARGET_64BIT"
12470   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12472 (define_insn "*rotrdi3_1_one_bit_rex64"
12473   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12474         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12475                      (match_operand:QI 2 "const1_operand" "")))
12476    (clobber (reg:CC FLAGS_REG))]
12477   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12478    && (TARGET_SHIFT1 || optimize_size)"
12479   "ror{q}\t%0"
12480   [(set_attr "type" "rotate")
12481    (set (attr "length") 
12482      (if_then_else (match_operand:DI 0 "register_operand" "") 
12483         (const_string "2")
12484         (const_string "*")))])
12486 (define_insn "*rotrdi3_1_rex64"
12487   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12488         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12489                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12490    (clobber (reg:CC FLAGS_REG))]
12491   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12492   "@
12493    ror{q}\t{%2, %0|%0, %2}
12494    ror{q}\t{%b2, %0|%0, %b2}"
12495   [(set_attr "type" "rotate")
12496    (set_attr "mode" "DI")])
12498 (define_expand "rotrsi3"
12499   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12500         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12501                      (match_operand:QI 2 "nonmemory_operand" "")))
12502    (clobber (reg:CC FLAGS_REG))]
12503   ""
12504   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12506 (define_insn "*rotrsi3_1_one_bit"
12507   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12508         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12509                      (match_operand:QI 2 "const1_operand" "")))
12510    (clobber (reg:CC FLAGS_REG))]
12511   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12512    && (TARGET_SHIFT1 || optimize_size)"
12513   "ror{l}\t%0"
12514   [(set_attr "type" "rotate")
12515    (set (attr "length") 
12516      (if_then_else (match_operand:SI 0 "register_operand" "") 
12517         (const_string "2")
12518         (const_string "*")))])
12520 (define_insn "*rotrsi3_1_one_bit_zext"
12521   [(set (match_operand:DI 0 "register_operand" "=r")
12522         (zero_extend:DI
12523           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12524                        (match_operand:QI 2 "const1_operand" ""))))
12525    (clobber (reg:CC FLAGS_REG))]
12526   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12527    && (TARGET_SHIFT1 || optimize_size)"
12528   "ror{l}\t%k0"
12529   [(set_attr "type" "rotate")
12530    (set (attr "length") 
12531      (if_then_else (match_operand:SI 0 "register_operand" "") 
12532         (const_string "2")
12533         (const_string "*")))])
12535 (define_insn "*rotrsi3_1"
12536   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12537         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12538                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12539    (clobber (reg:CC FLAGS_REG))]
12540   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12541   "@
12542    ror{l}\t{%2, %0|%0, %2}
12543    ror{l}\t{%b2, %0|%0, %b2}"
12544   [(set_attr "type" "rotate")
12545    (set_attr "mode" "SI")])
12547 (define_insn "*rotrsi3_1_zext"
12548   [(set (match_operand:DI 0 "register_operand" "=r,r")
12549         (zero_extend:DI
12550           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12551                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12552    (clobber (reg:CC FLAGS_REG))]
12553   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12554   "@
12555    ror{l}\t{%2, %k0|%k0, %2}
12556    ror{l}\t{%b2, %k0|%k0, %b2}"
12557   [(set_attr "type" "rotate")
12558    (set_attr "mode" "SI")])
12560 (define_expand "rotrhi3"
12561   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12562         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12563                      (match_operand:QI 2 "nonmemory_operand" "")))
12564    (clobber (reg:CC FLAGS_REG))]
12565   "TARGET_HIMODE_MATH"
12566   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12568 (define_insn "*rotrhi3_one_bit"
12569   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12570         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12571                      (match_operand:QI 2 "const1_operand" "")))
12572    (clobber (reg:CC FLAGS_REG))]
12573   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12574    && (TARGET_SHIFT1 || optimize_size)"
12575   "ror{w}\t%0"
12576   [(set_attr "type" "rotate")
12577    (set (attr "length") 
12578      (if_then_else (match_operand 0 "register_operand" "") 
12579         (const_string "2")
12580         (const_string "*")))])
12582 (define_insn "*rotrhi3"
12583   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12584         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12585                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12586    (clobber (reg:CC FLAGS_REG))]
12587   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12588   "@
12589    ror{w}\t{%2, %0|%0, %2}
12590    ror{w}\t{%b2, %0|%0, %b2}"
12591   [(set_attr "type" "rotate")
12592    (set_attr "mode" "HI")])
12594 (define_expand "rotrqi3"
12595   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12596         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12597                      (match_operand:QI 2 "nonmemory_operand" "")))
12598    (clobber (reg:CC FLAGS_REG))]
12599   "TARGET_QIMODE_MATH"
12600   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12602 (define_insn "*rotrqi3_1_one_bit"
12603   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12604         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12605                      (match_operand:QI 2 "const1_operand" "")))
12606    (clobber (reg:CC FLAGS_REG))]
12607   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12608    && (TARGET_SHIFT1 || optimize_size)"
12609   "ror{b}\t%0"
12610   [(set_attr "type" "rotate")
12611    (set (attr "length") 
12612      (if_then_else (match_operand 0 "register_operand" "") 
12613         (const_string "2")
12614         (const_string "*")))])
12616 (define_insn "*rotrqi3_1_one_bit_slp"
12617   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12618         (rotatert:QI (match_dup 0)
12619                      (match_operand:QI 1 "const1_operand" "")))
12620    (clobber (reg:CC FLAGS_REG))]
12621   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12622    && (TARGET_SHIFT1 || optimize_size)"
12623   "ror{b}\t%0"
12624   [(set_attr "type" "rotate1")
12625    (set (attr "length") 
12626      (if_then_else (match_operand 0 "register_operand" "") 
12627         (const_string "2")
12628         (const_string "*")))])
12630 (define_insn "*rotrqi3_1"
12631   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12632         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12633                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12634    (clobber (reg:CC FLAGS_REG))]
12635   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12636   "@
12637    ror{b}\t{%2, %0|%0, %2}
12638    ror{b}\t{%b2, %0|%0, %b2}"
12639   [(set_attr "type" "rotate")
12640    (set_attr "mode" "QI")])
12642 (define_insn "*rotrqi3_1_slp"
12643   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12644         (rotatert:QI (match_dup 0)
12645                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12646    (clobber (reg:CC FLAGS_REG))]
12647   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12648    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12649   "@
12650    ror{b}\t{%1, %0|%0, %1}
12651    ror{b}\t{%b1, %0|%0, %b1}"
12652   [(set_attr "type" "rotate1")
12653    (set_attr "mode" "QI")])
12655 ;; Bit set / bit test instructions
12657 (define_expand "extv"
12658   [(set (match_operand:SI 0 "register_operand" "")
12659         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12660                          (match_operand:SI 2 "immediate_operand" "")
12661                          (match_operand:SI 3 "immediate_operand" "")))]
12662   ""
12664   /* Handle extractions from %ah et al.  */
12665   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12666     FAIL;
12668   /* From mips.md: extract_bit_field doesn't verify that our source
12669      matches the predicate, so check it again here.  */
12670   if (! register_operand (operands[1], VOIDmode))
12671     FAIL;
12674 (define_expand "extzv"
12675   [(set (match_operand:SI 0 "register_operand" "")
12676         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12677                          (match_operand:SI 2 "immediate_operand" "")
12678                          (match_operand:SI 3 "immediate_operand" "")))]
12679   ""
12681   /* Handle extractions from %ah et al.  */
12682   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12683     FAIL;
12685   /* From mips.md: extract_bit_field doesn't verify that our source
12686      matches the predicate, so check it again here.  */
12687   if (! register_operand (operands[1], VOIDmode))
12688     FAIL;
12691 (define_expand "insv"
12692   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12693                       (match_operand 1 "immediate_operand" "")
12694                       (match_operand 2 "immediate_operand" ""))
12695         (match_operand 3 "register_operand" ""))]
12696   ""
12698   /* Handle extractions from %ah et al.  */
12699   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12700     FAIL;
12702   /* From mips.md: insert_bit_field doesn't verify that our source
12703      matches the predicate, so check it again here.  */
12704   if (! register_operand (operands[0], VOIDmode))
12705     FAIL;
12707   if (TARGET_64BIT)
12708     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12709   else
12710     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12712   DONE;
12715 ;; %%% bts, btr, btc, bt.
12717 ;; Store-flag instructions.
12719 ;; For all sCOND expanders, also expand the compare or test insn that
12720 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12722 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12723 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12724 ;; way, which can later delete the movzx if only QImode is needed.
12726 (define_expand "seq"
12727   [(set (match_operand:QI 0 "register_operand" "")
12728         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12729   ""
12730   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12732 (define_expand "sne"
12733   [(set (match_operand:QI 0 "register_operand" "")
12734         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12735   ""
12736   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12738 (define_expand "sgt"
12739   [(set (match_operand:QI 0 "register_operand" "")
12740         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12741   ""
12742   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12744 (define_expand "sgtu"
12745   [(set (match_operand:QI 0 "register_operand" "")
12746         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12747   ""
12748   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12750 (define_expand "slt"
12751   [(set (match_operand:QI 0 "register_operand" "")
12752         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12753   ""
12754   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12756 (define_expand "sltu"
12757   [(set (match_operand:QI 0 "register_operand" "")
12758         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12759   ""
12760   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12762 (define_expand "sge"
12763   [(set (match_operand:QI 0 "register_operand" "")
12764         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12765   ""
12766   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12768 (define_expand "sgeu"
12769   [(set (match_operand:QI 0 "register_operand" "")
12770         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12771   ""
12772   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12774 (define_expand "sle"
12775   [(set (match_operand:QI 0 "register_operand" "")
12776         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12777   ""
12778   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12780 (define_expand "sleu"
12781   [(set (match_operand:QI 0 "register_operand" "")
12782         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12783   ""
12784   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12786 (define_expand "sunordered"
12787   [(set (match_operand:QI 0 "register_operand" "")
12788         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12789   "TARGET_80387 || TARGET_SSE"
12790   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12792 (define_expand "sordered"
12793   [(set (match_operand:QI 0 "register_operand" "")
12794         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12795   "TARGET_80387"
12796   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12798 (define_expand "suneq"
12799   [(set (match_operand:QI 0 "register_operand" "")
12800         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12801   "TARGET_80387 || TARGET_SSE"
12802   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12804 (define_expand "sunge"
12805   [(set (match_operand:QI 0 "register_operand" "")
12806         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12807   "TARGET_80387 || TARGET_SSE"
12808   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12810 (define_expand "sungt"
12811   [(set (match_operand:QI 0 "register_operand" "")
12812         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12813   "TARGET_80387 || TARGET_SSE"
12814   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12816 (define_expand "sunle"
12817   [(set (match_operand:QI 0 "register_operand" "")
12818         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12819   "TARGET_80387 || TARGET_SSE"
12820   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12822 (define_expand "sunlt"
12823   [(set (match_operand:QI 0 "register_operand" "")
12824         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12825   "TARGET_80387 || TARGET_SSE"
12826   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12828 (define_expand "sltgt"
12829   [(set (match_operand:QI 0 "register_operand" "")
12830         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12831   "TARGET_80387 || TARGET_SSE"
12832   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12834 (define_insn "*setcc_1"
12835   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12836         (match_operator:QI 1 "ix86_comparison_operator"
12837           [(reg 17) (const_int 0)]))]
12838   ""
12839   "set%C1\t%0"
12840   [(set_attr "type" "setcc")
12841    (set_attr "mode" "QI")])
12843 (define_insn "setcc_2"
12844   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12845         (match_operator:QI 1 "ix86_comparison_operator"
12846           [(reg 17) (const_int 0)]))]
12847   ""
12848   "set%C1\t%0"
12849   [(set_attr "type" "setcc")
12850    (set_attr "mode" "QI")])
12852 ;; In general it is not safe to assume too much about CCmode registers,
12853 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12854 ;; conditions this is safe on x86, so help combine not create
12856 ;;      seta    %al
12857 ;;      testb   %al, %al
12858 ;;      sete    %al
12860 (define_split 
12861   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12862         (ne:QI (match_operator 1 "ix86_comparison_operator"
12863                  [(reg 17) (const_int 0)])
12864             (const_int 0)))]
12865   ""
12866   [(set (match_dup 0) (match_dup 1))]
12868   PUT_MODE (operands[1], QImode);
12871 (define_split 
12872   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12873         (ne:QI (match_operator 1 "ix86_comparison_operator"
12874                  [(reg 17) (const_int 0)])
12875             (const_int 0)))]
12876   ""
12877   [(set (match_dup 0) (match_dup 1))]
12879   PUT_MODE (operands[1], QImode);
12882 (define_split 
12883   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12884         (eq:QI (match_operator 1 "ix86_comparison_operator"
12885                  [(reg 17) (const_int 0)])
12886             (const_int 0)))]
12887   ""
12888   [(set (match_dup 0) (match_dup 1))]
12890   rtx new_op1 = copy_rtx (operands[1]);
12891   operands[1] = new_op1;
12892   PUT_MODE (new_op1, QImode);
12893   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12894                                              GET_MODE (XEXP (new_op1, 0))));
12896   /* Make sure that (a) the CCmode we have for the flags is strong
12897      enough for the reversed compare or (b) we have a valid FP compare.  */
12898   if (! ix86_comparison_operator (new_op1, VOIDmode))
12899     FAIL;
12902 (define_split 
12903   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12904         (eq:QI (match_operator 1 "ix86_comparison_operator"
12905                  [(reg 17) (const_int 0)])
12906             (const_int 0)))]
12907   ""
12908   [(set (match_dup 0) (match_dup 1))]
12910   rtx new_op1 = copy_rtx (operands[1]);
12911   operands[1] = new_op1;
12912   PUT_MODE (new_op1, QImode);
12913   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12914                                              GET_MODE (XEXP (new_op1, 0))));
12916   /* Make sure that (a) the CCmode we have for the flags is strong
12917      enough for the reversed compare or (b) we have a valid FP compare.  */
12918   if (! ix86_comparison_operator (new_op1, VOIDmode))
12919     FAIL;
12922 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12923 ;; subsequent logical operations are used to imitate conditional moves.
12924 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12925 ;; it directly.  Further holding this value in pseudo register might bring
12926 ;; problem in implicit normalization in spill code.
12927 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12928 ;; instructions after reload by splitting the conditional move patterns.
12930 (define_insn "*sse_setccsf"
12931   [(set (match_operand:SF 0 "register_operand" "=x")
12932         (match_operator:SF 1 "sse_comparison_operator"
12933           [(match_operand:SF 2 "register_operand" "0")
12934            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12935   "TARGET_SSE && reload_completed"
12936   "cmp%D1ss\t{%3, %0|%0, %3}"
12937   [(set_attr "type" "ssecmp")
12938    (set_attr "mode" "SF")])
12940 (define_insn "*sse_setccdf"
12941   [(set (match_operand:DF 0 "register_operand" "=Y")
12942         (match_operator:DF 1 "sse_comparison_operator"
12943           [(match_operand:DF 2 "register_operand" "0")
12944            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12945   "TARGET_SSE2 && reload_completed"
12946   "cmp%D1sd\t{%3, %0|%0, %3}"
12947   [(set_attr "type" "ssecmp")
12948    (set_attr "mode" "DF")])
12950 ;; Basic conditional jump instructions.
12951 ;; We ignore the overflow flag for signed branch instructions.
12953 ;; For all bCOND expanders, also expand the compare or test insn that
12954 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12956 (define_expand "beq"
12957   [(set (pc)
12958         (if_then_else (match_dup 1)
12959                       (label_ref (match_operand 0 "" ""))
12960                       (pc)))]
12961   ""
12962   "ix86_expand_branch (EQ, operands[0]); DONE;")
12964 (define_expand "bne"
12965   [(set (pc)
12966         (if_then_else (match_dup 1)
12967                       (label_ref (match_operand 0 "" ""))
12968                       (pc)))]
12969   ""
12970   "ix86_expand_branch (NE, operands[0]); DONE;")
12972 (define_expand "bgt"
12973   [(set (pc)
12974         (if_then_else (match_dup 1)
12975                       (label_ref (match_operand 0 "" ""))
12976                       (pc)))]
12977   ""
12978   "ix86_expand_branch (GT, operands[0]); DONE;")
12980 (define_expand "bgtu"
12981   [(set (pc)
12982         (if_then_else (match_dup 1)
12983                       (label_ref (match_operand 0 "" ""))
12984                       (pc)))]
12985   ""
12986   "ix86_expand_branch (GTU, operands[0]); DONE;")
12988 (define_expand "blt"
12989   [(set (pc)
12990         (if_then_else (match_dup 1)
12991                       (label_ref (match_operand 0 "" ""))
12992                       (pc)))]
12993   ""
12994   "ix86_expand_branch (LT, operands[0]); DONE;")
12996 (define_expand "bltu"
12997   [(set (pc)
12998         (if_then_else (match_dup 1)
12999                       (label_ref (match_operand 0 "" ""))
13000                       (pc)))]
13001   ""
13002   "ix86_expand_branch (LTU, operands[0]); DONE;")
13004 (define_expand "bge"
13005   [(set (pc)
13006         (if_then_else (match_dup 1)
13007                       (label_ref (match_operand 0 "" ""))
13008                       (pc)))]
13009   ""
13010   "ix86_expand_branch (GE, operands[0]); DONE;")
13012 (define_expand "bgeu"
13013   [(set (pc)
13014         (if_then_else (match_dup 1)
13015                       (label_ref (match_operand 0 "" ""))
13016                       (pc)))]
13017   ""
13018   "ix86_expand_branch (GEU, operands[0]); DONE;")
13020 (define_expand "ble"
13021   [(set (pc)
13022         (if_then_else (match_dup 1)
13023                       (label_ref (match_operand 0 "" ""))
13024                       (pc)))]
13025   ""
13026   "ix86_expand_branch (LE, operands[0]); DONE;")
13028 (define_expand "bleu"
13029   [(set (pc)
13030         (if_then_else (match_dup 1)
13031                       (label_ref (match_operand 0 "" ""))
13032                       (pc)))]
13033   ""
13034   "ix86_expand_branch (LEU, operands[0]); DONE;")
13036 (define_expand "bunordered"
13037   [(set (pc)
13038         (if_then_else (match_dup 1)
13039                       (label_ref (match_operand 0 "" ""))
13040                       (pc)))]
13041   "TARGET_80387 || TARGET_SSE"
13042   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13044 (define_expand "bordered"
13045   [(set (pc)
13046         (if_then_else (match_dup 1)
13047                       (label_ref (match_operand 0 "" ""))
13048                       (pc)))]
13049   "TARGET_80387 || TARGET_SSE"
13050   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13052 (define_expand "buneq"
13053   [(set (pc)
13054         (if_then_else (match_dup 1)
13055                       (label_ref (match_operand 0 "" ""))
13056                       (pc)))]
13057   "TARGET_80387 || TARGET_SSE"
13058   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13060 (define_expand "bunge"
13061   [(set (pc)
13062         (if_then_else (match_dup 1)
13063                       (label_ref (match_operand 0 "" ""))
13064                       (pc)))]
13065   "TARGET_80387 || TARGET_SSE"
13066   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13068 (define_expand "bungt"
13069   [(set (pc)
13070         (if_then_else (match_dup 1)
13071                       (label_ref (match_operand 0 "" ""))
13072                       (pc)))]
13073   "TARGET_80387 || TARGET_SSE"
13074   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13076 (define_expand "bunle"
13077   [(set (pc)
13078         (if_then_else (match_dup 1)
13079                       (label_ref (match_operand 0 "" ""))
13080                       (pc)))]
13081   "TARGET_80387 || TARGET_SSE"
13082   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13084 (define_expand "bunlt"
13085   [(set (pc)
13086         (if_then_else (match_dup 1)
13087                       (label_ref (match_operand 0 "" ""))
13088                       (pc)))]
13089   "TARGET_80387 || TARGET_SSE"
13090   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13092 (define_expand "bltgt"
13093   [(set (pc)
13094         (if_then_else (match_dup 1)
13095                       (label_ref (match_operand 0 "" ""))
13096                       (pc)))]
13097   "TARGET_80387 || TARGET_SSE"
13098   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13100 (define_insn "*jcc_1"
13101   [(set (pc)
13102         (if_then_else (match_operator 1 "ix86_comparison_operator"
13103                                       [(reg 17) (const_int 0)])
13104                       (label_ref (match_operand 0 "" ""))
13105                       (pc)))]
13106   ""
13107   "%+j%C1\t%l0"
13108   [(set_attr "type" "ibr")
13109    (set_attr "modrm" "0")
13110    (set (attr "length")
13111            (if_then_else (and (ge (minus (match_dup 0) (pc))
13112                                   (const_int -126))
13113                               (lt (minus (match_dup 0) (pc))
13114                                   (const_int 128)))
13115              (const_int 2)
13116              (const_int 6)))])
13118 (define_insn "*jcc_2"
13119   [(set (pc)
13120         (if_then_else (match_operator 1 "ix86_comparison_operator"
13121                                       [(reg 17) (const_int 0)])
13122                       (pc)
13123                       (label_ref (match_operand 0 "" ""))))]
13124   ""
13125   "%+j%c1\t%l0"
13126   [(set_attr "type" "ibr")
13127    (set_attr "modrm" "0")
13128    (set (attr "length")
13129            (if_then_else (and (ge (minus (match_dup 0) (pc))
13130                                   (const_int -126))
13131                               (lt (minus (match_dup 0) (pc))
13132                                   (const_int 128)))
13133              (const_int 2)
13134              (const_int 6)))])
13136 ;; In general it is not safe to assume too much about CCmode registers,
13137 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13138 ;; conditions this is safe on x86, so help combine not create
13140 ;;      seta    %al
13141 ;;      testb   %al, %al
13142 ;;      je      Lfoo
13144 (define_split 
13145   [(set (pc)
13146         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13147                                       [(reg 17) (const_int 0)])
13148                           (const_int 0))
13149                       (label_ref (match_operand 1 "" ""))
13150                       (pc)))]
13151   ""
13152   [(set (pc)
13153         (if_then_else (match_dup 0)
13154                       (label_ref (match_dup 1))
13155                       (pc)))]
13157   PUT_MODE (operands[0], VOIDmode);
13159   
13160 (define_split 
13161   [(set (pc)
13162         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13163                                       [(reg 17) (const_int 0)])
13164                           (const_int 0))
13165                       (label_ref (match_operand 1 "" ""))
13166                       (pc)))]
13167   ""
13168   [(set (pc)
13169         (if_then_else (match_dup 0)
13170                       (label_ref (match_dup 1))
13171                       (pc)))]
13173   rtx new_op0 = copy_rtx (operands[0]);
13174   operands[0] = new_op0;
13175   PUT_MODE (new_op0, VOIDmode);
13176   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13177                                              GET_MODE (XEXP (new_op0, 0))));
13179   /* Make sure that (a) the CCmode we have for the flags is strong
13180      enough for the reversed compare or (b) we have a valid FP compare.  */
13181   if (! ix86_comparison_operator (new_op0, VOIDmode))
13182     FAIL;
13185 ;; Define combination compare-and-branch fp compare instructions to use
13186 ;; during early optimization.  Splitting the operation apart early makes
13187 ;; for bad code when we want to reverse the operation.
13189 (define_insn "*fp_jcc_1"
13190   [(set (pc)
13191         (if_then_else (match_operator 0 "comparison_operator"
13192                         [(match_operand 1 "register_operand" "f")
13193                          (match_operand 2 "register_operand" "f")])
13194           (label_ref (match_operand 3 "" ""))
13195           (pc)))
13196    (clobber (reg:CCFP FPSR_REG))
13197    (clobber (reg:CCFP FLAGS_REG))]
13198   "TARGET_CMOVE && TARGET_80387
13199    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13200    && FLOAT_MODE_P (GET_MODE (operands[1]))
13201    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13202    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13203   "#")
13205 (define_insn "*fp_jcc_1_sse"
13206   [(set (pc)
13207         (if_then_else (match_operator 0 "comparison_operator"
13208                         [(match_operand 1 "register_operand" "f#x,x#f")
13209                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13210           (label_ref (match_operand 3 "" ""))
13211           (pc)))
13212    (clobber (reg:CCFP FPSR_REG))
13213    (clobber (reg:CCFP FLAGS_REG))]
13214   "TARGET_80387
13215    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13216    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13217    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13218   "#")
13220 (define_insn "*fp_jcc_1_sse_only"
13221   [(set (pc)
13222         (if_then_else (match_operator 0 "comparison_operator"
13223                         [(match_operand 1 "register_operand" "x")
13224                          (match_operand 2 "nonimmediate_operand" "xm")])
13225           (label_ref (match_operand 3 "" ""))
13226           (pc)))
13227    (clobber (reg:CCFP FPSR_REG))
13228    (clobber (reg:CCFP FLAGS_REG))]
13229   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13230    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13231    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13232   "#")
13234 (define_insn "*fp_jcc_2"
13235   [(set (pc)
13236         (if_then_else (match_operator 0 "comparison_operator"
13237                         [(match_operand 1 "register_operand" "f")
13238                          (match_operand 2 "register_operand" "f")])
13239           (pc)
13240           (label_ref (match_operand 3 "" ""))))
13241    (clobber (reg:CCFP FPSR_REG))
13242    (clobber (reg:CCFP FLAGS_REG))]
13243   "TARGET_CMOVE && TARGET_80387
13244    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13245    && FLOAT_MODE_P (GET_MODE (operands[1]))
13246    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13247    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13248   "#")
13250 (define_insn "*fp_jcc_2_sse"
13251   [(set (pc)
13252         (if_then_else (match_operator 0 "comparison_operator"
13253                         [(match_operand 1 "register_operand" "f#x,x#f")
13254                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13255           (pc)
13256           (label_ref (match_operand 3 "" ""))))
13257    (clobber (reg:CCFP FPSR_REG))
13258    (clobber (reg:CCFP FLAGS_REG))]
13259   "TARGET_80387
13260    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13261    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13262    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13263   "#")
13265 (define_insn "*fp_jcc_2_sse_only"
13266   [(set (pc)
13267         (if_then_else (match_operator 0 "comparison_operator"
13268                         [(match_operand 1 "register_operand" "x")
13269                          (match_operand 2 "nonimmediate_operand" "xm")])
13270           (pc)
13271           (label_ref (match_operand 3 "" ""))))
13272    (clobber (reg:CCFP FPSR_REG))
13273    (clobber (reg:CCFP FLAGS_REG))]
13274   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13275    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13276    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13277   "#")
13279 (define_insn "*fp_jcc_3"
13280   [(set (pc)
13281         (if_then_else (match_operator 0 "comparison_operator"
13282                         [(match_operand 1 "register_operand" "f")
13283                          (match_operand 2 "nonimmediate_operand" "fm")])
13284           (label_ref (match_operand 3 "" ""))
13285           (pc)))
13286    (clobber (reg:CCFP FPSR_REG))
13287    (clobber (reg:CCFP FLAGS_REG))
13288    (clobber (match_scratch:HI 4 "=a"))]
13289   "TARGET_80387
13290    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13291    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13292    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13293    && SELECT_CC_MODE (GET_CODE (operands[0]),
13294                       operands[1], operands[2]) == CCFPmode
13295    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13296   "#")
13298 (define_insn "*fp_jcc_4"
13299   [(set (pc)
13300         (if_then_else (match_operator 0 "comparison_operator"
13301                         [(match_operand 1 "register_operand" "f")
13302                          (match_operand 2 "nonimmediate_operand" "fm")])
13303           (pc)
13304           (label_ref (match_operand 3 "" ""))))
13305    (clobber (reg:CCFP FPSR_REG))
13306    (clobber (reg:CCFP FLAGS_REG))
13307    (clobber (match_scratch:HI 4 "=a"))]
13308   "TARGET_80387
13309    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13310    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13311    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13312    && SELECT_CC_MODE (GET_CODE (operands[0]),
13313                       operands[1], operands[2]) == CCFPmode
13314    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13315   "#")
13317 (define_insn "*fp_jcc_5"
13318   [(set (pc)
13319         (if_then_else (match_operator 0 "comparison_operator"
13320                         [(match_operand 1 "register_operand" "f")
13321                          (match_operand 2 "register_operand" "f")])
13322           (label_ref (match_operand 3 "" ""))
13323           (pc)))
13324    (clobber (reg:CCFP FPSR_REG))
13325    (clobber (reg:CCFP FLAGS_REG))
13326    (clobber (match_scratch:HI 4 "=a"))]
13327   "TARGET_80387
13328    && FLOAT_MODE_P (GET_MODE (operands[1]))
13329    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13330    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13331   "#")
13333 (define_insn "*fp_jcc_6"
13334   [(set (pc)
13335         (if_then_else (match_operator 0 "comparison_operator"
13336                         [(match_operand 1 "register_operand" "f")
13337                          (match_operand 2 "register_operand" "f")])
13338           (pc)
13339           (label_ref (match_operand 3 "" ""))))
13340    (clobber (reg:CCFP FPSR_REG))
13341    (clobber (reg:CCFP FLAGS_REG))
13342    (clobber (match_scratch:HI 4 "=a"))]
13343   "TARGET_80387
13344    && FLOAT_MODE_P (GET_MODE (operands[1]))
13345    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13346    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13347   "#")
13349 (define_insn "*fp_jcc_7"
13350   [(set (pc)
13351         (if_then_else (match_operator 0 "comparison_operator"
13352                         [(match_operand 1 "register_operand" "f")
13353                          (match_operand 2 "const_double_operand" "C")])
13354           (label_ref (match_operand 3 "" ""))
13355           (pc)))
13356    (clobber (reg:CCFP FPSR_REG))
13357    (clobber (reg:CCFP FLAGS_REG))
13358    (clobber (match_scratch:HI 4 "=a"))]
13359   "TARGET_80387
13360    && FLOAT_MODE_P (GET_MODE (operands[1]))
13361    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13362    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13363    && SELECT_CC_MODE (GET_CODE (operands[0]),
13364                       operands[1], operands[2]) == CCFPmode
13365    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13366   "#")
13368 (define_split
13369   [(set (pc)
13370         (if_then_else (match_operator 0 "comparison_operator"
13371                         [(match_operand 1 "register_operand" "")
13372                          (match_operand 2 "nonimmediate_operand" "")])
13373           (match_operand 3 "" "")
13374           (match_operand 4 "" "")))
13375    (clobber (reg:CCFP FPSR_REG))
13376    (clobber (reg:CCFP FLAGS_REG))]
13377   "reload_completed"
13378   [(const_int 0)]
13380   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13381                         operands[3], operands[4], NULL_RTX);
13382   DONE;
13385 (define_split
13386   [(set (pc)
13387         (if_then_else (match_operator 0 "comparison_operator"
13388                         [(match_operand 1 "register_operand" "")
13389                          (match_operand 2 "general_operand" "")])
13390           (match_operand 3 "" "")
13391           (match_operand 4 "" "")))
13392    (clobber (reg:CCFP FPSR_REG))
13393    (clobber (reg:CCFP FLAGS_REG))
13394    (clobber (match_scratch:HI 5 "=a"))]
13395   "reload_completed"
13396   [(const_int 0)]
13398   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13399                         operands[3], operands[4], operands[5]);
13400   DONE;
13403 ;; Unconditional and other jump instructions
13405 (define_insn "jump"
13406   [(set (pc)
13407         (label_ref (match_operand 0 "" "")))]
13408   ""
13409   "jmp\t%l0"
13410   [(set_attr "type" "ibr")
13411    (set (attr "length")
13412            (if_then_else (and (ge (minus (match_dup 0) (pc))
13413                                   (const_int -126))
13414                               (lt (minus (match_dup 0) (pc))
13415                                   (const_int 128)))
13416              (const_int 2)
13417              (const_int 5)))
13418    (set_attr "modrm" "0")])
13420 (define_expand "indirect_jump"
13421   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13422   ""
13423   "")
13425 (define_insn "*indirect_jump"
13426   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13427   "!TARGET_64BIT"
13428   "jmp\t%A0"
13429   [(set_attr "type" "ibr")
13430    (set_attr "length_immediate" "0")])
13432 (define_insn "*indirect_jump_rtx64"
13433   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13434   "TARGET_64BIT"
13435   "jmp\t%A0"
13436   [(set_attr "type" "ibr")
13437    (set_attr "length_immediate" "0")])
13439 (define_expand "tablejump"
13440   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13441               (use (label_ref (match_operand 1 "" "")))])]
13442   ""
13444   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13445      relative.  Convert the relative address to an absolute address.  */
13446   if (flag_pic)
13447     {
13448       rtx op0, op1;
13449       enum rtx_code code;
13451       if (TARGET_64BIT)
13452         {
13453           code = PLUS;
13454           op0 = operands[0];
13455           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13456         }
13457       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13458         {
13459           code = PLUS;
13460           op0 = operands[0];
13461           op1 = pic_offset_table_rtx;
13462         }
13463       else
13464         {
13465           code = MINUS;
13466           op0 = pic_offset_table_rtx;
13467           op1 = operands[0];
13468         }
13470       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13471                                          OPTAB_DIRECT);
13472     }
13475 (define_insn "*tablejump_1"
13476   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13477    (use (label_ref (match_operand 1 "" "")))]
13478   "!TARGET_64BIT"
13479   "jmp\t%A0"
13480   [(set_attr "type" "ibr")
13481    (set_attr "length_immediate" "0")])
13483 (define_insn "*tablejump_1_rtx64"
13484   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13485    (use (label_ref (match_operand 1 "" "")))]
13486   "TARGET_64BIT"
13487   "jmp\t%A0"
13488   [(set_attr "type" "ibr")
13489    (set_attr "length_immediate" "0")])
13491 ;; Loop instruction
13493 ;; This is all complicated by the fact that since this is a jump insn
13494 ;; we must handle our own reloads.
13496 (define_expand "doloop_end"
13497   [(use (match_operand 0 "" ""))        ; loop pseudo
13498    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13499    (use (match_operand 2 "" ""))        ; max iterations
13500    (use (match_operand 3 "" ""))        ; loop level 
13501    (use (match_operand 4 "" ""))]       ; label
13502   "!TARGET_64BIT && TARGET_USE_LOOP"
13503   "                                 
13505   /* Only use cloop on innermost loops.  */
13506   if (INTVAL (operands[3]) > 1)
13507     FAIL;
13508   if (GET_MODE (operands[0]) != SImode)
13509     FAIL;
13510   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13511                                            operands[0]));
13512   DONE;
13515 (define_insn "doloop_end_internal"
13516   [(set (pc)
13517         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13518                           (const_int 1))
13519                       (label_ref (match_operand 0 "" ""))
13520                       (pc)))
13521    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13522         (plus:SI (match_dup 1)
13523                  (const_int -1)))
13524    (clobber (match_scratch:SI 3 "=X,X,r"))
13525    (clobber (reg:CC FLAGS_REG))]
13526   "!TARGET_64BIT && TARGET_USE_LOOP
13527    && (reload_in_progress || reload_completed
13528        || register_operand (operands[2], VOIDmode))"
13530   if (which_alternative != 0)
13531     return "#";
13532   if (get_attr_length (insn) == 2)
13533     return "%+loop\t%l0";
13534   else
13535     return "dec{l}\t%1\;%+jne\t%l0";
13537   [(set (attr "length")
13538         (if_then_else (and (eq_attr "alternative" "0")
13539                            (and (ge (minus (match_dup 0) (pc))
13540                                     (const_int -126))
13541                                 (lt (minus (match_dup 0) (pc))
13542                                     (const_int 128))))
13543                       (const_int 2)
13544                       (const_int 16)))
13545    ;; We don't know the type before shorten branches.  Optimistically expect
13546    ;; the loop instruction to match.
13547    (set (attr "type") (const_string "ibr"))])
13549 (define_split
13550   [(set (pc)
13551         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13552                           (const_int 1))
13553                       (match_operand 0 "" "")
13554                       (pc)))
13555    (set (match_dup 1)
13556         (plus:SI (match_dup 1)
13557                  (const_int -1)))
13558    (clobber (match_scratch:SI 2 ""))
13559    (clobber (reg:CC FLAGS_REG))]
13560   "!TARGET_64BIT && TARGET_USE_LOOP
13561    && reload_completed
13562    && REGNO (operands[1]) != 2"
13563   [(parallel [(set (reg:CCZ FLAGS_REG)
13564                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13565                                  (const_int 0)))
13566               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13567    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13568                            (match_dup 0)
13569                            (pc)))]
13570   "")
13571   
13572 (define_split
13573   [(set (pc)
13574         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13575                           (const_int 1))
13576                       (match_operand 0 "" "")
13577                       (pc)))
13578    (set (match_operand:SI 2 "nonimmediate_operand" "")
13579         (plus:SI (match_dup 1)
13580                  (const_int -1)))
13581    (clobber (match_scratch:SI 3 ""))
13582    (clobber (reg:CC FLAGS_REG))]
13583   "!TARGET_64BIT && TARGET_USE_LOOP
13584    && reload_completed
13585    && (! REG_P (operands[2])
13586        || ! rtx_equal_p (operands[1], operands[2]))"
13587   [(set (match_dup 3) (match_dup 1))
13588    (parallel [(set (reg:CCZ FLAGS_REG)
13589                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13590                                 (const_int 0)))
13591               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13592    (set (match_dup 2) (match_dup 3))
13593    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13594                            (match_dup 0)
13595                            (pc)))]
13596   "")
13598 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13600 (define_peephole2
13601   [(set (reg 17) (match_operand 0 "" ""))
13602    (set (match_operand:QI 1 "register_operand" "")
13603         (match_operator:QI 2 "ix86_comparison_operator"
13604           [(reg 17) (const_int 0)]))
13605    (set (match_operand 3 "q_regs_operand" "")
13606         (zero_extend (match_dup 1)))]
13607   "(peep2_reg_dead_p (3, operands[1])
13608     || operands_match_p (operands[1], operands[3]))
13609    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13610   [(set (match_dup 4) (match_dup 0))
13611    (set (strict_low_part (match_dup 5))
13612         (match_dup 2))]
13614   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13615   operands[5] = gen_lowpart (QImode, operands[3]);
13616   ix86_expand_clear (operands[3]);
13619 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13621 (define_peephole2
13622   [(set (reg 17) (match_operand 0 "" ""))
13623    (set (match_operand:QI 1 "register_operand" "")
13624         (match_operator:QI 2 "ix86_comparison_operator"
13625           [(reg 17) (const_int 0)]))
13626    (parallel [(set (match_operand 3 "q_regs_operand" "")
13627                    (zero_extend (match_dup 1)))
13628               (clobber (reg:CC FLAGS_REG))])]
13629   "(peep2_reg_dead_p (3, operands[1])
13630     || operands_match_p (operands[1], operands[3]))
13631    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13632   [(set (match_dup 4) (match_dup 0))
13633    (set (strict_low_part (match_dup 5))
13634         (match_dup 2))]
13636   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13637   operands[5] = gen_lowpart (QImode, operands[3]);
13638   ix86_expand_clear (operands[3]);
13641 ;; Call instructions.
13643 ;; The predicates normally associated with named expanders are not properly
13644 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13645 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13647 ;; Call subroutine returning no value.
13649 (define_expand "call_pop"
13650   [(parallel [(call (match_operand:QI 0 "" "")
13651                     (match_operand:SI 1 "" ""))
13652               (set (reg:SI SP_REG)
13653                    (plus:SI (reg:SI SP_REG)
13654                             (match_operand:SI 3 "" "")))])]
13655   "!TARGET_64BIT"
13657   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13658   DONE;
13661 (define_insn "*call_pop_0"
13662   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13663          (match_operand:SI 1 "" ""))
13664    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13665                             (match_operand:SI 2 "immediate_operand" "")))]
13666   "!TARGET_64BIT"
13668   if (SIBLING_CALL_P (insn))
13669     return "jmp\t%P0";
13670   else
13671     return "call\t%P0";
13673   [(set_attr "type" "call")])
13674   
13675 (define_insn "*call_pop_1"
13676   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13677          (match_operand:SI 1 "" ""))
13678    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13679                             (match_operand:SI 2 "immediate_operand" "i")))]
13680   "!TARGET_64BIT"
13682   if (constant_call_address_operand (operands[0], Pmode))
13683     {
13684       if (SIBLING_CALL_P (insn))
13685         return "jmp\t%P0";
13686       else
13687         return "call\t%P0";
13688     }
13689   if (SIBLING_CALL_P (insn))
13690     return "jmp\t%A0";
13691   else
13692     return "call\t%A0";
13694   [(set_attr "type" "call")])
13696 (define_expand "call"
13697   [(call (match_operand:QI 0 "" "")
13698          (match_operand 1 "" ""))
13699    (use (match_operand 2 "" ""))]
13700   ""
13702   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13703   DONE;
13706 (define_expand "sibcall"
13707   [(call (match_operand:QI 0 "" "")
13708          (match_operand 1 "" ""))
13709    (use (match_operand 2 "" ""))]
13710   ""
13712   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13713   DONE;
13716 (define_insn "*call_0"
13717   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13718          (match_operand 1 "" ""))]
13719   ""
13721   if (SIBLING_CALL_P (insn))
13722     return "jmp\t%P0";
13723   else
13724     return "call\t%P0";
13726   [(set_attr "type" "call")])
13728 (define_insn "*call_1"
13729   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13730          (match_operand 1 "" ""))]
13731   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13733   if (constant_call_address_operand (operands[0], Pmode))
13734     return "call\t%P0";
13735   return "call\t%A0";
13737   [(set_attr "type" "call")])
13739 (define_insn "*sibcall_1"
13740   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13741          (match_operand 1 "" ""))]
13742   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13744   if (constant_call_address_operand (operands[0], Pmode))
13745     return "jmp\t%P0";
13746   return "jmp\t%A0";
13748   [(set_attr "type" "call")])
13750 (define_insn "*call_1_rex64"
13751   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13752          (match_operand 1 "" ""))]
13753   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13755   if (constant_call_address_operand (operands[0], Pmode))
13756     return "call\t%P0";
13757   return "call\t%A0";
13759   [(set_attr "type" "call")])
13761 (define_insn "*sibcall_1_rex64"
13762   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13763          (match_operand 1 "" ""))]
13764   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13765   "jmp\t%P0"
13766   [(set_attr "type" "call")])
13768 (define_insn "*sibcall_1_rex64_v"
13769   [(call (mem:QI (reg:DI 40))
13770          (match_operand 0 "" ""))]
13771   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13772   "jmp\t*%%r11"
13773   [(set_attr "type" "call")])
13776 ;; Call subroutine, returning value in operand 0
13778 (define_expand "call_value_pop"
13779   [(parallel [(set (match_operand 0 "" "")
13780                    (call (match_operand:QI 1 "" "")
13781                          (match_operand:SI 2 "" "")))
13782               (set (reg:SI SP_REG)
13783                    (plus:SI (reg:SI SP_REG)
13784                             (match_operand:SI 4 "" "")))])]
13785   "!TARGET_64BIT"
13787   ix86_expand_call (operands[0], operands[1], operands[2],
13788                     operands[3], operands[4], 0);
13789   DONE;
13792 (define_expand "call_value"
13793   [(set (match_operand 0 "" "")
13794         (call (match_operand:QI 1 "" "")
13795               (match_operand:SI 2 "" "")))
13796    (use (match_operand:SI 3 "" ""))]
13797   ;; Operand 2 not used on the i386.
13798   ""
13800   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13801   DONE;
13804 (define_expand "sibcall_value"
13805   [(set (match_operand 0 "" "")
13806         (call (match_operand:QI 1 "" "")
13807               (match_operand:SI 2 "" "")))
13808    (use (match_operand:SI 3 "" ""))]
13809   ;; Operand 2 not used on the i386.
13810   ""
13812   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13813   DONE;
13816 ;; Call subroutine returning any type.
13818 (define_expand "untyped_call"
13819   [(parallel [(call (match_operand 0 "" "")
13820                     (const_int 0))
13821               (match_operand 1 "" "")
13822               (match_operand 2 "" "")])]
13823   ""
13825   int i;
13827   /* In order to give reg-stack an easier job in validating two
13828      coprocessor registers as containing a possible return value,
13829      simply pretend the untyped call returns a complex long double
13830      value.  */
13832   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13833                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13834                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13835                     NULL, 0);
13837   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13838     {
13839       rtx set = XVECEXP (operands[2], 0, i);
13840       emit_move_insn (SET_DEST (set), SET_SRC (set));
13841     }
13843   /* The optimizer does not know that the call sets the function value
13844      registers we stored in the result block.  We avoid problems by
13845      claiming that all hard registers are used and clobbered at this
13846      point.  */
13847   emit_insn (gen_blockage (const0_rtx));
13849   DONE;
13852 ;; Prologue and epilogue instructions
13854 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13855 ;; all of memory.  This blocks insns from being moved across this point.
13857 (define_insn "blockage"
13858   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13859   ""
13860   ""
13861   [(set_attr "length" "0")])
13863 ;; Insn emitted into the body of a function to return from a function.
13864 ;; This is only done if the function's epilogue is known to be simple.
13865 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13867 (define_expand "return"
13868   [(return)]
13869   "ix86_can_use_return_insn_p ()"
13871   if (current_function_pops_args)
13872     {
13873       rtx popc = GEN_INT (current_function_pops_args);
13874       emit_jump_insn (gen_return_pop_internal (popc));
13875       DONE;
13876     }
13879 (define_insn "return_internal"
13880   [(return)]
13881   "reload_completed"
13882   "ret"
13883   [(set_attr "length" "1")
13884    (set_attr "length_immediate" "0")
13885    (set_attr "modrm" "0")])
13887 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13888 ;; instruction Athlon and K8 have.
13890 (define_insn "return_internal_long"
13891   [(return)
13892    (unspec [(const_int 0)] UNSPEC_REP)]
13893   "reload_completed"
13894   "rep {;} ret"
13895   [(set_attr "length" "1")
13896    (set_attr "length_immediate" "0")
13897    (set_attr "prefix_rep" "1")
13898    (set_attr "modrm" "0")])
13900 (define_insn "return_pop_internal"
13901   [(return)
13902    (use (match_operand:SI 0 "const_int_operand" ""))]
13903   "reload_completed"
13904   "ret\t%0"
13905   [(set_attr "length" "3")
13906    (set_attr "length_immediate" "2")
13907    (set_attr "modrm" "0")])
13909 (define_insn "return_indirect_internal"
13910   [(return)
13911    (use (match_operand:SI 0 "register_operand" "r"))]
13912   "reload_completed"
13913   "jmp\t%A0"
13914   [(set_attr "type" "ibr")
13915    (set_attr "length_immediate" "0")])
13917 (define_insn "nop"
13918   [(const_int 0)]
13919   ""
13920   "nop"
13921   [(set_attr "length" "1")
13922    (set_attr "length_immediate" "0")
13923    (set_attr "modrm" "0")])
13925 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13926 ;; branch prediction penalty for the third jump in a 16-byte
13927 ;; block on K8.
13929 (define_insn "align"
13930   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13931   ""
13933 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13934   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13935 #else
13936   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13937      The align insn is used to avoid 3 jump instructions in the row to improve
13938      branch prediction and the benefits hardly outweight the cost of extra 8
13939      nops on the average inserted by full alignment pseudo operation.  */
13940 #endif
13941   return "";
13943   [(set_attr "length" "16")])
13945 (define_expand "prologue"
13946   [(const_int 1)]
13947   ""
13948   "ix86_expand_prologue (); DONE;")
13950 (define_insn "set_got"
13951   [(set (match_operand:SI 0 "register_operand" "=r")
13952         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13953    (clobber (reg:CC FLAGS_REG))]
13954   "!TARGET_64BIT"
13955   { return output_set_got (operands[0]); }
13956   [(set_attr "type" "multi")
13957    (set_attr "length" "12")])
13959 (define_expand "epilogue"
13960   [(const_int 1)]
13961   ""
13962   "ix86_expand_epilogue (1); DONE;")
13964 (define_expand "sibcall_epilogue"
13965   [(const_int 1)]
13966   ""
13967   "ix86_expand_epilogue (0); DONE;")
13969 (define_expand "eh_return"
13970   [(use (match_operand 0 "register_operand" ""))]
13971   ""
13973   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13975   /* Tricky bit: we write the address of the handler to which we will
13976      be returning into someone else's stack frame, one word below the
13977      stack address we wish to restore.  */
13978   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13979   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13980   tmp = gen_rtx_MEM (Pmode, tmp);
13981   emit_move_insn (tmp, ra);
13983   if (Pmode == SImode)
13984     emit_jump_insn (gen_eh_return_si (sa));
13985   else
13986     emit_jump_insn (gen_eh_return_di (sa));
13987   emit_barrier ();
13988   DONE;
13991 (define_insn_and_split "eh_return_si"
13992   [(set (pc) 
13993         (unspec [(match_operand:SI 0 "register_operand" "c")]
13994                  UNSPEC_EH_RETURN))]
13995   "!TARGET_64BIT"
13996   "#"
13997   "reload_completed"
13998   [(const_int 1)]
13999   "ix86_expand_epilogue (2); DONE;")
14001 (define_insn_and_split "eh_return_di"
14002   [(set (pc) 
14003         (unspec [(match_operand:DI 0 "register_operand" "c")]
14004                  UNSPEC_EH_RETURN))]
14005   "TARGET_64BIT"
14006   "#"
14007   "reload_completed"
14008   [(const_int 1)]
14009   "ix86_expand_epilogue (2); DONE;")
14011 (define_insn "leave"
14012   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14013    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14014    (clobber (mem:BLK (scratch)))]
14015   "!TARGET_64BIT"
14016   "leave"
14017   [(set_attr "type" "leave")])
14019 (define_insn "leave_rex64"
14020   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14021    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14022    (clobber (mem:BLK (scratch)))]
14023   "TARGET_64BIT"
14024   "leave"
14025   [(set_attr "type" "leave")])
14027 (define_expand "ffssi2"
14028   [(parallel
14029      [(set (match_operand:SI 0 "register_operand" "") 
14030            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14031       (clobber (match_scratch:SI 2 ""))
14032       (clobber (reg:CC FLAGS_REG))])]
14033   ""
14034   "")
14036 (define_insn_and_split "*ffs_cmove"
14037   [(set (match_operand:SI 0 "register_operand" "=r") 
14038         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14039    (clobber (match_scratch:SI 2 "=&r"))
14040    (clobber (reg:CC FLAGS_REG))]
14041   "TARGET_CMOVE"
14042   "#"
14043   "&& reload_completed"
14044   [(set (match_dup 2) (const_int -1))
14045    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14046               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14047    (set (match_dup 0) (if_then_else:SI
14048                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14049                         (match_dup 2)
14050                         (match_dup 0)))
14051    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14052               (clobber (reg:CC FLAGS_REG))])]
14053   "")
14055 (define_insn_and_split "*ffs_no_cmove"
14056   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14057         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14058    (clobber (match_scratch:SI 2 "=&q"))
14059    (clobber (reg:CC FLAGS_REG))]
14060   ""
14061   "#"
14062   "reload_completed"
14063   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14064               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14065    (set (strict_low_part (match_dup 3))
14066         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14067    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14068               (clobber (reg:CC FLAGS_REG))])
14069    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14070               (clobber (reg:CC FLAGS_REG))])
14071    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14072               (clobber (reg:CC FLAGS_REG))])]
14074   operands[3] = gen_lowpart (QImode, operands[2]);
14075   ix86_expand_clear (operands[2]);
14078 (define_insn "*ffssi_1"
14079   [(set (reg:CCZ FLAGS_REG)
14080         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14081                      (const_int 0)))
14082    (set (match_operand:SI 0 "register_operand" "=r")
14083         (ctz:SI (match_dup 1)))]
14084   ""
14085   "bsf{l}\t{%1, %0|%0, %1}"
14086   [(set_attr "prefix_0f" "1")])
14088 (define_expand "ffsdi2"
14089   [(parallel
14090      [(set (match_operand:DI 0 "register_operand" "") 
14091            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14092       (clobber (match_scratch:DI 2 ""))
14093       (clobber (reg:CC 17))])]
14094   "TARGET_64BIT && TARGET_CMOVE"
14095   "")
14097 (define_insn_and_split "*ffs_rex64"
14098   [(set (match_operand:DI 0 "register_operand" "=r") 
14099         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14100    (clobber (match_scratch:DI 2 "=&r"))
14101    (clobber (reg:CC 17))]
14102   "TARGET_64BIT && TARGET_CMOVE"
14103   "#"
14104   "&& reload_completed"
14105   [(set (match_dup 2) (const_int -1))
14106    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14107               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14108    (set (match_dup 0) (if_then_else:DI
14109                         (eq (reg:CCZ 17) (const_int 0))
14110                         (match_dup 2)
14111                         (match_dup 0)))
14112    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14113               (clobber (reg:CC 17))])]
14114   "")
14116 (define_insn "*ffsdi_1"
14117   [(set (reg:CCZ 17)
14118         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14119                      (const_int 0)))
14120    (set (match_operand:DI 0 "register_operand" "=r")
14121         (ctz:DI (match_dup 1)))]
14122   "TARGET_64BIT"
14123   "bsf{q}\t{%1, %0|%0, %1}"
14124   [(set_attr "prefix_0f" "1")])
14126 (define_insn "ctzsi2"
14127   [(set (match_operand:SI 0 "register_operand" "=r")
14128         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14129    (clobber (reg:CC FLAGS_REG))]
14130   ""
14131   "bsf{l}\t{%1, %0|%0, %1}"
14132   [(set_attr "prefix_0f" "1")])
14134 (define_insn "ctzdi2"
14135   [(set (match_operand:DI 0 "register_operand" "=r")
14136         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14137    (clobber (reg:CC 17))]
14138   "TARGET_64BIT"
14139   "bsf{q}\t{%1, %0|%0, %1}"
14140   [(set_attr "prefix_0f" "1")])
14142 (define_expand "clzsi2"
14143   [(parallel
14144      [(set (match_operand:SI 0 "register_operand" "")
14145            (minus:SI (const_int 31)
14146                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14147       (clobber (reg:CC FLAGS_REG))])
14148    (parallel
14149      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14150       (clobber (reg:CC FLAGS_REG))])]
14151   ""
14152   "")
14154 (define_insn "*bsr"
14155   [(set (match_operand:SI 0 "register_operand" "=r")
14156         (minus:SI (const_int 31)
14157                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14158    (clobber (reg:CC FLAGS_REG))]
14159   ""
14160   "bsr{l}\t{%1, %0|%0, %1}"
14161   [(set_attr "prefix_0f" "1")])
14163 (define_expand "clzdi2"
14164   [(parallel
14165      [(set (match_operand:DI 0 "register_operand" "")
14166            (minus:DI (const_int 63)
14167                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14168       (clobber (reg:CC 17))])
14169    (parallel
14170      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14171       (clobber (reg:CC 17))])]
14172   "TARGET_64BIT"
14173   "")
14175 (define_insn "*bsr_rex64"
14176   [(set (match_operand:DI 0 "register_operand" "=r")
14177         (minus:DI (const_int 63)
14178                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14179    (clobber (reg:CC 17))]
14180   "TARGET_64BIT"
14181   "bsr{q}\t{%1, %0|%0, %1}"
14182   [(set_attr "prefix_0f" "1")])
14184 ;; Thread-local storage patterns for ELF.
14186 ;; Note that these code sequences must appear exactly as shown
14187 ;; in order to allow linker relaxation.
14189 (define_insn "*tls_global_dynamic_32_gnu"
14190   [(set (match_operand:SI 0 "register_operand" "=a")
14191         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14192                     (match_operand:SI 2 "tls_symbolic_operand" "")
14193                     (match_operand:SI 3 "call_insn_operand" "")]
14194                     UNSPEC_TLS_GD))
14195    (clobber (match_scratch:SI 4 "=d"))
14196    (clobber (match_scratch:SI 5 "=c"))
14197    (clobber (reg:CC FLAGS_REG))]
14198   "!TARGET_64BIT && TARGET_GNU_TLS"
14199   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14200   [(set_attr "type" "multi")
14201    (set_attr "length" "12")])
14203 (define_insn "*tls_global_dynamic_32_sun"
14204   [(set (match_operand:SI 0 "register_operand" "=a")
14205         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14206                     (match_operand:SI 2 "tls_symbolic_operand" "")
14207                     (match_operand:SI 3 "call_insn_operand" "")]
14208                     UNSPEC_TLS_GD))
14209    (clobber (match_scratch:SI 4 "=d"))
14210    (clobber (match_scratch:SI 5 "=c"))
14211    (clobber (reg:CC FLAGS_REG))]
14212   "!TARGET_64BIT && TARGET_SUN_TLS"
14213   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14214         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14215   [(set_attr "type" "multi")
14216    (set_attr "length" "14")])
14218 (define_expand "tls_global_dynamic_32"
14219   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14220                    (unspec:SI
14221                     [(match_dup 2)
14222                      (match_operand:SI 1 "tls_symbolic_operand" "")
14223                      (match_dup 3)]
14224                     UNSPEC_TLS_GD))
14225               (clobber (match_scratch:SI 4 ""))
14226               (clobber (match_scratch:SI 5 ""))
14227               (clobber (reg:CC FLAGS_REG))])]
14228   ""
14230   if (flag_pic)
14231     operands[2] = pic_offset_table_rtx;
14232   else
14233     {
14234       operands[2] = gen_reg_rtx (Pmode);
14235       emit_insn (gen_set_got (operands[2]));
14236     }
14237   operands[3] = ix86_tls_get_addr ();
14240 (define_insn "*tls_global_dynamic_64"
14241   [(set (match_operand:DI 0 "register_operand" "=a")
14242         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14243                       (match_operand:DI 3 "" "")))
14244    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14245               UNSPEC_TLS_GD)]
14246   "TARGET_64BIT"
14247   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14248   [(set_attr "type" "multi")
14249    (set_attr "length" "16")])
14251 (define_expand "tls_global_dynamic_64"
14252   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14253                    (call (mem:QI (match_dup 2)) (const_int 0)))
14254               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14255                          UNSPEC_TLS_GD)])]
14256   ""
14258   operands[2] = ix86_tls_get_addr ();
14261 (define_insn "*tls_local_dynamic_base_32_gnu"
14262   [(set (match_operand:SI 0 "register_operand" "=a")
14263         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14264                     (match_operand:SI 2 "call_insn_operand" "")]
14265                    UNSPEC_TLS_LD_BASE))
14266    (clobber (match_scratch:SI 3 "=d"))
14267    (clobber (match_scratch:SI 4 "=c"))
14268    (clobber (reg:CC FLAGS_REG))]
14269   "!TARGET_64BIT && TARGET_GNU_TLS"
14270   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14271   [(set_attr "type" "multi")
14272    (set_attr "length" "11")])
14274 (define_insn "*tls_local_dynamic_base_32_sun"
14275   [(set (match_operand:SI 0 "register_operand" "=a")
14276         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14277                     (match_operand:SI 2 "call_insn_operand" "")]
14278                    UNSPEC_TLS_LD_BASE))
14279    (clobber (match_scratch:SI 3 "=d"))
14280    (clobber (match_scratch:SI 4 "=c"))
14281    (clobber (reg:CC FLAGS_REG))]
14282   "!TARGET_64BIT && TARGET_SUN_TLS"
14283   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14284         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14285   [(set_attr "type" "multi")
14286    (set_attr "length" "13")])
14288 (define_expand "tls_local_dynamic_base_32"
14289   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14290                    (unspec:SI [(match_dup 1) (match_dup 2)]
14291                               UNSPEC_TLS_LD_BASE))
14292               (clobber (match_scratch:SI 3 ""))
14293               (clobber (match_scratch:SI 4 ""))
14294               (clobber (reg:CC FLAGS_REG))])]
14295   ""
14297   if (flag_pic)
14298     operands[1] = pic_offset_table_rtx;
14299   else
14300     {
14301       operands[1] = gen_reg_rtx (Pmode);
14302       emit_insn (gen_set_got (operands[1]));
14303     }
14304   operands[2] = ix86_tls_get_addr ();
14307 (define_insn "*tls_local_dynamic_base_64"
14308   [(set (match_operand:DI 0 "register_operand" "=a")
14309         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14310                       (match_operand:DI 2 "" "")))
14311    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14312   "TARGET_64BIT"
14313   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14314   [(set_attr "type" "multi")
14315    (set_attr "length" "12")])
14317 (define_expand "tls_local_dynamic_base_64"
14318   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14319                    (call (mem:QI (match_dup 1)) (const_int 0)))
14320               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14321   ""
14323   operands[1] = ix86_tls_get_addr ();
14326 ;; Local dynamic of a single variable is a lose.  Show combine how
14327 ;; to convert that back to global dynamic.
14329 (define_insn_and_split "*tls_local_dynamic_32_once"
14330   [(set (match_operand:SI 0 "register_operand" "=a")
14331         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14332                              (match_operand:SI 2 "call_insn_operand" "")]
14333                             UNSPEC_TLS_LD_BASE)
14334                  (const:SI (unspec:SI
14335                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14336                             UNSPEC_DTPOFF))))
14337    (clobber (match_scratch:SI 4 "=d"))
14338    (clobber (match_scratch:SI 5 "=c"))
14339    (clobber (reg:CC FLAGS_REG))]
14340   ""
14341   "#"
14342   ""
14343   [(parallel [(set (match_dup 0)
14344                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14345                               UNSPEC_TLS_GD))
14346               (clobber (match_dup 4))
14347               (clobber (match_dup 5))
14348               (clobber (reg:CC FLAGS_REG))])]
14349   "")
14351 ;; Load and add the thread base pointer from %gs:0.
14353 (define_insn "*load_tp_si"
14354   [(set (match_operand:SI 0 "register_operand" "=r")
14355         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14356   "!TARGET_64BIT"
14357   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14358   [(set_attr "type" "imov")
14359    (set_attr "modrm" "0")
14360    (set_attr "length" "7")
14361    (set_attr "memory" "load")
14362    (set_attr "imm_disp" "false")])
14364 (define_insn "*add_tp_si"
14365   [(set (match_operand:SI 0 "register_operand" "=r")
14366         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14367                  (match_operand:SI 1 "register_operand" "0")))
14368    (clobber (reg:CC FLAGS_REG))]
14369   "!TARGET_64BIT"
14370   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14371   [(set_attr "type" "alu")
14372    (set_attr "modrm" "0")
14373    (set_attr "length" "7")
14374    (set_attr "memory" "load")
14375    (set_attr "imm_disp" "false")])
14377 (define_insn "*load_tp_di"
14378   [(set (match_operand:DI 0 "register_operand" "=r")
14379         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14380   "TARGET_64BIT"
14381   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14382   [(set_attr "type" "imov")
14383    (set_attr "modrm" "0")
14384    (set_attr "length" "7")
14385    (set_attr "memory" "load")
14386    (set_attr "imm_disp" "false")])
14388 (define_insn "*add_tp_di"
14389   [(set (match_operand:DI 0 "register_operand" "=r")
14390         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14391                  (match_operand:DI 1 "register_operand" "0")))
14392    (clobber (reg:CC FLAGS_REG))]
14393   "TARGET_64BIT"
14394   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14395   [(set_attr "type" "alu")
14396    (set_attr "modrm" "0")
14397    (set_attr "length" "7")
14398    (set_attr "memory" "load")
14399    (set_attr "imm_disp" "false")])
14401 ;; These patterns match the binary 387 instructions for addM3, subM3,
14402 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14403 ;; SFmode.  The first is the normal insn, the second the same insn but
14404 ;; with one operand a conversion, and the third the same insn but with
14405 ;; the other operand a conversion.  The conversion may be SFmode or
14406 ;; SImode if the target mode DFmode, but only SImode if the target mode
14407 ;; is SFmode.
14409 ;; Gcc is slightly more smart about handling normal two address instructions
14410 ;; so use special patterns for add and mull.
14411 (define_insn "*fop_sf_comm_nosse"
14412   [(set (match_operand:SF 0 "register_operand" "=f")
14413         (match_operator:SF 3 "binary_fp_operator"
14414                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14415                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14416   "TARGET_80387 && !TARGET_SSE_MATH
14417    && COMMUTATIVE_ARITH_P (operands[3])
14418    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14419   "* return output_387_binary_op (insn, operands);"
14420   [(set (attr "type") 
14421         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14422            (const_string "fmul")
14423            (const_string "fop")))
14424    (set_attr "mode" "SF")])
14426 (define_insn "*fop_sf_comm"
14427   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14428         (match_operator:SF 3 "binary_fp_operator"
14429                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14430                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14431   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14432    && COMMUTATIVE_ARITH_P (operands[3])
14433    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14434   "* return output_387_binary_op (insn, operands);"
14435   [(set (attr "type") 
14436         (if_then_else (eq_attr "alternative" "1")
14437            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14438               (const_string "ssemul")
14439               (const_string "sseadd"))
14440            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14441               (const_string "fmul")
14442               (const_string "fop"))))
14443    (set_attr "mode" "SF")])
14445 (define_insn "*fop_sf_comm_sse"
14446   [(set (match_operand:SF 0 "register_operand" "=x")
14447         (match_operator:SF 3 "binary_fp_operator"
14448                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14449                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14450   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14451    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14452   "* return output_387_binary_op (insn, operands);"
14453   [(set (attr "type") 
14454         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14455            (const_string "ssemul")
14456            (const_string "sseadd")))
14457    (set_attr "mode" "SF")])
14459 (define_insn "*fop_df_comm_nosse"
14460   [(set (match_operand:DF 0 "register_operand" "=f")
14461         (match_operator:DF 3 "binary_fp_operator"
14462                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14463                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14464   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14465    && COMMUTATIVE_ARITH_P (operands[3])
14466    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14467   "* return output_387_binary_op (insn, operands);"
14468   [(set (attr "type") 
14469         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14470            (const_string "fmul")
14471            (const_string "fop")))
14472    (set_attr "mode" "DF")])
14474 (define_insn "*fop_df_comm"
14475   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14476         (match_operator:DF 3 "binary_fp_operator"
14477                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14478                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14479   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14480    && COMMUTATIVE_ARITH_P (operands[3])
14481    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14482   "* return output_387_binary_op (insn, operands);"
14483   [(set (attr "type") 
14484         (if_then_else (eq_attr "alternative" "1")
14485            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14486               (const_string "ssemul")
14487               (const_string "sseadd"))
14488            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14489               (const_string "fmul")
14490               (const_string "fop"))))
14491    (set_attr "mode" "DF")])
14493 (define_insn "*fop_df_comm_sse"
14494   [(set (match_operand:DF 0 "register_operand" "=Y")
14495         (match_operator:DF 3 "binary_fp_operator"
14496                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14497                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14498   "TARGET_SSE2 && TARGET_SSE_MATH
14499    && COMMUTATIVE_ARITH_P (operands[3])
14500    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14501   "* return output_387_binary_op (insn, operands);"
14502   [(set (attr "type") 
14503         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14504            (const_string "ssemul")
14505            (const_string "sseadd")))
14506    (set_attr "mode" "DF")])
14508 (define_insn "*fop_xf_comm"
14509   [(set (match_operand:XF 0 "register_operand" "=f")
14510         (match_operator:XF 3 "binary_fp_operator"
14511                         [(match_operand:XF 1 "register_operand" "%0")
14512                          (match_operand:XF 2 "register_operand" "f")]))]
14513   "TARGET_80387
14514    && COMMUTATIVE_ARITH_P (operands[3])"
14515   "* return output_387_binary_op (insn, operands);"
14516   [(set (attr "type") 
14517         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14518            (const_string "fmul")
14519            (const_string "fop")))
14520    (set_attr "mode" "XF")])
14522 (define_insn "*fop_sf_1_nosse"
14523   [(set (match_operand:SF 0 "register_operand" "=f,f")
14524         (match_operator:SF 3 "binary_fp_operator"
14525                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14526                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14527   "TARGET_80387 && !TARGET_SSE_MATH
14528    && !COMMUTATIVE_ARITH_P (operands[3])
14529    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14530   "* return output_387_binary_op (insn, operands);"
14531   [(set (attr "type") 
14532         (cond [(match_operand:SF 3 "mult_operator" "") 
14533                  (const_string "fmul")
14534                (match_operand:SF 3 "div_operator" "") 
14535                  (const_string "fdiv")
14536               ]
14537               (const_string "fop")))
14538    (set_attr "mode" "SF")])
14540 (define_insn "*fop_sf_1"
14541   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14542         (match_operator:SF 3 "binary_fp_operator"
14543                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14544                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14545   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14546    && !COMMUTATIVE_ARITH_P (operands[3])
14547    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14548   "* return output_387_binary_op (insn, operands);"
14549   [(set (attr "type") 
14550         (cond [(and (eq_attr "alternative" "2")
14551                     (match_operand:SF 3 "mult_operator" ""))
14552                  (const_string "ssemul")
14553                (and (eq_attr "alternative" "2")
14554                     (match_operand:SF 3 "div_operator" ""))
14555                  (const_string "ssediv")
14556                (eq_attr "alternative" "2")
14557                  (const_string "sseadd")
14558                (match_operand:SF 3 "mult_operator" "") 
14559                  (const_string "fmul")
14560                (match_operand:SF 3 "div_operator" "") 
14561                  (const_string "fdiv")
14562               ]
14563               (const_string "fop")))
14564    (set_attr "mode" "SF")])
14566 (define_insn "*fop_sf_1_sse"
14567   [(set (match_operand:SF 0 "register_operand" "=x")
14568         (match_operator:SF 3 "binary_fp_operator"
14569                         [(match_operand:SF 1 "register_operand" "0")
14570                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14571   "TARGET_SSE_MATH
14572    && !COMMUTATIVE_ARITH_P (operands[3])"
14573   "* return output_387_binary_op (insn, operands);"
14574   [(set (attr "type") 
14575         (cond [(match_operand:SF 3 "mult_operator" "")
14576                  (const_string "ssemul")
14577                (match_operand:SF 3 "div_operator" "")
14578                  (const_string "ssediv")
14579               ]
14580               (const_string "sseadd")))
14581    (set_attr "mode" "SF")])
14583 ;; ??? Add SSE splitters for these!
14584 (define_insn "*fop_sf_2"
14585   [(set (match_operand:SF 0 "register_operand" "=f,f")
14586         (match_operator:SF 3 "binary_fp_operator"
14587           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14588            (match_operand:SF 2 "register_operand" "0,0")]))]
14589   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14590   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14591   [(set (attr "type") 
14592         (cond [(match_operand:SF 3 "mult_operator" "") 
14593                  (const_string "fmul")
14594                (match_operand:SF 3 "div_operator" "") 
14595                  (const_string "fdiv")
14596               ]
14597               (const_string "fop")))
14598    (set_attr "fp_int_src" "true")
14599    (set_attr "mode" "SI")])
14601 (define_insn "*fop_sf_3"
14602   [(set (match_operand:SF 0 "register_operand" "=f,f")
14603         (match_operator:SF 3 "binary_fp_operator"
14604           [(match_operand:SF 1 "register_operand" "0,0")
14605            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14606   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14607   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14608   [(set (attr "type") 
14609         (cond [(match_operand:SF 3 "mult_operator" "") 
14610                  (const_string "fmul")
14611                (match_operand:SF 3 "div_operator" "") 
14612                  (const_string "fdiv")
14613               ]
14614               (const_string "fop")))
14615    (set_attr "fp_int_src" "true")
14616    (set_attr "mode" "SI")])
14618 (define_insn "*fop_df_1_nosse"
14619   [(set (match_operand:DF 0 "register_operand" "=f,f")
14620         (match_operator:DF 3 "binary_fp_operator"
14621                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14622                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14623   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14624    && !COMMUTATIVE_ARITH_P (operands[3])
14625    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14626   "* return output_387_binary_op (insn, operands);"
14627   [(set (attr "type") 
14628         (cond [(match_operand:DF 3 "mult_operator" "") 
14629                  (const_string "fmul")
14630                (match_operand:DF 3 "div_operator" "")
14631                  (const_string "fdiv")
14632               ]
14633               (const_string "fop")))
14634    (set_attr "mode" "DF")])
14637 (define_insn "*fop_df_1"
14638   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14639         (match_operator:DF 3 "binary_fp_operator"
14640                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14641                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14642   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14643    && !COMMUTATIVE_ARITH_P (operands[3])
14644    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14645   "* return output_387_binary_op (insn, operands);"
14646   [(set (attr "type") 
14647         (cond [(and (eq_attr "alternative" "2")
14648                     (match_operand:SF 3 "mult_operator" ""))
14649                  (const_string "ssemul")
14650                (and (eq_attr "alternative" "2")
14651                     (match_operand:SF 3 "div_operator" ""))
14652                  (const_string "ssediv")
14653                (eq_attr "alternative" "2")
14654                  (const_string "sseadd")
14655                (match_operand:DF 3 "mult_operator" "") 
14656                  (const_string "fmul")
14657                (match_operand:DF 3 "div_operator" "") 
14658                  (const_string "fdiv")
14659               ]
14660               (const_string "fop")))
14661    (set_attr "mode" "DF")])
14663 (define_insn "*fop_df_1_sse"
14664   [(set (match_operand:DF 0 "register_operand" "=Y")
14665         (match_operator:DF 3 "binary_fp_operator"
14666                         [(match_operand:DF 1 "register_operand" "0")
14667                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14668   "TARGET_SSE2 && TARGET_SSE_MATH
14669    && !COMMUTATIVE_ARITH_P (operands[3])"
14670   "* return output_387_binary_op (insn, operands);"
14671   [(set_attr "mode" "DF")
14672    (set (attr "type") 
14673         (cond [(match_operand:SF 3 "mult_operator" "")
14674                  (const_string "ssemul")
14675                (match_operand:SF 3 "div_operator" "")
14676                  (const_string "ssediv")
14677               ]
14678               (const_string "sseadd")))])
14680 ;; ??? Add SSE splitters for these!
14681 (define_insn "*fop_df_2"
14682   [(set (match_operand:DF 0 "register_operand" "=f,f")
14683         (match_operator:DF 3 "binary_fp_operator"
14684            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14685             (match_operand:DF 2 "register_operand" "0,0")]))]
14686   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14687   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14688   [(set (attr "type") 
14689         (cond [(match_operand:DF 3 "mult_operator" "") 
14690                  (const_string "fmul")
14691                (match_operand:DF 3 "div_operator" "") 
14692                  (const_string "fdiv")
14693               ]
14694               (const_string "fop")))
14695    (set_attr "fp_int_src" "true")
14696    (set_attr "mode" "SI")])
14698 (define_insn "*fop_df_3"
14699   [(set (match_operand:DF 0 "register_operand" "=f,f")
14700         (match_operator:DF 3 "binary_fp_operator"
14701            [(match_operand:DF 1 "register_operand" "0,0")
14702             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14703   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14704   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14705   [(set (attr "type") 
14706         (cond [(match_operand:DF 3 "mult_operator" "") 
14707                  (const_string "fmul")
14708                (match_operand:DF 3 "div_operator" "") 
14709                  (const_string "fdiv")
14710               ]
14711               (const_string "fop")))
14712    (set_attr "fp_int_src" "true")
14713    (set_attr "mode" "SI")])
14715 (define_insn "*fop_df_4"
14716   [(set (match_operand:DF 0 "register_operand" "=f,f")
14717         (match_operator:DF 3 "binary_fp_operator"
14718            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14719             (match_operand:DF 2 "register_operand" "0,f")]))]
14720   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14721    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14722   "* return output_387_binary_op (insn, operands);"
14723   [(set (attr "type") 
14724         (cond [(match_operand:DF 3 "mult_operator" "") 
14725                  (const_string "fmul")
14726                (match_operand:DF 3 "div_operator" "") 
14727                  (const_string "fdiv")
14728               ]
14729               (const_string "fop")))
14730    (set_attr "mode" "SF")])
14732 (define_insn "*fop_df_5"
14733   [(set (match_operand:DF 0 "register_operand" "=f,f")
14734         (match_operator:DF 3 "binary_fp_operator"
14735           [(match_operand:DF 1 "register_operand" "0,f")
14736            (float_extend:DF
14737             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14738   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14739   "* return output_387_binary_op (insn, operands);"
14740   [(set (attr "type") 
14741         (cond [(match_operand:DF 3 "mult_operator" "") 
14742                  (const_string "fmul")
14743                (match_operand:DF 3 "div_operator" "") 
14744                  (const_string "fdiv")
14745               ]
14746               (const_string "fop")))
14747    (set_attr "mode" "SF")])
14749 (define_insn "*fop_df_6"
14750   [(set (match_operand:DF 0 "register_operand" "=f,f")
14751         (match_operator:DF 3 "binary_fp_operator"
14752           [(float_extend:DF
14753             (match_operand:SF 1 "register_operand" "0,f"))
14754            (float_extend:DF
14755             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14756   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14757   "* return output_387_binary_op (insn, operands);"
14758   [(set (attr "type") 
14759         (cond [(match_operand:DF 3 "mult_operator" "") 
14760                  (const_string "fmul")
14761                (match_operand:DF 3 "div_operator" "") 
14762                  (const_string "fdiv")
14763               ]
14764               (const_string "fop")))
14765    (set_attr "mode" "SF")])
14767 (define_insn "*fop_xf_1"
14768   [(set (match_operand:XF 0 "register_operand" "=f,f")
14769         (match_operator:XF 3 "binary_fp_operator"
14770                         [(match_operand:XF 1 "register_operand" "0,f")
14771                          (match_operand:XF 2 "register_operand" "f,0")]))]
14772   "TARGET_80387
14773    && !COMMUTATIVE_ARITH_P (operands[3])"
14774   "* return output_387_binary_op (insn, operands);"
14775   [(set (attr "type") 
14776         (cond [(match_operand:XF 3 "mult_operator" "") 
14777                  (const_string "fmul")
14778                (match_operand:XF 3 "div_operator" "") 
14779                  (const_string "fdiv")
14780               ]
14781               (const_string "fop")))
14782    (set_attr "mode" "XF")])
14784 (define_insn "*fop_xf_2"
14785   [(set (match_operand:XF 0 "register_operand" "=f,f")
14786         (match_operator:XF 3 "binary_fp_operator"
14787            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14788             (match_operand:XF 2 "register_operand" "0,0")]))]
14789   "TARGET_80387 && TARGET_USE_FIOP"
14790   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14791   [(set (attr "type") 
14792         (cond [(match_operand:XF 3 "mult_operator" "") 
14793                  (const_string "fmul")
14794                (match_operand:XF 3 "div_operator" "") 
14795                  (const_string "fdiv")
14796               ]
14797               (const_string "fop")))
14798    (set_attr "fp_int_src" "true")
14799    (set_attr "mode" "SI")])
14801 (define_insn "*fop_xf_3"
14802   [(set (match_operand:XF 0 "register_operand" "=f,f")
14803         (match_operator:XF 3 "binary_fp_operator"
14804           [(match_operand:XF 1 "register_operand" "0,0")
14805            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14806   "TARGET_80387 && TARGET_USE_FIOP"
14807   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14808   [(set (attr "type") 
14809         (cond [(match_operand:XF 3 "mult_operator" "") 
14810                  (const_string "fmul")
14811                (match_operand:XF 3 "div_operator" "") 
14812                  (const_string "fdiv")
14813               ]
14814               (const_string "fop")))
14815    (set_attr "fp_int_src" "true")
14816    (set_attr "mode" "SI")])
14818 (define_insn "*fop_xf_4"
14819   [(set (match_operand:XF 0 "register_operand" "=f,f")
14820         (match_operator:XF 3 "binary_fp_operator"
14821            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14822             (match_operand:XF 2 "register_operand" "0,f")]))]
14823   "TARGET_80387"
14824   "* return output_387_binary_op (insn, operands);"
14825   [(set (attr "type") 
14826         (cond [(match_operand:XF 3 "mult_operator" "") 
14827                  (const_string "fmul")
14828                (match_operand:XF 3 "div_operator" "") 
14829                  (const_string "fdiv")
14830               ]
14831               (const_string "fop")))
14832    (set_attr "mode" "SF")])
14834 (define_insn "*fop_xf_5"
14835   [(set (match_operand:XF 0 "register_operand" "=f,f")
14836         (match_operator:XF 3 "binary_fp_operator"
14837           [(match_operand:XF 1 "register_operand" "0,f")
14838            (float_extend:XF
14839             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14840   "TARGET_80387"
14841   "* return output_387_binary_op (insn, operands);"
14842   [(set (attr "type") 
14843         (cond [(match_operand:XF 3 "mult_operator" "") 
14844                  (const_string "fmul")
14845                (match_operand:XF 3 "div_operator" "") 
14846                  (const_string "fdiv")
14847               ]
14848               (const_string "fop")))
14849    (set_attr "mode" "SF")])
14851 (define_insn "*fop_xf_6"
14852   [(set (match_operand:XF 0 "register_operand" "=f,f")
14853         (match_operator:XF 3 "binary_fp_operator"
14854           [(float_extend:XF
14855             (match_operand 1 "register_operand" "0,f"))
14856            (float_extend:XF
14857             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14858   "TARGET_80387"
14859   "* return output_387_binary_op (insn, operands);"
14860   [(set (attr "type") 
14861         (cond [(match_operand:XF 3 "mult_operator" "") 
14862                  (const_string "fmul")
14863                (match_operand:XF 3 "div_operator" "") 
14864                  (const_string "fdiv")
14865               ]
14866               (const_string "fop")))
14867    (set_attr "mode" "SF")])
14869 (define_split
14870   [(set (match_operand 0 "register_operand" "")
14871         (match_operator 3 "binary_fp_operator"
14872            [(float (match_operand:SI 1 "register_operand" ""))
14873             (match_operand 2 "register_operand" "")]))]
14874   "TARGET_80387 && reload_completed
14875    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14876   [(const_int 0)]
14878   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14879   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14880   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14881                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14882                                           GET_MODE (operands[3]),
14883                                           operands[4],
14884                                           operands[2])));
14885   ix86_free_from_memory (GET_MODE (operands[1]));
14886   DONE;
14889 (define_split
14890   [(set (match_operand 0 "register_operand" "")
14891         (match_operator 3 "binary_fp_operator"
14892            [(match_operand 1 "register_operand" "")
14893             (float (match_operand:SI 2 "register_operand" ""))]))]
14894   "TARGET_80387 && reload_completed
14895    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14896   [(const_int 0)]
14898   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14899   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14900   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14901                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14902                                           GET_MODE (operands[3]),
14903                                           operands[1],
14904                                           operands[4])));
14905   ix86_free_from_memory (GET_MODE (operands[2]));
14906   DONE;
14909 ;; FPU special functions.
14911 (define_expand "sqrtsf2"
14912   [(set (match_operand:SF 0 "register_operand" "")
14913         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14914   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14916   if (!TARGET_SSE_MATH)
14917     operands[1] = force_reg (SFmode, operands[1]);
14920 (define_insn "sqrtsf2_1"
14921   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14922         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14923   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14924    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14925   "@
14926    fsqrt
14927    sqrtss\t{%1, %0|%0, %1}"
14928   [(set_attr "type" "fpspc,sse")
14929    (set_attr "mode" "SF,SF")
14930    (set_attr "athlon_decode" "direct,*")])
14932 (define_insn "sqrtsf2_1_sse_only"
14933   [(set (match_operand:SF 0 "register_operand" "=x")
14934         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14935   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14936   "sqrtss\t{%1, %0|%0, %1}"
14937   [(set_attr "type" "sse")
14938    (set_attr "mode" "SF")
14939    (set_attr "athlon_decode" "*")])
14941 (define_insn "sqrtsf2_i387"
14942   [(set (match_operand:SF 0 "register_operand" "=f")
14943         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14944   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14945    && !TARGET_SSE_MATH"
14946   "fsqrt"
14947   [(set_attr "type" "fpspc")
14948    (set_attr "mode" "SF")
14949    (set_attr "athlon_decode" "direct")])
14951 (define_expand "sqrtdf2"
14952   [(set (match_operand:DF 0 "register_operand" "")
14953         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14954   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14955    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14957   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14958     operands[1] = force_reg (DFmode, operands[1]);
14961 (define_insn "sqrtdf2_1"
14962   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14963         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14964   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14965    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14966   "@
14967    fsqrt
14968    sqrtsd\t{%1, %0|%0, %1}"
14969   [(set_attr "type" "fpspc,sse")
14970    (set_attr "mode" "DF,DF")
14971    (set_attr "athlon_decode" "direct,*")])
14973 (define_insn "sqrtdf2_1_sse_only"
14974   [(set (match_operand:DF 0 "register_operand" "=Y")
14975         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14976   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14977   "sqrtsd\t{%1, %0|%0, %1}"
14978   [(set_attr "type" "sse")
14979    (set_attr "mode" "DF")
14980    (set_attr "athlon_decode" "*")])
14982 (define_insn "sqrtdf2_i387"
14983   [(set (match_operand:DF 0 "register_operand" "=f")
14984         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14985   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14986    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14987   "fsqrt"
14988   [(set_attr "type" "fpspc")
14989    (set_attr "mode" "DF")
14990    (set_attr "athlon_decode" "direct")])
14992 (define_insn "*sqrtextendsfdf2"
14993   [(set (match_operand:DF 0 "register_operand" "=f")
14994         (sqrt:DF (float_extend:DF
14995                   (match_operand:SF 1 "register_operand" "0"))))]
14996   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14997    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14998   "fsqrt"
14999   [(set_attr "type" "fpspc")
15000    (set_attr "mode" "DF")
15001    (set_attr "athlon_decode" "direct")])
15003 (define_insn "sqrtxf2"
15004   [(set (match_operand:XF 0 "register_operand" "=f")
15005         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15006   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
15007    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15008   "fsqrt"
15009   [(set_attr "type" "fpspc")
15010    (set_attr "mode" "XF")
15011    (set_attr "athlon_decode" "direct")])
15013 (define_insn "*sqrtextenddfxf2"
15014   [(set (match_operand:XF 0 "register_operand" "=f")
15015         (sqrt:XF (float_extend:XF
15016                   (match_operand:DF 1 "register_operand" "0"))))]
15017   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15018   "fsqrt"
15019   [(set_attr "type" "fpspc")
15020    (set_attr "mode" "XF")
15021    (set_attr "athlon_decode" "direct")])
15023 (define_insn "*sqrtextendsfxf2"
15024   [(set (match_operand:XF 0 "register_operand" "=f")
15025         (sqrt:XF (float_extend:XF
15026                   (match_operand:SF 1 "register_operand" "0"))))]
15027   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15028   "fsqrt"
15029   [(set_attr "type" "fpspc")
15030    (set_attr "mode" "XF")
15031    (set_attr "athlon_decode" "direct")])
15033 (define_insn "fpremxf4"
15034   [(set (match_operand:XF 0 "register_operand" "=f")
15035         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15036                     (match_operand:XF 3 "register_operand" "1")]
15037                    UNSPEC_FPREM_F))
15038    (set (match_operand:XF 1 "register_operand" "=u")
15039         (unspec:XF [(match_dup 2) (match_dup 3)]
15040                    UNSPEC_FPREM_U))
15041    (set (reg:CCFP FPSR_REG)
15042         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15043   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15044    && flag_unsafe_math_optimizations"
15045   "fprem"
15046   [(set_attr "type" "fpspc")
15047    (set_attr "mode" "XF")])
15049 (define_expand "fmodsf3"
15050   [(use (match_operand:SF 0 "register_operand" ""))
15051    (use (match_operand:SF 1 "register_operand" ""))
15052    (use (match_operand:SF 2 "register_operand" ""))]
15053   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15054    && flag_unsafe_math_optimizations"
15056   rtx label = gen_label_rtx ();
15058   rtx op1 = gen_reg_rtx (XFmode);
15059   rtx op2 = gen_reg_rtx (XFmode);
15061   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15062   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15064   emit_label (label);
15066   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15067   ix86_emit_fp_unordered_jump (label);
15069   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15070   DONE;
15073 (define_expand "fmoddf3"
15074   [(use (match_operand:DF 0 "register_operand" ""))
15075    (use (match_operand:DF 1 "register_operand" ""))
15076    (use (match_operand:DF 2 "register_operand" ""))]
15077   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15078    && flag_unsafe_math_optimizations"
15080   rtx label = gen_label_rtx ();
15082   rtx op1 = gen_reg_rtx (XFmode);
15083   rtx op2 = gen_reg_rtx (XFmode);
15085   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15086   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15088   emit_label (label);
15090   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15091   ix86_emit_fp_unordered_jump (label);
15093   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15094   DONE;
15097 (define_expand "fmodxf3"
15098   [(use (match_operand:XF 0 "register_operand" ""))
15099    (use (match_operand:XF 1 "register_operand" ""))
15100    (use (match_operand:XF 2 "register_operand" ""))]
15101   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15102    && flag_unsafe_math_optimizations"
15104   rtx label = gen_label_rtx ();
15106   emit_label (label);
15108   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15109                            operands[1], operands[2]));
15110   ix86_emit_fp_unordered_jump (label);
15112   emit_move_insn (operands[0], operands[1]);
15113   DONE;
15116 (define_insn "fprem1xf4"
15117   [(set (match_operand:XF 0 "register_operand" "=f")
15118         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15119                     (match_operand:XF 3 "register_operand" "1")]
15120                    UNSPEC_FPREM1_F))
15121    (set (match_operand:XF 1 "register_operand" "=u")
15122         (unspec:XF [(match_dup 2) (match_dup 3)]
15123                    UNSPEC_FPREM1_U))
15124    (set (reg:CCFP FPSR_REG)
15125         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15126   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15127    && flag_unsafe_math_optimizations"
15128   "fprem1"
15129   [(set_attr "type" "fpspc")
15130    (set_attr "mode" "XF")])
15132 (define_expand "dremsf3"
15133   [(use (match_operand:SF 0 "register_operand" ""))
15134    (use (match_operand:SF 1 "register_operand" ""))
15135    (use (match_operand:SF 2 "register_operand" ""))]
15136   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15137    && flag_unsafe_math_optimizations"
15139   rtx label = gen_label_rtx ();
15141   rtx op1 = gen_reg_rtx (XFmode);
15142   rtx op2 = gen_reg_rtx (XFmode);
15144   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15145   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15147   emit_label (label);
15149   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15150   ix86_emit_fp_unordered_jump (label);
15152   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15153   DONE;
15156 (define_expand "dremdf3"
15157   [(use (match_operand:DF 0 "register_operand" ""))
15158    (use (match_operand:DF 1 "register_operand" ""))
15159    (use (match_operand:DF 2 "register_operand" ""))]
15160   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15161    && flag_unsafe_math_optimizations"
15163   rtx label = gen_label_rtx ();
15165   rtx op1 = gen_reg_rtx (XFmode);
15166   rtx op2 = gen_reg_rtx (XFmode);
15168   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15169   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15171   emit_label (label);
15173   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15174   ix86_emit_fp_unordered_jump (label);
15176   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15177   DONE;
15180 (define_expand "dremxf3"
15181   [(use (match_operand:XF 0 "register_operand" ""))
15182    (use (match_operand:XF 1 "register_operand" ""))
15183    (use (match_operand:XF 2 "register_operand" ""))]
15184   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15185    && flag_unsafe_math_optimizations"
15187   rtx label = gen_label_rtx ();
15189   emit_label (label);
15191   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15192                             operands[1], operands[2]));
15193   ix86_emit_fp_unordered_jump (label);
15195   emit_move_insn (operands[0], operands[1]);
15196   DONE;
15199 (define_insn "*sindf2"
15200   [(set (match_operand:DF 0 "register_operand" "=f")
15201         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15202   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15203    && flag_unsafe_math_optimizations"
15204   "fsin"
15205   [(set_attr "type" "fpspc")
15206    (set_attr "mode" "DF")])
15208 (define_insn "*sinsf2"
15209   [(set (match_operand:SF 0 "register_operand" "=f")
15210         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15211   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15212    && flag_unsafe_math_optimizations"
15213   "fsin"
15214   [(set_attr "type" "fpspc")
15215    (set_attr "mode" "SF")])
15217 (define_insn "*sinextendsfdf2"
15218   [(set (match_operand:DF 0 "register_operand" "=f")
15219         (unspec:DF [(float_extend:DF
15220                      (match_operand:SF 1 "register_operand" "0"))]
15221                    UNSPEC_SIN))]
15222   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15223    && flag_unsafe_math_optimizations"
15224   "fsin"
15225   [(set_attr "type" "fpspc")
15226    (set_attr "mode" "DF")])
15228 (define_insn "*sinxf2"
15229   [(set (match_operand:XF 0 "register_operand" "=f")
15230         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15231   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15232    && flag_unsafe_math_optimizations"
15233   "fsin"
15234   [(set_attr "type" "fpspc")
15235    (set_attr "mode" "XF")])
15237 (define_insn "*cosdf2"
15238   [(set (match_operand:DF 0 "register_operand" "=f")
15239         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15240   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15241    && flag_unsafe_math_optimizations"
15242   "fcos"
15243   [(set_attr "type" "fpspc")
15244    (set_attr "mode" "DF")])
15246 (define_insn "*cossf2"
15247   [(set (match_operand:SF 0 "register_operand" "=f")
15248         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15249   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15250    && flag_unsafe_math_optimizations"
15251   "fcos"
15252   [(set_attr "type" "fpspc")
15253    (set_attr "mode" "SF")])
15255 (define_insn "*cosextendsfdf2"
15256   [(set (match_operand:DF 0 "register_operand" "=f")
15257         (unspec:DF [(float_extend:DF
15258                      (match_operand:SF 1 "register_operand" "0"))]
15259                    UNSPEC_COS))]
15260   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15261    && flag_unsafe_math_optimizations"
15262   "fcos"
15263   [(set_attr "type" "fpspc")
15264    (set_attr "mode" "DF")])
15266 (define_insn "*cosxf2"
15267   [(set (match_operand:XF 0 "register_operand" "=f")
15268         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15269   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15270    && flag_unsafe_math_optimizations"
15271   "fcos"
15272   [(set_attr "type" "fpspc")
15273    (set_attr "mode" "XF")])
15275 ;; With sincos pattern defined, sin and cos builtin function will be
15276 ;; expanded to sincos pattern with one of its outputs left unused. 
15277 ;; Cse pass  will detected, if two sincos patterns can be combined,
15278 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15279 ;; depending on the unused output.
15281 (define_insn "sincosdf3"
15282   [(set (match_operand:DF 0 "register_operand" "=f")
15283         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15284                    UNSPEC_SINCOS_COS))
15285    (set (match_operand:DF 1 "register_operand" "=u")
15286         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15287   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15288    && flag_unsafe_math_optimizations"
15289   "fsincos"
15290   [(set_attr "type" "fpspc")
15291    (set_attr "mode" "DF")])
15293 (define_split
15294   [(set (match_operand:DF 0 "register_operand" "")
15295         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15296                    UNSPEC_SINCOS_COS))
15297    (set (match_operand:DF 1 "register_operand" "")
15298         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15299   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15300    && !reload_completed && !reload_in_progress"
15301   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15302   "")
15304 (define_split
15305   [(set (match_operand:DF 0 "register_operand" "")
15306         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15307                    UNSPEC_SINCOS_COS))
15308    (set (match_operand:DF 1 "register_operand" "")
15309         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15310   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15311    && !reload_completed && !reload_in_progress"
15312   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15313   "")
15315 (define_insn "sincossf3"
15316   [(set (match_operand:SF 0 "register_operand" "=f")
15317         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15318                    UNSPEC_SINCOS_COS))
15319    (set (match_operand:SF 1 "register_operand" "=u")
15320         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15321   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15322    && flag_unsafe_math_optimizations"
15323   "fsincos"
15324   [(set_attr "type" "fpspc")
15325    (set_attr "mode" "SF")])
15327 (define_split
15328   [(set (match_operand:SF 0 "register_operand" "")
15329         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15330                    UNSPEC_SINCOS_COS))
15331    (set (match_operand:SF 1 "register_operand" "")
15332         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15333   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15334    && !reload_completed && !reload_in_progress"
15335   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15336   "")
15338 (define_split
15339   [(set (match_operand:SF 0 "register_operand" "")
15340         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15341                    UNSPEC_SINCOS_COS))
15342    (set (match_operand:SF 1 "register_operand" "")
15343         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15344   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15345    && !reload_completed && !reload_in_progress"
15346   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15347   "")
15349 (define_insn "*sincosextendsfdf3"
15350   [(set (match_operand:DF 0 "register_operand" "=f")
15351         (unspec:DF [(float_extend:DF
15352                      (match_operand:SF 2 "register_operand" "0"))]
15353                    UNSPEC_SINCOS_COS))
15354    (set (match_operand:DF 1 "register_operand" "=u")
15355         (unspec:DF [(float_extend:DF
15356                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15357   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15358    && flag_unsafe_math_optimizations"
15359   "fsincos"
15360   [(set_attr "type" "fpspc")
15361    (set_attr "mode" "DF")])
15363 (define_split
15364   [(set (match_operand:DF 0 "register_operand" "")
15365         (unspec:DF [(float_extend:DF
15366                      (match_operand:SF 2 "register_operand" ""))]
15367                    UNSPEC_SINCOS_COS))
15368    (set (match_operand:DF 1 "register_operand" "")
15369         (unspec:DF [(float_extend:DF
15370                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15371   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15372    && !reload_completed && !reload_in_progress"
15373   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15374                                    (match_dup 2))] UNSPEC_SIN))]
15375   "")
15377 (define_split
15378   [(set (match_operand:DF 0 "register_operand" "")
15379         (unspec:DF [(float_extend:DF
15380                      (match_operand:SF 2 "register_operand" ""))]
15381                    UNSPEC_SINCOS_COS))
15382    (set (match_operand:DF 1 "register_operand" "")
15383         (unspec:DF [(float_extend:DF
15384                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15385   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15386    && !reload_completed && !reload_in_progress"
15387   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15388                                    (match_dup 2))] UNSPEC_COS))]
15389   "")
15391 (define_insn "sincosxf3"
15392   [(set (match_operand:XF 0 "register_operand" "=f")
15393         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15394                    UNSPEC_SINCOS_COS))
15395    (set (match_operand:XF 1 "register_operand" "=u")
15396         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15397   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15398    && flag_unsafe_math_optimizations"
15399   "fsincos"
15400   [(set_attr "type" "fpspc")
15401    (set_attr "mode" "XF")])
15403 (define_split
15404   [(set (match_operand:XF 0 "register_operand" "")
15405         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15406                    UNSPEC_SINCOS_COS))
15407    (set (match_operand:XF 1 "register_operand" "")
15408         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15409   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15410    && !reload_completed && !reload_in_progress"
15411   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15412   "")
15414 (define_split
15415   [(set (match_operand:XF 0 "register_operand" "")
15416         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15417                    UNSPEC_SINCOS_COS))
15418    (set (match_operand:XF 1 "register_operand" "")
15419         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15420   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15421    && !reload_completed && !reload_in_progress"
15422   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15423   "")
15425 (define_insn "*tandf3_1"
15426   [(set (match_operand:DF 0 "register_operand" "=f")
15427         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15428                    UNSPEC_TAN_ONE))
15429    (set (match_operand:DF 1 "register_operand" "=u")
15430         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15431   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15432    && flag_unsafe_math_optimizations"
15433   "fptan"
15434   [(set_attr "type" "fpspc")
15435    (set_attr "mode" "DF")])
15437 ;; optimize sequence: fptan
15438 ;;                    fstp    %st(0)
15439 ;;                    fld1
15440 ;; into fptan insn.
15442 (define_peephole2
15443   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15444                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15445                              UNSPEC_TAN_ONE))
15446              (set (match_operand:DF 1 "register_operand" "")
15447                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15448    (set (match_dup 0)
15449         (match_operand:DF 3 "immediate_operand" ""))]
15450   "standard_80387_constant_p (operands[3]) == 2"
15451   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15452              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15453   "")
15455 (define_expand "tandf2"
15456   [(parallel [(set (match_dup 2)
15457                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15458                               UNSPEC_TAN_ONE))
15459               (set (match_operand:DF 0 "register_operand" "")
15460                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15461   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15462    && flag_unsafe_math_optimizations"
15464   operands[2] = gen_reg_rtx (DFmode);
15467 (define_insn "*tansf3_1"
15468   [(set (match_operand:SF 0 "register_operand" "=f")
15469         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15470                    UNSPEC_TAN_ONE))
15471    (set (match_operand:SF 1 "register_operand" "=u")
15472         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15473   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15474    && flag_unsafe_math_optimizations"
15475   "fptan"
15476   [(set_attr "type" "fpspc")
15477    (set_attr "mode" "SF")])
15479 ;; optimize sequence: fptan
15480 ;;                    fstp    %st(0)
15481 ;;                    fld1
15482 ;; into fptan insn.
15484 (define_peephole2
15485   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15486                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15487                              UNSPEC_TAN_ONE))
15488              (set (match_operand:SF 1 "register_operand" "")
15489                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15490    (set (match_dup 0)
15491         (match_operand:SF 3 "immediate_operand" ""))]
15492   "standard_80387_constant_p (operands[3]) == 2"
15493   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15494              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15495   "")
15497 (define_expand "tansf2"
15498   [(parallel [(set (match_dup 2)
15499                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15500                               UNSPEC_TAN_ONE))
15501               (set (match_operand:SF 0 "register_operand" "")
15502                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15503   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15504    && flag_unsafe_math_optimizations"
15506   operands[2] = gen_reg_rtx (SFmode);
15509 (define_insn "*tanxf3_1"
15510   [(set (match_operand:XF 0 "register_operand" "=f")
15511         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15512                    UNSPEC_TAN_ONE))
15513    (set (match_operand:XF 1 "register_operand" "=u")
15514         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15515   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15516    && flag_unsafe_math_optimizations"
15517   "fptan"
15518   [(set_attr "type" "fpspc")
15519    (set_attr "mode" "XF")])
15521 ;; optimize sequence: fptan
15522 ;;                    fstp    %st(0)
15523 ;;                    fld1
15524 ;; into fptan insn.
15526 (define_peephole2
15527   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15528                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15529                              UNSPEC_TAN_ONE))
15530              (set (match_operand:XF 1 "register_operand" "")
15531                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15532    (set (match_dup 0)
15533         (match_operand:XF 3 "immediate_operand" ""))]
15534   "standard_80387_constant_p (operands[3]) == 2"
15535   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15536              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15537   "")
15539 (define_expand "tanxf2"
15540   [(parallel [(set (match_dup 2)
15541                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15542                               UNSPEC_TAN_ONE))
15543               (set (match_operand:XF 0 "register_operand" "")
15544                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15545   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15546    && flag_unsafe_math_optimizations"
15548   operands[2] = gen_reg_rtx (XFmode);
15551 (define_insn "atan2df3_1"
15552   [(set (match_operand:DF 0 "register_operand" "=f")
15553         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15554                     (match_operand:DF 1 "register_operand" "u")]
15555                    UNSPEC_FPATAN))
15556    (clobber (match_scratch:DF 3 "=1"))]
15557   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15558    && flag_unsafe_math_optimizations"
15559   "fpatan"
15560   [(set_attr "type" "fpspc")
15561    (set_attr "mode" "DF")])
15563 (define_expand "atan2df3"
15564   [(use (match_operand:DF 0 "register_operand" "=f"))
15565    (use (match_operand:DF 2 "register_operand" "0"))
15566    (use (match_operand:DF 1 "register_operand" "u"))]
15567   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15568    && flag_unsafe_math_optimizations"
15570   rtx copy = gen_reg_rtx (DFmode);
15571   emit_move_insn (copy, operands[1]);
15572   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15573   DONE;
15576 (define_expand "atandf2"
15577   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15578                    (unspec:DF [(match_dup 2)
15579                                (match_operand:DF 1 "register_operand" "")]
15580                     UNSPEC_FPATAN))
15581               (clobber (match_scratch:DF 3 ""))])]
15582   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15583    && flag_unsafe_math_optimizations"
15585   operands[2] = gen_reg_rtx (DFmode);
15586   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15589 (define_insn "atan2sf3_1"
15590   [(set (match_operand:SF 0 "register_operand" "=f")
15591         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15592                     (match_operand:SF 1 "register_operand" "u")]
15593                    UNSPEC_FPATAN))
15594    (clobber (match_scratch:SF 3 "=1"))]
15595   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15596    && flag_unsafe_math_optimizations"
15597   "fpatan"
15598   [(set_attr "type" "fpspc")
15599    (set_attr "mode" "SF")])
15601 (define_expand "atan2sf3"
15602   [(use (match_operand:SF 0 "register_operand" "=f"))
15603    (use (match_operand:SF 2 "register_operand" "0"))
15604    (use (match_operand:SF 1 "register_operand" "u"))]
15605   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15606    && flag_unsafe_math_optimizations"
15608   rtx copy = gen_reg_rtx (SFmode);
15609   emit_move_insn (copy, operands[1]);
15610   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15611   DONE;
15614 (define_expand "atansf2"
15615   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15616                    (unspec:SF [(match_dup 2)
15617                                (match_operand:SF 1 "register_operand" "")]
15618                     UNSPEC_FPATAN))
15619               (clobber (match_scratch:SF 3 ""))])]
15620   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15621    && flag_unsafe_math_optimizations"
15623   operands[2] = gen_reg_rtx (SFmode);
15624   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15627 (define_insn "atan2xf3_1"
15628   [(set (match_operand:XF 0 "register_operand" "=f")
15629         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15630                     (match_operand:XF 1 "register_operand" "u")]
15631                    UNSPEC_FPATAN))
15632    (clobber (match_scratch:XF 3 "=1"))]
15633   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15634    && flag_unsafe_math_optimizations"
15635   "fpatan"
15636   [(set_attr "type" "fpspc")
15637    (set_attr "mode" "XF")])
15639 (define_expand "atan2xf3"
15640   [(use (match_operand:XF 0 "register_operand" "=f"))
15641    (use (match_operand:XF 2 "register_operand" "0"))
15642    (use (match_operand:XF 1 "register_operand" "u"))]
15643   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15644    && flag_unsafe_math_optimizations"
15646   rtx copy = gen_reg_rtx (XFmode);
15647   emit_move_insn (copy, operands[1]);
15648   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15649   DONE;
15652 (define_expand "atanxf2"
15653   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15654                    (unspec:XF [(match_dup 2)
15655                                (match_operand:XF 1 "register_operand" "")]
15656                     UNSPEC_FPATAN))
15657               (clobber (match_scratch:XF 3 ""))])]
15658   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15659    && flag_unsafe_math_optimizations"
15661   operands[2] = gen_reg_rtx (XFmode);
15662   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15665 (define_expand "asindf2"
15666   [(set (match_dup 2)
15667         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15668    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15669    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15670    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15671    (parallel [(set (match_dup 7)
15672                    (unspec:XF [(match_dup 6) (match_dup 2)]
15673                               UNSPEC_FPATAN))
15674               (clobber (match_scratch:XF 8 ""))])
15675    (set (match_operand:DF 0 "register_operand" "")
15676         (float_truncate:DF (match_dup 7)))]
15677   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15678    && flag_unsafe_math_optimizations"
15680   int i;
15682   for (i=2; i<8; i++)
15683     operands[i] = gen_reg_rtx (XFmode);
15685   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15688 (define_expand "asinsf2"
15689   [(set (match_dup 2)
15690         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15691    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15692    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15693    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15694    (parallel [(set (match_dup 7)
15695                    (unspec:XF [(match_dup 6) (match_dup 2)]
15696                               UNSPEC_FPATAN))
15697               (clobber (match_scratch:XF 8 ""))])
15698    (set (match_operand:SF 0 "register_operand" "")
15699         (float_truncate:SF (match_dup 7)))]
15700   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15701    && flag_unsafe_math_optimizations"
15703   int i;
15705   for (i=2; i<8; i++)
15706     operands[i] = gen_reg_rtx (XFmode);
15708   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15711 (define_expand "asinxf2"
15712   [(set (match_dup 2)
15713         (mult:XF (match_operand:XF 1 "register_operand" "")
15714                  (match_dup 1)))
15715    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15716    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15717    (parallel [(set (match_operand:XF 0 "register_operand" "")
15718                    (unspec:XF [(match_dup 5) (match_dup 1)]
15719                               UNSPEC_FPATAN))
15720               (clobber (match_scratch:XF 6 ""))])]
15721   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15722    && flag_unsafe_math_optimizations"
15724   int i;
15726   for (i=2; i<6; i++)
15727     operands[i] = gen_reg_rtx (XFmode);
15729   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15732 (define_expand "acosdf2"
15733   [(set (match_dup 2)
15734         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15735    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15736    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15737    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15738    (parallel [(set (match_dup 7)
15739                    (unspec:XF [(match_dup 2) (match_dup 6)]
15740                               UNSPEC_FPATAN))
15741               (clobber (match_scratch:XF 8 ""))])
15742    (set (match_operand:DF 0 "register_operand" "")
15743         (float_truncate:DF (match_dup 7)))]
15744   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15745    && flag_unsafe_math_optimizations"
15747   int i;
15749   for (i=2; i<8; i++)
15750     operands[i] = gen_reg_rtx (XFmode);
15752   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15755 (define_expand "acossf2"
15756   [(set (match_dup 2)
15757         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15758    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15759    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15760    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15761    (parallel [(set (match_dup 7)
15762                    (unspec:XF [(match_dup 2) (match_dup 6)]
15763                               UNSPEC_FPATAN))
15764               (clobber (match_scratch:XF 8 ""))])
15765    (set (match_operand:SF 0 "register_operand" "")
15766         (float_truncate:SF (match_dup 7)))]
15767   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15768    && flag_unsafe_math_optimizations"
15770   int i;
15772   for (i=2; i<8; i++)
15773     operands[i] = gen_reg_rtx (XFmode);
15775   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15778 (define_expand "acosxf2"
15779   [(set (match_dup 2)
15780         (mult:XF (match_operand:XF 1 "register_operand" "")
15781                  (match_dup 1)))
15782    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15783    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15784    (parallel [(set (match_operand:XF 0 "register_operand" "")
15785                    (unspec:XF [(match_dup 1) (match_dup 5)]
15786                               UNSPEC_FPATAN))
15787               (clobber (match_scratch:XF 6 ""))])]
15788   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15789    && flag_unsafe_math_optimizations"
15791   int i;
15793   for (i=2; i<6; i++)
15794     operands[i] = gen_reg_rtx (XFmode);
15796   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15799 (define_insn "fyl2x_xf3"
15800   [(set (match_operand:XF 0 "register_operand" "=f")
15801         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15802                     (match_operand:XF 1 "register_operand" "u")]
15803                    UNSPEC_FYL2X))
15804    (clobber (match_scratch:XF 3 "=1"))]
15805   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15806    && flag_unsafe_math_optimizations"
15807   "fyl2x"
15808   [(set_attr "type" "fpspc")
15809    (set_attr "mode" "XF")])
15811 (define_expand "logsf2"
15812   [(set (match_dup 2)
15813         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15814    (parallel [(set (match_dup 4)
15815                    (unspec:XF [(match_dup 2)
15816                                (match_dup 3)] UNSPEC_FYL2X))
15817               (clobber (match_scratch:XF 5 ""))])
15818    (set (match_operand:SF 0 "register_operand" "")
15819         (float_truncate:SF (match_dup 4)))]
15820   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15821    && flag_unsafe_math_optimizations"
15823   rtx temp;
15825   operands[2] = gen_reg_rtx (XFmode);
15826   operands[3] = gen_reg_rtx (XFmode);
15827   operands[4] = gen_reg_rtx (XFmode);
15829   temp = standard_80387_constant_rtx (4); /* fldln2 */
15830   emit_move_insn (operands[3], temp);
15833 (define_expand "logdf2"
15834   [(set (match_dup 2)
15835         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15836    (parallel [(set (match_dup 4)
15837                    (unspec:XF [(match_dup 2)
15838                                (match_dup 3)] UNSPEC_FYL2X))
15839               (clobber (match_scratch:XF 5 ""))])
15840    (set (match_operand:DF 0 "register_operand" "")
15841         (float_truncate:DF (match_dup 4)))]
15842   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15843    && flag_unsafe_math_optimizations"
15845   rtx temp;
15847   operands[2] = gen_reg_rtx (XFmode);
15848   operands[3] = gen_reg_rtx (XFmode);
15849   operands[4] = gen_reg_rtx (XFmode);
15851   temp = standard_80387_constant_rtx (4); /* fldln2 */
15852   emit_move_insn (operands[3], temp);
15855 (define_expand "logxf2"
15856   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15857                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15858                                (match_dup 2)] UNSPEC_FYL2X))
15859               (clobber (match_scratch:XF 3 ""))])]
15860   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15861    && flag_unsafe_math_optimizations"
15863   rtx temp;
15865   operands[2] = gen_reg_rtx (XFmode);
15866   temp = standard_80387_constant_rtx (4); /* fldln2 */
15867   emit_move_insn (operands[2], temp);
15870 (define_expand "log10sf2"
15871   [(set (match_dup 2)
15872         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15873    (parallel [(set (match_dup 4)
15874                    (unspec:XF [(match_dup 2)
15875                                (match_dup 3)] UNSPEC_FYL2X))
15876               (clobber (match_scratch:XF 5 ""))])
15877    (set (match_operand:SF 0 "register_operand" "")
15878         (float_truncate:SF (match_dup 4)))]
15879   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15880    && flag_unsafe_math_optimizations"
15882   rtx temp;
15884   operands[2] = gen_reg_rtx (XFmode);
15885   operands[3] = gen_reg_rtx (XFmode);
15886   operands[4] = gen_reg_rtx (XFmode);
15888   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15889   emit_move_insn (operands[3], temp);
15892 (define_expand "log10df2"
15893   [(set (match_dup 2)
15894         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15895    (parallel [(set (match_dup 4)
15896                    (unspec:XF [(match_dup 2)
15897                                (match_dup 3)] UNSPEC_FYL2X))
15898               (clobber (match_scratch:XF 5 ""))])
15899    (set (match_operand:DF 0 "register_operand" "")
15900         (float_truncate:DF (match_dup 4)))]
15901   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15902    && flag_unsafe_math_optimizations"
15904   rtx temp;
15906   operands[2] = gen_reg_rtx (XFmode);
15907   operands[3] = gen_reg_rtx (XFmode);
15908   operands[4] = gen_reg_rtx (XFmode);
15910   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15911   emit_move_insn (operands[3], temp);
15914 (define_expand "log10xf2"
15915   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15916                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15917                                (match_dup 2)] UNSPEC_FYL2X))
15918               (clobber (match_scratch:XF 3 ""))])]
15919   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15920    && flag_unsafe_math_optimizations"
15922   rtx temp;
15924   operands[2] = gen_reg_rtx (XFmode);
15925   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15926   emit_move_insn (operands[2], temp);
15929 (define_expand "log2sf2"
15930   [(set (match_dup 2)
15931         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15932    (parallel [(set (match_dup 4)
15933                    (unspec:XF [(match_dup 2)
15934                                (match_dup 3)] UNSPEC_FYL2X))
15935               (clobber (match_scratch:XF 5 ""))])
15936    (set (match_operand:SF 0 "register_operand" "")
15937         (float_truncate:SF (match_dup 4)))]
15938   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15939    && flag_unsafe_math_optimizations"
15941   operands[2] = gen_reg_rtx (XFmode);
15942   operands[3] = gen_reg_rtx (XFmode);
15943   operands[4] = gen_reg_rtx (XFmode);
15945   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15948 (define_expand "log2df2"
15949   [(set (match_dup 2)
15950         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15951    (parallel [(set (match_dup 4)
15952                    (unspec:XF [(match_dup 2)
15953                                (match_dup 3)] UNSPEC_FYL2X))
15954               (clobber (match_scratch:XF 5 ""))])
15955    (set (match_operand:DF 0 "register_operand" "")
15956         (float_truncate:DF (match_dup 4)))]
15957   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15958    && flag_unsafe_math_optimizations"
15960   operands[2] = gen_reg_rtx (XFmode);
15961   operands[3] = gen_reg_rtx (XFmode);
15962   operands[4] = gen_reg_rtx (XFmode);
15964   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15967 (define_expand "log2xf2"
15968   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15969                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15970                                (match_dup 2)] UNSPEC_FYL2X))
15971               (clobber (match_scratch:XF 3 ""))])]
15972   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15973    && flag_unsafe_math_optimizations"
15975   operands[2] = gen_reg_rtx (XFmode);
15976   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15979 (define_insn "fyl2xp1_xf3"
15980   [(set (match_operand:XF 0 "register_operand" "=f")
15981         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15982                     (match_operand:XF 1 "register_operand" "u")]
15983                    UNSPEC_FYL2XP1))
15984    (clobber (match_scratch:XF 3 "=1"))]
15985   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15986    && flag_unsafe_math_optimizations"
15987   "fyl2xp1"
15988   [(set_attr "type" "fpspc")
15989    (set_attr "mode" "XF")])
15991 (define_expand "log1psf2"
15992   [(use (match_operand:XF 0 "register_operand" ""))
15993    (use (match_operand:XF 1 "register_operand" ""))]
15994   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15995    && flag_unsafe_math_optimizations"
15997   rtx op0 = gen_reg_rtx (XFmode);
15998   rtx op1 = gen_reg_rtx (XFmode);
16000   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16001   ix86_emit_i387_log1p (op0, op1);
16002   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16003   DONE;
16006 (define_expand "log1pdf2"
16007   [(use (match_operand:XF 0 "register_operand" ""))
16008    (use (match_operand:XF 1 "register_operand" ""))]
16009   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16010    && flag_unsafe_math_optimizations"
16012   rtx op0 = gen_reg_rtx (XFmode);
16013   rtx op1 = gen_reg_rtx (XFmode);
16015   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16016   ix86_emit_i387_log1p (op0, op1);
16017   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16018   DONE;
16021 (define_expand "log1pxf2"
16022   [(use (match_operand:XF 0 "register_operand" ""))
16023    (use (match_operand:XF 1 "register_operand" ""))]
16024   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16025    && flag_unsafe_math_optimizations"
16027   ix86_emit_i387_log1p (operands[0], operands[1]);
16028   DONE;
16031 (define_insn "*fxtractxf3"
16032   [(set (match_operand:XF 0 "register_operand" "=f")
16033         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16034                    UNSPEC_XTRACT_FRACT))
16035    (set (match_operand:XF 1 "register_operand" "=u")
16036         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16037   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16038    && flag_unsafe_math_optimizations"
16039   "fxtract"
16040   [(set_attr "type" "fpspc")
16041    (set_attr "mode" "XF")])
16043 (define_expand "logbsf2"
16044   [(set (match_dup 2)
16045         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16046    (parallel [(set (match_dup 3)
16047                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16048               (set (match_dup 4)
16049                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16050    (set (match_operand:SF 0 "register_operand" "")
16051         (float_truncate:SF (match_dup 4)))]
16052   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16053    && flag_unsafe_math_optimizations"
16055   operands[2] = gen_reg_rtx (XFmode);
16056   operands[3] = gen_reg_rtx (XFmode);
16057   operands[4] = gen_reg_rtx (XFmode);
16060 (define_expand "logbdf2"
16061   [(set (match_dup 2)
16062         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16063    (parallel [(set (match_dup 3)
16064                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16065               (set (match_dup 4)
16066                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16067    (set (match_operand:DF 0 "register_operand" "")
16068         (float_truncate:DF (match_dup 4)))]
16069   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16070    && flag_unsafe_math_optimizations"
16072   operands[2] = gen_reg_rtx (XFmode);
16073   operands[3] = gen_reg_rtx (XFmode);
16074   operands[4] = gen_reg_rtx (XFmode);
16077 (define_expand "logbxf2"
16078   [(parallel [(set (match_dup 2)
16079                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16080                               UNSPEC_XTRACT_FRACT))
16081               (set (match_operand:XF 0 "register_operand" "")
16082                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16083   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16084    && flag_unsafe_math_optimizations"
16086   operands[2] = gen_reg_rtx (XFmode);
16089 (define_expand "ilogbsi2"
16090   [(parallel [(set (match_dup 2)
16091                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16092                               UNSPEC_XTRACT_FRACT))
16093               (set (match_operand:XF 3 "register_operand" "")
16094                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16095    (parallel [(set (match_operand:SI 0 "register_operand" "")
16096                    (fix:SI (match_dup 3)))
16097               (clobber (reg:CC FLAGS_REG))])]
16098   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16099    && flag_unsafe_math_optimizations"
16101   operands[2] = gen_reg_rtx (XFmode);
16102   operands[3] = gen_reg_rtx (XFmode);
16105 (define_insn "*f2xm1xf2"
16106   [(set (match_operand:XF 0 "register_operand" "=f")
16107         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16108          UNSPEC_F2XM1))]
16109   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16110    && flag_unsafe_math_optimizations"
16111   "f2xm1"
16112   [(set_attr "type" "fpspc")
16113    (set_attr "mode" "XF")])
16115 (define_insn "*fscalexf4"
16116   [(set (match_operand:XF 0 "register_operand" "=f")
16117         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16118                     (match_operand:XF 3 "register_operand" "1")]
16119                    UNSPEC_FSCALE_FRACT))
16120    (set (match_operand:XF 1 "register_operand" "=u")
16121         (unspec:XF [(match_dup 2) (match_dup 3)]
16122                    UNSPEC_FSCALE_EXP))]
16123   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16124    && flag_unsafe_math_optimizations"
16125   "fscale"
16126   [(set_attr "type" "fpspc")
16127    (set_attr "mode" "XF")])
16129 (define_expand "expsf2"
16130   [(set (match_dup 2)
16131         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16132    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16133    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16134    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16135    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16136    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16137    (parallel [(set (match_dup 10)
16138                    (unspec:XF [(match_dup 9) (match_dup 5)]
16139                               UNSPEC_FSCALE_FRACT))
16140               (set (match_dup 11)
16141                    (unspec:XF [(match_dup 9) (match_dup 5)]
16142                               UNSPEC_FSCALE_EXP))])
16143    (set (match_operand:SF 0 "register_operand" "")
16144         (float_truncate:SF (match_dup 10)))]
16145   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16146    && flag_unsafe_math_optimizations"
16148   rtx temp;
16149   int i;
16151   for (i=2; i<12; i++)
16152     operands[i] = gen_reg_rtx (XFmode);
16153   temp = standard_80387_constant_rtx (5); /* fldl2e */
16154   emit_move_insn (operands[3], temp);
16155   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16158 (define_expand "expdf2"
16159   [(set (match_dup 2)
16160         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16161    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16162    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16163    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16164    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16165    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16166    (parallel [(set (match_dup 10)
16167                    (unspec:XF [(match_dup 9) (match_dup 5)]
16168                               UNSPEC_FSCALE_FRACT))
16169               (set (match_dup 11)
16170                    (unspec:XF [(match_dup 9) (match_dup 5)]
16171                               UNSPEC_FSCALE_EXP))])
16172    (set (match_operand:DF 0 "register_operand" "")
16173         (float_truncate:DF (match_dup 10)))]
16174   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16175    && flag_unsafe_math_optimizations"
16177   rtx temp;
16178   int i;
16180   for (i=2; i<12; i++)
16181     operands[i] = gen_reg_rtx (XFmode);
16182   temp = standard_80387_constant_rtx (5); /* fldl2e */
16183   emit_move_insn (operands[3], temp);
16184   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16187 (define_expand "expxf2"
16188   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16189                                (match_dup 2)))
16190    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16191    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16192    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16193    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16194    (parallel [(set (match_operand:XF 0 "register_operand" "")
16195                    (unspec:XF [(match_dup 8) (match_dup 4)]
16196                               UNSPEC_FSCALE_FRACT))
16197               (set (match_dup 9)
16198                    (unspec:XF [(match_dup 8) (match_dup 4)]
16199                               UNSPEC_FSCALE_EXP))])]
16200   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16201    && flag_unsafe_math_optimizations"
16203   rtx temp;
16204   int i;
16206   for (i=2; i<10; i++)
16207     operands[i] = gen_reg_rtx (XFmode);
16208   temp = standard_80387_constant_rtx (5); /* fldl2e */
16209   emit_move_insn (operands[2], temp);
16210   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16213 (define_expand "exp10sf2"
16214   [(set (match_dup 2)
16215         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16216    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16217    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16218    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16219    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16220    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16221    (parallel [(set (match_dup 10)
16222                    (unspec:XF [(match_dup 9) (match_dup 5)]
16223                               UNSPEC_FSCALE_FRACT))
16224               (set (match_dup 11)
16225                    (unspec:XF [(match_dup 9) (match_dup 5)]
16226                               UNSPEC_FSCALE_EXP))])
16227    (set (match_operand:SF 0 "register_operand" "")
16228         (float_truncate:SF (match_dup 10)))]
16229   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16230    && flag_unsafe_math_optimizations"
16232   rtx temp;
16233   int i;
16235   for (i=2; i<12; i++)
16236     operands[i] = gen_reg_rtx (XFmode);
16237   temp = standard_80387_constant_rtx (6); /* fldl2t */
16238   emit_move_insn (operands[3], temp);
16239   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16242 (define_expand "exp10df2"
16243   [(set (match_dup 2)
16244         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16245    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16246    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16247    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16248    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16249    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16250    (parallel [(set (match_dup 10)
16251                    (unspec:XF [(match_dup 9) (match_dup 5)]
16252                               UNSPEC_FSCALE_FRACT))
16253               (set (match_dup 11)
16254                    (unspec:XF [(match_dup 9) (match_dup 5)]
16255                               UNSPEC_FSCALE_EXP))])
16256    (set (match_operand:DF 0 "register_operand" "")
16257         (float_truncate:DF (match_dup 10)))]
16258   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16259    && flag_unsafe_math_optimizations"
16261   rtx temp;
16262   int i;
16264   for (i=2; i<12; i++)
16265     operands[i] = gen_reg_rtx (XFmode);
16266   temp = standard_80387_constant_rtx (6); /* fldl2t */
16267   emit_move_insn (operands[3], temp);
16268   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16271 (define_expand "exp10xf2"
16272   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16273                                (match_dup 2)))
16274    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16275    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16276    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16277    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16278    (parallel [(set (match_operand:XF 0 "register_operand" "")
16279                    (unspec:XF [(match_dup 8) (match_dup 4)]
16280                               UNSPEC_FSCALE_FRACT))
16281               (set (match_dup 9)
16282                    (unspec:XF [(match_dup 8) (match_dup 4)]
16283                               UNSPEC_FSCALE_EXP))])]
16284   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16285    && flag_unsafe_math_optimizations"
16287   rtx temp;
16288   int i;
16290   for (i=2; i<10; i++)
16291     operands[i] = gen_reg_rtx (XFmode);
16292   temp = standard_80387_constant_rtx (6); /* fldl2t */
16293   emit_move_insn (operands[2], temp);
16294   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16297 (define_expand "exp2sf2"
16298   [(set (match_dup 2)
16299         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16300    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16301    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16302    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16303    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16304    (parallel [(set (match_dup 8)
16305                    (unspec:XF [(match_dup 7) (match_dup 3)]
16306                               UNSPEC_FSCALE_FRACT))
16307               (set (match_dup 9)
16308                    (unspec:XF [(match_dup 7) (match_dup 3)]
16309                               UNSPEC_FSCALE_EXP))])
16310    (set (match_operand:SF 0 "register_operand" "")
16311         (float_truncate:SF (match_dup 8)))]
16312   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16313    && flag_unsafe_math_optimizations"
16315   int i;
16317   for (i=2; i<10; i++)
16318     operands[i] = gen_reg_rtx (XFmode);
16319   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16322 (define_expand "exp2df2"
16323   [(set (match_dup 2)
16324         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16325    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16326    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16327    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16328    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16329    (parallel [(set (match_dup 8)
16330                    (unspec:XF [(match_dup 7) (match_dup 3)]
16331                               UNSPEC_FSCALE_FRACT))
16332               (set (match_dup 9)
16333                    (unspec:XF [(match_dup 7) (match_dup 3)]
16334                               UNSPEC_FSCALE_EXP))])
16335    (set (match_operand:DF 0 "register_operand" "")
16336         (float_truncate:DF (match_dup 8)))]
16337   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16338    && flag_unsafe_math_optimizations"
16340   int i;
16342   for (i=2; i<10; i++)
16343     operands[i] = gen_reg_rtx (XFmode);
16344   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16347 (define_expand "exp2xf2"
16348   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16349    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16350    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16351    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16352    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16353    (parallel [(set (match_operand:XF 0 "register_operand" "")
16354                    (unspec:XF [(match_dup 7) (match_dup 3)]
16355                               UNSPEC_FSCALE_FRACT))
16356               (set (match_dup 8)
16357                    (unspec:XF [(match_dup 7) (match_dup 3)]
16358                               UNSPEC_FSCALE_EXP))])]
16359   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16360    && flag_unsafe_math_optimizations"
16362   int i;
16364   for (i=2; i<9; i++)
16365     operands[i] = gen_reg_rtx (XFmode);
16366   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16369 (define_expand "expm1df2"
16370   [(set (match_dup 2)
16371         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16372    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16373    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16374    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16375    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16376    (parallel [(set (match_dup 8)
16377                    (unspec:XF [(match_dup 7) (match_dup 5)]
16378                               UNSPEC_FSCALE_FRACT))
16379                    (set (match_dup 9)
16380                    (unspec:XF [(match_dup 7) (match_dup 5)]
16381                               UNSPEC_FSCALE_EXP))])
16382    (parallel [(set (match_dup 11)
16383                    (unspec:XF [(match_dup 10) (match_dup 9)]
16384                               UNSPEC_FSCALE_FRACT))
16385               (set (match_dup 12)
16386                    (unspec:XF [(match_dup 10) (match_dup 9)]
16387                               UNSPEC_FSCALE_EXP))])
16388    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16389    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16390    (set (match_operand:DF 0 "register_operand" "")
16391         (float_truncate:DF (match_dup 14)))]
16392   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16393    && flag_unsafe_math_optimizations"
16395   rtx temp;
16396   int i;
16398   for (i=2; i<15; i++)
16399     operands[i] = gen_reg_rtx (XFmode);
16400   temp = standard_80387_constant_rtx (5); /* fldl2e */
16401   emit_move_insn (operands[3], temp);
16402   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16405 (define_expand "expm1sf2"
16406   [(set (match_dup 2)
16407         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16408    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16409    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16410    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16411    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16412    (parallel [(set (match_dup 8)
16413                    (unspec:XF [(match_dup 7) (match_dup 5)]
16414                               UNSPEC_FSCALE_FRACT))
16415                    (set (match_dup 9)
16416                    (unspec:XF [(match_dup 7) (match_dup 5)]
16417                               UNSPEC_FSCALE_EXP))])
16418    (parallel [(set (match_dup 11)
16419                    (unspec:XF [(match_dup 10) (match_dup 9)]
16420                               UNSPEC_FSCALE_FRACT))
16421               (set (match_dup 12)
16422                    (unspec:XF [(match_dup 10) (match_dup 9)]
16423                               UNSPEC_FSCALE_EXP))])
16424    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16425    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16426    (set (match_operand:SF 0 "register_operand" "")
16427         (float_truncate:SF (match_dup 14)))]
16428   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16429    && flag_unsafe_math_optimizations"
16431   rtx temp;
16432   int i;
16434   for (i=2; i<15; i++)
16435     operands[i] = gen_reg_rtx (XFmode);
16436   temp = standard_80387_constant_rtx (5); /* fldl2e */
16437   emit_move_insn (operands[3], temp);
16438   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16441 (define_expand "expm1xf2"
16442   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16443                                (match_dup 2)))
16444    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16445    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16446    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16447    (parallel [(set (match_dup 7)
16448                    (unspec:XF [(match_dup 6) (match_dup 4)]
16449                               UNSPEC_FSCALE_FRACT))
16450                    (set (match_dup 8)
16451                    (unspec:XF [(match_dup 6) (match_dup 4)]
16452                               UNSPEC_FSCALE_EXP))])
16453    (parallel [(set (match_dup 10)
16454                    (unspec:XF [(match_dup 9) (match_dup 8)]
16455                               UNSPEC_FSCALE_FRACT))
16456               (set (match_dup 11)
16457                    (unspec:XF [(match_dup 9) (match_dup 8)]
16458                               UNSPEC_FSCALE_EXP))])
16459    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16460    (set (match_operand:XF 0 "register_operand" "")
16461         (plus:XF (match_dup 12) (match_dup 7)))]
16462   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16463    && flag_unsafe_math_optimizations"
16465   rtx temp;
16466   int i;
16468   for (i=2; i<13; i++)
16469     operands[i] = gen_reg_rtx (XFmode);
16470   temp = standard_80387_constant_rtx (5); /* fldl2e */
16471   emit_move_insn (operands[2], temp);
16472   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16476 (define_insn "frndintxf2"
16477   [(set (match_operand:XF 0 "register_operand" "=f")
16478         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16479          UNSPEC_FRNDINT))]
16480   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16481    && flag_unsafe_math_optimizations"
16482   "frndint"
16483   [(set_attr "type" "fpspc")
16484    (set_attr "mode" "XF")])
16486 (define_expand "rintdf2"
16487   [(use (match_operand:DF 0 "register_operand" ""))
16488    (use (match_operand:DF 1 "register_operand" ""))]
16489   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16490    && flag_unsafe_math_optimizations"
16492   rtx op0 = gen_reg_rtx (XFmode);
16493   rtx op1 = gen_reg_rtx (XFmode);
16495   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16496   emit_insn (gen_frndintxf2 (op0, op1));
16498   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16499   DONE;
16502 (define_expand "rintsf2"
16503   [(use (match_operand:SF 0 "register_operand" ""))
16504    (use (match_operand:SF 1 "register_operand" ""))]
16505   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16506    && flag_unsafe_math_optimizations"
16508   rtx op0 = gen_reg_rtx (XFmode);
16509   rtx op1 = gen_reg_rtx (XFmode);
16511   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16512   emit_insn (gen_frndintxf2 (op0, op1));
16514   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16515   DONE;
16518 (define_expand "rintxf2"
16519   [(use (match_operand:XF 0 "register_operand" ""))
16520    (use (match_operand:XF 1 "register_operand" ""))]
16521   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16522    && flag_unsafe_math_optimizations"
16524   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16525   DONE;
16528 (define_insn "frndintxf2_floor"
16529   [(set (match_operand:XF 0 "register_operand" "=f")
16530         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16531          UNSPEC_FRNDINT_FLOOR))
16532    (use (match_operand:HI 2 "memory_operand" "m"))
16533    (use (match_operand:HI 3 "memory_operand" "m"))]
16534   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16535    && flag_unsafe_math_optimizations"
16536   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16537   [(set_attr "type" "frndint")
16538    (set_attr "i387_cw" "floor")
16539    (set_attr "mode" "XF")])
16541 (define_expand "floordf2"
16542   [(use (match_operand:DF 0 "register_operand" ""))
16543    (use (match_operand:DF 1 "register_operand" ""))]
16544   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16545    && flag_unsafe_math_optimizations"
16547   rtx op0 = gen_reg_rtx (XFmode);
16548   rtx op1 = gen_reg_rtx (XFmode);
16549   rtx op2 = assign_386_stack_local (HImode, 1);
16550   rtx op3 = assign_386_stack_local (HImode, 2);
16551         
16552   ix86_optimize_mode_switching = 1;
16554   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16555   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16557   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16558   DONE;
16561 (define_expand "floorsf2"
16562   [(use (match_operand:SF 0 "register_operand" ""))
16563    (use (match_operand:SF 1 "register_operand" ""))]
16564   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16565    && flag_unsafe_math_optimizations"
16567   rtx op0 = gen_reg_rtx (XFmode);
16568   rtx op1 = gen_reg_rtx (XFmode);
16569   rtx op2 = assign_386_stack_local (HImode, 1);
16570   rtx op3 = assign_386_stack_local (HImode, 2);
16571         
16572   ix86_optimize_mode_switching = 1;
16574   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16575   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16577   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16578   DONE;
16581 (define_expand "floorxf2"
16582   [(use (match_operand:XF 0 "register_operand" ""))
16583    (use (match_operand:XF 1 "register_operand" ""))]
16584   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16585    && flag_unsafe_math_optimizations"
16587   rtx op2 = assign_386_stack_local (HImode, 1);
16588   rtx op3 = assign_386_stack_local (HImode, 2);
16589         
16590   ix86_optimize_mode_switching = 1;
16592   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16593   DONE;
16596 (define_insn "frndintxf2_ceil"
16597   [(set (match_operand:XF 0 "register_operand" "=f")
16598         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16599          UNSPEC_FRNDINT_CEIL))
16600    (use (match_operand:HI 2 "memory_operand" "m"))
16601    (use (match_operand:HI 3 "memory_operand" "m"))]
16602   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16603    && flag_unsafe_math_optimizations"
16604   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16605   [(set_attr "type" "frndint")
16606    (set_attr "i387_cw" "ceil")
16607    (set_attr "mode" "XF")])
16609 (define_expand "ceildf2"
16610   [(use (match_operand:DF 0 "register_operand" ""))
16611    (use (match_operand:DF 1 "register_operand" ""))]
16612   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16613    && flag_unsafe_math_optimizations"
16615   rtx op0 = gen_reg_rtx (XFmode);
16616   rtx op1 = gen_reg_rtx (XFmode);
16617   rtx op2 = assign_386_stack_local (HImode, 1);
16618   rtx op3 = assign_386_stack_local (HImode, 2);
16619         
16620   ix86_optimize_mode_switching = 1;
16622   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16623   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16625   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16626   DONE;
16629 (define_expand "ceilsf2"
16630   [(use (match_operand:SF 0 "register_operand" ""))
16631    (use (match_operand:SF 1 "register_operand" ""))]
16632   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16633    && flag_unsafe_math_optimizations"
16635   rtx op0 = gen_reg_rtx (XFmode);
16636   rtx op1 = gen_reg_rtx (XFmode);
16637   rtx op2 = assign_386_stack_local (HImode, 1);
16638   rtx op3 = assign_386_stack_local (HImode, 2);
16639         
16640   ix86_optimize_mode_switching = 1;
16642   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16643   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16645   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16646   DONE;
16649 (define_expand "ceilxf2"
16650   [(use (match_operand:XF 0 "register_operand" ""))
16651    (use (match_operand:XF 1 "register_operand" ""))]
16652   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16653    && flag_unsafe_math_optimizations"
16655   rtx op2 = assign_386_stack_local (HImode, 1);
16656   rtx op3 = assign_386_stack_local (HImode, 2);
16657         
16658   ix86_optimize_mode_switching = 1;
16660   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16661   DONE;
16664 (define_insn "frndintxf2_trunc"
16665   [(set (match_operand:XF 0 "register_operand" "=f")
16666         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16667          UNSPEC_FRNDINT_TRUNC))
16668    (use (match_operand:HI 2 "memory_operand" "m"))
16669    (use (match_operand:HI 3 "memory_operand" "m"))]
16670   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16671    && flag_unsafe_math_optimizations"
16672   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16673   [(set_attr "type" "frndint")
16674    (set_attr "i387_cw" "trunc")
16675    (set_attr "mode" "XF")])
16677 (define_expand "btruncdf2"
16678   [(use (match_operand:DF 0 "register_operand" ""))
16679    (use (match_operand:DF 1 "register_operand" ""))]
16680   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16681    && flag_unsafe_math_optimizations"
16683   rtx op0 = gen_reg_rtx (XFmode);
16684   rtx op1 = gen_reg_rtx (XFmode);
16685   rtx op2 = assign_386_stack_local (HImode, 1);
16686   rtx op3 = assign_386_stack_local (HImode, 2);
16687         
16688   ix86_optimize_mode_switching = 1;
16690   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16691   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16693   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16694   DONE;
16697 (define_expand "btruncsf2"
16698   [(use (match_operand:SF 0 "register_operand" ""))
16699    (use (match_operand:SF 1 "register_operand" ""))]
16700   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16701    && flag_unsafe_math_optimizations"
16703   rtx op0 = gen_reg_rtx (XFmode);
16704   rtx op1 = gen_reg_rtx (XFmode);
16705   rtx op2 = assign_386_stack_local (HImode, 1);
16706   rtx op3 = assign_386_stack_local (HImode, 2);
16707         
16708   ix86_optimize_mode_switching = 1;
16710   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16711   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16713   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16714   DONE;
16717 (define_expand "btruncxf2"
16718   [(use (match_operand:XF 0 "register_operand" ""))
16719    (use (match_operand:XF 1 "register_operand" ""))]
16720   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16721    && flag_unsafe_math_optimizations"
16723   rtx op2 = assign_386_stack_local (HImode, 1);
16724   rtx op3 = assign_386_stack_local (HImode, 2);
16725         
16726   ix86_optimize_mode_switching = 1;
16728   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16729   DONE;
16732 (define_insn "frndintxf2_mask_pm"
16733   [(set (match_operand:XF 0 "register_operand" "=f")
16734         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16735          UNSPEC_FRNDINT_MASK_PM))
16736    (use (match_operand:HI 2 "memory_operand" "m"))
16737    (use (match_operand:HI 3 "memory_operand" "m"))]
16738   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16739    && flag_unsafe_math_optimizations"
16740   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16741   [(set_attr "type" "frndint")
16742    (set_attr "i387_cw" "mask_pm")
16743    (set_attr "mode" "XF")])
16745 (define_expand "nearbyintdf2"
16746   [(use (match_operand:DF 0 "register_operand" ""))
16747    (use (match_operand:DF 1 "register_operand" ""))]
16748   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16749    && flag_unsafe_math_optimizations"
16751   rtx op0 = gen_reg_rtx (XFmode);
16752   rtx op1 = gen_reg_rtx (XFmode);
16753   rtx op2 = assign_386_stack_local (HImode, 1);
16754   rtx op3 = assign_386_stack_local (HImode, 2);
16755         
16756   ix86_optimize_mode_switching = 1;
16758   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16759   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16761   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16762   DONE;
16765 (define_expand "nearbyintsf2"
16766   [(use (match_operand:SF 0 "register_operand" ""))
16767    (use (match_operand:SF 1 "register_operand" ""))]
16768   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16769    && flag_unsafe_math_optimizations"
16771   rtx op0 = gen_reg_rtx (XFmode);
16772   rtx op1 = gen_reg_rtx (XFmode);
16773   rtx op2 = assign_386_stack_local (HImode, 1);
16774   rtx op3 = assign_386_stack_local (HImode, 2);
16775         
16776   ix86_optimize_mode_switching = 1;
16778   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16779   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16781   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16782   DONE;
16785 (define_expand "nearbyintxf2"
16786   [(use (match_operand:XF 0 "register_operand" ""))
16787    (use (match_operand:XF 1 "register_operand" ""))]
16788   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16789    && flag_unsafe_math_optimizations"
16791   rtx op2 = assign_386_stack_local (HImode, 1);
16792   rtx op3 = assign_386_stack_local (HImode, 2);
16793         
16794   ix86_optimize_mode_switching = 1;
16796   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16797                                      op2, op3));
16798   DONE;
16802 ;; Block operation instructions
16804 (define_insn "cld"
16805  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16806  ""
16807  "cld"
16808   [(set_attr "type" "cld")])
16810 (define_expand "movmemsi"
16811   [(use (match_operand:BLK 0 "memory_operand" ""))
16812    (use (match_operand:BLK 1 "memory_operand" ""))
16813    (use (match_operand:SI 2 "nonmemory_operand" ""))
16814    (use (match_operand:SI 3 "const_int_operand" ""))]
16815   "! optimize_size"
16817  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16818    DONE;
16819  else
16820    FAIL;
16823 (define_expand "movmemdi"
16824   [(use (match_operand:BLK 0 "memory_operand" ""))
16825    (use (match_operand:BLK 1 "memory_operand" ""))
16826    (use (match_operand:DI 2 "nonmemory_operand" ""))
16827    (use (match_operand:DI 3 "const_int_operand" ""))]
16828   "TARGET_64BIT"
16830  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16831    DONE;
16832  else
16833    FAIL;
16836 ;; Most CPUs don't like single string operations
16837 ;; Handle this case here to simplify previous expander.
16839 (define_expand "strmov"
16840   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16841    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16842    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16843               (clobber (reg:CC FLAGS_REG))])
16844    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16845               (clobber (reg:CC FLAGS_REG))])]
16846   ""
16848   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16850   /* If .md ever supports :P for Pmode, these can be directly
16851      in the pattern above.  */
16852   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16853   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16855   if (TARGET_SINGLE_STRINGOP || optimize_size)
16856     {
16857       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16858                                       operands[2], operands[3],
16859                                       operands[5], operands[6]));
16860       DONE;
16861     }
16863   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16866 (define_expand "strmov_singleop"
16867   [(parallel [(set (match_operand 1 "memory_operand" "")
16868                    (match_operand 3 "memory_operand" ""))
16869               (set (match_operand 0 "register_operand" "")
16870                    (match_operand 4 "" ""))
16871               (set (match_operand 2 "register_operand" "")
16872                    (match_operand 5 "" ""))
16873               (use (reg:SI DIRFLAG_REG))])]
16874   "TARGET_SINGLE_STRINGOP || optimize_size"
16875   "")
16877 (define_insn "*strmovdi_rex_1"
16878   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16879         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16880    (set (match_operand:DI 0 "register_operand" "=D")
16881         (plus:DI (match_dup 2)
16882                  (const_int 8)))
16883    (set (match_operand:DI 1 "register_operand" "=S")
16884         (plus:DI (match_dup 3)
16885                  (const_int 8)))
16886    (use (reg:SI DIRFLAG_REG))]
16887   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16888   "movsq"
16889   [(set_attr "type" "str")
16890    (set_attr "mode" "DI")
16891    (set_attr "memory" "both")])
16893 (define_insn "*strmovsi_1"
16894   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16895         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16896    (set (match_operand:SI 0 "register_operand" "=D")
16897         (plus:SI (match_dup 2)
16898                  (const_int 4)))
16899    (set (match_operand:SI 1 "register_operand" "=S")
16900         (plus:SI (match_dup 3)
16901                  (const_int 4)))
16902    (use (reg:SI DIRFLAG_REG))]
16903   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16904   "{movsl|movsd}"
16905   [(set_attr "type" "str")
16906    (set_attr "mode" "SI")
16907    (set_attr "memory" "both")])
16909 (define_insn "*strmovsi_rex_1"
16910   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16911         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16912    (set (match_operand:DI 0 "register_operand" "=D")
16913         (plus:DI (match_dup 2)
16914                  (const_int 4)))
16915    (set (match_operand:DI 1 "register_operand" "=S")
16916         (plus:DI (match_dup 3)
16917                  (const_int 4)))
16918    (use (reg:SI DIRFLAG_REG))]
16919   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16920   "{movsl|movsd}"
16921   [(set_attr "type" "str")
16922    (set_attr "mode" "SI")
16923    (set_attr "memory" "both")])
16925 (define_insn "*strmovhi_1"
16926   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16927         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16928    (set (match_operand:SI 0 "register_operand" "=D")
16929         (plus:SI (match_dup 2)
16930                  (const_int 2)))
16931    (set (match_operand:SI 1 "register_operand" "=S")
16932         (plus:SI (match_dup 3)
16933                  (const_int 2)))
16934    (use (reg:SI DIRFLAG_REG))]
16935   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16936   "movsw"
16937   [(set_attr "type" "str")
16938    (set_attr "memory" "both")
16939    (set_attr "mode" "HI")])
16941 (define_insn "*strmovhi_rex_1"
16942   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16943         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16944    (set (match_operand:DI 0 "register_operand" "=D")
16945         (plus:DI (match_dup 2)
16946                  (const_int 2)))
16947    (set (match_operand:DI 1 "register_operand" "=S")
16948         (plus:DI (match_dup 3)
16949                  (const_int 2)))
16950    (use (reg:SI DIRFLAG_REG))]
16951   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16952   "movsw"
16953   [(set_attr "type" "str")
16954    (set_attr "memory" "both")
16955    (set_attr "mode" "HI")])
16957 (define_insn "*strmovqi_1"
16958   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16959         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16960    (set (match_operand:SI 0 "register_operand" "=D")
16961         (plus:SI (match_dup 2)
16962                  (const_int 1)))
16963    (set (match_operand:SI 1 "register_operand" "=S")
16964         (plus:SI (match_dup 3)
16965                  (const_int 1)))
16966    (use (reg:SI DIRFLAG_REG))]
16967   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16968   "movsb"
16969   [(set_attr "type" "str")
16970    (set_attr "memory" "both")
16971    (set_attr "mode" "QI")])
16973 (define_insn "*strmovqi_rex_1"
16974   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16975         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16976    (set (match_operand:DI 0 "register_operand" "=D")
16977         (plus:DI (match_dup 2)
16978                  (const_int 1)))
16979    (set (match_operand:DI 1 "register_operand" "=S")
16980         (plus:DI (match_dup 3)
16981                  (const_int 1)))
16982    (use (reg:SI DIRFLAG_REG))]
16983   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16984   "movsb"
16985   [(set_attr "type" "str")
16986    (set_attr "memory" "both")
16987    (set_attr "mode" "QI")])
16989 (define_expand "rep_mov"
16990   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16991               (set (match_operand 0 "register_operand" "")
16992                    (match_operand 5 "" ""))
16993               (set (match_operand 2 "register_operand" "")
16994                    (match_operand 6 "" ""))
16995               (set (match_operand 1 "memory_operand" "")
16996                    (match_operand 3 "memory_operand" ""))
16997               (use (match_dup 4))
16998               (use (reg:SI DIRFLAG_REG))])]
16999   ""
17000   "")
17002 (define_insn "*rep_movdi_rex64"
17003   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17004    (set (match_operand:DI 0 "register_operand" "=D") 
17005         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17006                             (const_int 3))
17007                  (match_operand:DI 3 "register_operand" "0")))
17008    (set (match_operand:DI 1 "register_operand" "=S") 
17009         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17010                  (match_operand:DI 4 "register_operand" "1")))
17011    (set (mem:BLK (match_dup 3))
17012         (mem:BLK (match_dup 4)))
17013    (use (match_dup 5))
17014    (use (reg:SI DIRFLAG_REG))]
17015   "TARGET_64BIT"
17016   "{rep\;movsq|rep movsq}"
17017   [(set_attr "type" "str")
17018    (set_attr "prefix_rep" "1")
17019    (set_attr "memory" "both")
17020    (set_attr "mode" "DI")])
17022 (define_insn "*rep_movsi"
17023   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17024    (set (match_operand:SI 0 "register_operand" "=D") 
17025         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17026                             (const_int 2))
17027                  (match_operand:SI 3 "register_operand" "0")))
17028    (set (match_operand:SI 1 "register_operand" "=S") 
17029         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17030                  (match_operand:SI 4 "register_operand" "1")))
17031    (set (mem:BLK (match_dup 3))
17032         (mem:BLK (match_dup 4)))
17033    (use (match_dup 5))
17034    (use (reg:SI DIRFLAG_REG))]
17035   "!TARGET_64BIT"
17036   "{rep\;movsl|rep movsd}"
17037   [(set_attr "type" "str")
17038    (set_attr "prefix_rep" "1")
17039    (set_attr "memory" "both")
17040    (set_attr "mode" "SI")])
17042 (define_insn "*rep_movsi_rex64"
17043   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17044    (set (match_operand:DI 0 "register_operand" "=D") 
17045         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17046                             (const_int 2))
17047                  (match_operand:DI 3 "register_operand" "0")))
17048    (set (match_operand:DI 1 "register_operand" "=S") 
17049         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17050                  (match_operand:DI 4 "register_operand" "1")))
17051    (set (mem:BLK (match_dup 3))
17052         (mem:BLK (match_dup 4)))
17053    (use (match_dup 5))
17054    (use (reg:SI DIRFLAG_REG))]
17055   "TARGET_64BIT"
17056   "{rep\;movsl|rep movsd}"
17057   [(set_attr "type" "str")
17058    (set_attr "prefix_rep" "1")
17059    (set_attr "memory" "both")
17060    (set_attr "mode" "SI")])
17062 (define_insn "*rep_movqi"
17063   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17064    (set (match_operand:SI 0 "register_operand" "=D") 
17065         (plus:SI (match_operand:SI 3 "register_operand" "0")
17066                  (match_operand:SI 5 "register_operand" "2")))
17067    (set (match_operand:SI 1 "register_operand" "=S") 
17068         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17069    (set (mem:BLK (match_dup 3))
17070         (mem:BLK (match_dup 4)))
17071    (use (match_dup 5))
17072    (use (reg:SI DIRFLAG_REG))]
17073   "!TARGET_64BIT"
17074   "{rep\;movsb|rep movsb}"
17075   [(set_attr "type" "str")
17076    (set_attr "prefix_rep" "1")
17077    (set_attr "memory" "both")
17078    (set_attr "mode" "SI")])
17080 (define_insn "*rep_movqi_rex64"
17081   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17082    (set (match_operand:DI 0 "register_operand" "=D") 
17083         (plus:DI (match_operand:DI 3 "register_operand" "0")
17084                  (match_operand:DI 5 "register_operand" "2")))
17085    (set (match_operand:DI 1 "register_operand" "=S") 
17086         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17087    (set (mem:BLK (match_dup 3))
17088         (mem:BLK (match_dup 4)))
17089    (use (match_dup 5))
17090    (use (reg:SI DIRFLAG_REG))]
17091   "TARGET_64BIT"
17092   "{rep\;movsb|rep movsb}"
17093   [(set_attr "type" "str")
17094    (set_attr "prefix_rep" "1")
17095    (set_attr "memory" "both")
17096    (set_attr "mode" "SI")])
17098 (define_expand "clrmemsi"
17099    [(use (match_operand:BLK 0 "memory_operand" ""))
17100     (use (match_operand:SI 1 "nonmemory_operand" ""))
17101     (use (match_operand 2 "const_int_operand" ""))]
17102   ""
17104  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17105    DONE;
17106  else
17107    FAIL;
17110 (define_expand "clrmemdi"
17111    [(use (match_operand:BLK 0 "memory_operand" ""))
17112     (use (match_operand:DI 1 "nonmemory_operand" ""))
17113     (use (match_operand 2 "const_int_operand" ""))]
17114   "TARGET_64BIT"
17116  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17117    DONE;
17118  else
17119    FAIL;
17122 ;; Most CPUs don't like single string operations
17123 ;; Handle this case here to simplify previous expander.
17125 (define_expand "strset"
17126   [(set (match_operand 1 "memory_operand" "")
17127         (match_operand 2 "register_operand" ""))
17128    (parallel [(set (match_operand 0 "register_operand" "")
17129                    (match_dup 3))
17130               (clobber (reg:CC FLAGS_REG))])]
17131   ""
17133   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17134     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17136   /* If .md ever supports :P for Pmode, this can be directly
17137      in the pattern above.  */
17138   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17139                               GEN_INT (GET_MODE_SIZE (GET_MODE
17140                                                       (operands[2]))));
17141   if (TARGET_SINGLE_STRINGOP || optimize_size)
17142     {
17143       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17144                                       operands[3]));
17145       DONE;
17146     }
17149 (define_expand "strset_singleop"
17150   [(parallel [(set (match_operand 1 "memory_operand" "")
17151                    (match_operand 2 "register_operand" ""))
17152               (set (match_operand 0 "register_operand" "")
17153                    (match_operand 3 "" ""))
17154               (use (reg:SI DIRFLAG_REG))])]
17155   "TARGET_SINGLE_STRINGOP || optimize_size"
17156   "")
17158 (define_insn "*strsetdi_rex_1"
17159   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17160         (match_operand:DI 2 "register_operand" "a"))
17161    (set (match_operand:DI 0 "register_operand" "=D")
17162         (plus:DI (match_dup 1)
17163                  (const_int 8)))
17164    (use (reg:SI DIRFLAG_REG))]
17165   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17166   "stosq"
17167   [(set_attr "type" "str")
17168    (set_attr "memory" "store")
17169    (set_attr "mode" "DI")])
17171 (define_insn "*strsetsi_1"
17172   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17173         (match_operand:SI 2 "register_operand" "a"))
17174    (set (match_operand:SI 0 "register_operand" "=D")
17175         (plus:SI (match_dup 1)
17176                  (const_int 4)))
17177    (use (reg:SI DIRFLAG_REG))]
17178   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17179   "{stosl|stosd}"
17180   [(set_attr "type" "str")
17181    (set_attr "memory" "store")
17182    (set_attr "mode" "SI")])
17184 (define_insn "*strsetsi_rex_1"
17185   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17186         (match_operand:SI 2 "register_operand" "a"))
17187    (set (match_operand:DI 0 "register_operand" "=D")
17188         (plus:DI (match_dup 1)
17189                  (const_int 4)))
17190    (use (reg:SI DIRFLAG_REG))]
17191   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17192   "{stosl|stosd}"
17193   [(set_attr "type" "str")
17194    (set_attr "memory" "store")
17195    (set_attr "mode" "SI")])
17197 (define_insn "*strsethi_1"
17198   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17199         (match_operand:HI 2 "register_operand" "a"))
17200    (set (match_operand:SI 0 "register_operand" "=D")
17201         (plus:SI (match_dup 1)
17202                  (const_int 2)))
17203    (use (reg:SI DIRFLAG_REG))]
17204   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17205   "stosw"
17206   [(set_attr "type" "str")
17207    (set_attr "memory" "store")
17208    (set_attr "mode" "HI")])
17210 (define_insn "*strsethi_rex_1"
17211   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17212         (match_operand:HI 2 "register_operand" "a"))
17213    (set (match_operand:DI 0 "register_operand" "=D")
17214         (plus:DI (match_dup 1)
17215                  (const_int 2)))
17216    (use (reg:SI DIRFLAG_REG))]
17217   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17218   "stosw"
17219   [(set_attr "type" "str")
17220    (set_attr "memory" "store")
17221    (set_attr "mode" "HI")])
17223 (define_insn "*strsetqi_1"
17224   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17225         (match_operand:QI 2 "register_operand" "a"))
17226    (set (match_operand:SI 0 "register_operand" "=D")
17227         (plus:SI (match_dup 1)
17228                  (const_int 1)))
17229    (use (reg:SI DIRFLAG_REG))]
17230   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17231   "stosb"
17232   [(set_attr "type" "str")
17233    (set_attr "memory" "store")
17234    (set_attr "mode" "QI")])
17236 (define_insn "*strsetqi_rex_1"
17237   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17238         (match_operand:QI 2 "register_operand" "a"))
17239    (set (match_operand:DI 0 "register_operand" "=D")
17240         (plus:DI (match_dup 1)
17241                  (const_int 1)))
17242    (use (reg:SI DIRFLAG_REG))]
17243   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17244   "stosb"
17245   [(set_attr "type" "str")
17246    (set_attr "memory" "store")
17247    (set_attr "mode" "QI")])
17249 (define_expand "rep_stos"
17250   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17251               (set (match_operand 0 "register_operand" "")
17252                    (match_operand 4 "" ""))
17253               (set (match_operand 2 "memory_operand" "") (const_int 0))
17254               (use (match_operand 3 "register_operand" ""))
17255               (use (match_dup 1))
17256               (use (reg:SI DIRFLAG_REG))])]
17257   ""
17258   "")
17260 (define_insn "*rep_stosdi_rex64"
17261   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17262    (set (match_operand:DI 0 "register_operand" "=D") 
17263         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17264                             (const_int 3))
17265                  (match_operand:DI 3 "register_operand" "0")))
17266    (set (mem:BLK (match_dup 3))
17267         (const_int 0))
17268    (use (match_operand:DI 2 "register_operand" "a"))
17269    (use (match_dup 4))
17270    (use (reg:SI DIRFLAG_REG))]
17271   "TARGET_64BIT"
17272   "{rep\;stosq|rep stosq}"
17273   [(set_attr "type" "str")
17274    (set_attr "prefix_rep" "1")
17275    (set_attr "memory" "store")
17276    (set_attr "mode" "DI")])
17278 (define_insn "*rep_stossi"
17279   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17280    (set (match_operand:SI 0 "register_operand" "=D") 
17281         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17282                             (const_int 2))
17283                  (match_operand:SI 3 "register_operand" "0")))
17284    (set (mem:BLK (match_dup 3))
17285         (const_int 0))
17286    (use (match_operand:SI 2 "register_operand" "a"))
17287    (use (match_dup 4))
17288    (use (reg:SI DIRFLAG_REG))]
17289   "!TARGET_64BIT"
17290   "{rep\;stosl|rep stosd}"
17291   [(set_attr "type" "str")
17292    (set_attr "prefix_rep" "1")
17293    (set_attr "memory" "store")
17294    (set_attr "mode" "SI")])
17296 (define_insn "*rep_stossi_rex64"
17297   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17298    (set (match_operand:DI 0 "register_operand" "=D") 
17299         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17300                             (const_int 2))
17301                  (match_operand:DI 3 "register_operand" "0")))
17302    (set (mem:BLK (match_dup 3))
17303         (const_int 0))
17304    (use (match_operand:SI 2 "register_operand" "a"))
17305    (use (match_dup 4))
17306    (use (reg:SI DIRFLAG_REG))]
17307   "TARGET_64BIT"
17308   "{rep\;stosl|rep stosd}"
17309   [(set_attr "type" "str")
17310    (set_attr "prefix_rep" "1")
17311    (set_attr "memory" "store")
17312    (set_attr "mode" "SI")])
17314 (define_insn "*rep_stosqi"
17315   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17316    (set (match_operand:SI 0 "register_operand" "=D") 
17317         (plus:SI (match_operand:SI 3 "register_operand" "0")
17318                  (match_operand:SI 4 "register_operand" "1")))
17319    (set (mem:BLK (match_dup 3))
17320         (const_int 0))
17321    (use (match_operand:QI 2 "register_operand" "a"))
17322    (use (match_dup 4))
17323    (use (reg:SI DIRFLAG_REG))]
17324   "!TARGET_64BIT"
17325   "{rep\;stosb|rep stosb}"
17326   [(set_attr "type" "str")
17327    (set_attr "prefix_rep" "1")
17328    (set_attr "memory" "store")
17329    (set_attr "mode" "QI")])
17331 (define_insn "*rep_stosqi_rex64"
17332   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17333    (set (match_operand:DI 0 "register_operand" "=D") 
17334         (plus:DI (match_operand:DI 3 "register_operand" "0")
17335                  (match_operand:DI 4 "register_operand" "1")))
17336    (set (mem:BLK (match_dup 3))
17337         (const_int 0))
17338    (use (match_operand:QI 2 "register_operand" "a"))
17339    (use (match_dup 4))
17340    (use (reg:SI DIRFLAG_REG))]
17341   "TARGET_64BIT"
17342   "{rep\;stosb|rep stosb}"
17343   [(set_attr "type" "str")
17344    (set_attr "prefix_rep" "1")
17345    (set_attr "memory" "store")
17346    (set_attr "mode" "QI")])
17348 (define_expand "cmpstrsi"
17349   [(set (match_operand:SI 0 "register_operand" "")
17350         (compare:SI (match_operand:BLK 1 "general_operand" "")
17351                     (match_operand:BLK 2 "general_operand" "")))
17352    (use (match_operand 3 "general_operand" ""))
17353    (use (match_operand 4 "immediate_operand" ""))]
17354   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17356   rtx addr1, addr2, out, outlow, count, countreg, align;
17358   /* Can't use this if the user has appropriated esi or edi.  */
17359   if (global_regs[4] || global_regs[5])
17360     FAIL;
17362   out = operands[0];
17363   if (GET_CODE (out) != REG)
17364     out = gen_reg_rtx (SImode);
17366   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17367   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17368   if (addr1 != XEXP (operands[1], 0))
17369     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17370   if (addr2 != XEXP (operands[2], 0))
17371     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17373   count = operands[3];
17374   countreg = ix86_zero_extend_to_Pmode (count);
17376   /* %%% Iff we are testing strict equality, we can use known alignment
17377      to good advantage.  This may be possible with combine, particularly
17378      once cc0 is dead.  */
17379   align = operands[4];
17381   emit_insn (gen_cld ());
17382   if (GET_CODE (count) == CONST_INT)
17383     {
17384       if (INTVAL (count) == 0)
17385         {
17386           emit_move_insn (operands[0], const0_rtx);
17387           DONE;
17388         }
17389       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17390                                     operands[1], operands[2]));
17391     }
17392   else
17393     {
17394       if (TARGET_64BIT)
17395         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17396       else
17397         emit_insn (gen_cmpsi_1 (countreg, countreg));
17398       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17399                                  operands[1], operands[2]));
17400     }
17402   outlow = gen_lowpart (QImode, out);
17403   emit_insn (gen_cmpintqi (outlow));
17404   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17406   if (operands[0] != out)
17407     emit_move_insn (operands[0], out);
17409   DONE;
17412 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17414 (define_expand "cmpintqi"
17415   [(set (match_dup 1)
17416         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17417    (set (match_dup 2)
17418         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17419    (parallel [(set (match_operand:QI 0 "register_operand" "")
17420                    (minus:QI (match_dup 1)
17421                              (match_dup 2)))
17422               (clobber (reg:CC FLAGS_REG))])]
17423   ""
17424   "operands[1] = gen_reg_rtx (QImode);
17425    operands[2] = gen_reg_rtx (QImode);")
17427 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17428 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17430 (define_expand "cmpstrqi_nz_1"
17431   [(parallel [(set (reg:CC FLAGS_REG)
17432                    (compare:CC (match_operand 4 "memory_operand" "")
17433                                (match_operand 5 "memory_operand" "")))
17434               (use (match_operand 2 "register_operand" ""))
17435               (use (match_operand:SI 3 "immediate_operand" ""))
17436               (use (reg:SI DIRFLAG_REG))
17437               (clobber (match_operand 0 "register_operand" ""))
17438               (clobber (match_operand 1 "register_operand" ""))
17439               (clobber (match_dup 2))])]
17440   ""
17441   "")
17443 (define_insn "*cmpstrqi_nz_1"
17444   [(set (reg:CC FLAGS_REG)
17445         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17446                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17447    (use (match_operand:SI 6 "register_operand" "2"))
17448    (use (match_operand:SI 3 "immediate_operand" "i"))
17449    (use (reg:SI DIRFLAG_REG))
17450    (clobber (match_operand:SI 0 "register_operand" "=S"))
17451    (clobber (match_operand:SI 1 "register_operand" "=D"))
17452    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17453   "!TARGET_64BIT"
17454   "repz{\;| }cmpsb"
17455   [(set_attr "type" "str")
17456    (set_attr "mode" "QI")
17457    (set_attr "prefix_rep" "1")])
17459 (define_insn "*cmpstrqi_nz_rex_1"
17460   [(set (reg:CC FLAGS_REG)
17461         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17462                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17463    (use (match_operand:DI 6 "register_operand" "2"))
17464    (use (match_operand:SI 3 "immediate_operand" "i"))
17465    (use (reg:SI DIRFLAG_REG))
17466    (clobber (match_operand:DI 0 "register_operand" "=S"))
17467    (clobber (match_operand:DI 1 "register_operand" "=D"))
17468    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17469   "TARGET_64BIT"
17470   "repz{\;| }cmpsb"
17471   [(set_attr "type" "str")
17472    (set_attr "mode" "QI")
17473    (set_attr "prefix_rep" "1")])
17475 ;; The same, but the count is not known to not be zero.
17477 (define_expand "cmpstrqi_1"
17478   [(parallel [(set (reg:CC FLAGS_REG)
17479                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17480                                      (const_int 0))
17481                   (compare:CC (match_operand 4 "memory_operand" "")
17482                               (match_operand 5 "memory_operand" ""))
17483                   (const_int 0)))
17484               (use (match_operand:SI 3 "immediate_operand" ""))
17485               (use (reg:CC FLAGS_REG))
17486               (use (reg:SI DIRFLAG_REG))
17487               (clobber (match_operand 0 "register_operand" ""))
17488               (clobber (match_operand 1 "register_operand" ""))
17489               (clobber (match_dup 2))])]
17490   ""
17491   "")
17493 (define_insn "*cmpstrqi_1"
17494   [(set (reg:CC FLAGS_REG)
17495         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17496                              (const_int 0))
17497           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17498                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17499           (const_int 0)))
17500    (use (match_operand:SI 3 "immediate_operand" "i"))
17501    (use (reg:CC FLAGS_REG))
17502    (use (reg:SI DIRFLAG_REG))
17503    (clobber (match_operand:SI 0 "register_operand" "=S"))
17504    (clobber (match_operand:SI 1 "register_operand" "=D"))
17505    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17506   "!TARGET_64BIT"
17507   "repz{\;| }cmpsb"
17508   [(set_attr "type" "str")
17509    (set_attr "mode" "QI")
17510    (set_attr "prefix_rep" "1")])
17512 (define_insn "*cmpstrqi_rex_1"
17513   [(set (reg:CC FLAGS_REG)
17514         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17515                              (const_int 0))
17516           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17517                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17518           (const_int 0)))
17519    (use (match_operand:SI 3 "immediate_operand" "i"))
17520    (use (reg:CC FLAGS_REG))
17521    (use (reg:SI DIRFLAG_REG))
17522    (clobber (match_operand:DI 0 "register_operand" "=S"))
17523    (clobber (match_operand:DI 1 "register_operand" "=D"))
17524    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17525   "TARGET_64BIT"
17526   "repz{\;| }cmpsb"
17527   [(set_attr "type" "str")
17528    (set_attr "mode" "QI")
17529    (set_attr "prefix_rep" "1")])
17531 (define_expand "strlensi"
17532   [(set (match_operand:SI 0 "register_operand" "")
17533         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17534                     (match_operand:QI 2 "immediate_operand" "")
17535                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17536   ""
17538  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17539    DONE;
17540  else
17541    FAIL;
17544 (define_expand "strlendi"
17545   [(set (match_operand:DI 0 "register_operand" "")
17546         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17547                     (match_operand:QI 2 "immediate_operand" "")
17548                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17549   ""
17551  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17552    DONE;
17553  else
17554    FAIL;
17557 (define_expand "strlenqi_1"
17558   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17559               (use (reg:SI DIRFLAG_REG))
17560               (clobber (match_operand 1 "register_operand" ""))
17561               (clobber (reg:CC FLAGS_REG))])]
17562   ""
17563   "")
17565 (define_insn "*strlenqi_1"
17566   [(set (match_operand:SI 0 "register_operand" "=&c")
17567         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17568                     (match_operand:QI 2 "register_operand" "a")
17569                     (match_operand:SI 3 "immediate_operand" "i")
17570                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17571    (use (reg:SI DIRFLAG_REG))
17572    (clobber (match_operand:SI 1 "register_operand" "=D"))
17573    (clobber (reg:CC FLAGS_REG))]
17574   "!TARGET_64BIT"
17575   "repnz{\;| }scasb"
17576   [(set_attr "type" "str")
17577    (set_attr "mode" "QI")
17578    (set_attr "prefix_rep" "1")])
17580 (define_insn "*strlenqi_rex_1"
17581   [(set (match_operand:DI 0 "register_operand" "=&c")
17582         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17583                     (match_operand:QI 2 "register_operand" "a")
17584                     (match_operand:DI 3 "immediate_operand" "i")
17585                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17586    (use (reg:SI DIRFLAG_REG))
17587    (clobber (match_operand:DI 1 "register_operand" "=D"))
17588    (clobber (reg:CC FLAGS_REG))]
17589   "TARGET_64BIT"
17590   "repnz{\;| }scasb"
17591   [(set_attr "type" "str")
17592    (set_attr "mode" "QI")
17593    (set_attr "prefix_rep" "1")])
17595 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17596 ;; handled in combine, but it is not currently up to the task.
17597 ;; When used for their truth value, the cmpstr* expanders generate
17598 ;; code like this:
17600 ;;   repz cmpsb
17601 ;;   seta       %al
17602 ;;   setb       %dl
17603 ;;   cmpb       %al, %dl
17604 ;;   jcc        label
17606 ;; The intermediate three instructions are unnecessary.
17608 ;; This one handles cmpstr*_nz_1...
17609 (define_peephole2
17610   [(parallel[
17611      (set (reg:CC FLAGS_REG)
17612           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17613                       (mem:BLK (match_operand 5 "register_operand" ""))))
17614      (use (match_operand 6 "register_operand" ""))
17615      (use (match_operand:SI 3 "immediate_operand" ""))
17616      (use (reg:SI DIRFLAG_REG))
17617      (clobber (match_operand 0 "register_operand" ""))
17618      (clobber (match_operand 1 "register_operand" ""))
17619      (clobber (match_operand 2 "register_operand" ""))])
17620    (set (match_operand:QI 7 "register_operand" "")
17621         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17622    (set (match_operand:QI 8 "register_operand" "")
17623         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17624    (set (reg 17)
17625         (compare (match_dup 7) (match_dup 8)))
17626   ]
17627   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17628   [(parallel[
17629      (set (reg:CC FLAGS_REG)
17630           (compare:CC (mem:BLK (match_dup 4))
17631                       (mem:BLK (match_dup 5))))
17632      (use (match_dup 6))
17633      (use (match_dup 3))
17634      (use (reg:SI DIRFLAG_REG))
17635      (clobber (match_dup 0))
17636      (clobber (match_dup 1))
17637      (clobber (match_dup 2))])]
17638   "")
17640 ;; ...and this one handles cmpstr*_1.
17641 (define_peephole2
17642   [(parallel[
17643      (set (reg:CC FLAGS_REG)
17644           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17645                                (const_int 0))
17646             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17647                         (mem:BLK (match_operand 5 "register_operand" "")))
17648             (const_int 0)))
17649      (use (match_operand:SI 3 "immediate_operand" ""))
17650      (use (reg:CC FLAGS_REG))
17651      (use (reg:SI DIRFLAG_REG))
17652      (clobber (match_operand 0 "register_operand" ""))
17653      (clobber (match_operand 1 "register_operand" ""))
17654      (clobber (match_operand 2 "register_operand" ""))])
17655    (set (match_operand:QI 7 "register_operand" "")
17656         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17657    (set (match_operand:QI 8 "register_operand" "")
17658         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17659    (set (reg 17)
17660         (compare (match_dup 7) (match_dup 8)))
17661   ]
17662   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17663   [(parallel[
17664      (set (reg:CC FLAGS_REG)
17665           (if_then_else:CC (ne (match_dup 6)
17666                                (const_int 0))
17667             (compare:CC (mem:BLK (match_dup 4))
17668                         (mem:BLK (match_dup 5)))
17669             (const_int 0)))
17670      (use (match_dup 3))
17671      (use (reg:CC FLAGS_REG))
17672      (use (reg:SI DIRFLAG_REG))
17673      (clobber (match_dup 0))
17674      (clobber (match_dup 1))
17675      (clobber (match_dup 2))])]
17676   "")
17680 ;; Conditional move instructions.
17682 (define_expand "movdicc"
17683   [(set (match_operand:DI 0 "register_operand" "")
17684         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17685                          (match_operand:DI 2 "general_operand" "")
17686                          (match_operand:DI 3 "general_operand" "")))]
17687   "TARGET_64BIT"
17688   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17690 (define_insn "x86_movdicc_0_m1_rex64"
17691   [(set (match_operand:DI 0 "register_operand" "=r")
17692         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17693           (const_int -1)
17694           (const_int 0)))
17695    (clobber (reg:CC FLAGS_REG))]
17696   "TARGET_64BIT"
17697   "sbb{q}\t%0, %0"
17698   ; Since we don't have the proper number of operands for an alu insn,
17699   ; fill in all the blanks.
17700   [(set_attr "type" "alu")
17701    (set_attr "pent_pair" "pu")
17702    (set_attr "memory" "none")
17703    (set_attr "imm_disp" "false")
17704    (set_attr "mode" "DI")
17705    (set_attr "length_immediate" "0")])
17707 (define_insn "movdicc_c_rex64"
17708   [(set (match_operand:DI 0 "register_operand" "=r,r")
17709         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17710                                 [(reg 17) (const_int 0)])
17711                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17712                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17713   "TARGET_64BIT && TARGET_CMOVE
17714    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17715   "@
17716    cmov%O2%C1\t{%2, %0|%0, %2}
17717    cmov%O2%c1\t{%3, %0|%0, %3}"
17718   [(set_attr "type" "icmov")
17719    (set_attr "mode" "DI")])
17721 (define_expand "movsicc"
17722   [(set (match_operand:SI 0 "register_operand" "")
17723         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17724                          (match_operand:SI 2 "general_operand" "")
17725                          (match_operand:SI 3 "general_operand" "")))]
17726   ""
17727   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17729 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17730 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17731 ;; So just document what we're doing explicitly.
17733 (define_insn "x86_movsicc_0_m1"
17734   [(set (match_operand:SI 0 "register_operand" "=r")
17735         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17736           (const_int -1)
17737           (const_int 0)))
17738    (clobber (reg:CC FLAGS_REG))]
17739   ""
17740   "sbb{l}\t%0, %0"
17741   ; Since we don't have the proper number of operands for an alu insn,
17742   ; fill in all the blanks.
17743   [(set_attr "type" "alu")
17744    (set_attr "pent_pair" "pu")
17745    (set_attr "memory" "none")
17746    (set_attr "imm_disp" "false")
17747    (set_attr "mode" "SI")
17748    (set_attr "length_immediate" "0")])
17750 (define_insn "*movsicc_noc"
17751   [(set (match_operand:SI 0 "register_operand" "=r,r")
17752         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17753                                 [(reg 17) (const_int 0)])
17754                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17755                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17756   "TARGET_CMOVE
17757    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17758   "@
17759    cmov%O2%C1\t{%2, %0|%0, %2}
17760    cmov%O2%c1\t{%3, %0|%0, %3}"
17761   [(set_attr "type" "icmov")
17762    (set_attr "mode" "SI")])
17764 (define_expand "movhicc"
17765   [(set (match_operand:HI 0 "register_operand" "")
17766         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17767                          (match_operand:HI 2 "general_operand" "")
17768                          (match_operand:HI 3 "general_operand" "")))]
17769   "TARGET_HIMODE_MATH"
17770   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17772 (define_insn "*movhicc_noc"
17773   [(set (match_operand:HI 0 "register_operand" "=r,r")
17774         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17775                                 [(reg 17) (const_int 0)])
17776                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17777                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17778   "TARGET_CMOVE
17779    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17780   "@
17781    cmov%O2%C1\t{%2, %0|%0, %2}
17782    cmov%O2%c1\t{%3, %0|%0, %3}"
17783   [(set_attr "type" "icmov")
17784    (set_attr "mode" "HI")])
17786 (define_expand "movqicc"
17787   [(set (match_operand:QI 0 "register_operand" "")
17788         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17789                          (match_operand:QI 2 "general_operand" "")
17790                          (match_operand:QI 3 "general_operand" "")))]
17791   "TARGET_QIMODE_MATH"
17792   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17794 (define_insn_and_split "*movqicc_noc"
17795   [(set (match_operand:QI 0 "register_operand" "=r,r")
17796         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17797                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17798                       (match_operand:QI 2 "register_operand" "r,0")
17799                       (match_operand:QI 3 "register_operand" "0,r")))]
17800   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17801   "#"
17802   "&& reload_completed"
17803   [(set (match_dup 0)
17804         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17805                       (match_dup 2)
17806                       (match_dup 3)))]
17807   "operands[0] = gen_lowpart (SImode, operands[0]);
17808    operands[2] = gen_lowpart (SImode, operands[2]);
17809    operands[3] = gen_lowpart (SImode, operands[3]);"
17810   [(set_attr "type" "icmov")
17811    (set_attr "mode" "SI")])
17813 (define_expand "movsfcc"
17814   [(set (match_operand:SF 0 "register_operand" "")
17815         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17816                          (match_operand:SF 2 "register_operand" "")
17817                          (match_operand:SF 3 "register_operand" "")))]
17818   "TARGET_CMOVE"
17819   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17821 (define_insn "*movsfcc_1"
17822   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17823         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17824                                 [(reg 17) (const_int 0)])
17825                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17826                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17827   "TARGET_CMOVE
17828    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17829   "@
17830    fcmov%F1\t{%2, %0|%0, %2}
17831    fcmov%f1\t{%3, %0|%0, %3}
17832    cmov%O2%C1\t{%2, %0|%0, %2}
17833    cmov%O2%c1\t{%3, %0|%0, %3}"
17834   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17835    (set_attr "mode" "SF,SF,SI,SI")])
17837 (define_expand "movdfcc"
17838   [(set (match_operand:DF 0 "register_operand" "")
17839         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17840                          (match_operand:DF 2 "register_operand" "")
17841                          (match_operand:DF 3 "register_operand" "")))]
17842   "TARGET_CMOVE"
17843   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17845 (define_insn "*movdfcc_1"
17846   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17847         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17848                                 [(reg 17) (const_int 0)])
17849                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17850                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17851   "!TARGET_64BIT && TARGET_CMOVE
17852    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17853   "@
17854    fcmov%F1\t{%2, %0|%0, %2}
17855    fcmov%f1\t{%3, %0|%0, %3}
17856    #
17857    #"
17858   [(set_attr "type" "fcmov,fcmov,multi,multi")
17859    (set_attr "mode" "DF")])
17861 (define_insn "*movdfcc_1_rex64"
17862   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17863         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17864                                 [(reg 17) (const_int 0)])
17865                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17866                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17867   "TARGET_64BIT && TARGET_CMOVE
17868    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17869   "@
17870    fcmov%F1\t{%2, %0|%0, %2}
17871    fcmov%f1\t{%3, %0|%0, %3}
17872    cmov%O2%C1\t{%2, %0|%0, %2}
17873    cmov%O2%c1\t{%3, %0|%0, %3}"
17874   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17875    (set_attr "mode" "DF")])
17877 (define_split
17878   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17879         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17880                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17881                       (match_operand:DF 2 "nonimmediate_operand" "")
17882                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17883   "!TARGET_64BIT && reload_completed"
17884   [(set (match_dup 2)
17885         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17886                       (match_dup 5)
17887                       (match_dup 7)))
17888    (set (match_dup 3)
17889         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17890                       (match_dup 6)
17891                       (match_dup 8)))]
17892   "split_di (operands+2, 1, operands+5, operands+6);
17893    split_di (operands+3, 1, operands+7, operands+8);
17894    split_di (operands, 1, operands+2, operands+3);")
17896 (define_expand "movxfcc"
17897   [(set (match_operand:XF 0 "register_operand" "")
17898         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17899                          (match_operand:XF 2 "register_operand" "")
17900                          (match_operand:XF 3 "register_operand" "")))]
17901   "TARGET_CMOVE"
17902   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17904 (define_insn "*movxfcc_1"
17905   [(set (match_operand:XF 0 "register_operand" "=f,f")
17906         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17907                                 [(reg 17) (const_int 0)])
17908                       (match_operand:XF 2 "register_operand" "f,0")
17909                       (match_operand:XF 3 "register_operand" "0,f")))]
17910   "TARGET_CMOVE"
17911   "@
17912    fcmov%F1\t{%2, %0|%0, %2}
17913    fcmov%f1\t{%3, %0|%0, %3}"
17914   [(set_attr "type" "fcmov")
17915    (set_attr "mode" "XF")])
17917 (define_expand "minsf3"
17918   [(parallel [
17919      (set (match_operand:SF 0 "register_operand" "")
17920           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17921                                (match_operand:SF 2 "nonimmediate_operand" ""))
17922                            (match_dup 1)
17923                            (match_dup 2)))
17924      (clobber (reg:CC FLAGS_REG))])]
17925   "TARGET_SSE"
17926   "")
17928 (define_insn "*minsf"
17929   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17930         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17931                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17932                          (match_dup 1)
17933                          (match_dup 2)))
17934    (clobber (reg:CC FLAGS_REG))]
17935   "TARGET_SSE && TARGET_IEEE_FP"
17936   "#")
17938 (define_insn "*minsf_nonieee"
17939   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17940         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17941                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17942                          (match_dup 1)
17943                          (match_dup 2)))
17944    (clobber (reg:CC FLAGS_REG))]
17945   "TARGET_SSE && !TARGET_IEEE_FP
17946    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17947   "#")
17949 (define_split
17950   [(set (match_operand:SF 0 "register_operand" "")
17951         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17952                              (match_operand:SF 2 "nonimmediate_operand" ""))
17953                          (match_operand:SF 3 "register_operand" "")
17954                          (match_operand:SF 4 "nonimmediate_operand" "")))
17955    (clobber (reg:CC FLAGS_REG))]
17956   "SSE_REG_P (operands[0]) && reload_completed
17957    && ((operands_match_p (operands[1], operands[3])
17958         && operands_match_p (operands[2], operands[4]))
17959        || (operands_match_p (operands[1], operands[4])
17960            && operands_match_p (operands[2], operands[3])))"
17961   [(set (match_dup 0)
17962         (if_then_else:SF (lt (match_dup 1)
17963                              (match_dup 2))
17964                          (match_dup 1)
17965                          (match_dup 2)))])
17967 ;; Conditional addition patterns
17968 (define_expand "addqicc"
17969   [(match_operand:QI 0 "register_operand" "")
17970    (match_operand 1 "comparison_operator" "")
17971    (match_operand:QI 2 "register_operand" "")
17972    (match_operand:QI 3 "const_int_operand" "")]
17973   ""
17974   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17976 (define_expand "addhicc"
17977   [(match_operand:HI 0 "register_operand" "")
17978    (match_operand 1 "comparison_operator" "")
17979    (match_operand:HI 2 "register_operand" "")
17980    (match_operand:HI 3 "const_int_operand" "")]
17981   ""
17982   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17984 (define_expand "addsicc"
17985   [(match_operand:SI 0 "register_operand" "")
17986    (match_operand 1 "comparison_operator" "")
17987    (match_operand:SI 2 "register_operand" "")
17988    (match_operand:SI 3 "const_int_operand" "")]
17989   ""
17990   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17992 (define_expand "adddicc"
17993   [(match_operand:DI 0 "register_operand" "")
17994    (match_operand 1 "comparison_operator" "")
17995    (match_operand:DI 2 "register_operand" "")
17996    (match_operand:DI 3 "const_int_operand" "")]
17997   "TARGET_64BIT"
17998   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18000 ;; We can't represent the LT test directly.  Do this by swapping the operands.
18002 (define_split
18003   [(set (match_operand:SF 0 "fp_register_operand" "")
18004         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
18005                              (match_operand:SF 2 "register_operand" ""))
18006                          (match_operand:SF 3 "register_operand" "")
18007                          (match_operand:SF 4 "register_operand" "")))
18008    (clobber (reg:CC FLAGS_REG))]
18009   "reload_completed
18010    && ((operands_match_p (operands[1], operands[3])
18011         && operands_match_p (operands[2], operands[4]))
18012        || (operands_match_p (operands[1], operands[4])
18013            && operands_match_p (operands[2], operands[3])))"
18014   [(set (reg:CCFP FLAGS_REG)
18015         (compare:CCFP (match_dup 2)
18016                       (match_dup 1)))
18017    (set (match_dup 0)
18018         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18019                          (match_dup 1)
18020                          (match_dup 2)))])
18022 (define_insn "*minsf_sse"
18023   [(set (match_operand:SF 0 "register_operand" "=x")
18024         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
18025                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18026                          (match_dup 1)
18027                          (match_dup 2)))]
18028   "TARGET_SSE && reload_completed"
18029   "minss\t{%2, %0|%0, %2}"
18030   [(set_attr "type" "sse")
18031    (set_attr "mode" "SF")])
18033 (define_expand "mindf3"
18034   [(parallel [
18035      (set (match_operand:DF 0 "register_operand" "")
18036           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18037                                (match_operand:DF 2 "nonimmediate_operand" ""))
18038                            (match_dup 1)
18039                            (match_dup 2)))
18040      (clobber (reg:CC FLAGS_REG))])]
18041   "TARGET_SSE2 && TARGET_SSE_MATH"
18042   "#")
18044 (define_insn "*mindf"
18045   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18046         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18047                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18048                          (match_dup 1)
18049                          (match_dup 2)))
18050    (clobber (reg:CC FLAGS_REG))]
18051   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
18052   "#")
18054 (define_insn "*mindf_nonieee"
18055   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18056         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18057                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18058                          (match_dup 1)
18059                          (match_dup 2)))
18060    (clobber (reg:CC FLAGS_REG))]
18061   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18062    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18063   "#")
18065 (define_split
18066   [(set (match_operand:DF 0 "register_operand" "")
18067         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18068                              (match_operand:DF 2 "nonimmediate_operand" ""))
18069                          (match_operand:DF 3 "register_operand" "")
18070                          (match_operand:DF 4 "nonimmediate_operand" "")))
18071    (clobber (reg:CC FLAGS_REG))]
18072   "SSE_REG_P (operands[0]) && reload_completed
18073    && ((operands_match_p (operands[1], operands[3])
18074         && operands_match_p (operands[2], operands[4]))
18075        || (operands_match_p (operands[1], operands[4])
18076            && operands_match_p (operands[2], operands[3])))"
18077   [(set (match_dup 0)
18078         (if_then_else:DF (lt (match_dup 1)
18079                              (match_dup 2))
18080                          (match_dup 1)
18081                          (match_dup 2)))])
18083 ;; We can't represent the LT test directly.  Do this by swapping the operands.
18084 (define_split
18085   [(set (match_operand:DF 0 "fp_register_operand" "")
18086         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18087                              (match_operand:DF 2 "register_operand" ""))
18088                          (match_operand:DF 3 "register_operand" "")
18089                          (match_operand:DF 4 "register_operand" "")))
18090    (clobber (reg:CC FLAGS_REG))]
18091   "reload_completed
18092    && ((operands_match_p (operands[1], operands[3])
18093         && operands_match_p (operands[2], operands[4]))
18094        || (operands_match_p (operands[1], operands[4])
18095            && operands_match_p (operands[2], operands[3])))"
18096   [(set (reg:CCFP FLAGS_REG)
18097         (compare:CCFP (match_dup 2)
18098                       (match_dup 1)))
18099    (set (match_dup 0)
18100         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18101                          (match_dup 1)
18102                          (match_dup 2)))])
18104 (define_insn "*mindf_sse"
18105   [(set (match_operand:DF 0 "register_operand" "=Y")
18106         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
18107                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18108                          (match_dup 1)
18109                          (match_dup 2)))]
18110   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18111   "minsd\t{%2, %0|%0, %2}"
18112   [(set_attr "type" "sse")
18113    (set_attr "mode" "DF")])
18115 (define_expand "maxsf3"
18116   [(parallel [
18117      (set (match_operand:SF 0 "register_operand" "")
18118           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18119                                (match_operand:SF 2 "nonimmediate_operand" ""))
18120                            (match_dup 1)
18121                            (match_dup 2)))
18122      (clobber (reg:CC FLAGS_REG))])]
18123   "TARGET_SSE"
18124   "#")
18126 (define_insn "*maxsf"
18127   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
18128         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
18129                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
18130                          (match_dup 1)
18131                          (match_dup 2)))
18132    (clobber (reg:CC FLAGS_REG))]
18133   "TARGET_SSE && TARGET_IEEE_FP"
18134   "#")
18136 (define_insn "*maxsf_nonieee"
18137   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
18138         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
18139                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
18140                          (match_dup 1)
18141                          (match_dup 2)))
18142    (clobber (reg:CC FLAGS_REG))]
18143   "TARGET_SSE && !TARGET_IEEE_FP
18144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18145   "#")
18147 (define_split
18148   [(set (match_operand:SF 0 "register_operand" "")
18149         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18150                              (match_operand:SF 2 "nonimmediate_operand" ""))
18151                          (match_operand:SF 3 "register_operand" "")
18152                          (match_operand:SF 4 "nonimmediate_operand" "")))
18153    (clobber (reg:CC FLAGS_REG))]
18154   "SSE_REG_P (operands[0]) && reload_completed
18155    && ((operands_match_p (operands[1], operands[3])
18156         && operands_match_p (operands[2], operands[4]))
18157        || (operands_match_p (operands[1], operands[4])
18158            && operands_match_p (operands[2], operands[3])))"
18159   [(set (match_dup 0)
18160         (if_then_else:SF (gt (match_dup 1)
18161                              (match_dup 2))
18162                          (match_dup 1)
18163                          (match_dup 2)))])
18165 (define_split
18166   [(set (match_operand:SF 0 "fp_register_operand" "")
18167         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18168                              (match_operand:SF 2 "register_operand" ""))
18169                          (match_operand:SF 3 "register_operand" "")
18170                          (match_operand:SF 4 "register_operand" "")))
18171    (clobber (reg:CC FLAGS_REG))]
18172   "reload_completed
18173    && ((operands_match_p (operands[1], operands[3])
18174         && operands_match_p (operands[2], operands[4]))
18175        || (operands_match_p (operands[1], operands[4])
18176            && operands_match_p (operands[2], operands[3])))"
18177   [(set (reg:CCFP FLAGS_REG)
18178         (compare:CCFP (match_dup 1)
18179                       (match_dup 2)))
18180    (set (match_dup 0)
18181         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18182                          (match_dup 1)
18183                          (match_dup 2)))])
18185 (define_insn "*maxsf_sse"
18186   [(set (match_operand:SF 0 "register_operand" "=x")
18187         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
18188                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18189                          (match_dup 1)
18190                          (match_dup 2)))]
18191   "TARGET_SSE && reload_completed"
18192   "maxss\t{%2, %0|%0, %2}"
18193   [(set_attr "type" "sse")
18194    (set_attr "mode" "SF")])
18196 (define_expand "maxdf3"
18197   [(parallel [
18198      (set (match_operand:DF 0 "register_operand" "")
18199           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18200                                (match_operand:DF 2 "nonimmediate_operand" ""))
18201                            (match_dup 1)
18202                            (match_dup 2)))
18203      (clobber (reg:CC FLAGS_REG))])]
18204   "TARGET_SSE2 && TARGET_SSE_MATH"
18205   "#")
18207 (define_insn "*maxdf"
18208   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18209         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18210                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18211                          (match_dup 1)
18212                          (match_dup 2)))
18213    (clobber (reg:CC FLAGS_REG))]
18214   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
18215   "#")
18217 (define_insn "*maxdf_nonieee"
18218   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18219         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18220                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18221                          (match_dup 1)
18222                          (match_dup 2)))
18223    (clobber (reg:CC FLAGS_REG))]
18224   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18225    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18226   "#")
18228 (define_split
18229   [(set (match_operand:DF 0 "register_operand" "")
18230         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18231                              (match_operand:DF 2 "nonimmediate_operand" ""))
18232                          (match_operand:DF 3 "register_operand" "")
18233                          (match_operand:DF 4 "nonimmediate_operand" "")))
18234    (clobber (reg:CC FLAGS_REG))]
18235   "SSE_REG_P (operands[0]) && reload_completed
18236    && ((operands_match_p (operands[1], operands[3])
18237         && operands_match_p (operands[2], operands[4]))
18238        || (operands_match_p (operands[1], operands[4])
18239            && operands_match_p (operands[2], operands[3])))"
18240   [(set (match_dup 0)
18241         (if_then_else:DF (gt (match_dup 1)
18242                              (match_dup 2))
18243                          (match_dup 1)
18244                          (match_dup 2)))])
18246 (define_split
18247   [(set (match_operand:DF 0 "fp_register_operand" "")
18248         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18249                              (match_operand:DF 2 "register_operand" ""))
18250                          (match_operand:DF 3 "register_operand" "")
18251                          (match_operand:DF 4 "register_operand" "")))
18252    (clobber (reg:CC FLAGS_REG))]
18253   "reload_completed
18254    && ((operands_match_p (operands[1], operands[3])
18255         && operands_match_p (operands[2], operands[4]))
18256        || (operands_match_p (operands[1], operands[4])
18257            && operands_match_p (operands[2], operands[3])))"
18258   [(set (reg:CCFP FLAGS_REG)
18259         (compare:CCFP (match_dup 1)
18260                       (match_dup 2)))
18261    (set (match_dup 0)
18262         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18263                          (match_dup 1)
18264                          (match_dup 2)))])
18266 (define_insn "*maxdf_sse"
18267   [(set (match_operand:DF 0 "register_operand" "=Y")
18268         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
18269                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18270                          (match_dup 1)
18271                          (match_dup 2)))]
18272   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18273   "maxsd\t{%2, %0|%0, %2}"
18274   [(set_attr "type" "sse")
18275    (set_attr "mode" "DF")])
18277 ;; Misc patterns (?)
18279 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18280 ;; Otherwise there will be nothing to keep
18281 ;; 
18282 ;; [(set (reg ebp) (reg esp))]
18283 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18284 ;;  (clobber (eflags)]
18285 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18287 ;; in proper program order.
18288 (define_insn "pro_epilogue_adjust_stack_1"
18289   [(set (match_operand:SI 0 "register_operand" "=r,r")
18290         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18291                  (match_operand:SI 2 "immediate_operand" "i,i")))
18292    (clobber (reg:CC FLAGS_REG))
18293    (clobber (mem:BLK (scratch)))]
18294   "!TARGET_64BIT"
18296   switch (get_attr_type (insn))
18297     {
18298     case TYPE_IMOV:
18299       return "mov{l}\t{%1, %0|%0, %1}";
18301     case TYPE_ALU:
18302       if (GET_CODE (operands[2]) == CONST_INT
18303           && (INTVAL (operands[2]) == 128
18304               || (INTVAL (operands[2]) < 0
18305                   && INTVAL (operands[2]) != -128)))
18306         {
18307           operands[2] = GEN_INT (-INTVAL (operands[2]));
18308           return "sub{l}\t{%2, %0|%0, %2}";
18309         }
18310       return "add{l}\t{%2, %0|%0, %2}";
18312     case TYPE_LEA:
18313       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18314       return "lea{l}\t{%a2, %0|%0, %a2}";
18316     default:
18317       abort ();
18318     }
18320   [(set (attr "type")
18321         (cond [(eq_attr "alternative" "0")
18322                  (const_string "alu")
18323                (match_operand:SI 2 "const0_operand" "")
18324                  (const_string "imov")
18325               ]
18326               (const_string "lea")))
18327    (set_attr "mode" "SI")])
18329 (define_insn "pro_epilogue_adjust_stack_rex64"
18330   [(set (match_operand:DI 0 "register_operand" "=r,r")
18331         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18332                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18333    (clobber (reg:CC FLAGS_REG))
18334    (clobber (mem:BLK (scratch)))]
18335   "TARGET_64BIT"
18337   switch (get_attr_type (insn))
18338     {
18339     case TYPE_IMOV:
18340       return "mov{q}\t{%1, %0|%0, %1}";
18342     case TYPE_ALU:
18343       if (GET_CODE (operands[2]) == CONST_INT
18344           /* Avoid overflows.  */
18345           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18346           && (INTVAL (operands[2]) == 128
18347               || (INTVAL (operands[2]) < 0
18348                   && INTVAL (operands[2]) != -128)))
18349         {
18350           operands[2] = GEN_INT (-INTVAL (operands[2]));
18351           return "sub{q}\t{%2, %0|%0, %2}";
18352         }
18353       return "add{q}\t{%2, %0|%0, %2}";
18355     case TYPE_LEA:
18356       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18357       return "lea{q}\t{%a2, %0|%0, %a2}";
18359     default:
18360       abort ();
18361     }
18363   [(set (attr "type")
18364         (cond [(eq_attr "alternative" "0")
18365                  (const_string "alu")
18366                (match_operand:DI 2 "const0_operand" "")
18367                  (const_string "imov")
18368               ]
18369               (const_string "lea")))
18370    (set_attr "mode" "DI")])
18372 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18373   [(set (match_operand:DI 0 "register_operand" "=r,r")
18374         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18375                  (match_operand:DI 3 "immediate_operand" "i,i")))
18376    (use (match_operand:DI 2 "register_operand" "r,r"))
18377    (clobber (reg:CC FLAGS_REG))
18378    (clobber (mem:BLK (scratch)))]
18379   "TARGET_64BIT"
18381   switch (get_attr_type (insn))
18382     {
18383     case TYPE_ALU:
18384       return "add{q}\t{%2, %0|%0, %2}";
18386     case TYPE_LEA:
18387       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18388       return "lea{q}\t{%a2, %0|%0, %a2}";
18390     default:
18391       abort ();
18392     }
18394   [(set_attr "type" "alu,lea")
18395    (set_attr "mode" "DI")])
18397 ;; Placeholder for the conditional moves.  This one is split either to SSE
18398 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18399 ;; fact is that compares supported by the cmp??ss instructions are exactly
18400 ;; swapped of those supported by cmove sequence.
18401 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18402 ;; supported by i387 comparisons and we do need to emit two conditional moves
18403 ;; in tandem.
18405 (define_insn "sse_movsfcc"
18406   [(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")
18407         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18408                         [(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")
18409                          (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")])
18410                       (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")
18411                       (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")))
18412    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18413    (clobber (reg:CC FLAGS_REG))]
18414   "TARGET_SSE
18415    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18416    /* Avoid combine from being smart and converting min/max
18417       instruction patterns into conditional moves.  */
18418    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18419         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18420        || !rtx_equal_p (operands[4], operands[2])
18421        || !rtx_equal_p (operands[5], operands[3]))
18422    && (!TARGET_IEEE_FP
18423        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18424   "#")
18426 (define_insn "sse_movsfcc_eq"
18427   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18428         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18429                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18430                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18431                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18432    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18433    (clobber (reg:CC FLAGS_REG))]
18434   "TARGET_SSE
18435    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18436   "#")
18438 (define_insn "sse_movdfcc"
18439   [(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")
18440         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18441                         [(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")
18442                          (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")])
18443                       (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")
18444                       (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")))
18445    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18446    (clobber (reg:CC FLAGS_REG))]
18447   "TARGET_SSE2
18448    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18449    /* Avoid combine from being smart and converting min/max
18450       instruction patterns into conditional moves.  */
18451    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18452         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18453        || !rtx_equal_p (operands[4], operands[2])
18454        || !rtx_equal_p (operands[5], operands[3]))
18455    && (!TARGET_IEEE_FP
18456        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18457   "#")
18459 (define_insn "sse_movdfcc_eq"
18460   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18461         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18462                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18463                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18464                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18465    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18466    (clobber (reg:CC FLAGS_REG))]
18467   "TARGET_SSE
18468    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18469   "#")
18471 ;; For non-sse moves just expand the usual cmove sequence.
18472 (define_split
18473   [(set (match_operand 0 "register_operand" "")
18474         (if_then_else (match_operator 1 "comparison_operator"
18475                         [(match_operand 4 "nonimmediate_operand" "")
18476                          (match_operand 5 "register_operand" "")])
18477                       (match_operand 2 "nonimmediate_operand" "")
18478                       (match_operand 3 "nonimmediate_operand" "")))
18479    (clobber (match_operand 6 "" ""))
18480    (clobber (reg:CC FLAGS_REG))]
18481   "!SSE_REG_P (operands[0]) && reload_completed
18482    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18483   [(const_int 0)]
18485    ix86_compare_op0 = operands[5];
18486    ix86_compare_op1 = operands[4];
18487    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18488                                  VOIDmode, operands[5], operands[4]);
18489    ix86_expand_fp_movcc (operands);
18490    DONE;
18493 ;; Split SSE based conditional move into sequence:
18494 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18495 ;; and   op2, op0   -  zero op2 if comparison was false
18496 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18497 ;; or    op2, op0   -  get the nonzero one into the result.
18498 (define_split
18499   [(set (match_operand:SF 0 "register_operand" "")
18500         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18501                         [(match_operand:SF 4 "register_operand" "")
18502                          (match_operand:SF 5 "nonimmediate_operand" "")])
18503                       (match_operand:SF 2 "register_operand" "")
18504                       (match_operand:SF 3 "register_operand" "")))
18505    (clobber (match_operand 6 "" ""))
18506    (clobber (reg:CC FLAGS_REG))]
18507   "SSE_REG_P (operands[0]) && reload_completed"
18508   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18509    (set (match_dup 2) (and:V4SF (match_dup 2)
18510                                 (match_dup 8)))
18511    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18512                                           (match_dup 3)))
18513    (set (match_dup 0) (ior:V4SF (match_dup 6)
18514                                 (match_dup 7)))]
18516   /* If op2 == op3, op3 would be clobbered before it is used.  */
18517   if (operands_match_p (operands[2], operands[3]))
18518     {
18519       emit_move_insn (operands[0], operands[2]);
18520       DONE;
18521     }
18523   PUT_MODE (operands[1], GET_MODE (operands[0]));
18524   if (operands_match_p (operands[0], operands[4]))
18525     operands[6] = operands[4], operands[7] = operands[2];
18526   else
18527     operands[6] = operands[2], operands[7] = operands[4];
18528   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18529   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18530   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18531   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18532   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18533   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18536 (define_split
18537   [(set (match_operand:DF 0 "register_operand" "")
18538         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18539                         [(match_operand:DF 4 "register_operand" "")
18540                          (match_operand:DF 5 "nonimmediate_operand" "")])
18541                       (match_operand:DF 2 "register_operand" "")
18542                       (match_operand:DF 3 "register_operand" "")))
18543    (clobber (match_operand 6 "" ""))
18544    (clobber (reg:CC FLAGS_REG))]
18545   "SSE_REG_P (operands[0]) && reload_completed"
18546   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18547    (set (match_dup 2) (and:V2DF (match_dup 2)
18548                                 (match_dup 8)))
18549    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18550                                           (match_dup 3)))
18551    (set (match_dup 0) (ior:V2DF (match_dup 6)
18552                                 (match_dup 7)))]
18554   if (GET_MODE (operands[2]) == DFmode
18555       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18556     {
18557       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18558       emit_insn (gen_sse2_unpcklpd (op, op, op));
18559       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18560       emit_insn (gen_sse2_unpcklpd (op, op, op));
18561     }
18563   /* If op2 == op3, op3 would be clobbered before it is used.  */
18564   if (operands_match_p (operands[2], operands[3]))
18565     {
18566       emit_move_insn (operands[0], operands[2]);
18567       DONE;
18568     }
18570   PUT_MODE (operands[1], GET_MODE (operands[0]));
18571   if (operands_match_p (operands[0], operands[4]))
18572     operands[6] = operands[4], operands[7] = operands[2];
18573   else
18574     operands[6] = operands[2], operands[7] = operands[4];
18575   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18576   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18577   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18578   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18579   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18580   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18583 ;; Special case of conditional move we can handle effectively.
18584 ;; Do not brother with the integer/floating point case, since these are
18585 ;; bot considerably slower, unlike in the generic case.
18586 (define_insn "*sse_movsfcc_const0_1"
18587   [(set (match_operand:SF 0 "register_operand" "=&x")
18588         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18589                         [(match_operand:SF 4 "register_operand" "0")
18590                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18591                       (match_operand:SF 2 "register_operand" "x")
18592                       (match_operand:SF 3 "const0_operand" "X")))]
18593   "TARGET_SSE"
18594   "#")
18596 (define_insn "*sse_movsfcc_const0_2"
18597   [(set (match_operand:SF 0 "register_operand" "=&x")
18598         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18599                         [(match_operand:SF 4 "register_operand" "0")
18600                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18601                       (match_operand:SF 2 "const0_operand" "X")
18602                       (match_operand:SF 3 "register_operand" "x")))]
18603   "TARGET_SSE"
18604   "#")
18606 (define_insn "*sse_movsfcc_const0_3"
18607   [(set (match_operand:SF 0 "register_operand" "=&x")
18608         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18609                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18610                          (match_operand:SF 5 "register_operand" "0")])
18611                       (match_operand:SF 2 "register_operand" "x")
18612                       (match_operand:SF 3 "const0_operand" "X")))]
18613   "TARGET_SSE"
18614   "#")
18616 (define_insn "*sse_movsfcc_const0_4"
18617   [(set (match_operand:SF 0 "register_operand" "=&x")
18618         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18619                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18620                          (match_operand:SF 5 "register_operand" "0")])
18621                       (match_operand:SF 2 "const0_operand" "X")
18622                       (match_operand:SF 3 "register_operand" "x")))]
18623   "TARGET_SSE"
18624   "#")
18626 (define_insn "*sse_movdfcc_const0_1"
18627   [(set (match_operand:DF 0 "register_operand" "=&Y")
18628         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18629                         [(match_operand:DF 4 "register_operand" "0")
18630                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18631                       (match_operand:DF 2 "register_operand" "Y")
18632                       (match_operand:DF 3 "const0_operand" "X")))]
18633   "TARGET_SSE2"
18634   "#")
18636 (define_insn "*sse_movdfcc_const0_2"
18637   [(set (match_operand:DF 0 "register_operand" "=&Y")
18638         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18639                         [(match_operand:DF 4 "register_operand" "0")
18640                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18641                       (match_operand:DF 2 "const0_operand" "X")
18642                       (match_operand:DF 3 "register_operand" "Y")))]
18643   "TARGET_SSE2"
18644   "#")
18646 (define_insn "*sse_movdfcc_const0_3"
18647   [(set (match_operand:DF 0 "register_operand" "=&Y")
18648         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18649                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18650                          (match_operand:DF 5 "register_operand" "0")])
18651                       (match_operand:DF 2 "register_operand" "Y")
18652                       (match_operand:DF 3 "const0_operand" "X")))]
18653   "TARGET_SSE2"
18654   "#")
18656 (define_insn "*sse_movdfcc_const0_4"
18657   [(set (match_operand:DF 0 "register_operand" "=&Y")
18658         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18659                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18660                          (match_operand:DF 5 "register_operand" "0")])
18661                       (match_operand:DF 2 "const0_operand" "X")
18662                       (match_operand:DF 3 "register_operand" "Y")))]
18663   "TARGET_SSE2"
18664   "#")
18666 (define_split
18667   [(set (match_operand:SF 0 "register_operand" "")
18668         (if_then_else (match_operator 1 "comparison_operator"
18669                         [(match_operand:SF 4 "nonimmediate_operand" "")
18670                          (match_operand:SF 5 "nonimmediate_operand" "")])
18671                       (match_operand:SF 2 "nonmemory_operand" "")
18672                       (match_operand:SF 3 "nonmemory_operand" "")))]
18673   "SSE_REG_P (operands[0]) && reload_completed
18674    && (const0_operand (operands[2], GET_MODE (operands[0]))
18675        || const0_operand (operands[3], GET_MODE (operands[0])))"
18676   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18677    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18679   PUT_MODE (operands[1], GET_MODE (operands[0]));
18680   if (!sse_comparison_operator (operands[1], VOIDmode)
18681       || !rtx_equal_p (operands[0], operands[4]))
18682     {
18683       rtx tmp = operands[5];
18684       operands[5] = operands[4];
18685       operands[4] = tmp;
18686       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18687     }
18688   if (!rtx_equal_p (operands[0], operands[4]))
18689     abort ();
18690   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18691   if (const0_operand (operands[2], GET_MODE (operands[2])))
18692     {
18693       operands[7] = operands[3];
18694       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18695     }
18696   else
18697     {
18698       operands[7] = operands[2];
18699       operands[6] = operands[8];
18700     }
18701   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18704 (define_split
18705   [(set (match_operand:DF 0 "register_operand" "")
18706         (if_then_else (match_operator 1 "comparison_operator"
18707                         [(match_operand:DF 4 "nonimmediate_operand" "")
18708                          (match_operand:DF 5 "nonimmediate_operand" "")])
18709                       (match_operand:DF 2 "nonmemory_operand" "")
18710                       (match_operand:DF 3 "nonmemory_operand" "")))]
18711   "SSE_REG_P (operands[0]) && reload_completed
18712    && (const0_operand (operands[2], GET_MODE (operands[0]))
18713        || const0_operand (operands[3], GET_MODE (operands[0])))"
18714   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18715    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18717   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18718       && GET_MODE (operands[2]) == DFmode)
18719     {
18720       if (REG_P (operands[2]))
18721         {
18722           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18723           emit_insn (gen_sse2_unpcklpd (op, op, op));
18724         }
18725       if (REG_P (operands[3]))
18726         {
18727           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18728           emit_insn (gen_sse2_unpcklpd (op, op, op));
18729         }
18730     }
18731   PUT_MODE (operands[1], GET_MODE (operands[0]));
18732   if (!sse_comparison_operator (operands[1], VOIDmode)
18733       || !rtx_equal_p (operands[0], operands[4]))
18734     {
18735       rtx tmp = operands[5];
18736       operands[5] = operands[4];
18737       operands[4] = tmp;
18738       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18739     }
18740   if (!rtx_equal_p (operands[0], operands[4]))
18741     abort ();
18742   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18743   if (const0_operand (operands[2], GET_MODE (operands[2])))
18744     {
18745       operands[7] = operands[3];
18746       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18747     }
18748   else
18749     {
18750       operands[7] = operands[2];
18751       operands[6] = operands[8];
18752     }
18753   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18756 (define_expand "allocate_stack_worker"
18757   [(match_operand:SI 0 "register_operand" "")]
18758   "TARGET_STACK_PROBE"
18760   if (reload_completed)
18761     {
18762       if (TARGET_64BIT)
18763         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18764       else
18765         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18766     }
18767   else
18768     {
18769       if (TARGET_64BIT)
18770         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18771       else
18772         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18773     }
18774   DONE;
18777 (define_insn "allocate_stack_worker_1"
18778   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18779     UNSPECV_STACK_PROBE)
18780    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18781    (clobber (match_scratch:SI 1 "=0"))
18782    (clobber (reg:CC FLAGS_REG))]
18783   "!TARGET_64BIT && TARGET_STACK_PROBE"
18784   "call\t__alloca"
18785   [(set_attr "type" "multi")
18786    (set_attr "length" "5")])
18788 (define_expand "allocate_stack_worker_postreload"
18789   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18790                                     UNSPECV_STACK_PROBE)
18791               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18792               (clobber (match_dup 0))
18793               (clobber (reg:CC FLAGS_REG))])]
18794   ""
18795   "")
18797 (define_insn "allocate_stack_worker_rex64"
18798   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18799     UNSPECV_STACK_PROBE)
18800    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18801    (clobber (match_scratch:DI 1 "=0"))
18802    (clobber (reg:CC FLAGS_REG))]
18803   "TARGET_64BIT && TARGET_STACK_PROBE"
18804   "call\t__alloca"
18805   [(set_attr "type" "multi")
18806    (set_attr "length" "5")])
18808 (define_expand "allocate_stack_worker_rex64_postreload"
18809   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18810                                     UNSPECV_STACK_PROBE)
18811               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18812               (clobber (match_dup 0))
18813               (clobber (reg:CC FLAGS_REG))])]
18814   ""
18815   "")
18817 (define_expand "allocate_stack"
18818   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18819                    (minus:SI (reg:SI SP_REG)
18820                              (match_operand:SI 1 "general_operand" "")))
18821               (clobber (reg:CC FLAGS_REG))])
18822    (parallel [(set (reg:SI SP_REG)
18823                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18824               (clobber (reg:CC FLAGS_REG))])]
18825   "TARGET_STACK_PROBE"
18827 #ifdef CHECK_STACK_LIMIT
18828   if (GET_CODE (operands[1]) == CONST_INT
18829       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18830     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18831                            operands[1]));
18832   else 
18833 #endif
18834     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18835                                                             operands[1])));
18837   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18838   DONE;
18841 (define_expand "builtin_setjmp_receiver"
18842   [(label_ref (match_operand 0 "" ""))]
18843   "!TARGET_64BIT && flag_pic"
18845   emit_insn (gen_set_got (pic_offset_table_rtx));
18846   DONE;
18849 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18851 (define_split
18852   [(set (match_operand 0 "register_operand" "")
18853         (match_operator 3 "promotable_binary_operator"
18854            [(match_operand 1 "register_operand" "")
18855             (match_operand 2 "aligned_operand" "")]))
18856    (clobber (reg:CC FLAGS_REG))]
18857   "! TARGET_PARTIAL_REG_STALL && reload_completed
18858    && ((GET_MODE (operands[0]) == HImode 
18859         && ((!optimize_size && !TARGET_FAST_PREFIX)
18860             || GET_CODE (operands[2]) != CONST_INT
18861             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18862        || (GET_MODE (operands[0]) == QImode 
18863            && (TARGET_PROMOTE_QImode || optimize_size)))"
18864   [(parallel [(set (match_dup 0)
18865                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18866               (clobber (reg:CC FLAGS_REG))])]
18867   "operands[0] = gen_lowpart (SImode, operands[0]);
18868    operands[1] = gen_lowpart (SImode, operands[1]);
18869    if (GET_CODE (operands[3]) != ASHIFT)
18870      operands[2] = gen_lowpart (SImode, operands[2]);
18871    PUT_MODE (operands[3], SImode);")
18873 ; Promote the QImode tests, as i386 has encoding of the AND
18874 ; instruction with 32-bit sign-extended immediate and thus the
18875 ; instruction size is unchanged, except in the %eax case for
18876 ; which it is increased by one byte, hence the ! optimize_size.
18877 (define_split
18878   [(set (reg 17)
18879         (compare (and (match_operand 1 "aligned_operand" "")
18880                       (match_operand 2 "const_int_operand" ""))
18881                  (const_int 0)))
18882    (set (match_operand 0 "register_operand" "")
18883         (and (match_dup 1) (match_dup 2)))]
18884   "! TARGET_PARTIAL_REG_STALL && reload_completed
18885    /* Ensure that the operand will remain sign-extended immediate.  */
18886    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18887    && ! optimize_size
18888    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18889        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18890   [(parallel [(set (reg:CCNO FLAGS_REG)
18891                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18892                                  (const_int 0)))
18893               (set (match_dup 0)
18894                    (and:SI (match_dup 1) (match_dup 2)))])]
18895   "operands[2]
18896      = gen_int_mode (INTVAL (operands[2])
18897                      & GET_MODE_MASK (GET_MODE (operands[0])),
18898                      SImode);
18899    operands[0] = gen_lowpart (SImode, operands[0]);
18900    operands[1] = gen_lowpart (SImode, operands[1]);")
18902 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18903 ; the TEST instruction with 32-bit sign-extended immediate and thus
18904 ; the instruction size would at least double, which is not what we
18905 ; want even with ! optimize_size.
18906 (define_split
18907   [(set (reg 17)
18908         (compare (and (match_operand:HI 0 "aligned_operand" "")
18909                       (match_operand:HI 1 "const_int_operand" ""))
18910                  (const_int 0)))]
18911   "! TARGET_PARTIAL_REG_STALL && reload_completed
18912    /* Ensure that the operand will remain sign-extended immediate.  */
18913    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18914    && ! TARGET_FAST_PREFIX
18915    && ! optimize_size"
18916   [(set (reg:CCNO FLAGS_REG)
18917         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18918                       (const_int 0)))]
18919   "operands[1]
18920      = gen_int_mode (INTVAL (operands[1])
18921                      & GET_MODE_MASK (GET_MODE (operands[0])),
18922                      SImode);
18923    operands[0] = gen_lowpart (SImode, operands[0]);")
18925 (define_split
18926   [(set (match_operand 0 "register_operand" "")
18927         (neg (match_operand 1 "register_operand" "")))
18928    (clobber (reg:CC FLAGS_REG))]
18929   "! TARGET_PARTIAL_REG_STALL && reload_completed
18930    && (GET_MODE (operands[0]) == HImode
18931        || (GET_MODE (operands[0]) == QImode 
18932            && (TARGET_PROMOTE_QImode || optimize_size)))"
18933   [(parallel [(set (match_dup 0)
18934                    (neg:SI (match_dup 1)))
18935               (clobber (reg:CC FLAGS_REG))])]
18936   "operands[0] = gen_lowpart (SImode, operands[0]);
18937    operands[1] = gen_lowpart (SImode, operands[1]);")
18939 (define_split
18940   [(set (match_operand 0 "register_operand" "")
18941         (not (match_operand 1 "register_operand" "")))]
18942   "! TARGET_PARTIAL_REG_STALL && reload_completed
18943    && (GET_MODE (operands[0]) == HImode
18944        || (GET_MODE (operands[0]) == QImode 
18945            && (TARGET_PROMOTE_QImode || optimize_size)))"
18946   [(set (match_dup 0)
18947         (not:SI (match_dup 1)))]
18948   "operands[0] = gen_lowpart (SImode, operands[0]);
18949    operands[1] = gen_lowpart (SImode, operands[1]);")
18951 (define_split 
18952   [(set (match_operand 0 "register_operand" "")
18953         (if_then_else (match_operator 1 "comparison_operator" 
18954                                 [(reg 17) (const_int 0)])
18955                       (match_operand 2 "register_operand" "")
18956                       (match_operand 3 "register_operand" "")))]
18957   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18958    && (GET_MODE (operands[0]) == HImode
18959        || (GET_MODE (operands[0]) == QImode 
18960            && (TARGET_PROMOTE_QImode || optimize_size)))"
18961   [(set (match_dup 0)
18962         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18963   "operands[0] = gen_lowpart (SImode, operands[0]);
18964    operands[2] = gen_lowpart (SImode, operands[2]);
18965    operands[3] = gen_lowpart (SImode, operands[3]);")
18966                         
18968 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18969 ;; transform a complex memory operation into two memory to register operations.
18971 ;; Don't push memory operands
18972 (define_peephole2
18973   [(set (match_operand:SI 0 "push_operand" "")
18974         (match_operand:SI 1 "memory_operand" ""))
18975    (match_scratch:SI 2 "r")]
18976   "! optimize_size && ! TARGET_PUSH_MEMORY"
18977   [(set (match_dup 2) (match_dup 1))
18978    (set (match_dup 0) (match_dup 2))]
18979   "")
18981 (define_peephole2
18982   [(set (match_operand:DI 0 "push_operand" "")
18983         (match_operand:DI 1 "memory_operand" ""))
18984    (match_scratch:DI 2 "r")]
18985   "! optimize_size && ! TARGET_PUSH_MEMORY"
18986   [(set (match_dup 2) (match_dup 1))
18987    (set (match_dup 0) (match_dup 2))]
18988   "")
18990 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18991 ;; SImode pushes.
18992 (define_peephole2
18993   [(set (match_operand:SF 0 "push_operand" "")
18994         (match_operand:SF 1 "memory_operand" ""))
18995    (match_scratch:SF 2 "r")]
18996   "! optimize_size && ! TARGET_PUSH_MEMORY"
18997   [(set (match_dup 2) (match_dup 1))
18998    (set (match_dup 0) (match_dup 2))]
18999   "")
19001 (define_peephole2
19002   [(set (match_operand:HI 0 "push_operand" "")
19003         (match_operand:HI 1 "memory_operand" ""))
19004    (match_scratch:HI 2 "r")]
19005   "! optimize_size && ! TARGET_PUSH_MEMORY"
19006   [(set (match_dup 2) (match_dup 1))
19007    (set (match_dup 0) (match_dup 2))]
19008   "")
19010 (define_peephole2
19011   [(set (match_operand:QI 0 "push_operand" "")
19012         (match_operand:QI 1 "memory_operand" ""))
19013    (match_scratch:QI 2 "q")]
19014   "! optimize_size && ! TARGET_PUSH_MEMORY"
19015   [(set (match_dup 2) (match_dup 1))
19016    (set (match_dup 0) (match_dup 2))]
19017   "")
19019 ;; Don't move an immediate directly to memory when the instruction
19020 ;; gets too big.
19021 (define_peephole2
19022   [(match_scratch:SI 1 "r")
19023    (set (match_operand:SI 0 "memory_operand" "")
19024         (const_int 0))]
19025   "! optimize_size
19026    && ! TARGET_USE_MOV0
19027    && TARGET_SPLIT_LONG_MOVES
19028    && get_attr_length (insn) >= ix86_cost->large_insn
19029    && peep2_regno_dead_p (0, FLAGS_REG)"
19030   [(parallel [(set (match_dup 1) (const_int 0))
19031               (clobber (reg:CC FLAGS_REG))])
19032    (set (match_dup 0) (match_dup 1))]
19033   "")
19035 (define_peephole2
19036   [(match_scratch:HI 1 "r")
19037    (set (match_operand:HI 0 "memory_operand" "")
19038         (const_int 0))]
19039   "! optimize_size
19040    && ! TARGET_USE_MOV0
19041    && TARGET_SPLIT_LONG_MOVES
19042    && get_attr_length (insn) >= ix86_cost->large_insn
19043    && peep2_regno_dead_p (0, FLAGS_REG)"
19044   [(parallel [(set (match_dup 2) (const_int 0))
19045               (clobber (reg:CC FLAGS_REG))])
19046    (set (match_dup 0) (match_dup 1))]
19047   "operands[2] = gen_lowpart (SImode, operands[1]);")
19049 (define_peephole2
19050   [(match_scratch:QI 1 "q")
19051    (set (match_operand:QI 0 "memory_operand" "")
19052         (const_int 0))]
19053   "! optimize_size
19054    && ! TARGET_USE_MOV0
19055    && TARGET_SPLIT_LONG_MOVES
19056    && get_attr_length (insn) >= ix86_cost->large_insn
19057    && peep2_regno_dead_p (0, FLAGS_REG)"
19058   [(parallel [(set (match_dup 2) (const_int 0))
19059               (clobber (reg:CC FLAGS_REG))])
19060    (set (match_dup 0) (match_dup 1))]
19061   "operands[2] = gen_lowpart (SImode, operands[1]);")
19063 (define_peephole2
19064   [(match_scratch:SI 2 "r")
19065    (set (match_operand:SI 0 "memory_operand" "")
19066         (match_operand:SI 1 "immediate_operand" ""))]
19067   "! optimize_size
19068    && get_attr_length (insn) >= ix86_cost->large_insn
19069    && TARGET_SPLIT_LONG_MOVES"
19070   [(set (match_dup 2) (match_dup 1))
19071    (set (match_dup 0) (match_dup 2))]
19072   "")
19074 (define_peephole2
19075   [(match_scratch:HI 2 "r")
19076    (set (match_operand:HI 0 "memory_operand" "")
19077         (match_operand:HI 1 "immediate_operand" ""))]
19078   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19079   && TARGET_SPLIT_LONG_MOVES"
19080   [(set (match_dup 2) (match_dup 1))
19081    (set (match_dup 0) (match_dup 2))]
19082   "")
19084 (define_peephole2
19085   [(match_scratch:QI 2 "q")
19086    (set (match_operand:QI 0 "memory_operand" "")
19087         (match_operand:QI 1 "immediate_operand" ""))]
19088   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19089   && TARGET_SPLIT_LONG_MOVES"
19090   [(set (match_dup 2) (match_dup 1))
19091    (set (match_dup 0) (match_dup 2))]
19092   "")
19094 ;; Don't compare memory with zero, load and use a test instead.
19095 (define_peephole2
19096   [(set (reg 17)
19097         (compare (match_operand:SI 0 "memory_operand" "")
19098                  (const_int 0)))
19099    (match_scratch:SI 3 "r")]
19100   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19101   [(set (match_dup 3) (match_dup 0))
19102    (set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
19103   "")
19105 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19106 ;; Don't split NOTs with a displacement operand, because resulting XOR
19107 ;; will not be pairable anyway.
19109 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19110 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19111 ;; so this split helps here as well.
19113 ;; Note: Can't do this as a regular split because we can't get proper
19114 ;; lifetime information then.
19116 (define_peephole2
19117   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19118         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19119   "!optimize_size
19120    && peep2_regno_dead_p (0, FLAGS_REG)
19121    && ((TARGET_PENTIUM 
19122         && (GET_CODE (operands[0]) != MEM
19123             || !memory_displacement_operand (operands[0], SImode)))
19124        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19125   [(parallel [(set (match_dup 0)
19126                    (xor:SI (match_dup 1) (const_int -1)))
19127               (clobber (reg:CC FLAGS_REG))])]
19128   "")
19130 (define_peephole2
19131   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19132         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19133   "!optimize_size
19134    && peep2_regno_dead_p (0, FLAGS_REG)
19135    && ((TARGET_PENTIUM 
19136         && (GET_CODE (operands[0]) != MEM
19137             || !memory_displacement_operand (operands[0], HImode)))
19138        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19139   [(parallel [(set (match_dup 0)
19140                    (xor:HI (match_dup 1) (const_int -1)))
19141               (clobber (reg:CC FLAGS_REG))])]
19142   "")
19144 (define_peephole2
19145   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19146         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19147   "!optimize_size
19148    && peep2_regno_dead_p (0, FLAGS_REG)
19149    && ((TARGET_PENTIUM 
19150         && (GET_CODE (operands[0]) != MEM
19151             || !memory_displacement_operand (operands[0], QImode)))
19152        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19153   [(parallel [(set (match_dup 0)
19154                    (xor:QI (match_dup 1) (const_int -1)))
19155               (clobber (reg:CC FLAGS_REG))])]
19156   "")
19158 ;; Non pairable "test imm, reg" instructions can be translated to
19159 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19160 ;; byte opcode instead of two, have a short form for byte operands),
19161 ;; so do it for other CPUs as well.  Given that the value was dead,
19162 ;; this should not create any new dependencies.  Pass on the sub-word
19163 ;; versions if we're concerned about partial register stalls.
19165 (define_peephole2
19166   [(set (reg 17)
19167         (compare (and:SI (match_operand:SI 0 "register_operand" "")
19168                          (match_operand:SI 1 "immediate_operand" ""))
19169                  (const_int 0)))]
19170   "ix86_match_ccmode (insn, CCNOmode)
19171    && (true_regnum (operands[0]) != 0
19172        || (GET_CODE (operands[1]) == CONST_INT
19173            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
19174    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19175   [(parallel
19176      [(set (reg:CCNO FLAGS_REG)
19177            (compare:CCNO (and:SI (match_dup 0)
19178                                  (match_dup 1))
19179                          (const_int 0)))
19180       (set (match_dup 0)
19181            (and:SI (match_dup 0) (match_dup 1)))])]
19182   "")
19184 ;; We don't need to handle HImode case, because it will be promoted to SImode
19185 ;; on ! TARGET_PARTIAL_REG_STALL
19187 (define_peephole2
19188   [(set (reg 17)
19189         (compare (and:QI (match_operand:QI 0 "register_operand" "")
19190                          (match_operand:QI 1 "immediate_operand" ""))
19191                  (const_int 0)))]
19192   "! TARGET_PARTIAL_REG_STALL
19193    && ix86_match_ccmode (insn, CCNOmode)
19194    && true_regnum (operands[0]) != 0
19195    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19196   [(parallel
19197      [(set (reg:CCNO FLAGS_REG)
19198            (compare:CCNO (and:QI (match_dup 0)
19199                                  (match_dup 1))
19200                          (const_int 0)))
19201       (set (match_dup 0)
19202            (and:QI (match_dup 0) (match_dup 1)))])]
19203   "")
19205 (define_peephole2
19206   [(set (reg 17)
19207         (compare
19208           (and:SI
19209             (zero_extract:SI
19210               (match_operand 0 "ext_register_operand" "")
19211               (const_int 8)
19212               (const_int 8))
19213             (match_operand 1 "const_int_operand" ""))
19214           (const_int 0)))]
19215   "! TARGET_PARTIAL_REG_STALL
19216    && ix86_match_ccmode (insn, CCNOmode)
19217    && true_regnum (operands[0]) != 0
19218    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19219   [(parallel [(set (reg:CCNO FLAGS_REG)
19220                    (compare:CCNO
19221                        (and:SI
19222                          (zero_extract:SI
19223                          (match_dup 0)
19224                          (const_int 8)
19225                          (const_int 8))
19226                         (match_dup 1))
19227                    (const_int 0)))
19228               (set (zero_extract:SI (match_dup 0)
19229                                     (const_int 8)
19230                                     (const_int 8))
19231                    (and:SI 
19232                      (zero_extract:SI
19233                        (match_dup 0)
19234                        (const_int 8)
19235                        (const_int 8))
19236                      (match_dup 1)))])]
19237   "")
19239 ;; Don't do logical operations with memory inputs.
19240 (define_peephole2
19241   [(match_scratch:SI 2 "r")
19242    (parallel [(set (match_operand:SI 0 "register_operand" "")
19243                    (match_operator:SI 3 "arith_or_logical_operator"
19244                      [(match_dup 0)
19245                       (match_operand:SI 1 "memory_operand" "")]))
19246               (clobber (reg:CC FLAGS_REG))])]
19247   "! optimize_size && ! TARGET_READ_MODIFY"
19248   [(set (match_dup 2) (match_dup 1))
19249    (parallel [(set (match_dup 0)
19250                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19251               (clobber (reg:CC FLAGS_REG))])]
19252   "")
19254 (define_peephole2
19255   [(match_scratch:SI 2 "r")
19256    (parallel [(set (match_operand:SI 0 "register_operand" "")
19257                    (match_operator:SI 3 "arith_or_logical_operator"
19258                      [(match_operand:SI 1 "memory_operand" "")
19259                       (match_dup 0)]))
19260               (clobber (reg:CC FLAGS_REG))])]
19261   "! optimize_size && ! TARGET_READ_MODIFY"
19262   [(set (match_dup 2) (match_dup 1))
19263    (parallel [(set (match_dup 0)
19264                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19265               (clobber (reg:CC FLAGS_REG))])]
19266   "")
19268 ; Don't do logical operations with memory outputs
19270 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19271 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19272 ; the same decoder scheduling characteristics as the original.
19274 (define_peephole2
19275   [(match_scratch:SI 2 "r")
19276    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19277                    (match_operator:SI 3 "arith_or_logical_operator"
19278                      [(match_dup 0)
19279                       (match_operand:SI 1 "nonmemory_operand" "")]))
19280               (clobber (reg:CC FLAGS_REG))])]
19281   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19282   [(set (match_dup 2) (match_dup 0))
19283    (parallel [(set (match_dup 2)
19284                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19285               (clobber (reg:CC FLAGS_REG))])
19286    (set (match_dup 0) (match_dup 2))]
19287   "")
19289 (define_peephole2
19290   [(match_scratch:SI 2 "r")
19291    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19292                    (match_operator:SI 3 "arith_or_logical_operator"
19293                      [(match_operand:SI 1 "nonmemory_operand" "")
19294                       (match_dup 0)]))
19295               (clobber (reg:CC FLAGS_REG))])]
19296   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19297   [(set (match_dup 2) (match_dup 0))
19298    (parallel [(set (match_dup 2)
19299                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19300               (clobber (reg:CC FLAGS_REG))])
19301    (set (match_dup 0) (match_dup 2))]
19302   "")
19304 ;; Attempt to always use XOR for zeroing registers.
19305 (define_peephole2
19306   [(set (match_operand 0 "register_operand" "")
19307         (const_int 0))]
19308   "(GET_MODE (operands[0]) == QImode
19309     || GET_MODE (operands[0]) == HImode
19310     || GET_MODE (operands[0]) == SImode
19311     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19312    && (! TARGET_USE_MOV0 || optimize_size)
19313    && peep2_regno_dead_p (0, FLAGS_REG)"
19314   [(parallel [(set (match_dup 0) (const_int 0))
19315               (clobber (reg:CC FLAGS_REG))])]
19316   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19317                               operands[0]);")
19319 (define_peephole2
19320   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19321         (const_int 0))]
19322   "(GET_MODE (operands[0]) == QImode
19323     || GET_MODE (operands[0]) == HImode)
19324    && (! TARGET_USE_MOV0 || optimize_size)
19325    && peep2_regno_dead_p (0, FLAGS_REG)"
19326   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19327               (clobber (reg:CC FLAGS_REG))])])
19329 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19330 (define_peephole2
19331   [(set (match_operand 0 "register_operand" "")
19332         (const_int -1))]
19333   "(GET_MODE (operands[0]) == HImode
19334     || GET_MODE (operands[0]) == SImode 
19335     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19336    && (optimize_size || TARGET_PENTIUM)
19337    && peep2_regno_dead_p (0, FLAGS_REG)"
19338   [(parallel [(set (match_dup 0) (const_int -1))
19339               (clobber (reg:CC FLAGS_REG))])]
19340   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19341                               operands[0]);")
19343 ;; Attempt to convert simple leas to adds. These can be created by
19344 ;; move expanders.
19345 (define_peephole2
19346   [(set (match_operand:SI 0 "register_operand" "")
19347         (plus:SI (match_dup 0)
19348                  (match_operand:SI 1 "nonmemory_operand" "")))]
19349   "peep2_regno_dead_p (0, FLAGS_REG)"
19350   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19351               (clobber (reg:CC FLAGS_REG))])]
19352   "")
19354 (define_peephole2
19355   [(set (match_operand:SI 0 "register_operand" "")
19356         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19357                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19358   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19359   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19360               (clobber (reg:CC FLAGS_REG))])]
19361   "operands[2] = gen_lowpart (SImode, operands[2]);")
19363 (define_peephole2
19364   [(set (match_operand:DI 0 "register_operand" "")
19365         (plus:DI (match_dup 0)
19366                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19367   "peep2_regno_dead_p (0, FLAGS_REG)"
19368   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19369               (clobber (reg:CC FLAGS_REG))])]
19370   "")
19372 (define_peephole2
19373   [(set (match_operand:SI 0 "register_operand" "")
19374         (mult:SI (match_dup 0)
19375                  (match_operand:SI 1 "const_int_operand" "")))]
19376   "exact_log2 (INTVAL (operands[1])) >= 0
19377    && peep2_regno_dead_p (0, FLAGS_REG)"
19378   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19379               (clobber (reg:CC FLAGS_REG))])]
19380   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19382 (define_peephole2
19383   [(set (match_operand:DI 0 "register_operand" "")
19384         (mult:DI (match_dup 0)
19385                  (match_operand:DI 1 "const_int_operand" "")))]
19386   "exact_log2 (INTVAL (operands[1])) >= 0
19387    && peep2_regno_dead_p (0, FLAGS_REG)"
19388   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19389               (clobber (reg:CC FLAGS_REG))])]
19390   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19392 (define_peephole2
19393   [(set (match_operand:SI 0 "register_operand" "")
19394         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19395                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19396   "exact_log2 (INTVAL (operands[2])) >= 0
19397    && REGNO (operands[0]) == REGNO (operands[1])
19398    && peep2_regno_dead_p (0, FLAGS_REG)"
19399   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19400               (clobber (reg:CC FLAGS_REG))])]
19401   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19403 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19404 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19405 ;; many CPUs it is also faster, since special hardware to avoid esp
19406 ;; dependencies is present.
19408 ;; While some of these conversions may be done using splitters, we use peepholes
19409 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19411 ;; Convert prologue esp subtractions to push.
19412 ;; We need register to push.  In order to keep verify_flow_info happy we have
19413 ;; two choices
19414 ;; - use scratch and clobber it in order to avoid dependencies
19415 ;; - use already live register
19416 ;; We can't use the second way right now, since there is no reliable way how to
19417 ;; verify that given register is live.  First choice will also most likely in
19418 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19419 ;; call clobbered registers are dead.  We may want to use base pointer as an
19420 ;; alternative when no register is available later.
19422 (define_peephole2
19423   [(match_scratch:SI 0 "r")
19424    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19425               (clobber (reg:CC FLAGS_REG))
19426               (clobber (mem:BLK (scratch)))])]
19427   "optimize_size || !TARGET_SUB_ESP_4"
19428   [(clobber (match_dup 0))
19429    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19430               (clobber (mem:BLK (scratch)))])])
19432 (define_peephole2
19433   [(match_scratch:SI 0 "r")
19434    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19435               (clobber (reg:CC FLAGS_REG))
19436               (clobber (mem:BLK (scratch)))])]
19437   "optimize_size || !TARGET_SUB_ESP_8"
19438   [(clobber (match_dup 0))
19439    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19440    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19441               (clobber (mem:BLK (scratch)))])])
19443 ;; Convert esp subtractions to push.
19444 (define_peephole2
19445   [(match_scratch:SI 0 "r")
19446    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19447               (clobber (reg:CC FLAGS_REG))])]
19448   "optimize_size || !TARGET_SUB_ESP_4"
19449   [(clobber (match_dup 0))
19450    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19452 (define_peephole2
19453   [(match_scratch:SI 0 "r")
19454    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19455               (clobber (reg:CC FLAGS_REG))])]
19456   "optimize_size || !TARGET_SUB_ESP_8"
19457   [(clobber (match_dup 0))
19458    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19459    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19461 ;; Convert epilogue deallocator to pop.
19462 (define_peephole2
19463   [(match_scratch:SI 0 "r")
19464    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19465               (clobber (reg:CC FLAGS_REG))
19466               (clobber (mem:BLK (scratch)))])]
19467   "optimize_size || !TARGET_ADD_ESP_4"
19468   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19469               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19470               (clobber (mem:BLK (scratch)))])]
19471   "")
19473 ;; Two pops case is tricky, since pop causes dependency on destination register.
19474 ;; We use two registers if available.
19475 (define_peephole2
19476   [(match_scratch:SI 0 "r")
19477    (match_scratch:SI 1 "r")
19478    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19479               (clobber (reg:CC FLAGS_REG))
19480               (clobber (mem:BLK (scratch)))])]
19481   "optimize_size || !TARGET_ADD_ESP_8"
19482   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19483               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19484               (clobber (mem:BLK (scratch)))])
19485    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19486               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19487   "")
19489 (define_peephole2
19490   [(match_scratch:SI 0 "r")
19491    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19492               (clobber (reg:CC FLAGS_REG))
19493               (clobber (mem:BLK (scratch)))])]
19494   "optimize_size"
19495   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19496               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19497               (clobber (mem:BLK (scratch)))])
19498    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19499               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19500   "")
19502 ;; Convert esp additions to pop.
19503 (define_peephole2
19504   [(match_scratch:SI 0 "r")
19505    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19506               (clobber (reg:CC FLAGS_REG))])]
19507   ""
19508   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19509               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19510   "")
19512 ;; Two pops case is tricky, since pop causes dependency on destination register.
19513 ;; We use two registers if available.
19514 (define_peephole2
19515   [(match_scratch:SI 0 "r")
19516    (match_scratch:SI 1 "r")
19517    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19518               (clobber (reg:CC FLAGS_REG))])]
19519   ""
19520   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19521               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19522    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19523               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19524   "")
19526 (define_peephole2
19527   [(match_scratch:SI 0 "r")
19528    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19529               (clobber (reg:CC FLAGS_REG))])]
19530   "optimize_size"
19531   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19532               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19533    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19534               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19535   "")
19537 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19538 ;; required and register dies.
19539 (define_peephole2
19540   [(set (reg 17)
19541         (compare (match_operand:SI 0 "register_operand" "")
19542                  (match_operand:SI 1 "incdec_operand" "")))]
19543   "ix86_match_ccmode (insn, CCGCmode)
19544    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19545   [(parallel [(set (reg:CCGC FLAGS_REG)
19546                    (compare:CCGC (match_dup 0)
19547                                  (match_dup 1)))
19548               (clobber (match_dup 0))])]
19549   "")
19551 (define_peephole2
19552   [(set (reg 17)
19553         (compare (match_operand:HI 0 "register_operand" "")
19554                  (match_operand:HI 1 "incdec_operand" "")))]
19555   "ix86_match_ccmode (insn, CCGCmode)
19556    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19557   [(parallel [(set (reg:CCGC FLAGS_REG)
19558                    (compare:CCGC (match_dup 0)
19559                                  (match_dup 1)))
19560               (clobber (match_dup 0))])]
19561   "")
19563 (define_peephole2
19564   [(set (reg 17)
19565         (compare (match_operand:QI 0 "register_operand" "")
19566                  (match_operand:QI 1 "incdec_operand" "")))]
19567   "ix86_match_ccmode (insn, CCGCmode)
19568    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19569   [(parallel [(set (reg:CCGC FLAGS_REG)
19570                    (compare:CCGC (match_dup 0)
19571                                  (match_dup 1)))
19572               (clobber (match_dup 0))])]
19573   "")
19575 ;; Convert compares with 128 to shorter add -128
19576 (define_peephole2
19577   [(set (reg 17)
19578         (compare (match_operand:SI 0 "register_operand" "")
19579                  (const_int 128)))]
19580   "ix86_match_ccmode (insn, CCGCmode)
19581    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19582   [(parallel [(set (reg:CCGC FLAGS_REG)
19583                    (compare:CCGC (match_dup 0)
19584                                  (const_int 128)))
19585               (clobber (match_dup 0))])]
19586   "")
19588 (define_peephole2
19589   [(set (reg 17)
19590         (compare (match_operand:HI 0 "register_operand" "")
19591                  (const_int 128)))]
19592   "ix86_match_ccmode (insn, CCGCmode)
19593    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19594   [(parallel [(set (reg:CCGC FLAGS_REG)
19595                    (compare:CCGC (match_dup 0)
19596                                  (const_int 128)))
19597               (clobber (match_dup 0))])]
19598   "")
19600 (define_peephole2
19601   [(match_scratch:DI 0 "r")
19602    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19603               (clobber (reg:CC FLAGS_REG))
19604               (clobber (mem:BLK (scratch)))])]
19605   "optimize_size || !TARGET_SUB_ESP_4"
19606   [(clobber (match_dup 0))
19607    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19608               (clobber (mem:BLK (scratch)))])])
19610 (define_peephole2
19611   [(match_scratch:DI 0 "r")
19612    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19613               (clobber (reg:CC FLAGS_REG))
19614               (clobber (mem:BLK (scratch)))])]
19615   "optimize_size || !TARGET_SUB_ESP_8"
19616   [(clobber (match_dup 0))
19617    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19618    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19619               (clobber (mem:BLK (scratch)))])])
19621 ;; Convert esp subtractions to push.
19622 (define_peephole2
19623   [(match_scratch:DI 0 "r")
19624    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19625               (clobber (reg:CC FLAGS_REG))])]
19626   "optimize_size || !TARGET_SUB_ESP_4"
19627   [(clobber (match_dup 0))
19628    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19630 (define_peephole2
19631   [(match_scratch:DI 0 "r")
19632    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19633               (clobber (reg:CC FLAGS_REG))])]
19634   "optimize_size || !TARGET_SUB_ESP_8"
19635   [(clobber (match_dup 0))
19636    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19637    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19639 ;; Convert epilogue deallocator to pop.
19640 (define_peephole2
19641   [(match_scratch:DI 0 "r")
19642    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19643               (clobber (reg:CC FLAGS_REG))
19644               (clobber (mem:BLK (scratch)))])]
19645   "optimize_size || !TARGET_ADD_ESP_4"
19646   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19647               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19648               (clobber (mem:BLK (scratch)))])]
19649   "")
19651 ;; Two pops case is tricky, since pop causes dependency on destination register.
19652 ;; We use two registers if available.
19653 (define_peephole2
19654   [(match_scratch:DI 0 "r")
19655    (match_scratch:DI 1 "r")
19656    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19657               (clobber (reg:CC FLAGS_REG))
19658               (clobber (mem:BLK (scratch)))])]
19659   "optimize_size || !TARGET_ADD_ESP_8"
19660   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19661               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19662               (clobber (mem:BLK (scratch)))])
19663    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19664               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19665   "")
19667 (define_peephole2
19668   [(match_scratch:DI 0 "r")
19669    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19670               (clobber (reg:CC FLAGS_REG))
19671               (clobber (mem:BLK (scratch)))])]
19672   "optimize_size"
19673   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19674               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19675               (clobber (mem:BLK (scratch)))])
19676    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19677               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19678   "")
19680 ;; Convert esp additions to pop.
19681 (define_peephole2
19682   [(match_scratch:DI 0 "r")
19683    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19684               (clobber (reg:CC FLAGS_REG))])]
19685   ""
19686   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19687               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19688   "")
19690 ;; Two pops case is tricky, since pop causes dependency on destination register.
19691 ;; We use two registers if available.
19692 (define_peephole2
19693   [(match_scratch:DI 0 "r")
19694    (match_scratch:DI 1 "r")
19695    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19696               (clobber (reg:CC FLAGS_REG))])]
19697   ""
19698   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19699               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19700    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19701               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19702   "")
19704 (define_peephole2
19705   [(match_scratch:DI 0 "r")
19706    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19707               (clobber (reg:CC FLAGS_REG))])]
19708   "optimize_size"
19709   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19710               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19711    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19712               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19713   "")
19715 ;; Convert imul by three, five and nine into lea
19716 (define_peephole2
19717   [(parallel
19718     [(set (match_operand:SI 0 "register_operand" "")
19719           (mult:SI (match_operand:SI 1 "register_operand" "")
19720                    (match_operand:SI 2 "const_int_operand" "")))
19721      (clobber (reg:CC FLAGS_REG))])]
19722   "INTVAL (operands[2]) == 3
19723    || INTVAL (operands[2]) == 5
19724    || INTVAL (operands[2]) == 9"
19725   [(set (match_dup 0)
19726         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19727                  (match_dup 1)))]
19728   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19730 (define_peephole2
19731   [(parallel
19732     [(set (match_operand:SI 0 "register_operand" "")
19733           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19734                    (match_operand:SI 2 "const_int_operand" "")))
19735      (clobber (reg:CC FLAGS_REG))])]
19736   "!optimize_size 
19737    && (INTVAL (operands[2]) == 3
19738        || INTVAL (operands[2]) == 5
19739        || INTVAL (operands[2]) == 9)"
19740   [(set (match_dup 0) (match_dup 1))
19741    (set (match_dup 0)
19742         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19743                  (match_dup 0)))]
19744   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19746 (define_peephole2
19747   [(parallel
19748     [(set (match_operand:DI 0 "register_operand" "")
19749           (mult:DI (match_operand:DI 1 "register_operand" "")
19750                    (match_operand:DI 2 "const_int_operand" "")))
19751      (clobber (reg:CC FLAGS_REG))])]
19752   "TARGET_64BIT
19753    && (INTVAL (operands[2]) == 3
19754        || INTVAL (operands[2]) == 5
19755        || INTVAL (operands[2]) == 9)"
19756   [(set (match_dup 0)
19757         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19758                  (match_dup 1)))]
19759   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19761 (define_peephole2
19762   [(parallel
19763     [(set (match_operand:DI 0 "register_operand" "")
19764           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19765                    (match_operand:DI 2 "const_int_operand" "")))
19766      (clobber (reg:CC FLAGS_REG))])]
19767   "TARGET_64BIT
19768    && !optimize_size 
19769    && (INTVAL (operands[2]) == 3
19770        || INTVAL (operands[2]) == 5
19771        || INTVAL (operands[2]) == 9)"
19772   [(set (match_dup 0) (match_dup 1))
19773    (set (match_dup 0)
19774         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19775                  (match_dup 0)))]
19776   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19778 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19779 ;; imul $32bit_imm, reg, reg is direct decoded.
19780 (define_peephole2
19781   [(match_scratch:DI 3 "r")
19782    (parallel [(set (match_operand:DI 0 "register_operand" "")
19783                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19784                             (match_operand:DI 2 "immediate_operand" "")))
19785               (clobber (reg:CC FLAGS_REG))])]
19786   "TARGET_K8 && !optimize_size
19787    && (GET_CODE (operands[2]) != CONST_INT
19788        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19789   [(set (match_dup 3) (match_dup 1))
19790    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19791               (clobber (reg:CC FLAGS_REG))])]
19794 (define_peephole2
19795   [(match_scratch:SI 3 "r")
19796    (parallel [(set (match_operand:SI 0 "register_operand" "")
19797                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19798                             (match_operand:SI 2 "immediate_operand" "")))
19799               (clobber (reg:CC FLAGS_REG))])]
19800   "TARGET_K8 && !optimize_size
19801    && (GET_CODE (operands[2]) != CONST_INT
19802        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19803   [(set (match_dup 3) (match_dup 1))
19804    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19805               (clobber (reg:CC FLAGS_REG))])]
19808 (define_peephole2
19809   [(match_scratch:SI 3 "r")
19810    (parallel [(set (match_operand:DI 0 "register_operand" "")
19811                    (zero_extend:DI
19812                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19813                               (match_operand:SI 2 "immediate_operand" ""))))
19814               (clobber (reg:CC FLAGS_REG))])]
19815   "TARGET_K8 && !optimize_size
19816    && (GET_CODE (operands[2]) != CONST_INT
19817        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19818   [(set (match_dup 3) (match_dup 1))
19819    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19820               (clobber (reg:CC FLAGS_REG))])]
19823 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19824 ;; Convert it into imul reg, reg
19825 ;; It would be better to force assembler to encode instruction using long
19826 ;; immediate, but there is apparently no way to do so.
19827 (define_peephole2
19828   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19829                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19830                             (match_operand:DI 2 "const_int_operand" "")))
19831               (clobber (reg:CC FLAGS_REG))])
19832    (match_scratch:DI 3 "r")]
19833   "TARGET_K8 && !optimize_size
19834    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19835   [(set (match_dup 3) (match_dup 2))
19836    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19837               (clobber (reg:CC FLAGS_REG))])]
19839   if (!rtx_equal_p (operands[0], operands[1]))
19840     emit_move_insn (operands[0], operands[1]);
19843 (define_peephole2
19844   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19845                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19846                             (match_operand:SI 2 "const_int_operand" "")))
19847               (clobber (reg:CC FLAGS_REG))])
19848    (match_scratch:SI 3 "r")]
19849   "TARGET_K8 && !optimize_size
19850    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19851   [(set (match_dup 3) (match_dup 2))
19852    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19853               (clobber (reg:CC FLAGS_REG))])]
19855   if (!rtx_equal_p (operands[0], operands[1]))
19856     emit_move_insn (operands[0], operands[1]);
19859 (define_peephole2
19860   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19861                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19862                             (match_operand:HI 2 "immediate_operand" "")))
19863               (clobber (reg:CC FLAGS_REG))])
19864    (match_scratch:HI 3 "r")]
19865   "TARGET_K8 && !optimize_size"
19866   [(set (match_dup 3) (match_dup 2))
19867    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19868               (clobber (reg:CC FLAGS_REG))])]
19870   if (!rtx_equal_p (operands[0], operands[1]))
19871     emit_move_insn (operands[0], operands[1]);
19874 ;; Call-value patterns last so that the wildcard operand does not
19875 ;; disrupt insn-recog's switch tables.
19877 (define_insn "*call_value_pop_0"
19878   [(set (match_operand 0 "" "")
19879         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19880               (match_operand:SI 2 "" "")))
19881    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19882                             (match_operand:SI 3 "immediate_operand" "")))]
19883   "!TARGET_64BIT"
19885   if (SIBLING_CALL_P (insn))
19886     return "jmp\t%P1";
19887   else
19888     return "call\t%P1";
19890   [(set_attr "type" "callv")])
19892 (define_insn "*call_value_pop_1"
19893   [(set (match_operand 0 "" "")
19894         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19895               (match_operand:SI 2 "" "")))
19896    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19897                             (match_operand:SI 3 "immediate_operand" "i")))]
19898   "!TARGET_64BIT"
19900   if (constant_call_address_operand (operands[1], Pmode))
19901     {
19902       if (SIBLING_CALL_P (insn))
19903         return "jmp\t%P1";
19904       else
19905         return "call\t%P1";
19906     }
19907   if (SIBLING_CALL_P (insn))
19908     return "jmp\t%A1";
19909   else
19910     return "call\t%A1";
19912   [(set_attr "type" "callv")])
19914 (define_insn "*call_value_0"
19915   [(set (match_operand 0 "" "")
19916         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19917               (match_operand:SI 2 "" "")))]
19918   "!TARGET_64BIT"
19920   if (SIBLING_CALL_P (insn))
19921     return "jmp\t%P1";
19922   else
19923     return "call\t%P1";
19925   [(set_attr "type" "callv")])
19927 (define_insn "*call_value_0_rex64"
19928   [(set (match_operand 0 "" "")
19929         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19930               (match_operand:DI 2 "const_int_operand" "")))]
19931   "TARGET_64BIT"
19933   if (SIBLING_CALL_P (insn))
19934     return "jmp\t%P1";
19935   else
19936     return "call\t%P1";
19938   [(set_attr "type" "callv")])
19940 (define_insn "*call_value_1"
19941   [(set (match_operand 0 "" "")
19942         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19943               (match_operand:SI 2 "" "")))]
19944   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19946   if (constant_call_address_operand (operands[1], Pmode))
19947     return "call\t%P1";
19948   return "call\t%*%1";
19950   [(set_attr "type" "callv")])
19952 (define_insn "*sibcall_value_1"
19953   [(set (match_operand 0 "" "")
19954         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19955               (match_operand:SI 2 "" "")))]
19956   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19958   if (constant_call_address_operand (operands[1], Pmode))
19959     return "jmp\t%P1";
19960   return "jmp\t%*%1";
19962   [(set_attr "type" "callv")])
19964 (define_insn "*call_value_1_rex64"
19965   [(set (match_operand 0 "" "")
19966         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19967               (match_operand:DI 2 "" "")))]
19968   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19970   if (constant_call_address_operand (operands[1], Pmode))
19971     return "call\t%P1";
19972   return "call\t%A1";
19974   [(set_attr "type" "callv")])
19976 (define_insn "*sibcall_value_1_rex64"
19977   [(set (match_operand 0 "" "")
19978         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19979               (match_operand:DI 2 "" "")))]
19980   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19981   "jmp\t%P1"
19982   [(set_attr "type" "callv")])
19984 (define_insn "*sibcall_value_1_rex64_v"
19985   [(set (match_operand 0 "" "")
19986         (call (mem:QI (reg:DI 40))
19987               (match_operand:DI 1 "" "")))]
19988   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19989   "jmp\t*%%r11"
19990   [(set_attr "type" "callv")])
19992 (define_insn "trap"
19993   [(trap_if (const_int 1) (const_int 5))]
19994   ""
19995   "int\t$5")
19997 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19998 ;;; for the sake of bounds checking.  By emitting bounds checks as
19999 ;;; conditional traps rather than as conditional jumps around
20000 ;;; unconditional traps we avoid introducing spurious basic-block
20001 ;;; boundaries and facilitate elimination of redundant checks.  In
20002 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
20003 ;;; interrupt 5.
20004 ;;; 
20005 ;;; FIXME: Static branch prediction rules for ix86 are such that
20006 ;;; forward conditional branches predict as untaken.  As implemented
20007 ;;; below, pseudo conditional traps violate that rule.  We should use
20008 ;;; .pushsection/.popsection to place all of the `int 5's in a special
20009 ;;; section loaded at the end of the text segment and branch forward
20010 ;;; there on bounds-failure, and then jump back immediately (in case
20011 ;;; the system chooses to ignore bounds violations, or to report
20012 ;;; violations and continue execution).
20014 (define_expand "conditional_trap"
20015   [(trap_if (match_operator 0 "comparison_operator"
20016              [(match_dup 2) (const_int 0)])
20017             (match_operand 1 "const_int_operand" ""))]
20018   ""
20020   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
20021                               ix86_expand_compare (GET_CODE (operands[0]),
20022                                                    NULL, NULL),
20023                               operands[1]));
20024   DONE;
20027 (define_insn "*conditional_trap_1"
20028   [(trap_if (match_operator 0 "comparison_operator"
20029              [(reg 17) (const_int 0)])
20030             (match_operand 1 "const_int_operand" ""))]
20031   ""
20033   operands[2] = gen_label_rtx ();
20034   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
20035   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20036                              CODE_LABEL_NUMBER (operands[2]));
20037   RET;
20040         ;; Pentium III SIMD instructions.
20042 ;; Moves for SSE/MMX regs.
20044 (define_insn "movv4sf_internal"
20045   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
20046         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
20047   "TARGET_SSE"
20048   "@
20049     xorps\t%0, %0
20050     movaps\t{%1, %0|%0, %1}
20051     movaps\t{%1, %0|%0, %1}"
20052   [(set_attr "type" "ssemov")
20053    (set_attr "mode" "V4SF")])
20055 (define_split
20056   [(set (match_operand:V4SF 0 "register_operand" "")
20057         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
20058   "TARGET_SSE"
20059   [(set (match_dup 0)
20060         (vec_merge:V4SF
20061          (vec_duplicate:V4SF (match_dup 1))
20062          (match_dup 2)
20063          (const_int 1)))]
20065   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
20066   operands[2] = CONST0_RTX (V4SFmode);
20069 (define_insn "movv4si_internal"
20070   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
20071         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
20072   "TARGET_SSE"
20074   switch (which_alternative)
20075     {
20076     case 0:
20077       if (get_attr_mode (insn) == MODE_V4SF)
20078         return "xorps\t%0, %0";
20079       else
20080         return "pxor\t%0, %0";
20081     case 1:
20082     case 2:
20083       if (get_attr_mode (insn) == MODE_V4SF)
20084         return "movaps\t{%1, %0|%0, %1}";
20085       else
20086         return "movdqa\t{%1, %0|%0, %1}";
20087     default:
20088       abort ();
20089     }
20091   [(set_attr "type" "ssemov")
20092    (set (attr "mode")
20093         (cond [(eq_attr "alternative" "0,1")
20094                  (if_then_else
20095                    (ne (symbol_ref "optimize_size")
20096                        (const_int 0))
20097                    (const_string "V4SF")
20098                    (const_string "TI"))
20099                (eq_attr "alternative" "2")
20100                  (if_then_else
20101                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20102                             (const_int 0))
20103                         (ne (symbol_ref "optimize_size")
20104                             (const_int 0)))
20105                    (const_string "V4SF")
20106                    (const_string "TI"))]
20107                (const_string "TI")))])
20109 (define_insn "movv2di_internal"
20110   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
20111         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
20112   "TARGET_SSE"
20114   switch (which_alternative)
20115     {
20116     case 0:
20117       if (get_attr_mode (insn) == MODE_V4SF)
20118         return "xorps\t%0, %0";
20119       else
20120         return "pxor\t%0, %0";
20121     case 1:
20122     case 2:
20123       if (get_attr_mode (insn) == MODE_V4SF)
20124         return "movaps\t{%1, %0|%0, %1}";
20125       else
20126         return "movdqa\t{%1, %0|%0, %1}";
20127     default:
20128       abort ();
20129     }
20131   [(set_attr "type" "ssemov")
20132    (set (attr "mode")
20133         (cond [(eq_attr "alternative" "0,1")
20134                  (if_then_else
20135                    (ne (symbol_ref "optimize_size")
20136                        (const_int 0))
20137                    (const_string "V4SF")
20138                    (const_string "TI"))
20139                (eq_attr "alternative" "2")
20140                  (if_then_else
20141                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20142                             (const_int 0))
20143                         (ne (symbol_ref "optimize_size")
20144                             (const_int 0)))
20145                    (const_string "V4SF")
20146                    (const_string "TI"))]
20147                (const_string "TI")))])
20149 (define_split
20150   [(set (match_operand:V2DF 0 "register_operand" "")
20151         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
20152   "TARGET_SSE2"
20153   [(set (match_dup 0)
20154         (vec_merge:V2DF
20155          (vec_duplicate:V2DF (match_dup 1))
20156          (match_dup 2)
20157          (const_int 1)))]
20159   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
20160   operands[2] = CONST0_RTX (V2DFmode);
20163 (define_insn "movv8qi_internal"
20164   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20165         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20166   "TARGET_MMX
20167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20168   "@
20169     pxor\t%0, %0
20170     movq\t{%1, %0|%0, %1}
20171     movq\t{%1, %0|%0, %1}
20172     movdq2q\t{%1, %0|%0, %1}
20173     movq2dq\t{%1, %0|%0, %1}
20174     movq\t{%1, %0|%0, %1}
20175     movq\t{%1, %0|%0, %1}"
20176   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20177    (set_attr "mode" "DI")])
20179 (define_insn "movv4hi_internal"
20180   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20181         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20182   "TARGET_MMX
20183    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20184   "@
20185     pxor\t%0, %0
20186     movq\t{%1, %0|%0, %1}
20187     movq\t{%1, %0|%0, %1}
20188     movdq2q\t{%1, %0|%0, %1}
20189     movq2dq\t{%1, %0|%0, %1}
20190     movq\t{%1, %0|%0, %1}
20191     movq\t{%1, %0|%0, %1}"
20192   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20193    (set_attr "mode" "DI")])
20195 (define_insn "*movv2si_internal"
20196   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20197         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20198   "TARGET_MMX
20199    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20200   "@
20201     pxor\t%0, %0
20202     movq\t{%1, %0|%0, %1}
20203     movq\t{%1, %0|%0, %1}
20204     movdq2q\t{%1, %0|%0, %1}
20205     movq2dq\t{%1, %0|%0, %1}
20206     movq\t{%1, %0|%0, %1}
20207     movq\t{%1, %0|%0, %1}"
20208   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20209    (set_attr "mode" "DI")])
20211 (define_insn "movv2sf_internal"
20212   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
20213         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
20214   "TARGET_3DNOW
20215    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20216   "@
20217     pxor\t%0, %0
20218     movq\t{%1, %0|%0, %1}
20219     movq\t{%1, %0|%0, %1}
20220     movdq2q\t{%1, %0|%0, %1}
20221     movq2dq\t{%1, %0|%0, %1}
20222     movlps\t{%1, %0|%0, %1}
20223     movlps\t{%1, %0|%0, %1}"
20224   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20225    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
20227 (define_expand "movti"
20228   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20229         (match_operand:TI 1 "nonimmediate_operand" ""))]
20230   "TARGET_SSE || TARGET_64BIT"
20232   if (TARGET_64BIT)
20233     ix86_expand_move (TImode, operands);
20234   else
20235     ix86_expand_vector_move (TImode, operands);
20236   DONE;
20239 (define_expand "movtf"
20240   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20241         (match_operand:TF 1 "nonimmediate_operand" ""))]
20242   "TARGET_64BIT"
20244   if (TARGET_64BIT)
20245     ix86_expand_move (TFmode, operands);
20246   else
20247     ix86_expand_vector_move (TFmode, operands);
20248   DONE;
20251 (define_insn "movv2df_internal"
20252   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
20253         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
20254   "TARGET_SSE2
20255    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20257   switch (which_alternative)
20258     {
20259     case 0:
20260       if (get_attr_mode (insn) == MODE_V4SF)
20261         return "xorps\t%0, %0";
20262       else
20263         return "xorpd\t%0, %0";
20264     case 1:
20265     case 2:
20266       if (get_attr_mode (insn) == MODE_V4SF)
20267         return "movaps\t{%1, %0|%0, %1}";
20268       else
20269         return "movapd\t{%1, %0|%0, %1}";
20270     default:
20271       abort ();
20272     }
20274   [(set_attr "type" "ssemov")
20275    (set (attr "mode")
20276         (cond [(eq_attr "alternative" "0,1")
20277                  (if_then_else
20278                    (ne (symbol_ref "optimize_size")
20279                        (const_int 0))
20280                    (const_string "V4SF")
20281                    (const_string "V2DF"))
20282                (eq_attr "alternative" "2")
20283                  (if_then_else
20284                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20285                             (const_int 0))
20286                         (ne (symbol_ref "optimize_size")
20287                             (const_int 0)))
20288                    (const_string "V4SF")
20289                    (const_string "V2DF"))]
20290                (const_string "V2DF")))])
20292 (define_insn "movv8hi_internal"
20293   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
20294         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
20295   "TARGET_SSE2
20296    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20298   switch (which_alternative)
20299     {
20300     case 0:
20301       if (get_attr_mode (insn) == MODE_V4SF)
20302         return "xorps\t%0, %0";
20303       else
20304         return "pxor\t%0, %0";
20305     case 1:
20306     case 2:
20307       if (get_attr_mode (insn) == MODE_V4SF)
20308         return "movaps\t{%1, %0|%0, %1}";
20309       else
20310         return "movdqa\t{%1, %0|%0, %1}";
20311     default:
20312       abort ();
20313     }
20315   [(set_attr "type" "ssemov")
20316    (set (attr "mode")
20317         (cond [(eq_attr "alternative" "0,1")
20318                  (if_then_else
20319                    (ne (symbol_ref "optimize_size")
20320                        (const_int 0))
20321                    (const_string "V4SF")
20322                    (const_string "TI"))
20323                (eq_attr "alternative" "2")
20324                  (if_then_else
20325                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20326                             (const_int 0))
20327                         (ne (symbol_ref "optimize_size")
20328                             (const_int 0)))
20329                    (const_string "V4SF")
20330                    (const_string "TI"))]
20331                (const_string "TI")))])
20333 (define_insn "movv16qi_internal"
20334   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20335         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20336   "TARGET_SSE2
20337    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20339   switch (which_alternative)
20340     {
20341     case 0:
20342       if (get_attr_mode (insn) == MODE_V4SF)
20343         return "xorps\t%0, %0";
20344       else
20345         return "pxor\t%0, %0";
20346     case 1:
20347     case 2:
20348       if (get_attr_mode (insn) == MODE_V4SF)
20349         return "movaps\t{%1, %0|%0, %1}";
20350       else
20351         return "movdqa\t{%1, %0|%0, %1}";
20352     default:
20353       abort ();
20354     }
20356   [(set_attr "type" "ssemov")
20357    (set (attr "mode")
20358         (cond [(eq_attr "alternative" "0,1")
20359                  (if_then_else
20360                    (ne (symbol_ref "optimize_size")
20361                        (const_int 0))
20362                    (const_string "V4SF")
20363                    (const_string "TI"))
20364                (eq_attr "alternative" "2")
20365                  (if_then_else
20366                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20367                             (const_int 0))
20368                         (ne (symbol_ref "optimize_size")
20369                             (const_int 0)))
20370                    (const_string "V4SF")
20371                    (const_string "TI"))]
20372                (const_string "TI")))])
20374 (define_expand "movv2df"
20375   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20376         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20377   "TARGET_SSE2"
20379   ix86_expand_vector_move (V2DFmode, operands);
20380   DONE;
20383 (define_expand "movv8hi"
20384   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20385         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20386   "TARGET_SSE2"
20388   ix86_expand_vector_move (V8HImode, operands);
20389   DONE;
20392 (define_expand "movv16qi"
20393   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20394         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20395   "TARGET_SSE2"
20397   ix86_expand_vector_move (V16QImode, operands);
20398   DONE;
20401 (define_expand "movv4sf"
20402   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20403         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20404   "TARGET_SSE"
20406   ix86_expand_vector_move (V4SFmode, operands);
20407   DONE;
20410 (define_expand "movv4si"
20411   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20412         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20413   "TARGET_SSE"
20415   ix86_expand_vector_move (V4SImode, operands);
20416   DONE;
20419 (define_expand "movv2di"
20420   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20421         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20422   "TARGET_SSE"
20424   ix86_expand_vector_move (V2DImode, operands);
20425   DONE;
20428 (define_expand "movv2si"
20429   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20430         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20431   "TARGET_MMX"
20433   ix86_expand_vector_move (V2SImode, operands);
20434   DONE;
20437 (define_expand "movv4hi"
20438   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20439         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20440   "TARGET_MMX"
20442   ix86_expand_vector_move (V4HImode, operands);
20443   DONE;
20446 (define_expand "movv8qi"
20447   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20448         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20449   "TARGET_MMX"
20451   ix86_expand_vector_move (V8QImode, operands);
20452   DONE;
20455 (define_expand "movv2sf"
20456   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20457         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20458    "TARGET_3DNOW"
20460   ix86_expand_vector_move (V2SFmode, operands);
20461   DONE;
20464 (define_insn "*pushti"
20465   [(set (match_operand:TI 0 "push_operand" "=<")
20466         (match_operand:TI 1 "register_operand" "x"))]
20467   "TARGET_SSE"
20468   "#")
20470 (define_insn "*pushv2df"
20471   [(set (match_operand:V2DF 0 "push_operand" "=<")
20472         (match_operand:V2DF 1 "register_operand" "x"))]
20473   "TARGET_SSE"
20474   "#")
20476 (define_insn "*pushv2di"
20477   [(set (match_operand:V2DI 0 "push_operand" "=<")
20478         (match_operand:V2DI 1 "register_operand" "x"))]
20479   "TARGET_SSE2"
20480   "#")
20482 (define_insn "*pushv8hi"
20483   [(set (match_operand:V8HI 0 "push_operand" "=<")
20484         (match_operand:V8HI 1 "register_operand" "x"))]
20485   "TARGET_SSE2"
20486   "#")
20488 (define_insn "*pushv16qi"
20489   [(set (match_operand:V16QI 0 "push_operand" "=<")
20490         (match_operand:V16QI 1 "register_operand" "x"))]
20491   "TARGET_SSE2"
20492   "#")
20494 (define_insn "*pushv4sf"
20495   [(set (match_operand:V4SF 0 "push_operand" "=<")
20496         (match_operand:V4SF 1 "register_operand" "x"))]
20497   "TARGET_SSE"
20498   "#")
20500 (define_insn "*pushv4si"
20501   [(set (match_operand:V4SI 0 "push_operand" "=<")
20502         (match_operand:V4SI 1 "register_operand" "x"))]
20503   "TARGET_SSE2"
20504   "#")
20506 (define_insn "*pushv2si"
20507   [(set (match_operand:V2SI 0 "push_operand" "=<")
20508         (match_operand:V2SI 1 "register_operand" "y"))]
20509   "TARGET_MMX"
20510   "#")
20512 (define_insn "*pushv4hi"
20513   [(set (match_operand:V4HI 0 "push_operand" "=<")
20514         (match_operand:V4HI 1 "register_operand" "y"))]
20515   "TARGET_MMX"
20516   "#")
20518 (define_insn "*pushv8qi"
20519   [(set (match_operand:V8QI 0 "push_operand" "=<")
20520         (match_operand:V8QI 1 "register_operand" "y"))]
20521   "TARGET_MMX"
20522   "#")
20524 (define_insn "*pushv2sf"
20525   [(set (match_operand:V2SF 0 "push_operand" "=<")
20526         (match_operand:V2SF 1 "register_operand" "y"))]
20527   "TARGET_3DNOW"
20528   "#")
20530 (define_split
20531   [(set (match_operand 0 "push_operand" "")
20532         (match_operand 1 "register_operand" ""))]
20533   "!TARGET_64BIT && reload_completed
20534    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20535   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20536    (set (match_dup 2) (match_dup 1))]
20537   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20538                                  stack_pointer_rtx);
20539    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20541 (define_split
20542   [(set (match_operand 0 "push_operand" "")
20543         (match_operand 1 "register_operand" ""))]
20544   "TARGET_64BIT && reload_completed
20545    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20546   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20547    (set (match_dup 2) (match_dup 1))]
20548   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20549                                  stack_pointer_rtx);
20550    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20553 (define_insn "movti_internal"
20554   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20555         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20556   "TARGET_SSE && !TARGET_64BIT
20557    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20559   switch (which_alternative)
20560     {
20561     case 0:
20562       if (get_attr_mode (insn) == MODE_V4SF)
20563         return "xorps\t%0, %0";
20564       else
20565         return "pxor\t%0, %0";
20566     case 1:
20567     case 2:
20568       if (get_attr_mode (insn) == MODE_V4SF)
20569         return "movaps\t{%1, %0|%0, %1}";
20570       else
20571         return "movdqa\t{%1, %0|%0, %1}";
20572     default:
20573       abort ();
20574     }
20576   [(set_attr "type" "ssemov,ssemov,ssemov")
20577    (set (attr "mode")
20578         (cond [(eq_attr "alternative" "0,1")
20579                  (if_then_else
20580                    (ne (symbol_ref "optimize_size")
20581                        (const_int 0))
20582                    (const_string "V4SF")
20583                    (const_string "TI"))
20584                (eq_attr "alternative" "2")
20585                  (if_then_else
20586                    (ne (symbol_ref "optimize_size")
20587                        (const_int 0))
20588                    (const_string "V4SF")
20589                    (const_string "TI"))]
20590                (const_string "TI")))])
20592 (define_insn "*movti_rex64"
20593   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20594         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20595   "TARGET_64BIT
20596    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20598   switch (which_alternative)
20599     {
20600     case 0:
20601     case 1:
20602       return "#";
20603     case 2:
20604       if (get_attr_mode (insn) == MODE_V4SF)
20605         return "xorps\t%0, %0";
20606       else
20607         return "pxor\t%0, %0";
20608     case 3:
20609     case 4:
20610       if (get_attr_mode (insn) == MODE_V4SF)
20611         return "movaps\t{%1, %0|%0, %1}";
20612       else
20613         return "movdqa\t{%1, %0|%0, %1}";
20614     default:
20615       abort ();
20616     }
20618   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20619    (set (attr "mode")
20620         (cond [(eq_attr "alternative" "2,3")
20621                  (if_then_else
20622                    (ne (symbol_ref "optimize_size")
20623                        (const_int 0))
20624                    (const_string "V4SF")
20625                    (const_string "TI"))
20626                (eq_attr "alternative" "4")
20627                  (if_then_else
20628                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20629                             (const_int 0))
20630                         (ne (symbol_ref "optimize_size")
20631                             (const_int 0)))
20632                    (const_string "V4SF")
20633                    (const_string "TI"))]
20634                (const_string "DI")))])
20636 (define_insn "*movtf_rex64"
20637   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20638         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20639   "TARGET_64BIT
20640    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20642   switch (which_alternative)
20643     {
20644     case 0:
20645     case 1:
20646       return "#";
20647     case 2:
20648       if (get_attr_mode (insn) == MODE_V4SF)
20649         return "xorps\t%0, %0";
20650       else
20651         return "pxor\t%0, %0";
20652     case 3:
20653     case 4:
20654       if (get_attr_mode (insn) == MODE_V4SF)
20655         return "movaps\t{%1, %0|%0, %1}";
20656       else
20657         return "movdqa\t{%1, %0|%0, %1}";
20658     default:
20659       abort ();
20660     }
20662   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20663    (set (attr "mode")
20664         (cond [(eq_attr "alternative" "2,3")
20665                  (if_then_else
20666                    (ne (symbol_ref "optimize_size")
20667                        (const_int 0))
20668                    (const_string "V4SF")
20669                    (const_string "TI"))
20670                (eq_attr "alternative" "4")
20671                  (if_then_else
20672                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20673                             (const_int 0))
20674                         (ne (symbol_ref "optimize_size")
20675                             (const_int 0)))
20676                    (const_string "V4SF")
20677                    (const_string "TI"))]
20678                (const_string "DI")))])
20680 (define_split
20681   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20682         (match_operand:TI 1 "general_operand" ""))]
20683   "reload_completed && !SSE_REG_P (operands[0])
20684    && !SSE_REG_P (operands[1])"
20685   [(const_int 0)]
20686   "ix86_split_long_move (operands); DONE;")
20688 (define_split
20689   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20690         (match_operand:TF 1 "general_operand" ""))]
20691   "reload_completed && !SSE_REG_P (operands[0])
20692    && !SSE_REG_P (operands[1])"
20693   [(const_int 0)]
20694   "ix86_split_long_move (operands); DONE;")
20696 ;; These two patterns are useful for specifying exactly whether to use
20697 ;; movaps or movups
20698 (define_expand "sse_movaps"
20699   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20700         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20701                      UNSPEC_MOVA))]
20702   "TARGET_SSE"
20704   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20705     {
20706       rtx tmp = gen_reg_rtx (V4SFmode);
20707       emit_insn (gen_sse_movaps (tmp, operands[1]));
20708       emit_move_insn (operands[0], tmp);
20709       DONE;
20710     }
20713 (define_insn "*sse_movaps_1"
20714   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20715         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20716                      UNSPEC_MOVA))]
20717   "TARGET_SSE
20718    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20719   "movaps\t{%1, %0|%0, %1}"
20720   [(set_attr "type" "ssemov,ssemov")
20721    (set_attr "mode" "V4SF")])
20723 (define_expand "sse_movups"
20724   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20725         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20726                      UNSPEC_MOVU))]
20727   "TARGET_SSE"
20729   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20730     {
20731       rtx tmp = gen_reg_rtx (V4SFmode);
20732       emit_insn (gen_sse_movups (tmp, operands[1]));
20733       emit_move_insn (operands[0], tmp);
20734       DONE;
20735     }
20738 (define_insn "*sse_movups_1"
20739   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20740         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20741                      UNSPEC_MOVU))]
20742   "TARGET_SSE
20743    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20744   "movups\t{%1, %0|%0, %1}"
20745   [(set_attr "type" "ssecvt,ssecvt")
20746    (set_attr "mode" "V4SF")])
20748 ;; SSE Strange Moves.
20750 (define_insn "sse_movmskps"
20751   [(set (match_operand:SI 0 "register_operand" "=r")
20752         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20753                    UNSPEC_MOVMSK))]
20754   "TARGET_SSE"
20755   "movmskps\t{%1, %0|%0, %1}"
20756   [(set_attr "type" "ssecvt")
20757    (set_attr "mode" "V4SF")])
20759 (define_insn "mmx_pmovmskb"
20760   [(set (match_operand:SI 0 "register_operand" "=r")
20761         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20762                    UNSPEC_MOVMSK))]
20763   "TARGET_SSE || TARGET_3DNOW_A"
20764   "pmovmskb\t{%1, %0|%0, %1}"
20765   [(set_attr "type" "ssecvt")
20766    (set_attr "mode" "V4SF")])
20769 (define_insn "mmx_maskmovq"
20770   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20771         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20772                       (match_operand:V8QI 2 "register_operand" "y")]
20773                      UNSPEC_MASKMOV))]
20774   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20775   ;; @@@ check ordering of operands in intel/nonintel syntax
20776   "maskmovq\t{%2, %1|%1, %2}"
20777   [(set_attr "type" "mmxcvt")
20778    (set_attr "mode" "DI")])
20780 (define_insn "mmx_maskmovq_rex"
20781   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20782         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20783                       (match_operand:V8QI 2 "register_operand" "y")]
20784                      UNSPEC_MASKMOV))]
20785   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20786   ;; @@@ check ordering of operands in intel/nonintel syntax
20787   "maskmovq\t{%2, %1|%1, %2}"
20788   [(set_attr "type" "mmxcvt")
20789    (set_attr "mode" "DI")])
20791 (define_insn "sse_movntv4sf"
20792   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20793         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20794                      UNSPEC_MOVNT))]
20795   "TARGET_SSE"
20796   "movntps\t{%1, %0|%0, %1}"
20797   [(set_attr "type" "ssemov")
20798    (set_attr "mode" "V4SF")])
20800 (define_insn "sse_movntdi"
20801   [(set (match_operand:DI 0 "memory_operand" "=m")
20802         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20803                    UNSPEC_MOVNT))]
20804   "TARGET_SSE || TARGET_3DNOW_A"
20805   "movntq\t{%1, %0|%0, %1}"
20806   [(set_attr "type" "mmxmov")
20807    (set_attr "mode" "DI")])
20809 (define_insn "sse_movhlps"
20810   [(set (match_operand:V4SF 0 "register_operand" "=x")
20811         (vec_merge:V4SF
20812          (match_operand:V4SF 1 "register_operand" "0")
20813          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20814                           (parallel [(const_int 2)
20815                                      (const_int 3)
20816                                      (const_int 0)
20817                                      (const_int 1)]))
20818          (const_int 3)))]
20819   "TARGET_SSE"
20820   "movhlps\t{%2, %0|%0, %2}"
20821   [(set_attr "type" "ssecvt")
20822    (set_attr "mode" "V4SF")])
20824 (define_insn "sse_movlhps"
20825   [(set (match_operand:V4SF 0 "register_operand" "=x")
20826         (vec_merge:V4SF
20827          (match_operand:V4SF 1 "register_operand" "0")
20828          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20829                           (parallel [(const_int 2)
20830                                      (const_int 3)
20831                                      (const_int 0)
20832                                      (const_int 1)]))
20833          (const_int 12)))]
20834   "TARGET_SSE"
20835   "movlhps\t{%2, %0|%0, %2}"
20836   [(set_attr "type" "ssecvt")
20837    (set_attr "mode" "V4SF")])
20839 (define_insn "sse_movhps"
20840   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20841         (vec_merge:V4SF
20842          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20843          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20844          (const_int 12)))]
20845   "TARGET_SSE
20846    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20847   "movhps\t{%2, %0|%0, %2}"
20848   [(set_attr "type" "ssecvt")
20849    (set_attr "mode" "V4SF")])
20851 (define_insn "sse_movlps"
20852   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20853         (vec_merge:V4SF
20854          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20855          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20856          (const_int 3)))]
20857   "TARGET_SSE
20858    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20859   "movlps\t{%2, %0|%0, %2}"
20860   [(set_attr "type" "ssecvt")
20861    (set_attr "mode" "V4SF")])
20863 (define_expand "sse_loadss"
20864   [(match_operand:V4SF 0 "register_operand" "")
20865    (match_operand:SF 1 "memory_operand" "")]
20866   "TARGET_SSE"
20868   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20869                                CONST0_RTX (V4SFmode)));
20870   DONE;
20873 (define_insn "sse_loadss_1"
20874   [(set (match_operand:V4SF 0 "register_operand" "=x")
20875         (vec_merge:V4SF
20876          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20877          (match_operand:V4SF 2 "const0_operand" "X")
20878          (const_int 1)))]
20879   "TARGET_SSE"
20880   "movss\t{%1, %0|%0, %1}"
20881   [(set_attr "type" "ssemov")
20882    (set_attr "mode" "SF")])
20884 (define_insn "sse_movss"
20885   [(set (match_operand:V4SF 0 "register_operand" "=x")
20886         (vec_merge:V4SF
20887          (match_operand:V4SF 1 "register_operand" "0")
20888          (match_operand:V4SF 2 "register_operand" "x")
20889          (const_int 1)))]
20890   "TARGET_SSE"
20891   "movss\t{%2, %0|%0, %2}"
20892   [(set_attr "type" "ssemov")
20893    (set_attr "mode" "SF")])
20895 (define_insn "sse_storess"
20896   [(set (match_operand:SF 0 "memory_operand" "=m")
20897         (vec_select:SF
20898          (match_operand:V4SF 1 "register_operand" "x")
20899          (parallel [(const_int 0)])))]
20900   "TARGET_SSE"
20901   "movss\t{%1, %0|%0, %1}"
20902   [(set_attr "type" "ssemov")
20903    (set_attr "mode" "SF")])
20905 (define_insn "sse_shufps"
20906   [(set (match_operand:V4SF 0 "register_operand" "=x")
20907         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20908                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20909                       (match_operand:SI 3 "immediate_operand" "i")]
20910                      UNSPEC_SHUFFLE))]
20911   "TARGET_SSE"
20912   ;; @@@ check operand order for intel/nonintel syntax
20913   "shufps\t{%3, %2, %0|%0, %2, %3}"
20914   [(set_attr "type" "ssecvt")
20915    (set_attr "mode" "V4SF")])
20918 ;; SSE arithmetic
20920 (define_insn "addv4sf3"
20921   [(set (match_operand:V4SF 0 "register_operand" "=x")
20922         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20923                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20924   "TARGET_SSE"
20925   "addps\t{%2, %0|%0, %2}"
20926   [(set_attr "type" "sseadd")
20927    (set_attr "mode" "V4SF")])
20929 (define_insn "vmaddv4sf3"
20930   [(set (match_operand:V4SF 0 "register_operand" "=x")
20931         (vec_merge:V4SF
20932          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20933                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20934          (match_dup 1)
20935          (const_int 1)))]
20936   "TARGET_SSE"
20937   "addss\t{%2, %0|%0, %2}"
20938   [(set_attr "type" "sseadd")
20939    (set_attr "mode" "SF")])
20941 (define_insn "subv4sf3"
20942   [(set (match_operand:V4SF 0 "register_operand" "=x")
20943         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20944                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20945   "TARGET_SSE"
20946   "subps\t{%2, %0|%0, %2}"
20947   [(set_attr "type" "sseadd")
20948    (set_attr "mode" "V4SF")])
20950 (define_insn "vmsubv4sf3"
20951   [(set (match_operand:V4SF 0 "register_operand" "=x")
20952         (vec_merge:V4SF
20953          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20954                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20955          (match_dup 1)
20956          (const_int 1)))]
20957   "TARGET_SSE"
20958   "subss\t{%2, %0|%0, %2}"
20959   [(set_attr "type" "sseadd")
20960    (set_attr "mode" "SF")])
20962 ;; ??? Should probably be done by generic code instead.
20963 (define_expand "negv4sf2"
20964   [(set (match_operand:V4SF 0 "register_operand" "")
20965         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20966                   (match_dup 2)))]
20967   "TARGET_SSE"
20969   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20970   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20971   operands[2] = force_reg (V4SFmode, vm0);
20974 (define_insn "mulv4sf3"
20975   [(set (match_operand:V4SF 0 "register_operand" "=x")
20976         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20977                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20978   "TARGET_SSE"
20979   "mulps\t{%2, %0|%0, %2}"
20980   [(set_attr "type" "ssemul")
20981    (set_attr "mode" "V4SF")])
20983 (define_insn "vmmulv4sf3"
20984   [(set (match_operand:V4SF 0 "register_operand" "=x")
20985         (vec_merge:V4SF
20986          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20987                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20988          (match_dup 1)
20989          (const_int 1)))]
20990   "TARGET_SSE"
20991   "mulss\t{%2, %0|%0, %2}"
20992   [(set_attr "type" "ssemul")
20993    (set_attr "mode" "SF")])
20995 (define_insn "divv4sf3"
20996   [(set (match_operand:V4SF 0 "register_operand" "=x")
20997         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20998                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20999   "TARGET_SSE"
21000   "divps\t{%2, %0|%0, %2}"
21001   [(set_attr "type" "ssediv")
21002    (set_attr "mode" "V4SF")])
21004 (define_insn "vmdivv4sf3"
21005   [(set (match_operand:V4SF 0 "register_operand" "=x")
21006         (vec_merge:V4SF
21007          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
21008                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21009          (match_dup 1)
21010          (const_int 1)))]
21011   "TARGET_SSE"
21012   "divss\t{%2, %0|%0, %2}"
21013   [(set_attr "type" "ssediv")
21014    (set_attr "mode" "SF")])
21017 ;; SSE square root/reciprocal
21019 (define_insn "rcpv4sf2"
21020   [(set (match_operand:V4SF 0 "register_operand" "=x")
21021         (unspec:V4SF
21022          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
21023   "TARGET_SSE"
21024   "rcpps\t{%1, %0|%0, %1}"
21025   [(set_attr "type" "sse")
21026    (set_attr "mode" "V4SF")])
21028 (define_insn "vmrcpv4sf2"
21029   [(set (match_operand:V4SF 0 "register_operand" "=x")
21030         (vec_merge:V4SF
21031          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21032                       UNSPEC_RCP)
21033          (match_operand:V4SF 2 "register_operand" "0")
21034          (const_int 1)))]
21035   "TARGET_SSE"
21036   "rcpss\t{%1, %0|%0, %1}"
21037   [(set_attr "type" "sse")
21038    (set_attr "mode" "SF")])
21040 (define_insn "rsqrtv4sf2"
21041   [(set (match_operand:V4SF 0 "register_operand" "=x")
21042         (unspec:V4SF
21043          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
21044   "TARGET_SSE"
21045   "rsqrtps\t{%1, %0|%0, %1}"
21046   [(set_attr "type" "sse")
21047    (set_attr "mode" "V4SF")])
21049 (define_insn "vmrsqrtv4sf2"
21050   [(set (match_operand:V4SF 0 "register_operand" "=x")
21051         (vec_merge:V4SF
21052          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21053                       UNSPEC_RSQRT)
21054          (match_operand:V4SF 2 "register_operand" "0")
21055          (const_int 1)))]
21056   "TARGET_SSE"
21057   "rsqrtss\t{%1, %0|%0, %1}"
21058   [(set_attr "type" "sse")
21059    (set_attr "mode" "SF")])
21061 (define_insn "sqrtv4sf2"
21062   [(set (match_operand:V4SF 0 "register_operand" "=x")
21063         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21064   "TARGET_SSE"
21065   "sqrtps\t{%1, %0|%0, %1}"
21066   [(set_attr "type" "sse")
21067    (set_attr "mode" "V4SF")])
21069 (define_insn "vmsqrtv4sf2"
21070   [(set (match_operand:V4SF 0 "register_operand" "=x")
21071         (vec_merge:V4SF
21072          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21073          (match_operand:V4SF 2 "register_operand" "0")
21074          (const_int 1)))]
21075   "TARGET_SSE"
21076   "sqrtss\t{%1, %0|%0, %1}"
21077   [(set_attr "type" "sse")
21078    (set_attr "mode" "SF")])
21080 ;; SSE logical operations.
21082 ;; SSE defines logical operations on floating point values.  This brings
21083 ;; interesting challenge to RTL representation where logicals are only valid
21084 ;; on integral types.  We deal with this by representing the floating point
21085 ;; logical as logical on arguments casted to TImode as this is what hardware
21086 ;; really does.  Unfortunately hardware requires the type information to be
21087 ;; present and thus we must avoid subregs from being simplified and eliminated
21088 ;; in later compilation phases.
21090 ;; We have following variants from each instruction:
21091 ;; sse_andsf3 - the operation taking V4SF vector operands
21092 ;;              and doing TImode cast on them
21093 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
21094 ;;                      TImode, since backend insist on eliminating casts
21095 ;;                      on memory operands
21096 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
21097 ;;                   We cannot accept memory operand here as instruction reads
21098 ;;                   whole scalar.  This is generated only post reload by GCC
21099 ;;                   scalar float operations that expands to logicals (fabs)
21100 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
21101 ;;                   memory operand.  Eventually combine can be able
21102 ;;                   to synthesize these using splitter.
21103 ;; sse2_anddf3, *sse2_anddf3_memory
21104 ;;              
21105 ;; 
21106 ;; These are not called andti3 etc. because we really really don't want
21107 ;; the compiler to widen DImode ands to TImode ands and then try to move
21108 ;; into DImode subregs of SSE registers, and them together, and move out
21109 ;; of DImode subregs again!
21110 ;; SSE1 single precision floating point logical operation
21111 (define_expand "sse_andv4sf3"
21112   [(set (match_operand:V4SF 0 "register_operand" "")
21113         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
21114                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21115   "TARGET_SSE"
21116   "")
21118 (define_insn "*sse_andv4sf3"
21119   [(set (match_operand:V4SF 0 "register_operand" "=x")
21120         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21121                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21122   "TARGET_SSE
21123    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21124   "andps\t{%2, %0|%0, %2}"
21125   [(set_attr "type" "sselog")
21126    (set_attr "mode" "V4SF")])
21128 (define_expand "sse_nandv4sf3"
21129   [(set (match_operand:V4SF 0 "register_operand" "")
21130         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
21131                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21132   "TARGET_SSE"
21133   "")
21135 (define_insn "*sse_nandv4sf3"
21136   [(set (match_operand:V4SF 0 "register_operand" "=x")
21137         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
21138                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21139   "TARGET_SSE"
21140   "andnps\t{%2, %0|%0, %2}"
21141   [(set_attr "type" "sselog")
21142    (set_attr "mode" "V4SF")])
21144 (define_expand "sse_iorv4sf3"
21145   [(set (match_operand:V4SF 0 "register_operand" "")
21146         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
21147                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21148   "TARGET_SSE"
21149   "")
21151 (define_insn "*sse_iorv4sf3"
21152   [(set (match_operand:V4SF 0 "register_operand" "=x")
21153         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21154                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21155   "TARGET_SSE
21156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21157   "orps\t{%2, %0|%0, %2}"
21158   [(set_attr "type" "sselog")
21159    (set_attr "mode" "V4SF")])
21161 (define_expand "sse_xorv4sf3"
21162   [(set (match_operand:V4SF 0 "register_operand" "")
21163         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
21164                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21165   "TARGET_SSE"
21166   "")
21168 (define_insn "*sse_xorv4sf3"
21169   [(set (match_operand:V4SF 0 "register_operand" "=x")
21170         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21171                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21172   "TARGET_SSE
21173    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21174   "xorps\t{%2, %0|%0, %2}"
21175   [(set_attr "type" "sselog")
21176    (set_attr "mode" "V4SF")])
21178 ;; SSE2 double precision floating point logical operation
21180 (define_expand "sse2_andv2df3"
21181   [(set (match_operand:V2DF 0 "register_operand" "")
21182         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
21183                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21184   "TARGET_SSE2"
21185   "")
21187 (define_insn "*sse2_andv2df3"
21188   [(set (match_operand:V2DF 0 "register_operand" "=x")
21189         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21190                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21191   "TARGET_SSE2
21192    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21193   "andpd\t{%2, %0|%0, %2}"
21194   [(set_attr "type" "sselog")
21195    (set_attr "mode" "V2DF")])
21197 (define_expand "sse2_nandv2df3"
21198   [(set (match_operand:V2DF 0 "register_operand" "")
21199         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
21200                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21201   "TARGET_SSE2"
21202   "")
21204 (define_insn "*sse2_nandv2df3"
21205   [(set (match_operand:V2DF 0 "register_operand" "=x")
21206         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
21207                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21208   "TARGET_SSE2"
21209   "andnpd\t{%2, %0|%0, %2}"
21210   [(set_attr "type" "sselog")
21211    (set_attr "mode" "V2DF")])
21213 (define_expand "sse2_iorv2df3"
21214   [(set (match_operand:V2DF 0 "register_operand" "")
21215         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
21216                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21217   "TARGET_SSE2"
21218   "")
21220 (define_insn "*sse2_iorv2df3"
21221   [(set (match_operand:V2DF 0 "register_operand" "=x")
21222         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21223                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21224   "TARGET_SSE2
21225    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21226   "orpd\t{%2, %0|%0, %2}"
21227   [(set_attr "type" "sselog")
21228    (set_attr "mode" "V2DF")])
21230 (define_expand "sse2_xorv2df3"
21231   [(set (match_operand:V2DF 0 "register_operand" "")
21232         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
21233                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21234   "TARGET_SSE2"
21235   "")
21237 (define_insn "*sse2_xorv2df3"
21238   [(set (match_operand:V2DF 0 "register_operand" "=x")
21239         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21240                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21241   "TARGET_SSE2
21242    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21243   "xorpd\t{%2, %0|%0, %2}"
21244   [(set_attr "type" "sselog")
21245    (set_attr "mode" "V2DF")])
21247 ;; SSE2 integral logicals.  These patterns must always come after floating
21248 ;; point ones since we don't want compiler to use integer opcodes on floating
21249 ;; point SSE values to avoid matching of subregs in the match_operand.
21250 (define_insn "*sse2_andti3"
21251   [(set (match_operand:TI 0 "register_operand" "=x")
21252         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21253                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21254   "TARGET_SSE2
21255    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21256   "pand\t{%2, %0|%0, %2}"
21257   [(set_attr "type" "sselog")
21258    (set_attr "mode" "TI")])
21260 (define_insn "sse2_andv2di3"
21261   [(set (match_operand:V2DI 0 "register_operand" "=x")
21262         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21263                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21264   "TARGET_SSE2
21265    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21266   "pand\t{%2, %0|%0, %2}"
21267   [(set_attr "type" "sselog")
21268    (set_attr "mode" "TI")])
21270 (define_insn "*sse2_nandti3"
21271   [(set (match_operand:TI 0 "register_operand" "=x")
21272         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
21273                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21274   "TARGET_SSE2"
21275   "pandn\t{%2, %0|%0, %2}"
21276   [(set_attr "type" "sselog")
21277    (set_attr "mode" "TI")])
21279 (define_insn "sse2_nandv2di3"
21280   [(set (match_operand:V2DI 0 "register_operand" "=x")
21281         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
21282                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21283   "TARGET_SSE2
21284    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21285   "pandn\t{%2, %0|%0, %2}"
21286   [(set_attr "type" "sselog")
21287    (set_attr "mode" "TI")])
21289 (define_insn "*sse2_iorti3"
21290   [(set (match_operand:TI 0 "register_operand" "=x")
21291         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21292                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21293   "TARGET_SSE2
21294    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21295   "por\t{%2, %0|%0, %2}"
21296   [(set_attr "type" "sselog")
21297    (set_attr "mode" "TI")])
21299 (define_insn "sse2_iorv2di3"
21300   [(set (match_operand:V2DI 0 "register_operand" "=x")
21301         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21302                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21303   "TARGET_SSE2
21304    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21305   "por\t{%2, %0|%0, %2}"
21306   [(set_attr "type" "sselog")
21307    (set_attr "mode" "TI")])
21309 (define_insn "*sse2_xorti3"
21310   [(set (match_operand:TI 0 "register_operand" "=x")
21311         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21312                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21313   "TARGET_SSE2
21314    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21315   "pxor\t{%2, %0|%0, %2}"
21316   [(set_attr "type" "sselog")
21317    (set_attr "mode" "TI")])
21319 (define_insn "sse2_xorv2di3"
21320   [(set (match_operand:V2DI 0 "register_operand" "=x")
21321         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21322                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21323   "TARGET_SSE2
21324    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21325   "pxor\t{%2, %0|%0, %2}"
21326   [(set_attr "type" "sselog")
21327    (set_attr "mode" "TI")])
21329 ;; Use xor, but don't show input operands so they aren't live before
21330 ;; this insn.
21331 (define_insn "sse_clrv4sf"
21332   [(set (match_operand:V4SF 0 "register_operand" "=x")
21333         (match_operand:V4SF 1 "const0_operand" "X"))]
21334   "TARGET_SSE"
21336   if (get_attr_mode (insn) == MODE_TI)
21337     return "pxor\t{%0, %0|%0, %0}";
21338   else
21339     return "xorps\t{%0, %0|%0, %0}";
21341   [(set_attr "type" "sselog")
21342    (set_attr "memory" "none")
21343    (set (attr "mode")
21344         (if_then_else
21345            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21346                          (const_int 0))
21347                      (ne (symbol_ref "TARGET_SSE2")
21348                          (const_int 0)))
21349                 (eq (symbol_ref "optimize_size")
21350                     (const_int 0)))
21351          (const_string "TI")
21352          (const_string "V4SF")))])
21354 ;; Use xor, but don't show input operands so they aren't live before
21355 ;; this insn.
21356 (define_insn "sse_clrv2df"
21357   [(set (match_operand:V2DF 0 "register_operand" "=x")
21358         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21359   "TARGET_SSE2"
21360   "xorpd\t{%0, %0|%0, %0}"
21361   [(set_attr "type" "sselog")
21362    (set_attr "memory" "none")
21363    (set_attr "mode" "V4SF")])
21365 ;; SSE mask-generating compares
21367 (define_insn "maskcmpv4sf3"
21368   [(set (match_operand:V4SI 0 "register_operand" "=x")
21369         (match_operator:V4SI 3 "sse_comparison_operator"
21370                 [(match_operand:V4SF 1 "register_operand" "0")
21371                  (match_operand:V4SF 2 "register_operand" "x")]))]
21372   "TARGET_SSE"
21373   "cmp%D3ps\t{%2, %0|%0, %2}"
21374   [(set_attr "type" "ssecmp")
21375    (set_attr "mode" "V4SF")])
21377 (define_insn "maskncmpv4sf3"
21378   [(set (match_operand:V4SI 0 "register_operand" "=x")
21379         (not:V4SI
21380          (match_operator:V4SI 3 "sse_comparison_operator"
21381                 [(match_operand:V4SF 1 "register_operand" "0")
21382                  (match_operand:V4SF 2 "register_operand" "x")])))]
21383   "TARGET_SSE"
21385   if (GET_CODE (operands[3]) == UNORDERED)
21386     return "cmpordps\t{%2, %0|%0, %2}";
21387   else
21388     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21390   [(set_attr "type" "ssecmp")
21391    (set_attr "mode" "V4SF")])
21393 (define_insn "vmmaskcmpv4sf3"
21394   [(set (match_operand:V4SI 0 "register_operand" "=x")
21395         (vec_merge:V4SI
21396          (match_operator:V4SI 3 "sse_comparison_operator"
21397                 [(match_operand:V4SF 1 "register_operand" "0")
21398                  (match_operand:V4SF 2 "register_operand" "x")])
21399          (subreg:V4SI (match_dup 1) 0)
21400          (const_int 1)))]
21401   "TARGET_SSE"
21402   "cmp%D3ss\t{%2, %0|%0, %2}"
21403   [(set_attr "type" "ssecmp")
21404    (set_attr "mode" "SF")])
21406 (define_insn "vmmaskncmpv4sf3"
21407   [(set (match_operand:V4SI 0 "register_operand" "=x")
21408         (vec_merge:V4SI
21409          (not:V4SI
21410           (match_operator:V4SI 3 "sse_comparison_operator"
21411                 [(match_operand:V4SF 1 "register_operand" "0")
21412                  (match_operand:V4SF 2 "register_operand" "x")]))
21413          (subreg:V4SI (match_dup 1) 0)
21414          (const_int 1)))]
21415   "TARGET_SSE"
21417   if (GET_CODE (operands[3]) == UNORDERED)
21418     return "cmpordss\t{%2, %0|%0, %2}";
21419   else
21420     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21422   [(set_attr "type" "ssecmp")
21423    (set_attr "mode" "SF")])
21425 (define_insn "sse_comi"
21426   [(set (reg:CCFP FLAGS_REG)
21427         (compare:CCFP (vec_select:SF
21428                        (match_operand:V4SF 0 "register_operand" "x")
21429                        (parallel [(const_int 0)]))
21430                       (vec_select:SF
21431                        (match_operand:V4SF 1 "register_operand" "x")
21432                        (parallel [(const_int 0)]))))]
21433   "TARGET_SSE"
21434   "comiss\t{%1, %0|%0, %1}"
21435   [(set_attr "type" "ssecomi")
21436    (set_attr "mode" "SF")])
21438 (define_insn "sse_ucomi"
21439   [(set (reg:CCFPU FLAGS_REG)
21440         (compare:CCFPU (vec_select:SF
21441                         (match_operand:V4SF 0 "register_operand" "x")
21442                         (parallel [(const_int 0)]))
21443                        (vec_select:SF
21444                         (match_operand:V4SF 1 "register_operand" "x")
21445                         (parallel [(const_int 0)]))))]
21446   "TARGET_SSE"
21447   "ucomiss\t{%1, %0|%0, %1}"
21448   [(set_attr "type" "ssecomi")
21449    (set_attr "mode" "SF")])
21452 ;; SSE unpack
21454 (define_insn "sse_unpckhps"
21455   [(set (match_operand:V4SF 0 "register_operand" "=x")
21456         (vec_merge:V4SF
21457          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21458                           (parallel [(const_int 2)
21459                                      (const_int 0)
21460                                      (const_int 3)
21461                                      (const_int 1)]))
21462          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21463                           (parallel [(const_int 0)
21464                                      (const_int 2)
21465                                      (const_int 1)
21466                                      (const_int 3)]))
21467          (const_int 5)))]
21468   "TARGET_SSE"
21469   "unpckhps\t{%2, %0|%0, %2}"
21470   [(set_attr "type" "ssecvt")
21471    (set_attr "mode" "V4SF")])
21473 (define_insn "sse_unpcklps"
21474   [(set (match_operand:V4SF 0 "register_operand" "=x")
21475         (vec_merge:V4SF
21476          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21477                           (parallel [(const_int 0)
21478                                      (const_int 2)
21479                                      (const_int 1)
21480                                      (const_int 3)]))
21481          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21482                           (parallel [(const_int 2)
21483                                      (const_int 0)
21484                                      (const_int 3)
21485                                      (const_int 1)]))
21486          (const_int 5)))]
21487   "TARGET_SSE"
21488   "unpcklps\t{%2, %0|%0, %2}"
21489   [(set_attr "type" "ssecvt")
21490    (set_attr "mode" "V4SF")])
21493 ;; SSE min/max
21495 (define_insn "smaxv4sf3"
21496   [(set (match_operand:V4SF 0 "register_operand" "=x")
21497         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21498                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21499   "TARGET_SSE"
21500   "maxps\t{%2, %0|%0, %2}"
21501   [(set_attr "type" "sse")
21502    (set_attr "mode" "V4SF")])
21504 (define_insn "vmsmaxv4sf3"
21505   [(set (match_operand:V4SF 0 "register_operand" "=x")
21506         (vec_merge:V4SF
21507          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21508                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21509          (match_dup 1)
21510          (const_int 1)))]
21511   "TARGET_SSE"
21512   "maxss\t{%2, %0|%0, %2}"
21513   [(set_attr "type" "sse")
21514    (set_attr "mode" "SF")])
21516 (define_insn "sminv4sf3"
21517   [(set (match_operand:V4SF 0 "register_operand" "=x")
21518         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21519                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21520   "TARGET_SSE"
21521   "minps\t{%2, %0|%0, %2}"
21522   [(set_attr "type" "sse")
21523    (set_attr "mode" "V4SF")])
21525 (define_insn "vmsminv4sf3"
21526   [(set (match_operand:V4SF 0 "register_operand" "=x")
21527         (vec_merge:V4SF
21528          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21529                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21530          (match_dup 1)
21531          (const_int 1)))]
21532   "TARGET_SSE"
21533   "minss\t{%2, %0|%0, %2}"
21534   [(set_attr "type" "sse")
21535    (set_attr "mode" "SF")])
21537 ;; SSE <-> integer/MMX conversions
21539 (define_insn "cvtpi2ps"
21540   [(set (match_operand:V4SF 0 "register_operand" "=x")
21541         (vec_merge:V4SF
21542          (match_operand:V4SF 1 "register_operand" "0")
21543          (vec_duplicate:V4SF
21544           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21545          (const_int 12)))]
21546   "TARGET_SSE"
21547   "cvtpi2ps\t{%2, %0|%0, %2}"
21548   [(set_attr "type" "ssecvt")
21549    (set_attr "mode" "V4SF")])
21551 (define_insn "cvtps2pi"
21552   [(set (match_operand:V2SI 0 "register_operand" "=y")
21553         (vec_select:V2SI
21554          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21555          (parallel [(const_int 0) (const_int 1)])))]
21556   "TARGET_SSE"
21557   "cvtps2pi\t{%1, %0|%0, %1}"
21558   [(set_attr "type" "ssecvt")
21559    (set_attr "mode" "V4SF")])
21561 (define_insn "cvttps2pi"
21562   [(set (match_operand:V2SI 0 "register_operand" "=y")
21563         (vec_select:V2SI
21564          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21565                       UNSPEC_FIX)
21566          (parallel [(const_int 0) (const_int 1)])))]
21567   "TARGET_SSE"
21568   "cvttps2pi\t{%1, %0|%0, %1}"
21569   [(set_attr "type" "ssecvt")
21570    (set_attr "mode" "SF")])
21572 (define_insn "cvtsi2ss"
21573   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21574         (vec_merge:V4SF
21575          (match_operand:V4SF 1 "register_operand" "0,0")
21576          (vec_duplicate:V4SF
21577           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21578          (const_int 14)))]
21579   "TARGET_SSE"
21580   "cvtsi2ss\t{%2, %0|%0, %2}"
21581   [(set_attr "type" "sseicvt")
21582    (set_attr "athlon_decode" "vector,double")
21583    (set_attr "mode" "SF")])
21585 (define_insn "cvtsi2ssq"
21586   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21587         (vec_merge:V4SF
21588          (match_operand:V4SF 1 "register_operand" "0,0")
21589          (vec_duplicate:V4SF
21590           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21591          (const_int 14)))]
21592   "TARGET_SSE && TARGET_64BIT"
21593   "cvtsi2ssq\t{%2, %0|%0, %2}"
21594   [(set_attr "type" "sseicvt")
21595    (set_attr "athlon_decode" "vector,double")
21596    (set_attr "mode" "SF")])
21598 (define_insn "cvtss2si"
21599   [(set (match_operand:SI 0 "register_operand" "=r,r")
21600         (vec_select:SI
21601          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21602          (parallel [(const_int 0)])))]
21603   "TARGET_SSE"
21604   "cvtss2si\t{%1, %0|%0, %1}"
21605   [(set_attr "type" "sseicvt")
21606    (set_attr "athlon_decode" "double,vector")
21607    (set_attr "mode" "SI")])
21609 (define_insn "cvtss2siq"
21610   [(set (match_operand:DI 0 "register_operand" "=r,r")
21611         (vec_select:DI
21612          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21613          (parallel [(const_int 0)])))]
21614   "TARGET_SSE"
21615   "cvtss2siq\t{%1, %0|%0, %1}"
21616   [(set_attr "type" "sseicvt")
21617    (set_attr "athlon_decode" "double,vector")
21618    (set_attr "mode" "DI")])
21620 (define_insn "cvttss2si"
21621   [(set (match_operand:SI 0 "register_operand" "=r,r")
21622         (vec_select:SI
21623          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21624                       UNSPEC_FIX)
21625          (parallel [(const_int 0)])))]
21626   "TARGET_SSE"
21627   "cvttss2si\t{%1, %0|%0, %1}"
21628   [(set_attr "type" "sseicvt")
21629    (set_attr "mode" "SF")
21630    (set_attr "athlon_decode" "double,vector")])
21632 (define_insn "cvttss2siq"
21633   [(set (match_operand:DI 0 "register_operand" "=r,r")
21634         (vec_select:DI
21635          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21636                       UNSPEC_FIX)
21637          (parallel [(const_int 0)])))]
21638   "TARGET_SSE && TARGET_64BIT"
21639   "cvttss2siq\t{%1, %0|%0, %1}"
21640   [(set_attr "type" "sseicvt")
21641    (set_attr "mode" "SF")
21642    (set_attr "athlon_decode" "double,vector")])
21645 ;; MMX insns
21647 ;; MMX arithmetic
21649 (define_insn "addv8qi3"
21650   [(set (match_operand:V8QI 0 "register_operand" "=y")
21651         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21652                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21653   "TARGET_MMX"
21654   "paddb\t{%2, %0|%0, %2}"
21655   [(set_attr "type" "mmxadd")
21656    (set_attr "mode" "DI")])
21658 (define_insn "addv4hi3"
21659   [(set (match_operand:V4HI 0 "register_operand" "=y")
21660         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21661                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21662   "TARGET_MMX"
21663   "paddw\t{%2, %0|%0, %2}"
21664   [(set_attr "type" "mmxadd")
21665    (set_attr "mode" "DI")])
21667 (define_insn "addv2si3"
21668   [(set (match_operand:V2SI 0 "register_operand" "=y")
21669         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21670                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21671   "TARGET_MMX"
21672   "paddd\t{%2, %0|%0, %2}"
21673   [(set_attr "type" "mmxadd")
21674    (set_attr "mode" "DI")])
21676 (define_insn "mmx_adddi3"
21677   [(set (match_operand:DI 0 "register_operand" "=y")
21678         (unspec:DI
21679          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21680                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21681          UNSPEC_NOP))]
21682   "TARGET_MMX"
21683   "paddq\t{%2, %0|%0, %2}"
21684   [(set_attr "type" "mmxadd")
21685    (set_attr "mode" "DI")])
21687 (define_insn "ssaddv8qi3"
21688   [(set (match_operand:V8QI 0 "register_operand" "=y")
21689         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21690                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21691   "TARGET_MMX"
21692   "paddsb\t{%2, %0|%0, %2}"
21693   [(set_attr "type" "mmxadd")
21694    (set_attr "mode" "DI")])
21696 (define_insn "ssaddv4hi3"
21697   [(set (match_operand:V4HI 0 "register_operand" "=y")
21698         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21699                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21700   "TARGET_MMX"
21701   "paddsw\t{%2, %0|%0, %2}"
21702   [(set_attr "type" "mmxadd")
21703    (set_attr "mode" "DI")])
21705 (define_insn "usaddv8qi3"
21706   [(set (match_operand:V8QI 0 "register_operand" "=y")
21707         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21708                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21709   "TARGET_MMX"
21710   "paddusb\t{%2, %0|%0, %2}"
21711   [(set_attr "type" "mmxadd")
21712    (set_attr "mode" "DI")])
21714 (define_insn "usaddv4hi3"
21715   [(set (match_operand:V4HI 0 "register_operand" "=y")
21716         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21717                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21718   "TARGET_MMX"
21719   "paddusw\t{%2, %0|%0, %2}"
21720   [(set_attr "type" "mmxadd")
21721    (set_attr "mode" "DI")])
21723 (define_insn "subv8qi3"
21724   [(set (match_operand:V8QI 0 "register_operand" "=y")
21725         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21726                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21727   "TARGET_MMX"
21728   "psubb\t{%2, %0|%0, %2}"
21729   [(set_attr "type" "mmxadd")
21730    (set_attr "mode" "DI")])
21732 (define_insn "subv4hi3"
21733   [(set (match_operand:V4HI 0 "register_operand" "=y")
21734         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21735                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21736   "TARGET_MMX"
21737   "psubw\t{%2, %0|%0, %2}"
21738   [(set_attr "type" "mmxadd")
21739    (set_attr "mode" "DI")])
21741 (define_insn "subv2si3"
21742   [(set (match_operand:V2SI 0 "register_operand" "=y")
21743         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21744                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21745   "TARGET_MMX"
21746   "psubd\t{%2, %0|%0, %2}"
21747   [(set_attr "type" "mmxadd")
21748    (set_attr "mode" "DI")])
21750 (define_insn "mmx_subdi3"
21751   [(set (match_operand:DI 0 "register_operand" "=y")
21752         (unspec:DI
21753          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21754                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21755          UNSPEC_NOP))]
21756   "TARGET_MMX"
21757   "psubq\t{%2, %0|%0, %2}"
21758   [(set_attr "type" "mmxadd")
21759    (set_attr "mode" "DI")])
21761 (define_insn "sssubv8qi3"
21762   [(set (match_operand:V8QI 0 "register_operand" "=y")
21763         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21764                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21765   "TARGET_MMX"
21766   "psubsb\t{%2, %0|%0, %2}"
21767   [(set_attr "type" "mmxadd")
21768    (set_attr "mode" "DI")])
21770 (define_insn "sssubv4hi3"
21771   [(set (match_operand:V4HI 0 "register_operand" "=y")
21772         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21773                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21774   "TARGET_MMX"
21775   "psubsw\t{%2, %0|%0, %2}"
21776   [(set_attr "type" "mmxadd")
21777    (set_attr "mode" "DI")])
21779 (define_insn "ussubv8qi3"
21780   [(set (match_operand:V8QI 0 "register_operand" "=y")
21781         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21782                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21783   "TARGET_MMX"
21784   "psubusb\t{%2, %0|%0, %2}"
21785   [(set_attr "type" "mmxadd")
21786    (set_attr "mode" "DI")])
21788 (define_insn "ussubv4hi3"
21789   [(set (match_operand:V4HI 0 "register_operand" "=y")
21790         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21791                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21792   "TARGET_MMX"
21793   "psubusw\t{%2, %0|%0, %2}"
21794   [(set_attr "type" "mmxadd")
21795    (set_attr "mode" "DI")])
21797 (define_insn "mulv4hi3"
21798   [(set (match_operand:V4HI 0 "register_operand" "=y")
21799         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21800                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21801   "TARGET_MMX"
21802   "pmullw\t{%2, %0|%0, %2}"
21803   [(set_attr "type" "mmxmul")
21804    (set_attr "mode" "DI")])
21806 (define_insn "smulv4hi3_highpart"
21807   [(set (match_operand:V4HI 0 "register_operand" "=y")
21808         (truncate:V4HI
21809          (lshiftrt:V4SI
21810           (mult:V4SI (sign_extend:V4SI
21811                       (match_operand:V4HI 1 "register_operand" "0"))
21812                      (sign_extend:V4SI
21813                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21814           (const_int 16))))]
21815   "TARGET_MMX"
21816   "pmulhw\t{%2, %0|%0, %2}"
21817   [(set_attr "type" "mmxmul")
21818    (set_attr "mode" "DI")])
21820 (define_insn "umulv4hi3_highpart"
21821   [(set (match_operand:V4HI 0 "register_operand" "=y")
21822         (truncate:V4HI
21823          (lshiftrt:V4SI
21824           (mult:V4SI (zero_extend:V4SI
21825                       (match_operand:V4HI 1 "register_operand" "0"))
21826                      (zero_extend:V4SI
21827                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21828           (const_int 16))))]
21829   "TARGET_SSE || TARGET_3DNOW_A"
21830   "pmulhuw\t{%2, %0|%0, %2}"
21831   [(set_attr "type" "mmxmul")
21832    (set_attr "mode" "DI")])
21834 (define_insn "mmx_pmaddwd"
21835   [(set (match_operand:V2SI 0 "register_operand" "=y")
21836         (plus:V2SI
21837          (mult:V2SI
21838           (sign_extend:V2SI
21839            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21840                             (parallel [(const_int 0) (const_int 2)])))
21841           (sign_extend:V2SI
21842            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21843                             (parallel [(const_int 0) (const_int 2)]))))
21844          (mult:V2SI
21845           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21846                                              (parallel [(const_int 1)
21847                                                         (const_int 3)])))
21848           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21849                                              (parallel [(const_int 1)
21850                                                         (const_int 3)]))))))]
21851   "TARGET_MMX"
21852   "pmaddwd\t{%2, %0|%0, %2}"
21853   [(set_attr "type" "mmxmul")
21854    (set_attr "mode" "DI")])
21857 ;; MMX logical operations
21858 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21859 ;; normal code that also wants to use the FPU from getting broken.
21860 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21861 (define_insn "mmx_iordi3"
21862   [(set (match_operand:DI 0 "register_operand" "=y")
21863         (unspec:DI
21864          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21865                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21866          UNSPEC_NOP))]
21867   "TARGET_MMX"
21868   "por\t{%2, %0|%0, %2}"
21869   [(set_attr "type" "mmxadd")
21870    (set_attr "mode" "DI")])
21872 (define_insn "mmx_xordi3"
21873   [(set (match_operand:DI 0 "register_operand" "=y")
21874         (unspec:DI
21875          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21876                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21877          UNSPEC_NOP))]
21878   "TARGET_MMX"
21879   "pxor\t{%2, %0|%0, %2}"
21880   [(set_attr "type" "mmxadd")
21881    (set_attr "mode" "DI")
21882    (set_attr "memory" "none")])
21884 ;; Same as pxor, but don't show input operands so that we don't think
21885 ;; they are live.
21886 (define_insn "mmx_clrdi"
21887   [(set (match_operand:DI 0 "register_operand" "=y")
21888         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21889   "TARGET_MMX"
21890   "pxor\t{%0, %0|%0, %0}"
21891   [(set_attr "type" "mmxadd")
21892    (set_attr "mode" "DI")
21893    (set_attr "memory" "none")])
21895 (define_insn "mmx_anddi3"
21896   [(set (match_operand:DI 0 "register_operand" "=y")
21897         (unspec:DI
21898          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21899                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21900          UNSPEC_NOP))]
21901   "TARGET_MMX"
21902   "pand\t{%2, %0|%0, %2}"
21903   [(set_attr "type" "mmxadd")
21904    (set_attr "mode" "DI")])
21906 (define_insn "mmx_nanddi3"
21907   [(set (match_operand:DI 0 "register_operand" "=y")
21908         (unspec:DI
21909          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21910                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21911          UNSPEC_NOP))]
21912   "TARGET_MMX"
21913   "pandn\t{%2, %0|%0, %2}"
21914   [(set_attr "type" "mmxadd")
21915    (set_attr "mode" "DI")])
21918 ;; MMX unsigned averages/sum of absolute differences
21920 (define_insn "mmx_uavgv8qi3"
21921   [(set (match_operand:V8QI 0 "register_operand" "=y")
21922         (ashiftrt:V8QI
21923          (plus:V8QI (plus:V8QI
21924                      (match_operand:V8QI 1 "register_operand" "0")
21925                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21926                     (const_vector:V8QI [(const_int 1)
21927                                         (const_int 1)
21928                                         (const_int 1)
21929                                         (const_int 1)
21930                                         (const_int 1)
21931                                         (const_int 1)
21932                                         (const_int 1)
21933                                         (const_int 1)]))
21934          (const_int 1)))]
21935   "TARGET_SSE || TARGET_3DNOW_A"
21936   "pavgb\t{%2, %0|%0, %2}"
21937   [(set_attr "type" "mmxshft")
21938    (set_attr "mode" "DI")])
21940 (define_insn "mmx_uavgv4hi3"
21941   [(set (match_operand:V4HI 0 "register_operand" "=y")
21942         (ashiftrt:V4HI
21943          (plus:V4HI (plus:V4HI
21944                      (match_operand:V4HI 1 "register_operand" "0")
21945                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21946                     (const_vector:V4HI [(const_int 1)
21947                                         (const_int 1)
21948                                         (const_int 1)
21949                                         (const_int 1)]))
21950          (const_int 1)))]
21951   "TARGET_SSE || TARGET_3DNOW_A"
21952   "pavgw\t{%2, %0|%0, %2}"
21953   [(set_attr "type" "mmxshft")
21954    (set_attr "mode" "DI")])
21956 (define_insn "mmx_psadbw"
21957   [(set (match_operand:DI 0 "register_operand" "=y")
21958         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21959                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21960                    UNSPEC_PSADBW))]
21961   "TARGET_SSE || TARGET_3DNOW_A"
21962   "psadbw\t{%2, %0|%0, %2}"
21963   [(set_attr "type" "mmxshft")
21964    (set_attr "mode" "DI")])
21967 ;; MMX insert/extract/shuffle
21969 (define_insn "mmx_pinsrw"
21970   [(set (match_operand:V4HI 0 "register_operand" "=y")
21971         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21972                         (vec_duplicate:V4HI
21973                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21974                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21975   "TARGET_SSE || TARGET_3DNOW_A"
21976   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21977   [(set_attr "type" "mmxcvt")
21978    (set_attr "mode" "DI")])
21980 (define_insn "mmx_pextrw"
21981   [(set (match_operand:SI 0 "register_operand" "=r")
21982         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21983                                        (parallel
21984                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21985   "TARGET_SSE || TARGET_3DNOW_A"
21986   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21987   [(set_attr "type" "mmxcvt")
21988    (set_attr "mode" "DI")])
21990 (define_insn "mmx_pshufw"
21991   [(set (match_operand:V4HI 0 "register_operand" "=y")
21992         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21993                       (match_operand:SI 2 "immediate_operand" "i")]
21994                      UNSPEC_SHUFFLE))]
21995   "TARGET_SSE || TARGET_3DNOW_A"
21996   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21997   [(set_attr "type" "mmxcvt")
21998    (set_attr "mode" "DI")])
22001 ;; MMX mask-generating comparisons
22003 (define_insn "eqv8qi3"
22004   [(set (match_operand:V8QI 0 "register_operand" "=y")
22005         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
22006                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22007   "TARGET_MMX"
22008   "pcmpeqb\t{%2, %0|%0, %2}"
22009   [(set_attr "type" "mmxcmp")
22010    (set_attr "mode" "DI")])
22012 (define_insn "eqv4hi3"
22013   [(set (match_operand:V4HI 0 "register_operand" "=y")
22014         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
22015                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22016   "TARGET_MMX"
22017   "pcmpeqw\t{%2, %0|%0, %2}"
22018   [(set_attr "type" "mmxcmp")
22019    (set_attr "mode" "DI")])
22021 (define_insn "eqv2si3"
22022   [(set (match_operand:V2SI 0 "register_operand" "=y")
22023         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
22024                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
22025   "TARGET_MMX"
22026   "pcmpeqd\t{%2, %0|%0, %2}"
22027   [(set_attr "type" "mmxcmp")
22028    (set_attr "mode" "DI")])
22030 (define_insn "gtv8qi3"
22031   [(set (match_operand:V8QI 0 "register_operand" "=y")
22032         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
22033                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22034   "TARGET_MMX"
22035   "pcmpgtb\t{%2, %0|%0, %2}"
22036   [(set_attr "type" "mmxcmp")
22037    (set_attr "mode" "DI")])
22039 (define_insn "gtv4hi3"
22040   [(set (match_operand:V4HI 0 "register_operand" "=y")
22041         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22042                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22043   "TARGET_MMX"
22044   "pcmpgtw\t{%2, %0|%0, %2}"
22045   [(set_attr "type" "mmxcmp")
22046    (set_attr "mode" "DI")])
22048 (define_insn "gtv2si3"
22049   [(set (match_operand:V2SI 0 "register_operand" "=y")
22050         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22051                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
22052   "TARGET_MMX"
22053   "pcmpgtd\t{%2, %0|%0, %2}"
22054   [(set_attr "type" "mmxcmp")
22055    (set_attr "mode" "DI")])
22058 ;; MMX max/min insns
22060 (define_insn "umaxv8qi3"
22061   [(set (match_operand:V8QI 0 "register_operand" "=y")
22062         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
22063                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22064   "TARGET_SSE || TARGET_3DNOW_A"
22065   "pmaxub\t{%2, %0|%0, %2}"
22066   [(set_attr "type" "mmxadd")
22067    (set_attr "mode" "DI")])
22069 (define_insn "smaxv4hi3"
22070   [(set (match_operand:V4HI 0 "register_operand" "=y")
22071         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
22072                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22073   "TARGET_SSE || TARGET_3DNOW_A"
22074   "pmaxsw\t{%2, %0|%0, %2}"
22075   [(set_attr "type" "mmxadd")
22076    (set_attr "mode" "DI")])
22078 (define_insn "uminv8qi3"
22079   [(set (match_operand:V8QI 0 "register_operand" "=y")
22080         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
22081                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22082   "TARGET_SSE || TARGET_3DNOW_A"
22083   "pminub\t{%2, %0|%0, %2}"
22084   [(set_attr "type" "mmxadd")
22085    (set_attr "mode" "DI")])
22087 (define_insn "sminv4hi3"
22088   [(set (match_operand:V4HI 0 "register_operand" "=y")
22089         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
22090                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22091   "TARGET_SSE || TARGET_3DNOW_A"
22092   "pminsw\t{%2, %0|%0, %2}"
22093   [(set_attr "type" "mmxadd")
22094    (set_attr "mode" "DI")])
22097 ;; MMX shifts
22099 (define_insn "ashrv4hi3"
22100   [(set (match_operand:V4HI 0 "register_operand" "=y")
22101         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22102                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22103   "TARGET_MMX"
22104   "psraw\t{%2, %0|%0, %2}"
22105   [(set_attr "type" "mmxshft")
22106    (set_attr "mode" "DI")])
22108 (define_insn "ashrv2si3"
22109   [(set (match_operand:V2SI 0 "register_operand" "=y")
22110         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22111                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22112   "TARGET_MMX"
22113   "psrad\t{%2, %0|%0, %2}"
22114   [(set_attr "type" "mmxshft")
22115    (set_attr "mode" "DI")])
22117 (define_insn "lshrv4hi3"
22118   [(set (match_operand:V4HI 0 "register_operand" "=y")
22119         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22120                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22121   "TARGET_MMX"
22122   "psrlw\t{%2, %0|%0, %2}"
22123   [(set_attr "type" "mmxshft")
22124    (set_attr "mode" "DI")])
22126 (define_insn "lshrv2si3"
22127   [(set (match_operand:V2SI 0 "register_operand" "=y")
22128         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22129                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22130   "TARGET_MMX"
22131   "psrld\t{%2, %0|%0, %2}"
22132   [(set_attr "type" "mmxshft")
22133    (set_attr "mode" "DI")])
22135 ;; See logical MMX insns.
22136 (define_insn "mmx_lshrdi3"
22137   [(set (match_operand:DI 0 "register_operand" "=y")
22138         (unspec:DI
22139           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
22140                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
22141           UNSPEC_NOP))]
22142   "TARGET_MMX"
22143   "psrlq\t{%2, %0|%0, %2}"
22144   [(set_attr "type" "mmxshft")
22145    (set_attr "mode" "DI")])
22147 (define_insn "ashlv4hi3"
22148   [(set (match_operand:V4HI 0 "register_operand" "=y")
22149         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
22150                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22151   "TARGET_MMX"
22152   "psllw\t{%2, %0|%0, %2}"
22153   [(set_attr "type" "mmxshft")
22154    (set_attr "mode" "DI")])
22156 (define_insn "ashlv2si3"
22157   [(set (match_operand:V2SI 0 "register_operand" "=y")
22158         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
22159                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22160   "TARGET_MMX"
22161   "pslld\t{%2, %0|%0, %2}"
22162   [(set_attr "type" "mmxshft")
22163    (set_attr "mode" "DI")])
22165 ;; See logical MMX insns.
22166 (define_insn "mmx_ashldi3"
22167   [(set (match_operand:DI 0 "register_operand" "=y")
22168         (unspec:DI
22169          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
22170                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
22171          UNSPEC_NOP))]
22172   "TARGET_MMX"
22173   "psllq\t{%2, %0|%0, %2}"
22174   [(set_attr "type" "mmxshft")
22175    (set_attr "mode" "DI")])
22178 ;; MMX pack/unpack insns.
22180 (define_insn "mmx_packsswb"
22181   [(set (match_operand:V8QI 0 "register_operand" "=y")
22182         (vec_concat:V8QI
22183          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22184          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22185   "TARGET_MMX"
22186   "packsswb\t{%2, %0|%0, %2}"
22187   [(set_attr "type" "mmxshft")
22188    (set_attr "mode" "DI")])
22190 (define_insn "mmx_packssdw"
22191   [(set (match_operand:V4HI 0 "register_operand" "=y")
22192         (vec_concat:V4HI
22193          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
22194          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
22195   "TARGET_MMX"
22196   "packssdw\t{%2, %0|%0, %2}"
22197   [(set_attr "type" "mmxshft")
22198    (set_attr "mode" "DI")])
22200 (define_insn "mmx_packuswb"
22201   [(set (match_operand:V8QI 0 "register_operand" "=y")
22202         (vec_concat:V8QI
22203          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22204          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22205   "TARGET_MMX"
22206   "packuswb\t{%2, %0|%0, %2}"
22207   [(set_attr "type" "mmxshft")
22208    (set_attr "mode" "DI")])
22210 (define_insn "mmx_punpckhbw"
22211   [(set (match_operand:V8QI 0 "register_operand" "=y")
22212         (vec_merge:V8QI
22213          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22214                           (parallel [(const_int 4)
22215                                      (const_int 0)
22216                                      (const_int 5)
22217                                      (const_int 1)
22218                                      (const_int 6)
22219                                      (const_int 2)
22220                                      (const_int 7)
22221                                      (const_int 3)]))
22222          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22223                           (parallel [(const_int 0)
22224                                      (const_int 4)
22225                                      (const_int 1)
22226                                      (const_int 5)
22227                                      (const_int 2)
22228                                      (const_int 6)
22229                                      (const_int 3)
22230                                      (const_int 7)]))
22231          (const_int 85)))]
22232   "TARGET_MMX"
22233   "punpckhbw\t{%2, %0|%0, %2}"
22234   [(set_attr "type" "mmxcvt")
22235    (set_attr "mode" "DI")])
22237 (define_insn "mmx_punpckhwd"
22238   [(set (match_operand:V4HI 0 "register_operand" "=y")
22239         (vec_merge:V4HI
22240          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22241                           (parallel [(const_int 0)
22242                                      (const_int 2)
22243                                      (const_int 1)
22244                                      (const_int 3)]))
22245          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22246                           (parallel [(const_int 2)
22247                                      (const_int 0)
22248                                      (const_int 3)
22249                                      (const_int 1)]))
22250          (const_int 5)))]
22251   "TARGET_MMX"
22252   "punpckhwd\t{%2, %0|%0, %2}"
22253   [(set_attr "type" "mmxcvt")
22254    (set_attr "mode" "DI")])
22256 (define_insn "mmx_punpckhdq"
22257   [(set (match_operand:V2SI 0 "register_operand" "=y")
22258         (vec_merge:V2SI
22259          (match_operand:V2SI 1 "register_operand" "0")
22260          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
22261                           (parallel [(const_int 1)
22262                                      (const_int 0)]))
22263          (const_int 1)))]
22264   "TARGET_MMX"
22265   "punpckhdq\t{%2, %0|%0, %2}"
22266   [(set_attr "type" "mmxcvt")
22267    (set_attr "mode" "DI")])
22269 (define_insn "mmx_punpcklbw"
22270   [(set (match_operand:V8QI 0 "register_operand" "=y")
22271         (vec_merge:V8QI
22272          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22273                           (parallel [(const_int 0)
22274                                      (const_int 4)
22275                                      (const_int 1)
22276                                      (const_int 5)
22277                                      (const_int 2)
22278                                      (const_int 6)
22279                                      (const_int 3)
22280                                      (const_int 7)]))
22281          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22282                           (parallel [(const_int 4)
22283                                      (const_int 0)
22284                                      (const_int 5)
22285                                      (const_int 1)
22286                                      (const_int 6)
22287                                      (const_int 2)
22288                                      (const_int 7)
22289                                      (const_int 3)]))
22290          (const_int 85)))]
22291   "TARGET_MMX"
22292   "punpcklbw\t{%2, %0|%0, %2}"
22293   [(set_attr "type" "mmxcvt")
22294    (set_attr "mode" "DI")])
22296 (define_insn "mmx_punpcklwd"
22297   [(set (match_operand:V4HI 0 "register_operand" "=y")
22298         (vec_merge:V4HI
22299          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22300                           (parallel [(const_int 2)
22301                                      (const_int 0)
22302                                      (const_int 3)
22303                                      (const_int 1)]))
22304          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22305                           (parallel [(const_int 0)
22306                                      (const_int 2)
22307                                      (const_int 1)
22308                                      (const_int 3)]))
22309          (const_int 5)))]
22310   "TARGET_MMX"
22311   "punpcklwd\t{%2, %0|%0, %2}"
22312   [(set_attr "type" "mmxcvt")
22313    (set_attr "mode" "DI")])
22315 (define_insn "mmx_punpckldq"
22316   [(set (match_operand:V2SI 0 "register_operand" "=y")
22317         (vec_merge:V2SI
22318          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22319                            (parallel [(const_int 1)
22320                                       (const_int 0)]))
22321          (match_operand:V2SI 2 "register_operand" "y")
22322          (const_int 1)))]
22323   "TARGET_MMX"
22324   "punpckldq\t{%2, %0|%0, %2}"
22325   [(set_attr "type" "mmxcvt")
22326    (set_attr "mode" "DI")])
22329 ;; Miscellaneous stuff
22331 (define_insn "emms"
22332   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22333    (clobber (reg:XF 8))
22334    (clobber (reg:XF 9))
22335    (clobber (reg:XF 10))
22336    (clobber (reg:XF 11))
22337    (clobber (reg:XF 12))
22338    (clobber (reg:XF 13))
22339    (clobber (reg:XF 14))
22340    (clobber (reg:XF 15))
22341    (clobber (reg:DI 29))
22342    (clobber (reg:DI 30))
22343    (clobber (reg:DI 31))
22344    (clobber (reg:DI 32))
22345    (clobber (reg:DI 33))
22346    (clobber (reg:DI 34))
22347    (clobber (reg:DI 35))
22348    (clobber (reg:DI 36))]
22349   "TARGET_MMX"
22350   "emms"
22351   [(set_attr "type" "mmx")
22352    (set_attr "memory" "unknown")])
22354 (define_insn "ldmxcsr"
22355   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22356                     UNSPECV_LDMXCSR)]
22357   "TARGET_SSE"
22358   "ldmxcsr\t%0"
22359   [(set_attr "type" "sse")
22360    (set_attr "memory" "load")])
22362 (define_insn "stmxcsr"
22363   [(set (match_operand:SI 0 "memory_operand" "=m")
22364         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22365   "TARGET_SSE"
22366   "stmxcsr\t%0"
22367   [(set_attr "type" "sse")
22368    (set_attr "memory" "store")])
22370 (define_expand "sfence"
22371   [(set (match_dup 0)
22372         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22373   "TARGET_SSE || TARGET_3DNOW_A"
22375   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22376   MEM_VOLATILE_P (operands[0]) = 1;
22379 (define_insn "*sfence_insn"
22380   [(set (match_operand:BLK 0 "" "")
22381         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22382   "TARGET_SSE || TARGET_3DNOW_A"
22383   "sfence"
22384   [(set_attr "type" "sse")
22385    (set_attr "memory" "unknown")])
22387 (define_expand "sse_prologue_save"
22388   [(parallel [(set (match_operand:BLK 0 "" "")
22389                    (unspec:BLK [(reg:DI 21)
22390                                 (reg:DI 22)
22391                                 (reg:DI 23)
22392                                 (reg:DI 24)
22393                                 (reg:DI 25)
22394                                 (reg:DI 26)
22395                                 (reg:DI 27)
22396                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22397               (use (match_operand:DI 1 "register_operand" ""))
22398               (use (match_operand:DI 2 "immediate_operand" ""))
22399               (use (label_ref:DI (match_operand 3 "" "")))])]
22400   "TARGET_64BIT"
22401   "")
22403 (define_insn "*sse_prologue_save_insn"
22404   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22405                           (match_operand:DI 4 "const_int_operand" "n")))
22406         (unspec:BLK [(reg:DI 21)
22407                      (reg:DI 22)
22408                      (reg:DI 23)
22409                      (reg:DI 24)
22410                      (reg:DI 25)
22411                      (reg:DI 26)
22412                      (reg:DI 27)
22413                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22414    (use (match_operand:DI 1 "register_operand" "r"))
22415    (use (match_operand:DI 2 "const_int_operand" "i"))
22416    (use (label_ref:DI (match_operand 3 "" "X")))]
22417   "TARGET_64BIT
22418    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22419    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22420   "*
22422   int i;
22423   operands[0] = gen_rtx_MEM (Pmode,
22424                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22425   output_asm_insn (\"jmp\\t%A1\", operands);
22426   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22427     {
22428       operands[4] = adjust_address (operands[0], DImode, i*16);
22429       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22430       PUT_MODE (operands[4], TImode);
22431       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22432         output_asm_insn (\"rex\", operands);
22433       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22434     }
22435   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22436                              CODE_LABEL_NUMBER (operands[3]));
22437   RET;
22439   "
22440   [(set_attr "type" "other")
22441    (set_attr "length_immediate" "0")
22442    (set_attr "length_address" "0")
22443    (set_attr "length" "135")
22444    (set_attr "memory" "store")
22445    (set_attr "modrm" "0")
22446    (set_attr "mode" "DI")])
22448 ;; 3Dnow! instructions
22450 (define_insn "addv2sf3"
22451   [(set (match_operand:V2SF 0 "register_operand" "=y")
22452         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22453                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22454   "TARGET_3DNOW"
22455   "pfadd\\t{%2, %0|%0, %2}"
22456   [(set_attr "type" "mmxadd")
22457    (set_attr "mode" "V2SF")])
22459 (define_insn "subv2sf3"
22460   [(set (match_operand:V2SF 0 "register_operand" "=y")
22461         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22462                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22463   "TARGET_3DNOW"
22464   "pfsub\\t{%2, %0|%0, %2}"
22465   [(set_attr "type" "mmxadd")
22466    (set_attr "mode" "V2SF")])
22468 (define_insn "subrv2sf3"
22469   [(set (match_operand:V2SF 0 "register_operand" "=y")
22470         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22471                     (match_operand:V2SF 1 "register_operand" "0")))]
22472   "TARGET_3DNOW"
22473   "pfsubr\\t{%2, %0|%0, %2}"
22474   [(set_attr "type" "mmxadd")
22475    (set_attr "mode" "V2SF")])
22477 (define_insn "gtv2sf3"
22478   [(set (match_operand:V2SI 0 "register_operand" "=y")
22479         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22480                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22481  "TARGET_3DNOW"
22482   "pfcmpgt\\t{%2, %0|%0, %2}"
22483   [(set_attr "type" "mmxcmp")
22484    (set_attr "mode" "V2SF")])
22486 (define_insn "gev2sf3"
22487   [(set (match_operand:V2SI 0 "register_operand" "=y")
22488         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22489                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22490   "TARGET_3DNOW"
22491   "pfcmpge\\t{%2, %0|%0, %2}"
22492   [(set_attr "type" "mmxcmp")
22493    (set_attr "mode" "V2SF")])
22495 (define_insn "eqv2sf3"
22496   [(set (match_operand:V2SI 0 "register_operand" "=y")
22497         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22498                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22499   "TARGET_3DNOW"
22500   "pfcmpeq\\t{%2, %0|%0, %2}"
22501   [(set_attr "type" "mmxcmp")
22502    (set_attr "mode" "V2SF")])
22504 (define_insn "pfmaxv2sf3"
22505   [(set (match_operand:V2SF 0 "register_operand" "=y")
22506         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22507                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22508   "TARGET_3DNOW"
22509   "pfmax\\t{%2, %0|%0, %2}"
22510   [(set_attr "type" "mmxadd")
22511    (set_attr "mode" "V2SF")])
22513 (define_insn "pfminv2sf3"
22514   [(set (match_operand:V2SF 0 "register_operand" "=y")
22515         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22516                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22517   "TARGET_3DNOW"
22518   "pfmin\\t{%2, %0|%0, %2}"
22519   [(set_attr "type" "mmxadd")
22520    (set_attr "mode" "V2SF")])
22522 (define_insn "mulv2sf3"
22523   [(set (match_operand:V2SF 0 "register_operand" "=y")
22524         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22525                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22526   "TARGET_3DNOW"
22527   "pfmul\\t{%2, %0|%0, %2}"
22528   [(set_attr "type" "mmxmul")
22529    (set_attr "mode" "V2SF")])
22531 (define_insn "femms"
22532   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22533    (clobber (reg:XF 8))
22534    (clobber (reg:XF 9))
22535    (clobber (reg:XF 10))
22536    (clobber (reg:XF 11))
22537    (clobber (reg:XF 12))
22538    (clobber (reg:XF 13))
22539    (clobber (reg:XF 14))
22540    (clobber (reg:XF 15))
22541    (clobber (reg:DI 29))
22542    (clobber (reg:DI 30))
22543    (clobber (reg:DI 31))
22544    (clobber (reg:DI 32))
22545    (clobber (reg:DI 33))
22546    (clobber (reg:DI 34))
22547    (clobber (reg:DI 35))
22548    (clobber (reg:DI 36))]
22549   "TARGET_3DNOW"
22550   "femms"
22551   [(set_attr "type" "mmx")
22552    (set_attr "memory" "none")]) 
22554 (define_insn "pf2id"
22555   [(set (match_operand:V2SI 0 "register_operand" "=y")
22556         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22557   "TARGET_3DNOW"
22558   "pf2id\\t{%1, %0|%0, %1}"
22559   [(set_attr "type" "mmxcvt")
22560    (set_attr "mode" "V2SF")])
22562 (define_insn "pf2iw"
22563   [(set (match_operand:V2SI 0 "register_operand" "=y")
22564         (sign_extend:V2SI
22565            (ss_truncate:V2HI
22566               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22567   "TARGET_3DNOW_A"
22568   "pf2iw\\t{%1, %0|%0, %1}"
22569   [(set_attr "type" "mmxcvt")
22570    (set_attr "mode" "V2SF")])
22572 (define_insn "pfacc"
22573   [(set (match_operand:V2SF 0 "register_operand" "=y")
22574         (vec_concat:V2SF
22575            (plus:SF
22576               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22577                              (parallel [(const_int  0)]))
22578               (vec_select:SF (match_dup 1)
22579                              (parallel [(const_int 1)])))
22580            (plus:SF
22581               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22582                              (parallel [(const_int  0)]))
22583               (vec_select:SF (match_dup 2)
22584                              (parallel [(const_int 1)])))))]
22585   "TARGET_3DNOW"
22586   "pfacc\\t{%2, %0|%0, %2}"
22587   [(set_attr "type" "mmxadd")
22588    (set_attr "mode" "V2SF")])
22590 (define_insn "pfnacc"
22591   [(set (match_operand:V2SF 0 "register_operand" "=y")
22592         (vec_concat:V2SF
22593            (minus:SF
22594               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22595                              (parallel [(const_int 0)]))
22596               (vec_select:SF (match_dup 1)
22597                              (parallel [(const_int 1)])))
22598            (minus:SF
22599               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22600                              (parallel [(const_int  0)]))
22601               (vec_select:SF (match_dup 2)
22602                              (parallel [(const_int 1)])))))]
22603   "TARGET_3DNOW_A"
22604   "pfnacc\\t{%2, %0|%0, %2}"
22605   [(set_attr "type" "mmxadd")
22606    (set_attr "mode" "V2SF")])
22608 (define_insn "pfpnacc"
22609   [(set (match_operand:V2SF 0 "register_operand" "=y")
22610         (vec_concat:V2SF
22611            (minus:SF
22612               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22613                              (parallel [(const_int 0)]))
22614               (vec_select:SF (match_dup 1)
22615                              (parallel [(const_int 1)])))
22616            (plus:SF
22617               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22618                              (parallel [(const_int 0)]))
22619               (vec_select:SF (match_dup 2)
22620                              (parallel [(const_int 1)])))))]
22621   "TARGET_3DNOW_A"
22622   "pfpnacc\\t{%2, %0|%0, %2}"
22623   [(set_attr "type" "mmxadd")
22624    (set_attr "mode" "V2SF")])
22626 (define_insn "pi2fw"
22627   [(set (match_operand:V2SF 0 "register_operand" "=y")
22628         (float:V2SF
22629            (vec_concat:V2SI
22630               (sign_extend:SI
22631                  (truncate:HI
22632                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22633                                    (parallel [(const_int 0)]))))
22634               (sign_extend:SI
22635                  (truncate:HI
22636                     (vec_select:SI (match_dup 1)
22637                                    (parallel [(const_int  1)])))))))]
22638   "TARGET_3DNOW_A"
22639   "pi2fw\\t{%1, %0|%0, %1}"
22640   [(set_attr "type" "mmxcvt")
22641    (set_attr "mode" "V2SF")])
22643 (define_insn "floatv2si2"
22644   [(set (match_operand:V2SF 0 "register_operand" "=y")
22645         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22646   "TARGET_3DNOW"
22647   "pi2fd\\t{%1, %0|%0, %1}"
22648   [(set_attr "type" "mmxcvt")
22649    (set_attr "mode" "V2SF")])
22651 ;; This insn is identical to pavgb in operation, but the opcode is
22652 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22654 (define_insn "pavgusb"
22655  [(set (match_operand:V8QI 0 "register_operand" "=y")
22656        (unspec:V8QI
22657           [(match_operand:V8QI 1 "register_operand" "0")
22658            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22659           UNSPEC_PAVGUSB))]
22660   "TARGET_3DNOW"
22661   "pavgusb\\t{%2, %0|%0, %2}"
22662   [(set_attr "type" "mmxshft")
22663    (set_attr "mode" "TI")])
22665 ;; 3DNow reciprocal and sqrt
22667 (define_insn "pfrcpv2sf2"
22668   [(set (match_operand:V2SF 0 "register_operand" "=y")
22669         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22670         UNSPEC_PFRCP))]
22671   "TARGET_3DNOW"
22672   "pfrcp\\t{%1, %0|%0, %1}"
22673   [(set_attr "type" "mmx")
22674    (set_attr "mode" "TI")])
22676 (define_insn "pfrcpit1v2sf3"
22677   [(set (match_operand:V2SF 0 "register_operand" "=y")
22678         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22679                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22680                      UNSPEC_PFRCPIT1))]
22681   "TARGET_3DNOW"
22682   "pfrcpit1\\t{%2, %0|%0, %2}"
22683   [(set_attr "type" "mmx")
22684    (set_attr "mode" "TI")])
22686 (define_insn "pfrcpit2v2sf3"
22687   [(set (match_operand:V2SF 0 "register_operand" "=y")
22688         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22689                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22690                      UNSPEC_PFRCPIT2))]
22691   "TARGET_3DNOW"
22692   "pfrcpit2\\t{%2, %0|%0, %2}"
22693   [(set_attr "type" "mmx")
22694    (set_attr "mode" "TI")])
22696 (define_insn "pfrsqrtv2sf2"
22697   [(set (match_operand:V2SF 0 "register_operand" "=y")
22698         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22699                      UNSPEC_PFRSQRT))]
22700   "TARGET_3DNOW"
22701   "pfrsqrt\\t{%1, %0|%0, %1}"
22702   [(set_attr "type" "mmx")
22703    (set_attr "mode" "TI")])
22704                 
22705 (define_insn "pfrsqit1v2sf3"
22706   [(set (match_operand:V2SF 0 "register_operand" "=y")
22707         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22708                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22709                      UNSPEC_PFRSQIT1))]
22710   "TARGET_3DNOW"
22711   "pfrsqit1\\t{%2, %0|%0, %2}"
22712   [(set_attr "type" "mmx")
22713    (set_attr "mode" "TI")])
22715 (define_insn "pmulhrwv4hi3"
22716   [(set (match_operand:V4HI 0 "register_operand" "=y")
22717         (truncate:V4HI
22718            (lshiftrt:V4SI
22719               (plus:V4SI
22720                  (mult:V4SI
22721                     (sign_extend:V4SI
22722                        (match_operand:V4HI 1 "register_operand" "0"))
22723                     (sign_extend:V4SI
22724                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22725                  (const_vector:V4SI [(const_int 32768)
22726                                      (const_int 32768)
22727                                      (const_int 32768)
22728                                      (const_int 32768)]))
22729               (const_int 16))))]
22730   "TARGET_3DNOW"
22731   "pmulhrw\\t{%2, %0|%0, %2}"
22732   [(set_attr "type" "mmxmul")
22733    (set_attr "mode" "TI")])
22735 (define_insn "pswapdv2si2"
22736   [(set (match_operand:V2SI 0 "register_operand" "=y")
22737         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22738                          (parallel [(const_int 1) (const_int 0)])))]
22739   "TARGET_3DNOW_A"
22740   "pswapd\\t{%1, %0|%0, %1}"
22741   [(set_attr "type" "mmxcvt")
22742    (set_attr "mode" "TI")])
22744 (define_insn "pswapdv2sf2"
22745   [(set (match_operand:V2SF 0 "register_operand" "=y")
22746         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22747                          (parallel [(const_int 1) (const_int 0)])))]
22748   "TARGET_3DNOW_A"
22749   "pswapd\\t{%1, %0|%0, %1}"
22750   [(set_attr "type" "mmxcvt")
22751    (set_attr "mode" "TI")])
22753 (define_expand "prefetch"
22754   [(prefetch (match_operand 0 "address_operand" "")
22755              (match_operand:SI 1 "const_int_operand" "")
22756              (match_operand:SI 2 "const_int_operand" ""))]
22757   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22759   int rw = INTVAL (operands[1]);
22760   int locality = INTVAL (operands[2]);
22762   if (rw != 0 && rw != 1)
22763     abort ();
22764   if (locality < 0 || locality > 3)
22765     abort ();
22766   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22767     abort ();
22769   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22770      suported by SSE counterpart or the SSE prefetch is not available
22771      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22772      of locality.  */
22773   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22774     operands[2] = GEN_INT (3);
22775   else
22776     operands[1] = const0_rtx;
22779 (define_insn "*prefetch_sse"
22780   [(prefetch (match_operand:SI 0 "address_operand" "p")
22781              (const_int 0)
22782              (match_operand:SI 1 "const_int_operand" ""))]
22783   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22785   static const char * const patterns[4] = {
22786    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22787   };
22789   int locality = INTVAL (operands[1]);
22790   if (locality < 0 || locality > 3)
22791     abort ();
22793   return patterns[locality];  
22795   [(set_attr "type" "sse")
22796    (set_attr "memory" "none")])
22798 (define_insn "*prefetch_sse_rex"
22799   [(prefetch (match_operand:DI 0 "address_operand" "p")
22800              (const_int 0)
22801              (match_operand:SI 1 "const_int_operand" ""))]
22802   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22804   static const char * const patterns[4] = {
22805    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22806   };
22808   int locality = INTVAL (operands[1]);
22809   if (locality < 0 || locality > 3)
22810     abort ();
22812   return patterns[locality];  
22814   [(set_attr "type" "sse")
22815    (set_attr "memory" "none")])
22817 (define_insn "*prefetch_3dnow"
22818   [(prefetch (match_operand:SI 0 "address_operand" "p")
22819              (match_operand:SI 1 "const_int_operand" "n")
22820              (const_int 3))]
22821   "TARGET_3DNOW && !TARGET_64BIT"
22823   if (INTVAL (operands[1]) == 0)
22824     return "prefetch\t%a0";
22825   else
22826     return "prefetchw\t%a0";
22828   [(set_attr "type" "mmx")
22829    (set_attr "memory" "none")])
22831 (define_insn "*prefetch_3dnow_rex"
22832   [(prefetch (match_operand:DI 0 "address_operand" "p")
22833              (match_operand:SI 1 "const_int_operand" "n")
22834              (const_int 3))]
22835   "TARGET_3DNOW && TARGET_64BIT"
22837   if (INTVAL (operands[1]) == 0)
22838     return "prefetch\t%a0";
22839   else
22840     return "prefetchw\t%a0";
22842   [(set_attr "type" "mmx")
22843    (set_attr "memory" "none")])
22845 ;; SSE2 support
22847 (define_insn "addv2df3"
22848   [(set (match_operand:V2DF 0 "register_operand" "=x")
22849         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22850                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22851   "TARGET_SSE2"
22852   "addpd\t{%2, %0|%0, %2}"
22853   [(set_attr "type" "sseadd")
22854    (set_attr "mode" "V2DF")])
22856 (define_insn "vmaddv2df3"
22857   [(set (match_operand:V2DF 0 "register_operand" "=x")
22858         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22859                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22860                         (match_dup 1)
22861                         (const_int 1)))]
22862   "TARGET_SSE2"
22863   "addsd\t{%2, %0|%0, %2}"
22864   [(set_attr "type" "sseadd")
22865    (set_attr "mode" "DF")])
22867 (define_insn "subv2df3"
22868   [(set (match_operand:V2DF 0 "register_operand" "=x")
22869         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22870                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22871   "TARGET_SSE2"
22872   "subpd\t{%2, %0|%0, %2}"
22873   [(set_attr "type" "sseadd")
22874    (set_attr "mode" "V2DF")])
22876 (define_insn "vmsubv2df3"
22877   [(set (match_operand:V2DF 0 "register_operand" "=x")
22878         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22879                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22880                         (match_dup 1)
22881                         (const_int 1)))]
22882   "TARGET_SSE2"
22883   "subsd\t{%2, %0|%0, %2}"
22884   [(set_attr "type" "sseadd")
22885    (set_attr "mode" "DF")])
22887 (define_insn "mulv2df3"
22888   [(set (match_operand:V2DF 0 "register_operand" "=x")
22889         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22890                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22891   "TARGET_SSE2"
22892   "mulpd\t{%2, %0|%0, %2}"
22893   [(set_attr "type" "ssemul")
22894    (set_attr "mode" "V2DF")])
22896 (define_insn "vmmulv2df3"
22897   [(set (match_operand:V2DF 0 "register_operand" "=x")
22898         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22899                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22900                         (match_dup 1)
22901                         (const_int 1)))]
22902   "TARGET_SSE2"
22903   "mulsd\t{%2, %0|%0, %2}"
22904   [(set_attr "type" "ssemul")
22905    (set_attr "mode" "DF")])
22907 (define_insn "divv2df3"
22908   [(set (match_operand:V2DF 0 "register_operand" "=x")
22909         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22910                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22911   "TARGET_SSE2"
22912   "divpd\t{%2, %0|%0, %2}"
22913   [(set_attr "type" "ssediv")
22914    (set_attr "mode" "V2DF")])
22916 (define_insn "vmdivv2df3"
22917   [(set (match_operand:V2DF 0 "register_operand" "=x")
22918         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22919                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22920                         (match_dup 1)
22921                         (const_int 1)))]
22922   "TARGET_SSE2"
22923   "divsd\t{%2, %0|%0, %2}"
22924   [(set_attr "type" "ssediv")
22925    (set_attr "mode" "DF")])
22927 ;; SSE min/max
22929 (define_insn "smaxv2df3"
22930   [(set (match_operand:V2DF 0 "register_operand" "=x")
22931         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22932                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22933   "TARGET_SSE2"
22934   "maxpd\t{%2, %0|%0, %2}"
22935   [(set_attr "type" "sseadd")
22936    (set_attr "mode" "V2DF")])
22938 (define_insn "vmsmaxv2df3"
22939   [(set (match_operand:V2DF 0 "register_operand" "=x")
22940         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22941                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22942                         (match_dup 1)
22943                         (const_int 1)))]
22944   "TARGET_SSE2"
22945   "maxsd\t{%2, %0|%0, %2}"
22946   [(set_attr "type" "sseadd")
22947    (set_attr "mode" "DF")])
22949 (define_insn "sminv2df3"
22950   [(set (match_operand:V2DF 0 "register_operand" "=x")
22951         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22952                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22953   "TARGET_SSE2"
22954   "minpd\t{%2, %0|%0, %2}"
22955   [(set_attr "type" "sseadd")
22956    (set_attr "mode" "V2DF")])
22958 (define_insn "vmsminv2df3"
22959   [(set (match_operand:V2DF 0 "register_operand" "=x")
22960         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22961                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22962                         (match_dup 1)
22963                         (const_int 1)))]
22964   "TARGET_SSE2"
22965   "minsd\t{%2, %0|%0, %2}"
22966   [(set_attr "type" "sseadd")
22967    (set_attr "mode" "DF")])
22968 ;; SSE2 square root.  There doesn't appear to be an extension for the
22969 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22971 (define_insn "sqrtv2df2"
22972   [(set (match_operand:V2DF 0 "register_operand" "=x")
22973         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22974   "TARGET_SSE2"
22975   "sqrtpd\t{%1, %0|%0, %1}"
22976   [(set_attr "type" "sse")
22977    (set_attr "mode" "V2DF")])
22979 (define_insn "vmsqrtv2df2"
22980   [(set (match_operand:V2DF 0 "register_operand" "=x")
22981         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22982                         (match_operand:V2DF 2 "register_operand" "0")
22983                         (const_int 1)))]
22984   "TARGET_SSE2"
22985   "sqrtsd\t{%1, %0|%0, %1}"
22986   [(set_attr "type" "sse")
22987    (set_attr "mode" "SF")])
22989 ;; SSE mask-generating compares
22991 (define_insn "maskcmpv2df3"
22992   [(set (match_operand:V2DI 0 "register_operand" "=x")
22993         (match_operator:V2DI 3 "sse_comparison_operator"
22994                              [(match_operand:V2DF 1 "register_operand" "0")
22995                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22996   "TARGET_SSE2"
22997   "cmp%D3pd\t{%2, %0|%0, %2}"
22998   [(set_attr "type" "ssecmp")
22999    (set_attr "mode" "V2DF")])
23001 (define_insn "maskncmpv2df3"
23002   [(set (match_operand:V2DI 0 "register_operand" "=x")
23003         (not:V2DI
23004          (match_operator:V2DI 3 "sse_comparison_operator"
23005                               [(match_operand:V2DF 1 "register_operand" "0")
23006                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
23007   "TARGET_SSE2"
23009   if (GET_CODE (operands[3]) == UNORDERED)
23010     return "cmpordps\t{%2, %0|%0, %2}";
23011   else
23012     return "cmpn%D3pd\t{%2, %0|%0, %2}";
23014   [(set_attr "type" "ssecmp")
23015    (set_attr "mode" "V2DF")])
23017 (define_insn "vmmaskcmpv2df3"
23018   [(set (match_operand:V2DI 0 "register_operand" "=x")
23019         (vec_merge:V2DI
23020          (match_operator:V2DI 3 "sse_comparison_operator"
23021                               [(match_operand:V2DF 1 "register_operand" "0")
23022                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
23023          (subreg:V2DI (match_dup 1) 0)
23024          (const_int 1)))]
23025   "TARGET_SSE2"
23026   "cmp%D3sd\t{%2, %0|%0, %2}"
23027   [(set_attr "type" "ssecmp")
23028    (set_attr "mode" "DF")])
23030 (define_insn "vmmaskncmpv2df3"
23031   [(set (match_operand:V2DI 0 "register_operand" "=x")
23032         (vec_merge:V2DI
23033          (not:V2DI
23034           (match_operator:V2DI 3 "sse_comparison_operator"
23035                                [(match_operand:V2DF 1 "register_operand" "0")
23036                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
23037          (subreg:V2DI (match_dup 1) 0)
23038          (const_int 1)))]
23039   "TARGET_SSE2"
23041   if (GET_CODE (operands[3]) == UNORDERED)
23042     return "cmpordsd\t{%2, %0|%0, %2}";
23043   else
23044     return "cmpn%D3sd\t{%2, %0|%0, %2}";
23046   [(set_attr "type" "ssecmp")
23047    (set_attr "mode" "DF")])
23049 (define_insn "sse2_comi"
23050   [(set (reg:CCFP FLAGS_REG)
23051         (compare:CCFP (vec_select:DF
23052                        (match_operand:V2DF 0 "register_operand" "x")
23053                        (parallel [(const_int 0)]))
23054                       (vec_select:DF
23055                        (match_operand:V2DF 1 "register_operand" "x")
23056                        (parallel [(const_int 0)]))))]
23057   "TARGET_SSE2"
23058   "comisd\t{%1, %0|%0, %1}"
23059   [(set_attr "type" "ssecomi")
23060    (set_attr "mode" "DF")])
23062 (define_insn "sse2_ucomi"
23063   [(set (reg:CCFPU FLAGS_REG)
23064         (compare:CCFPU (vec_select:DF
23065                          (match_operand:V2DF 0 "register_operand" "x")
23066                          (parallel [(const_int 0)]))
23067                         (vec_select:DF
23068                          (match_operand:V2DF 1 "register_operand" "x")
23069                          (parallel [(const_int 0)]))))]
23070   "TARGET_SSE2"
23071   "ucomisd\t{%1, %0|%0, %1}"
23072   [(set_attr "type" "ssecomi")
23073    (set_attr "mode" "DF")])
23075 ;; SSE Strange Moves.
23077 (define_insn "sse2_movmskpd"
23078   [(set (match_operand:SI 0 "register_operand" "=r")
23079         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
23080                    UNSPEC_MOVMSK))]
23081   "TARGET_SSE2"
23082   "movmskpd\t{%1, %0|%0, %1}"
23083   [(set_attr "type" "ssecvt")
23084    (set_attr "mode" "V2DF")])
23086 (define_insn "sse2_pmovmskb"
23087   [(set (match_operand:SI 0 "register_operand" "=r")
23088         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
23089                    UNSPEC_MOVMSK))]
23090   "TARGET_SSE2"
23091   "pmovmskb\t{%1, %0|%0, %1}"
23092   [(set_attr "type" "ssecvt")
23093    (set_attr "mode" "V2DF")])
23095 (define_insn "sse2_maskmovdqu"
23096   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
23097         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23098                        (match_operand:V16QI 2 "register_operand" "x")]
23099                       UNSPEC_MASKMOV))]
23100   "TARGET_SSE2"
23101   ;; @@@ check ordering of operands in intel/nonintel syntax
23102   "maskmovdqu\t{%2, %1|%1, %2}"
23103   [(set_attr "type" "ssecvt")
23104    (set_attr "mode" "TI")])
23106 (define_insn "sse2_maskmovdqu_rex64"
23107   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
23108         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23109                        (match_operand:V16QI 2 "register_operand" "x")]
23110                       UNSPEC_MASKMOV))]
23111   "TARGET_SSE2"
23112   ;; @@@ check ordering of operands in intel/nonintel syntax
23113   "maskmovdqu\t{%2, %1|%1, %2}"
23114   [(set_attr "type" "ssecvt")
23115    (set_attr "mode" "TI")])
23117 (define_insn "sse2_movntv2df"
23118   [(set (match_operand:V2DF 0 "memory_operand" "=m")
23119         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
23120                      UNSPEC_MOVNT))]
23121   "TARGET_SSE2"
23122   "movntpd\t{%1, %0|%0, %1}"
23123   [(set_attr "type" "ssecvt")
23124    (set_attr "mode" "V2DF")])
23126 (define_insn "sse2_movntv2di"
23127   [(set (match_operand:V2DI 0 "memory_operand" "=m")
23128         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
23129                      UNSPEC_MOVNT))]
23130   "TARGET_SSE2"
23131   "movntdq\t{%1, %0|%0, %1}"
23132   [(set_attr "type" "ssecvt")
23133    (set_attr "mode" "TI")])
23135 (define_insn "sse2_movntsi"
23136   [(set (match_operand:SI 0 "memory_operand" "=m")
23137         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
23138                    UNSPEC_MOVNT))]
23139   "TARGET_SSE2"
23140   "movnti\t{%1, %0|%0, %1}"
23141   [(set_attr "type" "ssecvt")
23142    (set_attr "mode" "V2DF")])
23144 ;; SSE <-> integer/MMX conversions
23146 ;; Conversions between SI and SF
23148 (define_insn "cvtdq2ps"
23149   [(set (match_operand:V4SF 0 "register_operand" "=x")
23150         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
23151   "TARGET_SSE2"
23152   "cvtdq2ps\t{%1, %0|%0, %1}"
23153   [(set_attr "type" "ssecvt")
23154    (set_attr "mode" "V2DF")])
23156 (define_insn "cvtps2dq"
23157   [(set (match_operand:V4SI 0 "register_operand" "=x")
23158         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
23159   "TARGET_SSE2"
23160   "cvtps2dq\t{%1, %0|%0, %1}"
23161   [(set_attr "type" "ssecvt")
23162    (set_attr "mode" "TI")])
23164 (define_insn "cvttps2dq"
23165   [(set (match_operand:V4SI 0 "register_operand" "=x")
23166         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
23167                      UNSPEC_FIX))]
23168   "TARGET_SSE2"
23169   "cvttps2dq\t{%1, %0|%0, %1}"
23170   [(set_attr "type" "ssecvt")
23171    (set_attr "mode" "TI")])
23173 ;; Conversions between SI and DF
23175 (define_insn "cvtdq2pd"
23176   [(set (match_operand:V2DF 0 "register_operand" "=x")
23177         (float:V2DF (vec_select:V2SI
23178                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
23179                      (parallel
23180                       [(const_int 0)
23181                        (const_int 1)]))))]
23182   "TARGET_SSE2"
23183   "cvtdq2pd\t{%1, %0|%0, %1}"
23184   [(set_attr "type" "ssecvt")
23185    (set_attr "mode" "V2DF")])
23187 (define_insn "cvtpd2dq"
23188   [(set (match_operand:V4SI 0 "register_operand" "=x")
23189         (vec_concat:V4SI
23190          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
23191          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23192   "TARGET_SSE2"
23193   "cvtpd2dq\t{%1, %0|%0, %1}"
23194   [(set_attr "type" "ssecvt")
23195    (set_attr "mode" "TI")])
23197 (define_insn "cvttpd2dq"
23198   [(set (match_operand:V4SI 0 "register_operand" "=x")
23199         (vec_concat:V4SI
23200          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23201                       UNSPEC_FIX)
23202          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23203   "TARGET_SSE2"
23204   "cvttpd2dq\t{%1, %0|%0, %1}"
23205   [(set_attr "type" "ssecvt")
23206    (set_attr "mode" "TI")])
23208 (define_insn "cvtpd2pi"
23209   [(set (match_operand:V2SI 0 "register_operand" "=y")
23210         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
23211   "TARGET_SSE2"
23212   "cvtpd2pi\t{%1, %0|%0, %1}"
23213   [(set_attr "type" "ssecvt")
23214    (set_attr "mode" "TI")])
23216 (define_insn "cvttpd2pi"
23217   [(set (match_operand:V2SI 0 "register_operand" "=y")
23218         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23219                      UNSPEC_FIX))]
23220   "TARGET_SSE2"
23221   "cvttpd2pi\t{%1, %0|%0, %1}"
23222   [(set_attr "type" "ssecvt")
23223    (set_attr "mode" "TI")])
23225 (define_insn "cvtpi2pd"
23226   [(set (match_operand:V2DF 0 "register_operand" "=x")
23227         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
23228   "TARGET_SSE2"
23229   "cvtpi2pd\t{%1, %0|%0, %1}"
23230   [(set_attr "type" "ssecvt")
23231    (set_attr "mode" "TI")])
23233 ;; Conversions between SI and DF
23235 (define_insn "cvtsd2si"
23236   [(set (match_operand:SI 0 "register_operand" "=r,r")
23237         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23238                                (parallel [(const_int 0)]))))]
23239   "TARGET_SSE2"
23240   "cvtsd2si\t{%1, %0|%0, %1}"
23241   [(set_attr "type" "sseicvt")
23242    (set_attr "athlon_decode" "double,vector")
23243    (set_attr "mode" "SI")])
23245 (define_insn "cvtsd2siq"
23246   [(set (match_operand:DI 0 "register_operand" "=r,r")
23247         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23248                                (parallel [(const_int 0)]))))]
23249   "TARGET_SSE2 && TARGET_64BIT"
23250   "cvtsd2siq\t{%1, %0|%0, %1}"
23251   [(set_attr "type" "sseicvt")
23252    (set_attr "athlon_decode" "double,vector")
23253    (set_attr "mode" "DI")])
23255 (define_insn "cvttsd2si"
23256   [(set (match_operand:SI 0 "register_operand" "=r,r")
23257         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23258                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23259   "TARGET_SSE2"
23260   "cvttsd2si\t{%1, %0|%0, %1}"
23261   [(set_attr "type" "sseicvt")
23262    (set_attr "mode" "SI")
23263    (set_attr "athlon_decode" "double,vector")])
23265 (define_insn "cvttsd2siq"
23266   [(set (match_operand:DI 0 "register_operand" "=r,r")
23267         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23268                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23269   "TARGET_SSE2 && TARGET_64BIT"
23270   "cvttsd2siq\t{%1, %0|%0, %1}"
23271   [(set_attr "type" "sseicvt")
23272    (set_attr "mode" "DI")
23273    (set_attr "athlon_decode" "double,vector")])
23275 (define_insn "cvtsi2sd"
23276   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23277         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23278                         (vec_duplicate:V2DF
23279                           (float:DF
23280                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
23281                         (const_int 2)))]
23282   "TARGET_SSE2"
23283   "cvtsi2sd\t{%2, %0|%0, %2}"
23284   [(set_attr "type" "sseicvt")
23285    (set_attr "mode" "DF")
23286    (set_attr "athlon_decode" "double,direct")])
23288 (define_insn "cvtsi2sdq"
23289   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23290         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23291                         (vec_duplicate:V2DF
23292                           (float:DF
23293                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
23294                         (const_int 2)))]
23295   "TARGET_SSE2 && TARGET_64BIT"
23296   "cvtsi2sdq\t{%2, %0|%0, %2}"
23297   [(set_attr "type" "sseicvt")
23298    (set_attr "mode" "DF")
23299    (set_attr "athlon_decode" "double,direct")])
23301 ;; Conversions between SF and DF
23303 (define_insn "cvtsd2ss"
23304   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
23305         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
23306                         (vec_duplicate:V4SF
23307                           (float_truncate:V2SF
23308                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
23309                         (const_int 14)))]
23310   "TARGET_SSE2"
23311   "cvtsd2ss\t{%2, %0|%0, %2}"
23312   [(set_attr "type" "ssecvt")
23313    (set_attr "athlon_decode" "vector,double")
23314    (set_attr "mode" "SF")])
23316 (define_insn "cvtss2sd"
23317   [(set (match_operand:V2DF 0 "register_operand" "=x")
23318         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23319                         (float_extend:V2DF
23320                           (vec_select:V2SF
23321                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23322                             (parallel [(const_int 0)
23323                                        (const_int 1)])))
23324                         (const_int 2)))]
23325   "TARGET_SSE2"
23326   "cvtss2sd\t{%2, %0|%0, %2}"
23327   [(set_attr "type" "ssecvt")
23328    (set_attr "mode" "DF")])
23330 (define_insn "cvtpd2ps"
23331   [(set (match_operand:V4SF 0 "register_operand" "=x")
23332         (subreg:V4SF
23333           (vec_concat:V4SI
23334             (subreg:V2SI (float_truncate:V2SF
23335                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23336             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23337   "TARGET_SSE2"
23338   "cvtpd2ps\t{%1, %0|%0, %1}"
23339   [(set_attr "type" "ssecvt")
23340    (set_attr "mode" "V4SF")])
23342 (define_insn "cvtps2pd"
23343   [(set (match_operand:V2DF 0 "register_operand" "=x")
23344         (float_extend:V2DF
23345           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23346                            (parallel [(const_int 0)
23347                                       (const_int 1)]))))]
23348   "TARGET_SSE2"
23349   "cvtps2pd\t{%1, %0|%0, %1}"
23350   [(set_attr "type" "ssecvt")
23351    (set_attr "mode" "V2DF")])
23353 ;; SSE2 variants of MMX insns
23355 ;; MMX arithmetic
23357 (define_insn "addv16qi3"
23358   [(set (match_operand:V16QI 0 "register_operand" "=x")
23359         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23360                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23361   "TARGET_SSE2"
23362   "paddb\t{%2, %0|%0, %2}"
23363   [(set_attr "type" "sseiadd")
23364    (set_attr "mode" "TI")])
23366 (define_insn "addv8hi3"
23367   [(set (match_operand:V8HI 0 "register_operand" "=x")
23368         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23369                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23370   "TARGET_SSE2"
23371   "paddw\t{%2, %0|%0, %2}"
23372   [(set_attr "type" "sseiadd")
23373    (set_attr "mode" "TI")])
23375 (define_insn "addv4si3"
23376   [(set (match_operand:V4SI 0 "register_operand" "=x")
23377         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23378                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23379   "TARGET_SSE2"
23380   "paddd\t{%2, %0|%0, %2}"
23381   [(set_attr "type" "sseiadd")
23382    (set_attr "mode" "TI")])
23384 (define_insn "addv2di3"
23385   [(set (match_operand:V2DI 0 "register_operand" "=x")
23386         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23387                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23388   "TARGET_SSE2"
23389   "paddq\t{%2, %0|%0, %2}"
23390   [(set_attr "type" "sseiadd")
23391    (set_attr "mode" "TI")])
23393 (define_insn "ssaddv16qi3"
23394   [(set (match_operand:V16QI 0 "register_operand" "=x")
23395         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23396                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23397   "TARGET_SSE2"
23398   "paddsb\t{%2, %0|%0, %2}"
23399   [(set_attr "type" "sseiadd")
23400    (set_attr "mode" "TI")])
23402 (define_insn "ssaddv8hi3"
23403   [(set (match_operand:V8HI 0 "register_operand" "=x")
23404         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23405                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23406   "TARGET_SSE2"
23407   "paddsw\t{%2, %0|%0, %2}"
23408   [(set_attr "type" "sseiadd")
23409    (set_attr "mode" "TI")])
23411 (define_insn "usaddv16qi3"
23412   [(set (match_operand:V16QI 0 "register_operand" "=x")
23413         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23414                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23415   "TARGET_SSE2"
23416   "paddusb\t{%2, %0|%0, %2}"
23417   [(set_attr "type" "sseiadd")
23418    (set_attr "mode" "TI")])
23420 (define_insn "usaddv8hi3"
23421   [(set (match_operand:V8HI 0 "register_operand" "=x")
23422         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23423                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23424   "TARGET_SSE2"
23425   "paddusw\t{%2, %0|%0, %2}"
23426   [(set_attr "type" "sseiadd")
23427    (set_attr "mode" "TI")])
23429 (define_insn "subv16qi3"
23430   [(set (match_operand:V16QI 0 "register_operand" "=x")
23431         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23432                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23433   "TARGET_SSE2"
23434   "psubb\t{%2, %0|%0, %2}"
23435   [(set_attr "type" "sseiadd")
23436    (set_attr "mode" "TI")])
23438 (define_insn "subv8hi3"
23439   [(set (match_operand:V8HI 0 "register_operand" "=x")
23440         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23441                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23442   "TARGET_SSE2"
23443   "psubw\t{%2, %0|%0, %2}"
23444   [(set_attr "type" "sseiadd")
23445    (set_attr "mode" "TI")])
23447 (define_insn "subv4si3"
23448   [(set (match_operand:V4SI 0 "register_operand" "=x")
23449         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23450                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23451   "TARGET_SSE2"
23452   "psubd\t{%2, %0|%0, %2}"
23453   [(set_attr "type" "sseiadd")
23454    (set_attr "mode" "TI")])
23456 (define_insn "subv2di3"
23457   [(set (match_operand:V2DI 0 "register_operand" "=x")
23458         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23459                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23460   "TARGET_SSE2"
23461   "psubq\t{%2, %0|%0, %2}"
23462   [(set_attr "type" "sseiadd")
23463    (set_attr "mode" "TI")])
23465 (define_insn "sssubv16qi3"
23466   [(set (match_operand:V16QI 0 "register_operand" "=x")
23467         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23468                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23469   "TARGET_SSE2"
23470   "psubsb\t{%2, %0|%0, %2}"
23471   [(set_attr "type" "sseiadd")
23472    (set_attr "mode" "TI")])
23474 (define_insn "sssubv8hi3"
23475   [(set (match_operand:V8HI 0 "register_operand" "=x")
23476         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23477                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23478   "TARGET_SSE2"
23479   "psubsw\t{%2, %0|%0, %2}"
23480   [(set_attr "type" "sseiadd")
23481    (set_attr "mode" "TI")])
23483 (define_insn "ussubv16qi3"
23484   [(set (match_operand:V16QI 0 "register_operand" "=x")
23485         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23486                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23487   "TARGET_SSE2"
23488   "psubusb\t{%2, %0|%0, %2}"
23489   [(set_attr "type" "sseiadd")
23490    (set_attr "mode" "TI")])
23492 (define_insn "ussubv8hi3"
23493   [(set (match_operand:V8HI 0 "register_operand" "=x")
23494         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23495                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23496   "TARGET_SSE2"
23497   "psubusw\t{%2, %0|%0, %2}"
23498   [(set_attr "type" "sseiadd")
23499    (set_attr "mode" "TI")])
23501 (define_insn "mulv8hi3"
23502   [(set (match_operand:V8HI 0 "register_operand" "=x")
23503         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23504                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23505   "TARGET_SSE2"
23506   "pmullw\t{%2, %0|%0, %2}"
23507   [(set_attr "type" "sseimul")
23508    (set_attr "mode" "TI")])
23510 (define_insn "smulv8hi3_highpart"
23511   [(set (match_operand:V8HI 0 "register_operand" "=x")
23512         (truncate:V8HI
23513          (lshiftrt:V8SI
23514           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23515                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23516           (const_int 16))))]
23517   "TARGET_SSE2"
23518   "pmulhw\t{%2, %0|%0, %2}"
23519   [(set_attr "type" "sseimul")
23520    (set_attr "mode" "TI")])
23522 (define_insn "umulv8hi3_highpart"
23523   [(set (match_operand:V8HI 0 "register_operand" "=x")
23524         (truncate:V8HI
23525          (lshiftrt:V8SI
23526           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23527                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23528           (const_int 16))))]
23529   "TARGET_SSE2"
23530   "pmulhuw\t{%2, %0|%0, %2}"
23531   [(set_attr "type" "sseimul")
23532    (set_attr "mode" "TI")])
23534 (define_insn "sse2_umulsidi3"
23535   [(set (match_operand:DI 0 "register_operand" "=y")
23536         (mult:DI (zero_extend:DI (vec_select:SI
23537                                   (match_operand:V2SI 1 "register_operand" "0")
23538                                   (parallel [(const_int 0)])))
23539                  (zero_extend:DI (vec_select:SI
23540                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23541                                   (parallel [(const_int 0)])))))]
23542   "TARGET_SSE2"
23543   "pmuludq\t{%2, %0|%0, %2}"
23544   [(set_attr "type" "mmxmul")
23545    (set_attr "mode" "DI")])
23547 (define_insn "sse2_umulv2siv2di3"
23548   [(set (match_operand:V2DI 0 "register_operand" "=x")
23549         (mult:V2DI (zero_extend:V2DI
23550                      (vec_select:V2SI
23551                        (match_operand:V4SI 1 "register_operand" "0")
23552                        (parallel [(const_int 0) (const_int 2)])))
23553                    (zero_extend:V2DI
23554                      (vec_select:V2SI
23555                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23556                        (parallel [(const_int 0) (const_int 2)])))))]
23557   "TARGET_SSE2"
23558   "pmuludq\t{%2, %0|%0, %2}"
23559   [(set_attr "type" "sseimul")
23560    (set_attr "mode" "TI")])
23562 (define_insn "sse2_pmaddwd"
23563   [(set (match_operand:V4SI 0 "register_operand" "=x")
23564         (plus:V4SI
23565          (mult:V4SI
23566           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23567                                              (parallel [(const_int 0)
23568                                                         (const_int 2)
23569                                                         (const_int 4)
23570                                                         (const_int 6)])))
23571           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23572                                              (parallel [(const_int 0)
23573                                                         (const_int 2)
23574                                                         (const_int 4)
23575                                                         (const_int 6)]))))
23576          (mult:V4SI
23577           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23578                                              (parallel [(const_int 1)
23579                                                         (const_int 3)
23580                                                         (const_int 5)
23581                                                         (const_int 7)])))
23582           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23583                                              (parallel [(const_int 1)
23584                                                         (const_int 3)
23585                                                         (const_int 5)
23586                                                         (const_int 7)]))))))]
23587   "TARGET_SSE2"
23588   "pmaddwd\t{%2, %0|%0, %2}"
23589   [(set_attr "type" "sseiadd")
23590    (set_attr "mode" "TI")])
23592 ;; Same as pxor, but don't show input operands so that we don't think
23593 ;; they are live.
23594 (define_insn "sse2_clrti"
23595   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23596   "TARGET_SSE2"
23598   if (get_attr_mode (insn) == MODE_TI)
23599     return "pxor\t%0, %0";
23600   else
23601     return "xorps\t%0, %0";
23603   [(set_attr "type" "ssemov")
23604    (set_attr "memory" "none")
23605    (set (attr "mode")
23606               (if_then_else
23607                 (ne (symbol_ref "optimize_size")
23608                     (const_int 0))
23609                 (const_string "V4SF")
23610                 (const_string "TI")))])
23612 ;; MMX unsigned averages/sum of absolute differences
23614 (define_insn "sse2_uavgv16qi3"
23615   [(set (match_operand:V16QI 0 "register_operand" "=x")
23616         (ashiftrt:V16QI
23617          (plus:V16QI (plus:V16QI
23618                      (match_operand:V16QI 1 "register_operand" "0")
23619                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23620                      (const_vector:V16QI [(const_int 1) (const_int 1)
23621                                           (const_int 1) (const_int 1)
23622                                           (const_int 1) (const_int 1)
23623                                           (const_int 1) (const_int 1)
23624                                           (const_int 1) (const_int 1)
23625                                           (const_int 1) (const_int 1)
23626                                           (const_int 1) (const_int 1)
23627                                           (const_int 1) (const_int 1)]))
23628          (const_int 1)))]
23629   "TARGET_SSE2"
23630   "pavgb\t{%2, %0|%0, %2}"
23631   [(set_attr "type" "sseiadd")
23632    (set_attr "mode" "TI")])
23634 (define_insn "sse2_uavgv8hi3"
23635   [(set (match_operand:V8HI 0 "register_operand" "=x")
23636         (ashiftrt:V8HI
23637          (plus:V8HI (plus:V8HI
23638                      (match_operand:V8HI 1 "register_operand" "0")
23639                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23640                     (const_vector:V8HI [(const_int 1) (const_int 1)
23641                                         (const_int 1) (const_int 1)
23642                                         (const_int 1) (const_int 1)
23643                                         (const_int 1) (const_int 1)]))
23644          (const_int 1)))]
23645   "TARGET_SSE2"
23646   "pavgw\t{%2, %0|%0, %2}"
23647   [(set_attr "type" "sseiadd")
23648    (set_attr "mode" "TI")])
23650 ;; @@@ this isn't the right representation.
23651 (define_insn "sse2_psadbw"
23652   [(set (match_operand:V2DI 0 "register_operand" "=x")
23653         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23654                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23655                      UNSPEC_PSADBW))]
23656   "TARGET_SSE2"
23657   "psadbw\t{%2, %0|%0, %2}"
23658   [(set_attr "type" "sseiadd")
23659    (set_attr "mode" "TI")])
23662 ;; MMX insert/extract/shuffle
23664 (define_insn "sse2_pinsrw"
23665   [(set (match_operand:V8HI 0 "register_operand" "=x")
23666         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23667                         (vec_duplicate:V8HI
23668                          (truncate:HI
23669                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23670                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23671   "TARGET_SSE2"
23672   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23673   [(set_attr "type" "ssecvt")
23674    (set_attr "mode" "TI")])
23676 (define_insn "sse2_pextrw"
23677   [(set (match_operand:SI 0 "register_operand" "=r")
23678         (zero_extend:SI
23679           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23680                          (parallel
23681                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23682   "TARGET_SSE2"
23683   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23684   [(set_attr "type" "ssecvt")
23685    (set_attr "mode" "TI")])
23687 (define_insn "sse2_pshufd"
23688   [(set (match_operand:V4SI 0 "register_operand" "=x")
23689         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23690                       (match_operand:SI 2 "immediate_operand" "i")]
23691                      UNSPEC_SHUFFLE))]
23692   "TARGET_SSE2"
23693   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23694   [(set_attr "type" "ssecvt")
23695    (set_attr "mode" "TI")])
23697 (define_insn "sse2_pshuflw"
23698   [(set (match_operand:V8HI 0 "register_operand" "=x")
23699         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23700                       (match_operand:SI 2 "immediate_operand" "i")]
23701                      UNSPEC_PSHUFLW))]
23702   "TARGET_SSE2"
23703   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23704   [(set_attr "type" "ssecvt")
23705    (set_attr "mode" "TI")])
23707 (define_insn "sse2_pshufhw"
23708   [(set (match_operand:V8HI 0 "register_operand" "=x")
23709         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23710                       (match_operand:SI 2 "immediate_operand" "i")]
23711                      UNSPEC_PSHUFHW))]
23712   "TARGET_SSE2"
23713   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23714   [(set_attr "type" "ssecvt")
23715    (set_attr "mode" "TI")])
23717 ;; MMX mask-generating comparisons
23719 (define_insn "eqv16qi3"
23720   [(set (match_operand:V16QI 0 "register_operand" "=x")
23721         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23722                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23723   "TARGET_SSE2"
23724   "pcmpeqb\t{%2, %0|%0, %2}"
23725   [(set_attr "type" "ssecmp")
23726    (set_attr "mode" "TI")])
23728 (define_insn "eqv8hi3"
23729   [(set (match_operand:V8HI 0 "register_operand" "=x")
23730         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23731                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23732   "TARGET_SSE2"
23733   "pcmpeqw\t{%2, %0|%0, %2}"
23734   [(set_attr "type" "ssecmp")
23735    (set_attr "mode" "TI")])
23737 (define_insn "eqv4si3"
23738   [(set (match_operand:V4SI 0 "register_operand" "=x")
23739         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23740                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23741   "TARGET_SSE2"
23742   "pcmpeqd\t{%2, %0|%0, %2}"
23743   [(set_attr "type" "ssecmp")
23744    (set_attr "mode" "TI")])
23746 (define_insn "gtv16qi3"
23747   [(set (match_operand:V16QI 0 "register_operand" "=x")
23748         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23749                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23750   "TARGET_SSE2"
23751   "pcmpgtb\t{%2, %0|%0, %2}"
23752   [(set_attr "type" "ssecmp")
23753    (set_attr "mode" "TI")])
23755 (define_insn "gtv8hi3"
23756   [(set (match_operand:V8HI 0 "register_operand" "=x")
23757         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23758                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23759   "TARGET_SSE2"
23760   "pcmpgtw\t{%2, %0|%0, %2}"
23761   [(set_attr "type" "ssecmp")
23762    (set_attr "mode" "TI")])
23764 (define_insn "gtv4si3"
23765   [(set (match_operand:V4SI 0 "register_operand" "=x")
23766         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23767                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23768   "TARGET_SSE2"
23769   "pcmpgtd\t{%2, %0|%0, %2}"
23770   [(set_attr "type" "ssecmp")
23771    (set_attr "mode" "TI")])
23774 ;; MMX max/min insns
23776 (define_insn "umaxv16qi3"
23777   [(set (match_operand:V16QI 0 "register_operand" "=x")
23778         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23779                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23780   "TARGET_SSE2"
23781   "pmaxub\t{%2, %0|%0, %2}"
23782   [(set_attr "type" "sseiadd")
23783    (set_attr "mode" "TI")])
23785 (define_insn "smaxv8hi3"
23786   [(set (match_operand:V8HI 0 "register_operand" "=x")
23787         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23788                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23789   "TARGET_SSE2"
23790   "pmaxsw\t{%2, %0|%0, %2}"
23791   [(set_attr "type" "sseiadd")
23792    (set_attr "mode" "TI")])
23794 (define_insn "uminv16qi3"
23795   [(set (match_operand:V16QI 0 "register_operand" "=x")
23796         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23797                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23798   "TARGET_SSE2"
23799   "pminub\t{%2, %0|%0, %2}"
23800   [(set_attr "type" "sseiadd")
23801    (set_attr "mode" "TI")])
23803 (define_insn "sminv8hi3"
23804   [(set (match_operand:V8HI 0 "register_operand" "=x")
23805         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23806                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23807   "TARGET_SSE2"
23808   "pminsw\t{%2, %0|%0, %2}"
23809   [(set_attr "type" "sseiadd")
23810    (set_attr "mode" "TI")])
23813 ;; MMX shifts
23815 (define_insn "ashrv8hi3"
23816   [(set (match_operand:V8HI 0 "register_operand" "=x")
23817         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23818                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23819   "TARGET_SSE2"
23820   "psraw\t{%2, %0|%0, %2}"
23821   [(set_attr "type" "sseishft")
23822    (set_attr "mode" "TI")])
23824 (define_insn "ashrv4si3"
23825   [(set (match_operand:V4SI 0 "register_operand" "=x")
23826         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23827                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23828   "TARGET_SSE2"
23829   "psrad\t{%2, %0|%0, %2}"
23830   [(set_attr "type" "sseishft")
23831    (set_attr "mode" "TI")])
23833 (define_insn "lshrv8hi3"
23834   [(set (match_operand:V8HI 0 "register_operand" "=x")
23835         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23836                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23837   "TARGET_SSE2"
23838   "psrlw\t{%2, %0|%0, %2}"
23839   [(set_attr "type" "sseishft")
23840    (set_attr "mode" "TI")])
23842 (define_insn "lshrv4si3"
23843   [(set (match_operand:V4SI 0 "register_operand" "=x")
23844         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23845                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23846   "TARGET_SSE2"
23847   "psrld\t{%2, %0|%0, %2}"
23848   [(set_attr "type" "sseishft")
23849    (set_attr "mode" "TI")])
23851 (define_insn "lshrv2di3"
23852   [(set (match_operand:V2DI 0 "register_operand" "=x")
23853         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23854                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23855   "TARGET_SSE2"
23856   "psrlq\t{%2, %0|%0, %2}"
23857   [(set_attr "type" "sseishft")
23858    (set_attr "mode" "TI")])
23860 (define_insn "ashlv8hi3"
23861   [(set (match_operand:V8HI 0 "register_operand" "=x")
23862         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23863                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23864   "TARGET_SSE2"
23865   "psllw\t{%2, %0|%0, %2}"
23866   [(set_attr "type" "sseishft")
23867    (set_attr "mode" "TI")])
23869 (define_insn "ashlv4si3"
23870   [(set (match_operand:V4SI 0 "register_operand" "=x")
23871         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23872                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23873   "TARGET_SSE2"
23874   "pslld\t{%2, %0|%0, %2}"
23875   [(set_attr "type" "sseishft")
23876    (set_attr "mode" "TI")])
23878 (define_insn "ashlv2di3"
23879   [(set (match_operand:V2DI 0 "register_operand" "=x")
23880         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23881                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23882   "TARGET_SSE2"
23883   "psllq\t{%2, %0|%0, %2}"
23884   [(set_attr "type" "sseishft")
23885    (set_attr "mode" "TI")])
23887 (define_insn "ashrv8hi3_ti"
23888   [(set (match_operand:V8HI 0 "register_operand" "=x")
23889         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23890                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23891   "TARGET_SSE2"
23892   "psraw\t{%2, %0|%0, %2}"
23893   [(set_attr "type" "sseishft")
23894    (set_attr "mode" "TI")])
23896 (define_insn "ashrv4si3_ti"
23897   [(set (match_operand:V4SI 0 "register_operand" "=x")
23898         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23899                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23900   "TARGET_SSE2"
23901   "psrad\t{%2, %0|%0, %2}"
23902   [(set_attr "type" "sseishft")
23903    (set_attr "mode" "TI")])
23905 (define_insn "lshrv8hi3_ti"
23906   [(set (match_operand:V8HI 0 "register_operand" "=x")
23907         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23908                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23909   "TARGET_SSE2"
23910   "psrlw\t{%2, %0|%0, %2}"
23911   [(set_attr "type" "sseishft")
23912    (set_attr "mode" "TI")])
23914 (define_insn "lshrv4si3_ti"
23915   [(set (match_operand:V4SI 0 "register_operand" "=x")
23916         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23917                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23918   "TARGET_SSE2"
23919   "psrld\t{%2, %0|%0, %2}"
23920   [(set_attr "type" "sseishft")
23921    (set_attr "mode" "TI")])
23923 (define_insn "lshrv2di3_ti"
23924   [(set (match_operand:V2DI 0 "register_operand" "=x")
23925         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23926                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23927   "TARGET_SSE2"
23928   "psrlq\t{%2, %0|%0, %2}"
23929   [(set_attr "type" "sseishft")
23930    (set_attr "mode" "TI")])
23932 (define_insn "ashlv8hi3_ti"
23933   [(set (match_operand:V8HI 0 "register_operand" "=x")
23934         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23935                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23936   "TARGET_SSE2"
23937   "psllw\t{%2, %0|%0, %2}"
23938   [(set_attr "type" "sseishft")
23939    (set_attr "mode" "TI")])
23941 (define_insn "ashlv4si3_ti"
23942   [(set (match_operand:V4SI 0 "register_operand" "=x")
23943         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23944                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23945   "TARGET_SSE2"
23946   "pslld\t{%2, %0|%0, %2}"
23947   [(set_attr "type" "sseishft")
23948    (set_attr "mode" "TI")])
23950 (define_insn "ashlv2di3_ti"
23951   [(set (match_operand:V2DI 0 "register_operand" "=x")
23952         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23953                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23954   "TARGET_SSE2"
23955   "psllq\t{%2, %0|%0, %2}"
23956   [(set_attr "type" "sseishft")
23957    (set_attr "mode" "TI")])
23959 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23960 ;; we wouldn't need here it since we never generate TImode arithmetic.
23962 ;; There has to be some kind of prize for the weirdest new instruction...
23963 (define_insn "sse2_ashlti3"
23964   [(set (match_operand:TI 0 "register_operand" "=x")
23965         (unspec:TI
23966          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23967                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23968                                (const_int 8)))] UNSPEC_NOP))]
23969   "TARGET_SSE2"
23970   "pslldq\t{%2, %0|%0, %2}"
23971   [(set_attr "type" "sseishft")
23972    (set_attr "mode" "TI")])
23974 (define_insn "sse2_lshrti3"
23975   [(set (match_operand:TI 0 "register_operand" "=x")
23976         (unspec:TI
23977          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23978                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23979                                 (const_int 8)))] UNSPEC_NOP))]
23980   "TARGET_SSE2"
23981   "psrldq\t{%2, %0|%0, %2}"
23982   [(set_attr "type" "sseishft")
23983    (set_attr "mode" "TI")])
23985 ;; SSE unpack
23987 (define_insn "sse2_unpckhpd"
23988   [(set (match_operand:V2DF 0 "register_operand" "=x")
23989         (vec_concat:V2DF
23990          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23991                         (parallel [(const_int 1)]))
23992          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23993                         (parallel [(const_int 1)]))))]
23994   "TARGET_SSE2"
23995   "unpckhpd\t{%2, %0|%0, %2}"
23996   [(set_attr "type" "ssecvt")
23997    (set_attr "mode" "V2DF")])
23999 (define_insn "sse2_unpcklpd"
24000   [(set (match_operand:V2DF 0 "register_operand" "=x")
24001         (vec_concat:V2DF
24002          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
24003                         (parallel [(const_int 0)]))
24004          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
24005                         (parallel [(const_int 0)]))))]
24006   "TARGET_SSE2"
24007   "unpcklpd\t{%2, %0|%0, %2}"
24008   [(set_attr "type" "ssecvt")
24009    (set_attr "mode" "V2DF")])
24011 ;; MMX pack/unpack insns.
24013 (define_insn "sse2_packsswb"
24014   [(set (match_operand:V16QI 0 "register_operand" "=x")
24015         (vec_concat:V16QI
24016          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
24017          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
24018   "TARGET_SSE2"
24019   "packsswb\t{%2, %0|%0, %2}"
24020   [(set_attr "type" "ssecvt")
24021    (set_attr "mode" "TI")])
24023 (define_insn "sse2_packssdw"
24024   [(set (match_operand:V8HI 0 "register_operand" "=x")
24025         (vec_concat:V8HI
24026          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
24027          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
24028   "TARGET_SSE2"
24029   "packssdw\t{%2, %0|%0, %2}"
24030   [(set_attr "type" "ssecvt")
24031    (set_attr "mode" "TI")])
24033 (define_insn "sse2_packuswb"
24034   [(set (match_operand:V16QI 0 "register_operand" "=x")
24035         (vec_concat:V16QI
24036          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
24037          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
24038   "TARGET_SSE2"
24039   "packuswb\t{%2, %0|%0, %2}"
24040   [(set_attr "type" "ssecvt")
24041    (set_attr "mode" "TI")])
24043 (define_insn "sse2_punpckhbw"
24044   [(set (match_operand:V16QI 0 "register_operand" "=x")
24045         (vec_merge:V16QI
24046          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24047                            (parallel [(const_int 8) (const_int 0)
24048                                       (const_int 9) (const_int 1)
24049                                       (const_int 10) (const_int 2)
24050                                       (const_int 11) (const_int 3)
24051                                       (const_int 12) (const_int 4)
24052                                       (const_int 13) (const_int 5)
24053                                       (const_int 14) (const_int 6)
24054                                       (const_int 15) (const_int 7)]))
24055          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24056                            (parallel [(const_int 0) (const_int 8)
24057                                       (const_int 1) (const_int 9)
24058                                       (const_int 2) (const_int 10)
24059                                       (const_int 3) (const_int 11)
24060                                       (const_int 4) (const_int 12)
24061                                       (const_int 5) (const_int 13)
24062                                       (const_int 6) (const_int 14)
24063                                       (const_int 7) (const_int 15)]))
24064          (const_int 21845)))]
24065   "TARGET_SSE2"
24066   "punpckhbw\t{%2, %0|%0, %2}"
24067   [(set_attr "type" "ssecvt")
24068    (set_attr "mode" "TI")])
24070 (define_insn "sse2_punpckhwd"
24071   [(set (match_operand:V8HI 0 "register_operand" "=x")
24072         (vec_merge:V8HI
24073          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24074                           (parallel [(const_int 4) (const_int 0)
24075                                      (const_int 5) (const_int 1)
24076                                      (const_int 6) (const_int 2)
24077                                      (const_int 7) (const_int 3)]))
24078          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24079                           (parallel [(const_int 0) (const_int 4)
24080                                      (const_int 1) (const_int 5)
24081                                      (const_int 2) (const_int 6)
24082                                      (const_int 3) (const_int 7)]))
24083          (const_int 85)))]
24084   "TARGET_SSE2"
24085   "punpckhwd\t{%2, %0|%0, %2}"
24086   [(set_attr "type" "ssecvt")
24087    (set_attr "mode" "TI")])
24089 (define_insn "sse2_punpckhdq"
24090   [(set (match_operand:V4SI 0 "register_operand" "=x")
24091         (vec_merge:V4SI
24092          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24093                           (parallel [(const_int 2) (const_int 0)
24094                                      (const_int 3) (const_int 1)]))
24095          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24096                           (parallel [(const_int 0) (const_int 2)
24097                                      (const_int 1) (const_int 3)]))
24098          (const_int 5)))]
24099   "TARGET_SSE2"
24100   "punpckhdq\t{%2, %0|%0, %2}"
24101   [(set_attr "type" "ssecvt")
24102    (set_attr "mode" "TI")])
24104 (define_insn "sse2_punpcklbw"
24105   [(set (match_operand:V16QI 0 "register_operand" "=x")
24106         (vec_merge:V16QI
24107          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24108                            (parallel [(const_int 0) (const_int 8)
24109                                       (const_int 1) (const_int 9)
24110                                       (const_int 2) (const_int 10)
24111                                       (const_int 3) (const_int 11)
24112                                       (const_int 4) (const_int 12)
24113                                       (const_int 5) (const_int 13)
24114                                       (const_int 6) (const_int 14)
24115                                       (const_int 7) (const_int 15)]))
24116          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24117                            (parallel [(const_int 8) (const_int 0)
24118                                       (const_int 9) (const_int 1)
24119                                       (const_int 10) (const_int 2)
24120                                       (const_int 11) (const_int 3)
24121                                       (const_int 12) (const_int 4)
24122                                       (const_int 13) (const_int 5)
24123                                       (const_int 14) (const_int 6)
24124                                       (const_int 15) (const_int 7)]))
24125          (const_int 21845)))]
24126   "TARGET_SSE2"
24127   "punpcklbw\t{%2, %0|%0, %2}"
24128   [(set_attr "type" "ssecvt")
24129    (set_attr "mode" "TI")])
24131 (define_insn "sse2_punpcklwd"
24132   [(set (match_operand:V8HI 0 "register_operand" "=x")
24133         (vec_merge:V8HI
24134          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24135                           (parallel [(const_int 0) (const_int 4)
24136                                      (const_int 1) (const_int 5)
24137                                      (const_int 2) (const_int 6)
24138                                      (const_int 3) (const_int 7)]))
24139          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24140                           (parallel [(const_int 4) (const_int 0)
24141                                      (const_int 5) (const_int 1)
24142                                      (const_int 6) (const_int 2)
24143                                      (const_int 7) (const_int 3)]))
24144          (const_int 85)))]
24145   "TARGET_SSE2"
24146   "punpcklwd\t{%2, %0|%0, %2}"
24147   [(set_attr "type" "ssecvt")
24148    (set_attr "mode" "TI")])
24150 (define_insn "sse2_punpckldq"
24151   [(set (match_operand:V4SI 0 "register_operand" "=x")
24152         (vec_merge:V4SI
24153          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24154                           (parallel [(const_int 0) (const_int 2)
24155                                      (const_int 1) (const_int 3)]))
24156          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24157                           (parallel [(const_int 2) (const_int 0)
24158                                      (const_int 3) (const_int 1)]))
24159          (const_int 5)))]
24160   "TARGET_SSE2"
24161   "punpckldq\t{%2, %0|%0, %2}"
24162   [(set_attr "type" "ssecvt")
24163    (set_attr "mode" "TI")])
24165 (define_insn "sse2_punpcklqdq"
24166   [(set (match_operand:V2DI 0 "register_operand" "=x")
24167         (vec_merge:V2DI
24168          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24169                           (parallel [(const_int 1)
24170                                      (const_int 0)]))
24171          (match_operand:V2DI 1 "register_operand" "0")
24172          (const_int 1)))]
24173   "TARGET_SSE2"
24174   "punpcklqdq\t{%2, %0|%0, %2}"
24175   [(set_attr "type" "ssecvt")
24176    (set_attr "mode" "TI")])
24178 (define_insn "sse2_punpckhqdq"
24179   [(set (match_operand:V2DI 0 "register_operand" "=x")
24180         (vec_merge:V2DI
24181          (match_operand:V2DI 1 "register_operand" "0")
24182          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24183                           (parallel [(const_int 1)
24184                                      (const_int 0)]))
24185          (const_int 1)))]
24186   "TARGET_SSE2"
24187   "punpckhqdq\t{%2, %0|%0, %2}"
24188   [(set_attr "type" "ssecvt")
24189    (set_attr "mode" "TI")])
24191 ;; SSE2 moves
24193 (define_insn "sse2_movapd"
24194   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24195         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24196                      UNSPEC_MOVA))]
24197   "TARGET_SSE2
24198    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24199   "movapd\t{%1, %0|%0, %1}"
24200   [(set_attr "type" "ssemov")
24201    (set_attr "mode" "V2DF")])
24203 (define_insn "sse2_movupd"
24204   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24205         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24206                      UNSPEC_MOVU))]
24207   "TARGET_SSE2
24208    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24209   "movupd\t{%1, %0|%0, %1}"
24210   [(set_attr "type" "ssecvt")
24211    (set_attr "mode" "V2DF")])
24213 (define_insn "sse2_movdqa"
24214   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24215         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24216                        UNSPEC_MOVA))]
24217   "TARGET_SSE2
24218    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24219   "movdqa\t{%1, %0|%0, %1}"
24220   [(set_attr "type" "ssemov")
24221    (set_attr "mode" "TI")])
24223 (define_insn "sse2_movdqu"
24224   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24225         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24226                        UNSPEC_MOVU))]
24227   "TARGET_SSE2
24228    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24229   "movdqu\t{%1, %0|%0, %1}"
24230   [(set_attr "type" "ssecvt")
24231    (set_attr "mode" "TI")])
24233 (define_insn "sse2_movdq2q"
24234   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
24235         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
24236                        (parallel [(const_int 0)])))]
24237   "TARGET_SSE2 && !TARGET_64BIT"
24238   "@
24239    movq\t{%1, %0|%0, %1}
24240    movdq2q\t{%1, %0|%0, %1}"
24241   [(set_attr "type" "ssecvt")
24242    (set_attr "mode" "TI")])
24244 (define_insn "sse2_movdq2q_rex64"
24245   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
24246         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
24247                        (parallel [(const_int 0)])))]
24248   "TARGET_SSE2 && TARGET_64BIT"
24249   "@
24250    movq\t{%1, %0|%0, %1}
24251    movdq2q\t{%1, %0|%0, %1}
24252    movd\t{%1, %0|%0, %1}"
24253   [(set_attr "type" "ssecvt")
24254    (set_attr "mode" "TI")])
24256 (define_insn "sse2_movq2dq"
24257   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
24258         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
24259                          (const_int 0)))]
24260   "TARGET_SSE2 && !TARGET_64BIT"
24261   "@
24262    movq\t{%1, %0|%0, %1}
24263    movq2dq\t{%1, %0|%0, %1}"
24264   [(set_attr "type" "ssecvt,ssemov")
24265    (set_attr "mode" "TI")])
24267 (define_insn "sse2_movq2dq_rex64"
24268   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
24269         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
24270                          (const_int 0)))]
24271   "TARGET_SSE2 && TARGET_64BIT"
24272   "@
24273    movq\t{%1, %0|%0, %1}
24274    movq2dq\t{%1, %0|%0, %1}
24275    movd\t{%1, %0|%0, %1}"
24276   [(set_attr "type" "ssecvt,ssemov,ssecvt")
24277    (set_attr "mode" "TI")])
24279 (define_insn "sse2_movq"
24280   [(set (match_operand:V2DI 0 "register_operand" "=x")
24281         (vec_concat:V2DI (vec_select:DI
24282                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
24283                           (parallel [(const_int 0)]))
24284                          (const_int 0)))]
24285   "TARGET_SSE2"
24286   "movq\t{%1, %0|%0, %1}"
24287   [(set_attr "type" "ssemov")
24288    (set_attr "mode" "TI")])
24290 (define_insn "sse2_loadd"
24291   [(set (match_operand:V4SI 0 "register_operand" "=x")
24292         (vec_merge:V4SI
24293          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
24294          (const_vector:V4SI [(const_int 0)
24295                              (const_int 0)
24296                              (const_int 0)
24297                              (const_int 0)])
24298          (const_int 1)))]
24299   "TARGET_SSE2"
24300   "movd\t{%1, %0|%0, %1}"
24301   [(set_attr "type" "ssemov")
24302    (set_attr "mode" "TI")])
24304 (define_insn "sse2_stored"
24305   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
24306         (vec_select:SI
24307          (match_operand:V4SI 1 "register_operand" "x")
24308          (parallel [(const_int 0)])))]
24309   "TARGET_SSE2"
24310   "movd\t{%1, %0|%0, %1}"
24311   [(set_attr "type" "ssemov")
24312    (set_attr "mode" "TI")])
24314 (define_insn "sse2_movhpd"
24315   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24316         (vec_merge:V2DF
24317          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24318          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24319          (const_int 2)))]
24320   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24321   "movhpd\t{%2, %0|%0, %2}"
24322   [(set_attr "type" "ssecvt")
24323    (set_attr "mode" "V2DF")])
24325 (define_expand "sse2_loadsd"
24326   [(match_operand:V2DF 0 "register_operand" "")
24327    (match_operand:DF 1 "memory_operand" "")]
24328   "TARGET_SSE2"
24330   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24331                                 CONST0_RTX (V2DFmode)));
24332   DONE;
24335 (define_insn "sse2_loadsd_1"
24336   [(set (match_operand:V2DF 0 "register_operand" "=x")
24337         (vec_merge:V2DF
24338          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24339          (match_operand:V2DF 2 "const0_operand" "X")
24340          (const_int 1)))]
24341   "TARGET_SSE2"
24342   "movsd\t{%1, %0|%0, %1}"
24343   [(set_attr "type" "ssecvt")
24344    (set_attr "mode" "DF")])
24346 (define_insn "sse2_movsd"
24347   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24348         (vec_merge:V2DF
24349          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24350          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24351          (const_int 1)))]
24352   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24353   "@movsd\t{%2, %0|%0, %2}
24354     movlpd\t{%2, %0|%0, %2}
24355     movlpd\t{%2, %0|%0, %2}"
24356   [(set_attr "type" "ssecvt")
24357    (set_attr "mode" "DF,V2DF,V2DF")])
24359 (define_insn "sse2_storesd"
24360   [(set (match_operand:DF 0 "memory_operand" "=m")
24361         (vec_select:DF
24362          (match_operand:V2DF 1 "register_operand" "x")
24363          (parallel [(const_int 0)])))]
24364   "TARGET_SSE2"
24365   "movsd\t{%1, %0|%0, %1}"
24366   [(set_attr "type" "ssecvt")
24367    (set_attr "mode" "DF")])
24369 (define_insn "sse2_shufpd"
24370   [(set (match_operand:V2DF 0 "register_operand" "=x")
24371         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24372                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24373                       (match_operand:SI 3 "immediate_operand" "i")]
24374                      UNSPEC_SHUFFLE))]
24375   "TARGET_SSE2"
24376   ;; @@@ check operand order for intel/nonintel syntax
24377   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24378   [(set_attr "type" "ssecvt")
24379    (set_attr "mode" "V2DF")])
24381 (define_insn "sse2_clflush"
24382   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24383                     UNSPECV_CLFLUSH)]
24384   "TARGET_SSE2"
24385   "clflush\t%a0"
24386   [(set_attr "type" "sse")
24387    (set_attr "memory" "unknown")])
24389 (define_expand "sse2_mfence"
24390   [(set (match_dup 0)
24391         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24392   "TARGET_SSE2"
24394   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24395   MEM_VOLATILE_P (operands[0]) = 1;
24398 (define_insn "*mfence_insn"
24399   [(set (match_operand:BLK 0 "" "")
24400         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24401   "TARGET_SSE2"
24402   "mfence"
24403   [(set_attr "type" "sse")
24404    (set_attr "memory" "unknown")])
24406 (define_expand "sse2_lfence"
24407   [(set (match_dup 0)
24408         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24409   "TARGET_SSE2"
24411   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24412   MEM_VOLATILE_P (operands[0]) = 1;
24415 (define_insn "*lfence_insn"
24416   [(set (match_operand:BLK 0 "" "")
24417         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24418   "TARGET_SSE2"
24419   "lfence"
24420   [(set_attr "type" "sse")
24421    (set_attr "memory" "unknown")])
24423 ;; SSE3
24425 (define_insn "mwait"
24426   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24427                      (match_operand:SI 1 "register_operand" "c")]
24428                     UNSPECV_MWAIT)]
24429   "TARGET_SSE3"
24430   "mwait\t%0, %1"
24431   [(set_attr "length" "3")])
24433 (define_insn "monitor"
24434   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24435                      (match_operand:SI 1 "register_operand" "c")
24436                      (match_operand:SI 2 "register_operand" "d")]
24437                     UNSPECV_MONITOR)]
24438   "TARGET_SSE3"
24439   "monitor\t%0, %1, %2"
24440   [(set_attr "length" "3")])
24442 ;; SSE3 arithmetic
24444 (define_insn "addsubv4sf3"
24445   [(set (match_operand:V4SF 0 "register_operand" "=x")
24446         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24447                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24448                      UNSPEC_ADDSUB))]
24449   "TARGET_SSE3"
24450   "addsubps\t{%2, %0|%0, %2}"
24451   [(set_attr "type" "sseadd")
24452    (set_attr "mode" "V4SF")])
24454 (define_insn "addsubv2df3"
24455   [(set (match_operand:V2DF 0 "register_operand" "=x")
24456         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24457                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24458                      UNSPEC_ADDSUB))]
24459   "TARGET_SSE3"
24460   "addsubpd\t{%2, %0|%0, %2}"
24461   [(set_attr "type" "sseadd")
24462    (set_attr "mode" "V2DF")])
24464 (define_insn "haddv4sf3"
24465   [(set (match_operand:V4SF 0 "register_operand" "=x")
24466         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24467                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24468                      UNSPEC_HADD))]
24469   "TARGET_SSE3"
24470   "haddps\t{%2, %0|%0, %2}"
24471   [(set_attr "type" "sseadd")
24472    (set_attr "mode" "V4SF")])
24474 (define_insn "haddv2df3"
24475   [(set (match_operand:V2DF 0 "register_operand" "=x")
24476         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24477                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24478                      UNSPEC_HADD))]
24479   "TARGET_SSE3"
24480   "haddpd\t{%2, %0|%0, %2}"
24481   [(set_attr "type" "sseadd")
24482    (set_attr "mode" "V2DF")])
24484 (define_insn "hsubv4sf3"
24485   [(set (match_operand:V4SF 0 "register_operand" "=x")
24486         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24487                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24488                      UNSPEC_HSUB))]
24489   "TARGET_SSE3"
24490   "hsubps\t{%2, %0|%0, %2}"
24491   [(set_attr "type" "sseadd")
24492    (set_attr "mode" "V4SF")])
24494 (define_insn "hsubv2df3"
24495   [(set (match_operand:V2DF 0 "register_operand" "=x")
24496         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24497                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24498                      UNSPEC_HSUB))]
24499   "TARGET_SSE3"
24500   "hsubpd\t{%2, %0|%0, %2}"
24501   [(set_attr "type" "sseadd")
24502    (set_attr "mode" "V2DF")])
24504 (define_insn "movshdup"
24505   [(set (match_operand:V4SF 0 "register_operand" "=x")
24506         (unspec:V4SF
24507          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24508   "TARGET_SSE3"
24509   "movshdup\t{%1, %0|%0, %1}"
24510   [(set_attr "type" "sse")
24511    (set_attr "mode" "V4SF")])
24513 (define_insn "movsldup"
24514   [(set (match_operand:V4SF 0 "register_operand" "=x")
24515         (unspec:V4SF
24516          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24517   "TARGET_SSE3"
24518   "movsldup\t{%1, %0|%0, %1}"
24519   [(set_attr "type" "sse")
24520    (set_attr "mode" "V4SF")])
24522 (define_insn "lddqu"
24523   [(set (match_operand:V16QI 0 "register_operand" "=x")
24524         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24525                        UNSPEC_LDQQU))]
24526   "TARGET_SSE3"
24527   "lddqu\t{%1, %0|%0, %1}"
24528   [(set_attr "type" "ssecvt")
24529    (set_attr "mode" "TI")])
24531 (define_insn "loadddup"
24532   [(set (match_operand:V2DF 0 "register_operand" "=x")
24533         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24534   "TARGET_SSE3"
24535   "movddup\t{%1, %0|%0, %1}"
24536   [(set_attr "type" "ssecvt")
24537    (set_attr "mode" "DF")])
24539 (define_insn "movddup"
24540   [(set (match_operand:V2DF 0 "register_operand" "=x")
24541         (vec_duplicate:V2DF
24542          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24543                         (parallel [(const_int 0)]))))]
24544   "TARGET_SSE3"
24545   "movddup\t{%1, %0|%0, %1}"
24546   [(set_attr "type" "ssecvt")
24547    (set_attr "mode" "DF")])