* configure/i386/i386.md (*fix_trunch_1): Add "&& 1" to
[official-gcc.git] / gcc / config / i386 / i386.md
blobbed44e92aaeb8627784dc57cd95961823dc365ba
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,uninitialized,any"
435   (const_string "any"))
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
442 ;; Scheduling descriptions
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
450 ;; Operand and operator predicates
452 (include "predicates.md")
455 ;; Compare instructions.
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg 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"
808   "* return output_fp_compare (insn, operands, 2, 0);"
809   [(set_attr "type" "multi")
810    (set_attr "mode" "SF")])
812 (define_insn "*cmpfp_0_df"
813   [(set (match_operand:HI 0 "register_operand" "=a")
814         (unspec:HI
815           [(compare:CCFP
816              (match_operand:DF 1 "register_operand" "f")
817              (match_operand:DF 2 "const0_operand" "X"))]
818         UNSPEC_FNSTSW))]
819   "TARGET_80387"
820   "* return output_fp_compare (insn, operands, 2, 0);"
821   [(set_attr "type" "multi")
822    (set_attr "mode" "DF")])
824 (define_insn "*cmpfp_0_xf"
825   [(set (match_operand:HI 0 "register_operand" "=a")
826         (unspec:HI
827           [(compare:CCFP
828              (match_operand:XF 1 "register_operand" "f")
829              (match_operand:XF 2 "const0_operand" "X"))]
830         UNSPEC_FNSTSW))]
831   "TARGET_80387"
832   "* return output_fp_compare (insn, operands, 2, 0);"
833   [(set_attr "type" "multi")
834    (set_attr "mode" "XF")])
836 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
837 ;; used to manage the reg stack popping would not be preserved.
839 (define_insn "*cmpfp_2_sf"
840   [(set (reg:CCFP FPSR_REG)
841         (compare:CCFP
842           (match_operand:SF 0 "register_operand" "f")
843           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
844   "TARGET_80387"
845   "* return output_fp_compare (insn, operands, 0, 0);"
846   [(set_attr "type" "fcmp")
847    (set_attr "mode" "SF")])
849 (define_insn "*cmpfp_2_sf_1"
850   [(set (match_operand:HI 0 "register_operand" "=a")
851         (unspec:HI
852           [(compare:CCFP
853              (match_operand:SF 1 "register_operand" "f")
854              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
855           UNSPEC_FNSTSW))]
856   "TARGET_80387"
857   "* return output_fp_compare (insn, operands, 2, 0);"
858   [(set_attr "type" "fcmp")
859    (set_attr "mode" "SF")])
861 (define_insn "*cmpfp_2_df"
862   [(set (reg:CCFP FPSR_REG)
863         (compare:CCFP
864           (match_operand:DF 0 "register_operand" "f")
865           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
866   "TARGET_80387"
867   "* return output_fp_compare (insn, operands, 0, 0);"
868   [(set_attr "type" "fcmp")
869    (set_attr "mode" "DF")])
871 (define_insn "*cmpfp_2_df_1"
872   [(set (match_operand:HI 0 "register_operand" "=a")
873         (unspec:HI
874           [(compare:CCFP
875              (match_operand:DF 1 "register_operand" "f")
876              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
877           UNSPEC_FNSTSW))]
878   "TARGET_80387"
879   "* return output_fp_compare (insn, operands, 2, 0);"
880   [(set_attr "type" "multi")
881    (set_attr "mode" "DF")])
883 (define_insn "*cmpfp_2_xf"
884   [(set (reg:CCFP FPSR_REG)
885         (compare:CCFP
886           (match_operand:XF 0 "register_operand" "f")
887           (match_operand:XF 1 "register_operand" "f")))]
888   "TARGET_80387"
889   "* return output_fp_compare (insn, operands, 0, 0);"
890   [(set_attr "type" "fcmp")
891    (set_attr "mode" "XF")])
893 (define_insn "*cmpfp_2_xf_1"
894   [(set (match_operand:HI 0 "register_operand" "=a")
895         (unspec:HI
896           [(compare:CCFP
897              (match_operand:XF 1 "register_operand" "f")
898              (match_operand:XF 2 "register_operand" "f"))]
899           UNSPEC_FNSTSW))]
900   "TARGET_80387"
901   "* return output_fp_compare (insn, operands, 2, 0);"
902   [(set_attr "type" "multi")
903    (set_attr "mode" "XF")])
905 (define_insn "*cmpfp_2u"
906   [(set (reg:CCFPU FPSR_REG)
907         (compare:CCFPU
908           (match_operand 0 "register_operand" "f")
909           (match_operand 1 "register_operand" "f")))]
910   "TARGET_80387
911    && FLOAT_MODE_P (GET_MODE (operands[0]))
912    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
913   "* return output_fp_compare (insn, operands, 0, 1);"
914   [(set_attr "type" "fcmp")
915    (set (attr "mode")
916      (cond [(match_operand:SF 1 "" "")
917               (const_string "SF")
918             (match_operand:DF 1 "" "")
919               (const_string "DF")
920            ]
921            (const_string "XF")))])
923 (define_insn "*cmpfp_2u_1"
924   [(set (match_operand:HI 0 "register_operand" "=a")
925         (unspec:HI
926           [(compare:CCFPU
927              (match_operand 1 "register_operand" "f")
928              (match_operand 2 "register_operand" "f"))]
929           UNSPEC_FNSTSW))]
930   "TARGET_80387
931    && FLOAT_MODE_P (GET_MODE (operands[1]))
932    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
933   "* return output_fp_compare (insn, operands, 2, 1);"
934   [(set_attr "type" "multi")
935    (set (attr "mode")
936      (cond [(match_operand:SF 1 "" "")
937               (const_string "SF")
938             (match_operand:DF 1 "" "")
939               (const_string "DF")
940            ]
941            (const_string "XF")))])
943 ;; Patterns to match the SImode-in-memory ficom instructions.
945 ;; %%% Play games with accepting gp registers, as otherwise we have to
946 ;; force them to memory during rtl generation, which is no good.  We
947 ;; can get rid of this once we teach reload to do memory input reloads 
948 ;; via pushes.
950 (define_insn "*ficom_1"
951   [(set (reg:CCFP FPSR_REG)
952         (compare:CCFP
953           (match_operand 0 "register_operand" "f,f")
954           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
955   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
956    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
957   "#")
959 ;; Split the not-really-implemented gp register case into a
960 ;; push-op-pop sequence.
962 ;; %%% This is most efficient, but am I gonna get in trouble
963 ;; for separating cc0_setter and cc0_user?
965 (define_split
966   [(set (reg:CCFP FPSR_REG)
967         (compare:CCFP
968           (match_operand:SF 0 "register_operand" "")
969           (float (match_operand:SI 1 "register_operand" ""))))]
970   "0 && TARGET_80387 && reload_completed"
971   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 1))
972    (set (reg:CCFP FPSR_REG) (compare:CCFP (match_dup 0) (match_dup 2)))
973    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
974               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
975   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
976    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
978 ;; FP compares, step 2
979 ;; Move the fpsw to ax.
981 (define_insn "x86_fnstsw_1"
982   [(set (match_operand:HI 0 "register_operand" "=a")
983         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
984   "TARGET_80387"
985   "fnstsw\t%0"
986   [(set_attr "length" "2")
987    (set_attr "mode" "SI")
988    (set_attr "unit" "i387")])
990 ;; FP compares, step 3
991 ;; Get ax into flags, general case.
993 (define_insn "x86_sahf_1"
994   [(set (reg:CC FLAGS_REG)
995         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
996   "!TARGET_64BIT"
997   "sahf"
998   [(set_attr "length" "1")
999    (set_attr "athlon_decode" "vector")
1000    (set_attr "mode" "SI")])
1002 ;; Pentium Pro can do steps 1 through 3 in one go.
1004 (define_insn "*cmpfp_i"
1005   [(set (reg:CCFP FLAGS_REG)
1006         (compare:CCFP (match_operand 0 "register_operand" "f")
1007                       (match_operand 1 "register_operand" "f")))]
1008   "TARGET_80387 && TARGET_CMOVE
1009    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && FLOAT_MODE_P (GET_MODE (operands[0]))
1011    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1012   "* return output_fp_compare (insn, operands, 1, 0);"
1013   [(set_attr "type" "fcmp")
1014    (set (attr "mode")
1015      (cond [(match_operand:SF 1 "" "")
1016               (const_string "SF")
1017             (match_operand:DF 1 "" "")
1018               (const_string "DF")
1019            ]
1020            (const_string "XF")))
1021    (set_attr "athlon_decode" "vector")])
1023 (define_insn "*cmpfp_i_sse"
1024   [(set (reg:CCFP FLAGS_REG)
1025         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1026                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1027   "TARGET_80387
1028    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1029    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1030   "* return output_fp_compare (insn, operands, 1, 0);"
1031   [(set_attr "type" "fcmp,ssecomi")
1032    (set (attr "mode")
1033      (if_then_else (match_operand:SF 1 "" "")
1034         (const_string "SF")
1035         (const_string "DF")))
1036    (set_attr "athlon_decode" "vector")])
1038 (define_insn "*cmpfp_i_sse_only"
1039   [(set (reg:CCFP FLAGS_REG)
1040         (compare:CCFP (match_operand 0 "register_operand" "x")
1041                       (match_operand 1 "nonimmediate_operand" "xm")))]
1042   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1043    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1044   "* return output_fp_compare (insn, operands, 1, 0);"
1045   [(set_attr "type" "ssecomi")
1046    (set (attr "mode")
1047      (if_then_else (match_operand:SF 1 "" "")
1048         (const_string "SF")
1049         (const_string "DF")))
1050    (set_attr "athlon_decode" "vector")])
1052 (define_insn "*cmpfp_iu"
1053   [(set (reg:CCFPU FLAGS_REG)
1054         (compare:CCFPU (match_operand 0 "register_operand" "f")
1055                        (match_operand 1 "register_operand" "f")))]
1056   "TARGET_80387 && TARGET_CMOVE
1057    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1058    && FLOAT_MODE_P (GET_MODE (operands[0]))
1059    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1060   "* return output_fp_compare (insn, operands, 1, 1);"
1061   [(set_attr "type" "fcmp")
1062    (set (attr "mode")
1063      (cond [(match_operand:SF 1 "" "")
1064               (const_string "SF")
1065             (match_operand:DF 1 "" "")
1066               (const_string "DF")
1067            ]
1068            (const_string "XF")))
1069    (set_attr "athlon_decode" "vector")])
1071 (define_insn "*cmpfp_iu_sse"
1072   [(set (reg:CCFPU FLAGS_REG)
1073         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1074                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1075   "TARGET_80387
1076    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1077    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1078   "* return output_fp_compare (insn, operands, 1, 1);"
1079   [(set_attr "type" "fcmp,ssecomi")
1080    (set (attr "mode")
1081      (if_then_else (match_operand:SF 1 "" "")
1082         (const_string "SF")
1083         (const_string "DF")))
1084    (set_attr "athlon_decode" "vector")])
1086 (define_insn "*cmpfp_iu_sse_only"
1087   [(set (reg:CCFPU FLAGS_REG)
1088         (compare:CCFPU (match_operand 0 "register_operand" "x")
1089                        (match_operand 1 "nonimmediate_operand" "xm")))]
1090   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1091    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1092   "* return output_fp_compare (insn, operands, 1, 1);"
1093   [(set_attr "type" "ssecomi")
1094    (set (attr "mode")
1095      (if_then_else (match_operand:SF 1 "" "")
1096         (const_string "SF")
1097         (const_string "DF")))
1098    (set_attr "athlon_decode" "vector")])
1100 ;; Move instructions.
1102 ;; General case of fullword move.
1104 (define_expand "movsi"
1105   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1106         (match_operand:SI 1 "general_operand" ""))]
1107   ""
1108   "ix86_expand_move (SImode, operands); DONE;")
1110 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1111 ;; general_operand.
1113 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1114 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1115 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1116 ;; targets without our curiosities, and it is just as easy to represent
1117 ;; this differently.
1119 (define_insn "*pushsi2"
1120   [(set (match_operand:SI 0 "push_operand" "=<")
1121         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1122   "!TARGET_64BIT"
1123   "push{l}\t%1"
1124   [(set_attr "type" "push")
1125    (set_attr "mode" "SI")])
1127 ;; For 64BIT abi we always round up to 8 bytes.
1128 (define_insn "*pushsi2_rex64"
1129   [(set (match_operand:SI 0 "push_operand" "=X")
1130         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1131   "TARGET_64BIT"
1132   "push{q}\t%q1"
1133   [(set_attr "type" "push")
1134    (set_attr "mode" "SI")])
1136 (define_insn "*pushsi2_prologue"
1137   [(set (match_operand:SI 0 "push_operand" "=<")
1138         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1139    (clobber (mem:BLK (scratch)))]
1140   "!TARGET_64BIT"
1141   "push{l}\t%1"
1142   [(set_attr "type" "push")
1143    (set_attr "mode" "SI")])
1145 (define_insn "*popsi1_epilogue"
1146   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1147         (mem:SI (reg:SI SP_REG)))
1148    (set (reg:SI SP_REG)
1149         (plus:SI (reg:SI SP_REG) (const_int 4)))
1150    (clobber (mem:BLK (scratch)))]
1151   "!TARGET_64BIT"
1152   "pop{l}\t%0"
1153   [(set_attr "type" "pop")
1154    (set_attr "mode" "SI")])
1156 (define_insn "popsi1"
1157   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1158         (mem:SI (reg:SI SP_REG)))
1159    (set (reg:SI SP_REG)
1160         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1161   "!TARGET_64BIT"
1162   "pop{l}\t%0"
1163   [(set_attr "type" "pop")
1164    (set_attr "mode" "SI")])
1166 (define_insn "*movsi_xor"
1167   [(set (match_operand:SI 0 "register_operand" "=r")
1168         (match_operand:SI 1 "const0_operand" "i"))
1169    (clobber (reg:CC FLAGS_REG))]
1170   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1171   "xor{l}\t{%0, %0|%0, %0}"
1172   [(set_attr "type" "alu1")
1173    (set_attr "mode" "SI")
1174    (set_attr "length_immediate" "0")])
1176 (define_insn "*movsi_or"
1177   [(set (match_operand:SI 0 "register_operand" "=r")
1178         (match_operand:SI 1 "immediate_operand" "i"))
1179    (clobber (reg:CC FLAGS_REG))]
1180   "reload_completed
1181    && operands[1] == constm1_rtx
1182    && (TARGET_PENTIUM || optimize_size)"
1184   operands[1] = constm1_rtx;
1185   return "or{l}\t{%1, %0|%0, %1}";
1187   [(set_attr "type" "alu1")
1188    (set_attr "mode" "SI")
1189    (set_attr "length_immediate" "1")])
1191 (define_insn "*movsi_1"
1192   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1193         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1194   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1195    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1197   switch (get_attr_type (insn))
1198     {
1199     case TYPE_SSEMOV:
1200       if (get_attr_mode (insn) == MODE_TI)
1201         return "movdqa\t{%1, %0|%0, %1}";
1202       return "movd\t{%1, %0|%0, %1}";
1204     case TYPE_MMXMOV:
1205       if (get_attr_mode (insn) == MODE_DI)
1206         return "movq\t{%1, %0|%0, %1}";
1207       return "movd\t{%1, %0|%0, %1}";
1209     case TYPE_LEA:
1210       return "lea{l}\t{%1, %0|%0, %1}";
1212     default:
1213       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1214         abort();
1215       return "mov{l}\t{%1, %0|%0, %1}";
1216     }
1218   [(set (attr "type")
1219      (cond [(eq_attr "alternative" "2,3,4")
1220               (const_string "mmxmov")
1221             (eq_attr "alternative" "5,6,7")
1222               (const_string "ssemov")
1223             (and (ne (symbol_ref "flag_pic") (const_int 0))
1224                  (match_operand:SI 1 "symbolic_operand" ""))
1225               (const_string "lea")
1226            ]
1227            (const_string "imov")))
1228    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1230 (define_insn "*movsi_1_nointernunit"
1231   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1232         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1233   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1234    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1236   switch (get_attr_type (insn))
1237     {
1238     case TYPE_SSEMOV:
1239       if (get_attr_mode (insn) == MODE_TI)
1240         return "movdqa\t{%1, %0|%0, %1}";
1241       return "movd\t{%1, %0|%0, %1}";
1243     case TYPE_MMXMOV:
1244       if (get_attr_mode (insn) == MODE_DI)
1245         return "movq\t{%1, %0|%0, %1}";
1246       return "movd\t{%1, %0|%0, %1}";
1248     case TYPE_LEA:
1249       return "lea{l}\t{%1, %0|%0, %1}";
1251     default:
1252       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1253         abort();
1254       return "mov{l}\t{%1, %0|%0, %1}";
1255     }
1257   [(set (attr "type")
1258      (cond [(eq_attr "alternative" "2,3,4")
1259               (const_string "mmxmov")
1260             (eq_attr "alternative" "5,6,7")
1261               (const_string "ssemov")
1262             (and (ne (symbol_ref "flag_pic") (const_int 0))
1263                  (match_operand:SI 1 "symbolic_operand" ""))
1264               (const_string "lea")
1265            ]
1266            (const_string "imov")))
1267    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1269 ;; Stores and loads of ax to arbitrary constant address.
1270 ;; We fake an second form of instruction to force reload to load address
1271 ;; into register when rax is not available
1272 (define_insn "*movabssi_1_rex64"
1273   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1274         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1275   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1276   "@
1277    movabs{l}\t{%1, %P0|%P0, %1}
1278    mov{l}\t{%1, %a0|%a0, %1}"
1279   [(set_attr "type" "imov")
1280    (set_attr "modrm" "0,*")
1281    (set_attr "length_address" "8,0")
1282    (set_attr "length_immediate" "0,*")
1283    (set_attr "memory" "store")
1284    (set_attr "mode" "SI")])
1286 (define_insn "*movabssi_2_rex64"
1287   [(set (match_operand:SI 0 "register_operand" "=a,r")
1288         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1289   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1290   "@
1291    movabs{l}\t{%P1, %0|%0, %P1}
1292    mov{l}\t{%a1, %0|%0, %a1}"
1293   [(set_attr "type" "imov")
1294    (set_attr "modrm" "0,*")
1295    (set_attr "length_address" "8,0")
1296    (set_attr "length_immediate" "0")
1297    (set_attr "memory" "load")
1298    (set_attr "mode" "SI")])
1300 (define_insn "*swapsi"
1301   [(set (match_operand:SI 0 "register_operand" "+r")
1302         (match_operand:SI 1 "register_operand" "+r"))
1303    (set (match_dup 1)
1304         (match_dup 0))]
1305   ""
1306   "xchg{l}\t%1, %0"
1307   [(set_attr "type" "imov")
1308    (set_attr "pent_pair" "np")
1309    (set_attr "athlon_decode" "vector")
1310    (set_attr "mode" "SI")
1311    (set_attr "modrm" "0")])
1313 (define_expand "movhi"
1314   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1315         (match_operand:HI 1 "general_operand" ""))]
1316   ""
1317   "ix86_expand_move (HImode, operands); DONE;")
1319 (define_insn "*pushhi2"
1320   [(set (match_operand:HI 0 "push_operand" "=<,<")
1321         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1322   "!TARGET_64BIT"
1323   "@
1324    push{w}\t{|WORD PTR }%1
1325    push{w}\t%1"
1326   [(set_attr "type" "push")
1327    (set_attr "mode" "HI")])
1329 ;; For 64BIT abi we always round up to 8 bytes.
1330 (define_insn "*pushhi2_rex64"
1331   [(set (match_operand:HI 0 "push_operand" "=X")
1332         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1333   "TARGET_64BIT"
1334   "push{q}\t%q1"
1335   [(set_attr "type" "push")
1336    (set_attr "mode" "QI")])
1338 (define_insn "*movhi_1"
1339   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1340         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1341   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1343   switch (get_attr_type (insn))
1344     {
1345     case TYPE_IMOVX:
1346       /* movzwl is faster than movw on p2 due to partial word stalls,
1347          though not as fast as an aligned movl.  */
1348       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1349     default:
1350       if (get_attr_mode (insn) == MODE_SI)
1351         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1352       else
1353         return "mov{w}\t{%1, %0|%0, %1}";
1354     }
1356   [(set (attr "type")
1357      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1358               (const_string "imov")
1359             (and (eq_attr "alternative" "0")
1360                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1361                           (const_int 0))
1362                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1363                           (const_int 0))))
1364               (const_string "imov")
1365             (and (eq_attr "alternative" "1,2")
1366                  (match_operand:HI 1 "aligned_operand" ""))
1367               (const_string "imov")
1368             (and (ne (symbol_ref "TARGET_MOVX")
1369                      (const_int 0))
1370                  (eq_attr "alternative" "0,2"))
1371               (const_string "imovx")
1372            ]
1373            (const_string "imov")))
1374     (set (attr "mode")
1375       (cond [(eq_attr "type" "imovx")
1376                (const_string "SI")
1377              (and (eq_attr "alternative" "1,2")
1378                   (match_operand:HI 1 "aligned_operand" ""))
1379                (const_string "SI")
1380              (and (eq_attr "alternative" "0")
1381                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1382                            (const_int 0))
1383                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1384                            (const_int 0))))
1385                (const_string "SI")
1386             ]
1387             (const_string "HI")))])
1389 ;; Stores and loads of ax to arbitrary constant address.
1390 ;; We fake an second form of instruction to force reload to load address
1391 ;; into register when rax is not available
1392 (define_insn "*movabshi_1_rex64"
1393   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1394         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1395   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1396   "@
1397    movabs{w}\t{%1, %P0|%P0, %1}
1398    mov{w}\t{%1, %a0|%a0, %1}"
1399   [(set_attr "type" "imov")
1400    (set_attr "modrm" "0,*")
1401    (set_attr "length_address" "8,0")
1402    (set_attr "length_immediate" "0,*")
1403    (set_attr "memory" "store")
1404    (set_attr "mode" "HI")])
1406 (define_insn "*movabshi_2_rex64"
1407   [(set (match_operand:HI 0 "register_operand" "=a,r")
1408         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1409   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1410   "@
1411    movabs{w}\t{%P1, %0|%0, %P1}
1412    mov{w}\t{%a1, %0|%0, %a1}"
1413   [(set_attr "type" "imov")
1414    (set_attr "modrm" "0,*")
1415    (set_attr "length_address" "8,0")
1416    (set_attr "length_immediate" "0")
1417    (set_attr "memory" "load")
1418    (set_attr "mode" "HI")])
1420 (define_insn "*swaphi_1"
1421   [(set (match_operand:HI 0 "register_operand" "+r")
1422         (match_operand:HI 1 "register_operand" "+r"))
1423    (set (match_dup 1)
1424         (match_dup 0))]
1425   "TARGET_PARTIAL_REG_STALL"
1426   "xchg{w}\t%1, %0"
1427   [(set_attr "type" "imov")
1428    (set_attr "pent_pair" "np")
1429    (set_attr "mode" "HI")
1430    (set_attr "modrm" "0")])
1432 (define_insn "*swaphi_2"
1433   [(set (match_operand:HI 0 "register_operand" "+r")
1434         (match_operand:HI 1 "register_operand" "+r"))
1435    (set (match_dup 1)
1436         (match_dup 0))]
1437   "! TARGET_PARTIAL_REG_STALL"
1438   "xchg{l}\t%k1, %k0"
1439   [(set_attr "type" "imov")
1440    (set_attr "pent_pair" "np")
1441    (set_attr "mode" "SI")
1442    (set_attr "modrm" "0")])
1444 (define_expand "movstricthi"
1445   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1446         (match_operand:HI 1 "general_operand" ""))]
1447   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1449   /* Don't generate memory->memory moves, go through a register */
1450   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1451     operands[1] = force_reg (HImode, operands[1]);
1454 (define_insn "*movstricthi_1"
1455   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1456         (match_operand:HI 1 "general_operand" "rn,m"))]
1457   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1458    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1459   "mov{w}\t{%1, %0|%0, %1}"
1460   [(set_attr "type" "imov")
1461    (set_attr "mode" "HI")])
1463 (define_insn "*movstricthi_xor"
1464   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1465         (match_operand:HI 1 "const0_operand" "i"))
1466    (clobber (reg:CC FLAGS_REG))]
1467   "reload_completed
1468    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1469   "xor{w}\t{%0, %0|%0, %0}"
1470   [(set_attr "type" "alu1")
1471    (set_attr "mode" "HI")
1472    (set_attr "length_immediate" "0")])
1474 (define_expand "movqi"
1475   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1476         (match_operand:QI 1 "general_operand" ""))]
1477   ""
1478   "ix86_expand_move (QImode, operands); DONE;")
1480 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1481 ;; "push a byte".  But actually we use pushw, which has the effect
1482 ;; of rounding the amount pushed up to a halfword.
1484 (define_insn "*pushqi2"
1485   [(set (match_operand:QI 0 "push_operand" "=X,X")
1486         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1487   "!TARGET_64BIT"
1488   "@
1489    push{w}\t{|word ptr }%1
1490    push{w}\t%w1"
1491   [(set_attr "type" "push")
1492    (set_attr "mode" "HI")])
1494 ;; For 64BIT abi we always round up to 8 bytes.
1495 (define_insn "*pushqi2_rex64"
1496   [(set (match_operand:QI 0 "push_operand" "=X")
1497         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1498   "TARGET_64BIT"
1499   "push{q}\t%q1"
1500   [(set_attr "type" "push")
1501    (set_attr "mode" "QI")])
1503 ;; Situation is quite tricky about when to choose full sized (SImode) move
1504 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1505 ;; partial register dependency machines (such as AMD Athlon), where QImode
1506 ;; moves issue extra dependency and for partial register stalls machines
1507 ;; that don't use QImode patterns (and QImode move cause stall on the next
1508 ;; instruction).
1510 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1511 ;; register stall machines with, where we use QImode instructions, since
1512 ;; partial register stall can be caused there.  Then we use movzx.
1513 (define_insn "*movqi_1"
1514   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1515         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1516   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1518   switch (get_attr_type (insn))
1519     {
1520     case TYPE_IMOVX:
1521       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1522         abort ();
1523       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1524     default:
1525       if (get_attr_mode (insn) == MODE_SI)
1526         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1527       else
1528         return "mov{b}\t{%1, %0|%0, %1}";
1529     }
1531   [(set (attr "type")
1532      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1533               (const_string "imov")
1534             (and (eq_attr "alternative" "3")
1535                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1536                           (const_int 0))
1537                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1538                           (const_int 0))))
1539               (const_string "imov")
1540             (eq_attr "alternative" "3,5")
1541               (const_string "imovx")
1542             (and (ne (symbol_ref "TARGET_MOVX")
1543                      (const_int 0))
1544                  (eq_attr "alternative" "2"))
1545               (const_string "imovx")
1546            ]
1547            (const_string "imov")))
1548    (set (attr "mode")
1549       (cond [(eq_attr "alternative" "3,4,5")
1550                (const_string "SI")
1551              (eq_attr "alternative" "6")
1552                (const_string "QI")
1553              (eq_attr "type" "imovx")
1554                (const_string "SI")
1555              (and (eq_attr "type" "imov")
1556                   (and (eq_attr "alternative" "0,1,2")
1557                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1558                            (const_int 0))))
1559                (const_string "SI")
1560              ;; Avoid partial register stalls when not using QImode arithmetic
1561              (and (eq_attr "type" "imov")
1562                   (and (eq_attr "alternative" "0,1,2")
1563                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1564                                 (const_int 0))
1565                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1566                                 (const_int 0)))))
1567                (const_string "SI")
1568            ]
1569            (const_string "QI")))])
1571 (define_expand "reload_outqi"
1572   [(parallel [(match_operand:QI 0 "" "=m")
1573               (match_operand:QI 1 "register_operand" "r")
1574               (match_operand:QI 2 "register_operand" "=&q")])]
1575   ""
1577   rtx op0, op1, op2;
1578   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1580   if (reg_overlap_mentioned_p (op2, op0))
1581     abort ();
1582   if (! q_regs_operand (op1, QImode))
1583     {
1584       emit_insn (gen_movqi (op2, op1));
1585       op1 = op2;
1586     }
1587   emit_insn (gen_movqi (op0, op1));
1588   DONE;
1591 (define_insn "*swapqi"
1592   [(set (match_operand:QI 0 "register_operand" "+r")
1593         (match_operand:QI 1 "register_operand" "+r"))
1594    (set (match_dup 1)
1595         (match_dup 0))]
1596   ""
1597   "xchg{b}\t%1, %0"
1598   [(set_attr "type" "imov")
1599    (set_attr "pent_pair" "np")
1600    (set_attr "mode" "QI")
1601    (set_attr "modrm" "0")])
1603 (define_expand "movstrictqi"
1604   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1605         (match_operand:QI 1 "general_operand" ""))]
1606   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1608   /* Don't generate memory->memory moves, go through a register.  */
1609   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1610     operands[1] = force_reg (QImode, operands[1]);
1613 (define_insn "*movstrictqi_1"
1614   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1615         (match_operand:QI 1 "general_operand" "*qn,m"))]
1616   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1617    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1618   "mov{b}\t{%1, %0|%0, %1}"
1619   [(set_attr "type" "imov")
1620    (set_attr "mode" "QI")])
1622 (define_insn "*movstrictqi_xor"
1623   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1624         (match_operand:QI 1 "const0_operand" "i"))
1625    (clobber (reg:CC FLAGS_REG))]
1626   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1627   "xor{b}\t{%0, %0|%0, %0}"
1628   [(set_attr "type" "alu1")
1629    (set_attr "mode" "QI")
1630    (set_attr "length_immediate" "0")])
1632 (define_insn "*movsi_extv_1"
1633   [(set (match_operand:SI 0 "register_operand" "=R")
1634         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1635                          (const_int 8)
1636                          (const_int 8)))]
1637   ""
1638   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1639   [(set_attr "type" "imovx")
1640    (set_attr "mode" "SI")])
1642 (define_insn "*movhi_extv_1"
1643   [(set (match_operand:HI 0 "register_operand" "=R")
1644         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1645                          (const_int 8)
1646                          (const_int 8)))]
1647   ""
1648   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1649   [(set_attr "type" "imovx")
1650    (set_attr "mode" "SI")])
1652 (define_insn "*movqi_extv_1"
1653   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1654         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1655                          (const_int 8)
1656                          (const_int 8)))]
1657   "!TARGET_64BIT"
1659   switch (get_attr_type (insn))
1660     {
1661     case TYPE_IMOVX:
1662       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1663     default:
1664       return "mov{b}\t{%h1, %0|%0, %h1}";
1665     }
1667   [(set (attr "type")
1668      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1669                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670                              (ne (symbol_ref "TARGET_MOVX")
1671                                  (const_int 0))))
1672         (const_string "imovx")
1673         (const_string "imov")))
1674    (set (attr "mode")
1675      (if_then_else (eq_attr "type" "imovx")
1676         (const_string "SI")
1677         (const_string "QI")))])
1679 (define_insn "*movqi_extv_1_rex64"
1680   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1681         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1682                          (const_int 8)
1683                          (const_int 8)))]
1684   "TARGET_64BIT"
1686   switch (get_attr_type (insn))
1687     {
1688     case TYPE_IMOVX:
1689       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1690     default:
1691       return "mov{b}\t{%h1, %0|%0, %h1}";
1692     }
1694   [(set (attr "type")
1695      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1696                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1697                              (ne (symbol_ref "TARGET_MOVX")
1698                                  (const_int 0))))
1699         (const_string "imovx")
1700         (const_string "imov")))
1701    (set (attr "mode")
1702      (if_then_else (eq_attr "type" "imovx")
1703         (const_string "SI")
1704         (const_string "QI")))])
1706 ;; Stores and loads of ax to arbitrary constant address.
1707 ;; We fake an second form of instruction to force reload to load address
1708 ;; into register when rax is not available
1709 (define_insn "*movabsqi_1_rex64"
1710   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1711         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1712   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1713   "@
1714    movabs{b}\t{%1, %P0|%P0, %1}
1715    mov{b}\t{%1, %a0|%a0, %1}"
1716   [(set_attr "type" "imov")
1717    (set_attr "modrm" "0,*")
1718    (set_attr "length_address" "8,0")
1719    (set_attr "length_immediate" "0,*")
1720    (set_attr "memory" "store")
1721    (set_attr "mode" "QI")])
1723 (define_insn "*movabsqi_2_rex64"
1724   [(set (match_operand:QI 0 "register_operand" "=a,r")
1725         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1726   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1727   "@
1728    movabs{b}\t{%P1, %0|%0, %P1}
1729    mov{b}\t{%a1, %0|%0, %a1}"
1730   [(set_attr "type" "imov")
1731    (set_attr "modrm" "0,*")
1732    (set_attr "length_address" "8,0")
1733    (set_attr "length_immediate" "0")
1734    (set_attr "memory" "load")
1735    (set_attr "mode" "QI")])
1737 (define_insn "*movsi_extzv_1"
1738   [(set (match_operand:SI 0 "register_operand" "=R")
1739         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1740                          (const_int 8)
1741                          (const_int 8)))]
1742   ""
1743   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1744   [(set_attr "type" "imovx")
1745    (set_attr "mode" "SI")])
1747 (define_insn "*movqi_extzv_2"
1748   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1749         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1750                                     (const_int 8)
1751                                     (const_int 8)) 0))]
1752   "!TARGET_64BIT"
1754   switch (get_attr_type (insn))
1755     {
1756     case TYPE_IMOVX:
1757       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1758     default:
1759       return "mov{b}\t{%h1, %0|%0, %h1}";
1760     }
1762   [(set (attr "type")
1763      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1764                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1765                              (ne (symbol_ref "TARGET_MOVX")
1766                                  (const_int 0))))
1767         (const_string "imovx")
1768         (const_string "imov")))
1769    (set (attr "mode")
1770      (if_then_else (eq_attr "type" "imovx")
1771         (const_string "SI")
1772         (const_string "QI")))])
1774 (define_insn "*movqi_extzv_2_rex64"
1775   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1776         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1777                                     (const_int 8)
1778                                     (const_int 8)) 0))]
1779   "TARGET_64BIT"
1781   switch (get_attr_type (insn))
1782     {
1783     case TYPE_IMOVX:
1784       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1785     default:
1786       return "mov{b}\t{%h1, %0|%0, %h1}";
1787     }
1789   [(set (attr "type")
1790      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1791                         (ne (symbol_ref "TARGET_MOVX")
1792                             (const_int 0)))
1793         (const_string "imovx")
1794         (const_string "imov")))
1795    (set (attr "mode")
1796      (if_then_else (eq_attr "type" "imovx")
1797         (const_string "SI")
1798         (const_string "QI")))])
1800 (define_insn "movsi_insv_1"
1801   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1802                          (const_int 8)
1803                          (const_int 8))
1804         (match_operand:SI 1 "general_operand" "Qmn"))]
1805   "!TARGET_64BIT"
1806   "mov{b}\t{%b1, %h0|%h0, %b1}"
1807   [(set_attr "type" "imov")
1808    (set_attr "mode" "QI")])
1810 (define_insn "movdi_insv_1_rex64"
1811   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1812                          (const_int 8)
1813                          (const_int 8))
1814         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1815   "TARGET_64BIT"
1816   "mov{b}\t{%b1, %h0|%h0, %b1}"
1817   [(set_attr "type" "imov")
1818    (set_attr "mode" "QI")])
1820 (define_insn "*movqi_insv_2"
1821   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1822                          (const_int 8)
1823                          (const_int 8))
1824         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1825                      (const_int 8)))]
1826   ""
1827   "mov{b}\t{%h1, %h0|%h0, %h1}"
1828   [(set_attr "type" "imov")
1829    (set_attr "mode" "QI")])
1831 (define_expand "movdi"
1832   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1833         (match_operand:DI 1 "general_operand" ""))]
1834   ""
1835   "ix86_expand_move (DImode, operands); DONE;")
1837 (define_insn "*pushdi"
1838   [(set (match_operand:DI 0 "push_operand" "=<")
1839         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1840   "!TARGET_64BIT"
1841   "#")
1843 (define_insn "pushdi2_rex64"
1844   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1845         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1846   "TARGET_64BIT"
1847   "@
1848    push{q}\t%1
1849    #"
1850   [(set_attr "type" "push,multi")
1851    (set_attr "mode" "DI")])
1853 ;; Convert impossible pushes of immediate to existing instructions.
1854 ;; First try to get scratch register and go through it.  In case this
1855 ;; fails, push sign extended lower part first and then overwrite
1856 ;; upper part by 32bit move.
1857 (define_peephole2
1858   [(match_scratch:DI 2 "r")
1859    (set (match_operand:DI 0 "push_operand" "")
1860         (match_operand:DI 1 "immediate_operand" ""))]
1861   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1862    && !x86_64_immediate_operand (operands[1], DImode)"
1863   [(set (match_dup 2) (match_dup 1))
1864    (set (match_dup 0) (match_dup 2))]
1865   "")
1867 ;; We need to define this as both peepholer and splitter for case
1868 ;; peephole2 pass is not run.
1869 (define_peephole2
1870   [(set (match_operand:DI 0 "push_operand" "")
1871         (match_operand:DI 1 "immediate_operand" ""))]
1872   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1873    && !x86_64_immediate_operand (operands[1], DImode)"
1874   [(set (match_dup 0) (match_dup 1))
1875    (set (match_dup 2) (match_dup 3))]
1876   "split_di (operands + 1, 1, operands + 2, operands + 3);
1877    operands[1] = gen_lowpart (DImode, operands[2]);
1878    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1879                                                     GEN_INT (4)));
1880   ")
1882 (define_split
1883   [(set (match_operand:DI 0 "push_operand" "")
1884         (match_operand:DI 1 "immediate_operand" ""))]
1885   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1886    && !symbolic_operand (operands[1], DImode)
1887    && !x86_64_immediate_operand (operands[1], DImode)"
1888   [(set (match_dup 0) (match_dup 1))
1889    (set (match_dup 2) (match_dup 3))]
1890   "split_di (operands + 1, 1, operands + 2, operands + 3);
1891    operands[1] = gen_lowpart (DImode, operands[2]);
1892    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1893                                                     GEN_INT (4)));
1894   ")
1896 (define_insn "*pushdi2_prologue_rex64"
1897   [(set (match_operand:DI 0 "push_operand" "=<")
1898         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1899    (clobber (mem:BLK (scratch)))]
1900   "TARGET_64BIT"
1901   "push{q}\t%1"
1902   [(set_attr "type" "push")
1903    (set_attr "mode" "DI")])
1905 (define_insn "*popdi1_epilogue_rex64"
1906   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1907         (mem:DI (reg:DI SP_REG)))
1908    (set (reg:DI SP_REG)
1909         (plus:DI (reg:DI SP_REG) (const_int 8)))
1910    (clobber (mem:BLK (scratch)))]
1911   "TARGET_64BIT"
1912   "pop{q}\t%0"
1913   [(set_attr "type" "pop")
1914    (set_attr "mode" "DI")])
1916 (define_insn "popdi1"
1917   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1918         (mem:DI (reg:DI SP_REG)))
1919    (set (reg:DI SP_REG)
1920         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1921   "TARGET_64BIT"
1922   "pop{q}\t%0"
1923   [(set_attr "type" "pop")
1924    (set_attr "mode" "DI")])
1926 (define_insn "*movdi_xor_rex64"
1927   [(set (match_operand:DI 0 "register_operand" "=r")
1928         (match_operand:DI 1 "const0_operand" "i"))
1929    (clobber (reg:CC FLAGS_REG))]
1930   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1931    && reload_completed"
1932   "xor{l}\t{%k0, %k0|%k0, %k0}"
1933   [(set_attr "type" "alu1")
1934    (set_attr "mode" "SI")
1935    (set_attr "length_immediate" "0")])
1937 (define_insn "*movdi_or_rex64"
1938   [(set (match_operand:DI 0 "register_operand" "=r")
1939         (match_operand:DI 1 "const_int_operand" "i"))
1940    (clobber (reg:CC FLAGS_REG))]
1941   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1942    && reload_completed
1943    && operands[1] == constm1_rtx"
1945   operands[1] = constm1_rtx;
1946   return "or{q}\t{%1, %0|%0, %1}";
1948   [(set_attr "type" "alu1")
1949    (set_attr "mode" "DI")
1950    (set_attr "length_immediate" "1")])
1952 (define_insn "*movdi_2"
1953   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1954         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1955   "!TARGET_64BIT
1956    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1957   "@
1958    #
1959    #
1960    movq\t{%1, %0|%0, %1}
1961    movq\t{%1, %0|%0, %1}
1962    movq\t{%1, %0|%0, %1}
1963    movdqa\t{%1, %0|%0, %1}
1964    movq\t{%1, %0|%0, %1}"
1965   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1966    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1968 (define_split
1969   [(set (match_operand:DI 0 "push_operand" "")
1970         (match_operand:DI 1 "general_operand" ""))]
1971   "!TARGET_64BIT && reload_completed
1972    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1973   [(const_int 0)]
1974   "ix86_split_long_move (operands); DONE;")
1976 ;; %%% This multiword shite has got to go.
1977 (define_split
1978   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1979         (match_operand:DI 1 "general_operand" ""))]
1980   "!TARGET_64BIT && reload_completed
1981    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1982    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1983   [(const_int 0)]
1984   "ix86_split_long_move (operands); DONE;")
1986 (define_insn "*movdi_1_rex64"
1987   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1988         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1989   "TARGET_64BIT
1990    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1991    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1993   switch (get_attr_type (insn))
1994     {
1995     case TYPE_SSECVT:
1996       if (which_alternative == 11)
1997         return "movq2dq\t{%1, %0|%0, %1}";
1998       else
1999         return "movdq2q\t{%1, %0|%0, %1}";
2000     case TYPE_SSEMOV:
2001       if (get_attr_mode (insn) == MODE_TI)
2002           return "movdqa\t{%1, %0|%0, %1}";
2003       /* FALLTHRU */
2004     case TYPE_MMXMOV:
2005       /* Moves from and into integer register is done using movd opcode with
2006          REX prefix.  */
2007       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2008           return "movd\t{%1, %0|%0, %1}";
2009       return "movq\t{%1, %0|%0, %1}";
2010     case TYPE_MULTI:
2011       return "#";
2012     case TYPE_LEA:
2013       return "lea{q}\t{%a1, %0|%0, %a1}";
2014     default:
2015       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2016         abort ();
2017       if (get_attr_mode (insn) == MODE_SI)
2018         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2019       else if (which_alternative == 2)
2020         return "movabs{q}\t{%1, %0|%0, %1}";
2021       else
2022         return "mov{q}\t{%1, %0|%0, %1}";
2023     }
2025   [(set (attr "type")
2026      (cond [(eq_attr "alternative" "5,6,7")
2027               (const_string "mmxmov")
2028             (eq_attr "alternative" "8,9,10")
2029               (const_string "ssemov")
2030             (eq_attr "alternative" "11,12")
2031               (const_string "ssecvt")
2032             (eq_attr "alternative" "4")
2033               (const_string "multi")
2034             (and (ne (symbol_ref "flag_pic") (const_int 0))
2035                  (match_operand:DI 1 "symbolic_operand" ""))
2036               (const_string "lea")
2037            ]
2038            (const_string "imov")))
2039    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
2040    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2041    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
2043 (define_insn "*movdi_1_rex64_nointerunit"
2044   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2045         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2046   "TARGET_64BIT
2047    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2048    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2050   switch (get_attr_type (insn))
2051     {
2052     case TYPE_SSEMOV:
2053       if (get_attr_mode (insn) == MODE_TI)
2054           return "movdqa\t{%1, %0|%0, %1}";
2055       /* FALLTHRU */
2056     case TYPE_MMXMOV:
2057       return "movq\t{%1, %0|%0, %1}";
2058     case TYPE_MULTI:
2059       return "#";
2060     case TYPE_LEA:
2061       return "lea{q}\t{%a1, %0|%0, %a1}";
2062     default:
2063       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2064         abort ();
2065       if (get_attr_mode (insn) == MODE_SI)
2066         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2067       else if (which_alternative == 2)
2068         return "movabs{q}\t{%1, %0|%0, %1}";
2069       else
2070         return "mov{q}\t{%1, %0|%0, %1}";
2071     }
2073   [(set (attr "type")
2074      (cond [(eq_attr "alternative" "5,6,7")
2075               (const_string "mmxmov")
2076             (eq_attr "alternative" "8,9,10")
2077               (const_string "ssemov")
2078             (eq_attr "alternative" "4")
2079               (const_string "multi")
2080             (and (ne (symbol_ref "flag_pic") (const_int 0))
2081                  (match_operand:DI 1 "symbolic_operand" ""))
2082               (const_string "lea")
2083            ]
2084            (const_string "imov")))
2085    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2086    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2087    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2089 ;; Stores and loads of ax to arbitrary constant address.
2090 ;; We fake an second form of instruction to force reload to load address
2091 ;; into register when rax is not available
2092 (define_insn "*movabsdi_1_rex64"
2093   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2094         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2095   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2096   "@
2097    movabs{q}\t{%1, %P0|%P0, %1}
2098    mov{q}\t{%1, %a0|%a0, %1}"
2099   [(set_attr "type" "imov")
2100    (set_attr "modrm" "0,*")
2101    (set_attr "length_address" "8,0")
2102    (set_attr "length_immediate" "0,*")
2103    (set_attr "memory" "store")
2104    (set_attr "mode" "DI")])
2106 (define_insn "*movabsdi_2_rex64"
2107   [(set (match_operand:DI 0 "register_operand" "=a,r")
2108         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2109   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2110   "@
2111    movabs{q}\t{%P1, %0|%0, %P1}
2112    mov{q}\t{%a1, %0|%0, %a1}"
2113   [(set_attr "type" "imov")
2114    (set_attr "modrm" "0,*")
2115    (set_attr "length_address" "8,0")
2116    (set_attr "length_immediate" "0")
2117    (set_attr "memory" "load")
2118    (set_attr "mode" "DI")])
2120 ;; Convert impossible stores of immediate to existing instructions.
2121 ;; First try to get scratch register and go through it.  In case this
2122 ;; fails, move by 32bit parts.
2123 (define_peephole2
2124   [(match_scratch:DI 2 "r")
2125    (set (match_operand:DI 0 "memory_operand" "")
2126         (match_operand:DI 1 "immediate_operand" ""))]
2127   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2128    && !x86_64_immediate_operand (operands[1], DImode)"
2129   [(set (match_dup 2) (match_dup 1))
2130    (set (match_dup 0) (match_dup 2))]
2131   "")
2133 ;; We need to define this as both peepholer and splitter for case
2134 ;; peephole2 pass is not run.
2135 (define_peephole2
2136   [(set (match_operand:DI 0 "memory_operand" "")
2137         (match_operand:DI 1 "immediate_operand" ""))]
2138   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2139    && !x86_64_immediate_operand (operands[1], DImode)"
2140   [(set (match_dup 2) (match_dup 3))
2141    (set (match_dup 4) (match_dup 5))]
2142   "split_di (operands, 2, operands + 2, operands + 4);")
2144 (define_split
2145   [(set (match_operand:DI 0 "memory_operand" "")
2146         (match_operand:DI 1 "immediate_operand" ""))]
2147   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2148    && !symbolic_operand (operands[1], DImode)
2149    && !x86_64_immediate_operand (operands[1], DImode)"
2150   [(set (match_dup 2) (match_dup 3))
2151    (set (match_dup 4) (match_dup 5))]
2152   "split_di (operands, 2, operands + 2, operands + 4);")
2154 (define_insn "*swapdi_rex64"
2155   [(set (match_operand:DI 0 "register_operand" "+r")
2156         (match_operand:DI 1 "register_operand" "+r"))
2157    (set (match_dup 1)
2158         (match_dup 0))]
2159   "TARGET_64BIT"
2160   "xchg{q}\t%1, %0"
2161   [(set_attr "type" "imov")
2162    (set_attr "pent_pair" "np")
2163    (set_attr "athlon_decode" "vector")
2164    (set_attr "mode" "DI")
2165    (set_attr "modrm" "0")])
2167   
2168 (define_expand "movsf"
2169   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2170         (match_operand:SF 1 "general_operand" ""))]
2171   ""
2172   "ix86_expand_move (SFmode, operands); DONE;")
2174 (define_insn "*pushsf"
2175   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2176         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2177   "!TARGET_64BIT"
2179   switch (which_alternative)
2180     {
2181     case 1:
2182       return "push{l}\t%1";
2184     default:
2185       /* This insn should be already split before reg-stack.  */
2186       abort ();
2187     }
2189   [(set_attr "type" "multi,push,multi")
2190    (set_attr "mode" "SF,SI,SF")])
2192 (define_insn "*pushsf_rex64"
2193   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2194         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2195   "TARGET_64BIT"
2197   switch (which_alternative)
2198     {
2199     case 1:
2200       return "push{q}\t%q1";
2202     default:
2203       /* This insn should be already split before reg-stack.  */
2204       abort ();
2205     }
2207   [(set_attr "type" "multi,push,multi")
2208    (set_attr "mode" "SF,DI,SF")])
2210 (define_split
2211   [(set (match_operand:SF 0 "push_operand" "")
2212         (match_operand:SF 1 "memory_operand" ""))]
2213   "reload_completed
2214    && GET_CODE (operands[1]) == MEM
2215    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2216    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2217   [(set (match_dup 0)
2218         (match_dup 1))]
2219   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2222 ;; %%% Kill this when call knows how to work this out.
2223 (define_split
2224   [(set (match_operand:SF 0 "push_operand" "")
2225         (match_operand:SF 1 "any_fp_register_operand" ""))]
2226   "!TARGET_64BIT"
2227   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2228    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2230 (define_split
2231   [(set (match_operand:SF 0 "push_operand" "")
2232         (match_operand:SF 1 "any_fp_register_operand" ""))]
2233   "TARGET_64BIT"
2234   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2235    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2237 (define_insn "*movsf_1"
2238   [(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")
2239         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2240   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2241    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2242    && (reload_in_progress || reload_completed
2243        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2244        || GET_CODE (operands[1]) != CONST_DOUBLE
2245        || memory_operand (operands[0], SFmode))" 
2247   switch (which_alternative)
2248     {
2249     case 0:
2250       return output_387_reg_move (insn, operands);
2252     case 1:
2253       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2254         return "fstp%z0\t%y0";
2255       else
2256         return "fst%z0\t%y0";
2258     case 2:
2259       return standard_80387_constant_opcode (operands[1]);
2261     case 3:
2262     case 4:
2263       return "mov{l}\t{%1, %0|%0, %1}";
2264     case 5:
2265       if (get_attr_mode (insn) == MODE_TI)
2266         return "pxor\t%0, %0";
2267       else
2268         return "xorps\t%0, %0";
2269     case 6:
2270       if (get_attr_mode (insn) == MODE_V4SF)
2271         return "movaps\t{%1, %0|%0, %1}";
2272       else
2273         return "movss\t{%1, %0|%0, %1}";
2274     case 7:
2275     case 8:
2276       return "movss\t{%1, %0|%0, %1}";
2278     case 9:
2279     case 10:
2280       return "movd\t{%1, %0|%0, %1}";
2282     case 11:
2283       return "movq\t{%1, %0|%0, %1}";
2285     default:
2286       abort();
2287     }
2289   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2290    (set (attr "mode")
2291         (cond [(eq_attr "alternative" "3,4,9,10")
2292                  (const_string "SI")
2293                (eq_attr "alternative" "5")
2294                  (if_then_else
2295                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2296                                  (const_int 0))
2297                              (ne (symbol_ref "TARGET_SSE2")
2298                                  (const_int 0)))
2299                         (eq (symbol_ref "optimize_size")
2300                             (const_int 0)))
2301                    (const_string "TI")
2302                    (const_string "V4SF"))
2303                /* For architectures resolving dependencies on
2304                   whole SSE registers use APS move to break dependency
2305                   chains, otherwise use short move to avoid extra work. 
2307                   Do the same for architectures resolving dependencies on
2308                   the parts.  While in DF mode it is better to always handle
2309                   just register parts, the SF mode is different due to lack
2310                   of instructions to load just part of the register.  It is
2311                   better to maintain the whole registers in single format
2312                   to avoid problems on using packed logical operations.  */
2313                (eq_attr "alternative" "6")
2314                  (if_then_else
2315                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2316                             (const_int 0))
2317                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2318                             (const_int 0)))
2319                    (const_string "V4SF")
2320                    (const_string "SF"))
2321                (eq_attr "alternative" "11")
2322                  (const_string "DI")]
2323                (const_string "SF")))])
2325 (define_insn "*movsf_1_nointerunit"
2326   [(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")
2327         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2328   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2329    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2330    && (reload_in_progress || reload_completed
2331        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2332        || GET_CODE (operands[1]) != CONST_DOUBLE
2333        || memory_operand (operands[0], SFmode))" 
2335   switch (which_alternative)
2336     {
2337     case 0:
2338       return output_387_reg_move (insn, operands);
2340     case 1:
2341       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2342         return "fstp%z0\t%y0";
2343       else
2344         return "fst%z0\t%y0";
2346     case 2:
2347       return standard_80387_constant_opcode (operands[1]);
2349     case 3:
2350     case 4:
2351       return "mov{l}\t{%1, %0|%0, %1}";
2352     case 5:
2353       if (get_attr_mode (insn) == MODE_TI)
2354         return "pxor\t%0, %0";
2355       else
2356         return "xorps\t%0, %0";
2357     case 6:
2358       if (get_attr_mode (insn) == MODE_V4SF)
2359         return "movaps\t{%1, %0|%0, %1}";
2360       else
2361         return "movss\t{%1, %0|%0, %1}";
2362     case 7:
2363     case 8:
2364       return "movss\t{%1, %0|%0, %1}";
2366     case 9:
2367     case 10:
2368       return "movd\t{%1, %0|%0, %1}";
2370     case 11:
2371       return "movq\t{%1, %0|%0, %1}";
2373     default:
2374       abort();
2375     }
2377   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2378    (set (attr "mode")
2379         (cond [(eq_attr "alternative" "3,4,9,10")
2380                  (const_string "SI")
2381                (eq_attr "alternative" "5")
2382                  (if_then_else
2383                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2384                                  (const_int 0))
2385                              (ne (symbol_ref "TARGET_SSE2")
2386                                  (const_int 0)))
2387                         (eq (symbol_ref "optimize_size")
2388                             (const_int 0)))
2389                    (const_string "TI")
2390                    (const_string "V4SF"))
2391                /* For architectures resolving dependencies on
2392                   whole SSE registers use APS move to break dependency
2393                   chains, otherwise use short move to avoid extra work. 
2395                   Do the same for architectures resolving dependencies on
2396                   the parts.  While in DF mode it is better to always handle
2397                   just register parts, the SF mode is different due to lack
2398                   of instructions to load just part of the register.  It is
2399                   better to maintain the whole registers in single format
2400                   to avoid problems on using packed logical operations.  */
2401                (eq_attr "alternative" "6")
2402                  (if_then_else
2403                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2404                             (const_int 0))
2405                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2406                             (const_int 0)))
2407                    (const_string "V4SF")
2408                    (const_string "SF"))
2409                (eq_attr "alternative" "11")
2410                  (const_string "DI")]
2411                (const_string "SF")))])
2413 (define_insn "*swapsf"
2414   [(set (match_operand:SF 0 "register_operand" "+f")
2415         (match_operand:SF 1 "register_operand" "+f"))
2416    (set (match_dup 1)
2417         (match_dup 0))]
2418   "reload_completed || !TARGET_SSE"
2420   if (STACK_TOP_P (operands[0]))
2421     return "fxch\t%1";
2422   else
2423     return "fxch\t%0";
2425   [(set_attr "type" "fxch")
2426    (set_attr "mode" "SF")])
2428 (define_expand "movdf"
2429   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2430         (match_operand:DF 1 "general_operand" ""))]
2431   ""
2432   "ix86_expand_move (DFmode, operands); DONE;")
2434 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2435 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2436 ;; On the average, pushdf using integers can be still shorter.  Allow this
2437 ;; pattern for optimize_size too.
2439 (define_insn "*pushdf_nointeger"
2440   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2441         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2442   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2444   /* This insn should be already split before reg-stack.  */
2445   abort ();
2447   [(set_attr "type" "multi")
2448    (set_attr "mode" "DF,SI,SI,DF")])
2450 (define_insn "*pushdf_integer"
2451   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2452         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2453   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2455   /* This insn should be already split before reg-stack.  */
2456   abort ();
2458   [(set_attr "type" "multi")
2459    (set_attr "mode" "DF,SI,DF")])
2461 ;; %%% Kill this when call knows how to work this out.
2462 (define_split
2463   [(set (match_operand:DF 0 "push_operand" "")
2464         (match_operand:DF 1 "any_fp_register_operand" ""))]
2465   "!TARGET_64BIT && reload_completed"
2466   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2467    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2468   "")
2470 (define_split
2471   [(set (match_operand:DF 0 "push_operand" "")
2472         (match_operand:DF 1 "any_fp_register_operand" ""))]
2473   "TARGET_64BIT && reload_completed"
2474   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2475    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2476   "")
2478 (define_split
2479   [(set (match_operand:DF 0 "push_operand" "")
2480         (match_operand:DF 1 "general_operand" ""))]
2481   "reload_completed"
2482   [(const_int 0)]
2483   "ix86_split_long_move (operands); DONE;")
2485 ;; Moving is usually shorter when only FP registers are used. This separate
2486 ;; movdf pattern avoids the use of integer registers for FP operations
2487 ;; when optimizing for size.
2489 (define_insn "*movdf_nointeger"
2490   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2491         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2492   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2493    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2494    && (reload_in_progress || reload_completed
2495        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2496        || GET_CODE (operands[1]) != CONST_DOUBLE
2497        || memory_operand (operands[0], DFmode))" 
2499   switch (which_alternative)
2500     {
2501     case 0:
2502       return output_387_reg_move (insn, operands);
2504     case 1:
2505       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2506         return "fstp%z0\t%y0";
2507       else
2508         return "fst%z0\t%y0";
2510     case 2:
2511       return standard_80387_constant_opcode (operands[1]);
2513     case 3:
2514     case 4:
2515       return "#";
2516     case 5:
2517       switch (get_attr_mode (insn))
2518         {
2519         case MODE_V4SF:
2520           return "xorps\t%0, %0";
2521         case MODE_V2DF:
2522           return "xorpd\t%0, %0";
2523         case MODE_TI:
2524           return "pxor\t%0, %0";
2525         default:
2526           abort ();
2527         }
2528     case 6:
2529       switch (get_attr_mode (insn))
2530         {
2531         case MODE_V4SF:
2532           return "movaps\t{%1, %0|%0, %1}";
2533         case MODE_V2DF:
2534           return "movapd\t{%1, %0|%0, %1}";
2535         case MODE_DF:
2536           return "movsd\t{%1, %0|%0, %1}";
2537         default:
2538           abort ();
2539         }
2540     case 7:
2541       if (get_attr_mode (insn) == MODE_V2DF)
2542         return "movlpd\t{%1, %0|%0, %1}";
2543       else
2544         return "movsd\t{%1, %0|%0, %1}";
2545     case 8:
2546       return "movsd\t{%1, %0|%0, %1}";
2548     default:
2549       abort();
2550     }
2552   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2553    (set (attr "mode")
2554         (cond [(eq_attr "alternative" "3,4")
2555                  (const_string "SI")
2556                /* xorps is one byte shorter.  */
2557                (eq_attr "alternative" "5")
2558                  (cond [(ne (symbol_ref "optimize_size")
2559                             (const_int 0))
2560                           (const_string "V4SF")
2561                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2562                             (const_int 0))
2563                           (const_string "TI")]
2564                        (const_string "V2DF"))
2565                /* For architectures resolving dependencies on
2566                   whole SSE registers use APD move to break dependency
2567                   chains, otherwise use short move to avoid extra work.
2569                   movaps encodes one byte shorter.  */
2570                (eq_attr "alternative" "6")
2571                  (cond
2572                   [(ne (symbol_ref "optimize_size")
2573                        (const_int 0))
2574                      (const_string "V4SF")
2575                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2576                        (const_int 0))
2577                      (const_string "V2DF")]
2578                    (const_string "DF"))
2579                /* For architectures resolving dependencies on register
2580                   parts we may avoid extra work to zero out upper part
2581                   of register.  */
2582                (eq_attr "alternative" "7")
2583                  (if_then_else
2584                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2585                        (const_int 0))
2586                    (const_string "V2DF")
2587                    (const_string "DF"))]
2588                (const_string "DF")))])
2590 (define_insn "*movdf_integer"
2591   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2592         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2593   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2594    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2595    && (reload_in_progress || reload_completed
2596        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2597        || GET_CODE (operands[1]) != CONST_DOUBLE
2598        || memory_operand (operands[0], DFmode))" 
2600   switch (which_alternative)
2601     {
2602     case 0:
2603       return output_387_reg_move (insn, operands);
2605     case 1:
2606       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2607         return "fstp%z0\t%y0";
2608       else
2609         return "fst%z0\t%y0";
2611     case 2:
2612       return standard_80387_constant_opcode (operands[1]);
2614     case 3:
2615     case 4:
2616       return "#";
2618     case 5:
2619       switch (get_attr_mode (insn))
2620         {
2621         case MODE_V4SF:
2622           return "xorps\t%0, %0";
2623         case MODE_V2DF:
2624           return "xorpd\t%0, %0";
2625         case MODE_TI:
2626           return "pxor\t%0, %0";
2627         default:
2628           abort ();
2629         }
2630     case 6:
2631       switch (get_attr_mode (insn))
2632         {
2633         case MODE_V4SF:
2634           return "movaps\t{%1, %0|%0, %1}";
2635         case MODE_V2DF:
2636           return "movapd\t{%1, %0|%0, %1}";
2637         case MODE_DF:
2638           return "movsd\t{%1, %0|%0, %1}";
2639         default:
2640           abort ();
2641         }
2642     case 7:
2643       if (get_attr_mode (insn) == MODE_V2DF)
2644         return "movlpd\t{%1, %0|%0, %1}";
2645       else
2646         return "movsd\t{%1, %0|%0, %1}";
2647     case 8:
2648       return "movsd\t{%1, %0|%0, %1}";
2650     default:
2651       abort();
2652     }
2654   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2655    (set (attr "mode")
2656         (cond [(eq_attr "alternative" "3,4")
2657                  (const_string "SI")
2658                /* xorps is one byte shorter.  */
2659                (eq_attr "alternative" "5")
2660                  (cond [(ne (symbol_ref "optimize_size")
2661                             (const_int 0))
2662                           (const_string "V4SF")
2663                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2664                             (const_int 0))
2665                           (const_string "TI")]
2666                        (const_string "V2DF"))
2667                /* For architectures resolving dependencies on
2668                   whole SSE registers use APD move to break dependency
2669                   chains, otherwise use short move to avoid extra work.  
2671                   movaps encodes one byte shorter.  */
2672                (eq_attr "alternative" "6")
2673                  (cond
2674                   [(ne (symbol_ref "optimize_size")
2675                        (const_int 0))
2676                      (const_string "V4SF")
2677                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2678                        (const_int 0))
2679                      (const_string "V2DF")]
2680                    (const_string "DF"))
2681                /* For architectures resolving dependencies on register
2682                   parts we may avoid extra work to zero out upper part
2683                   of register.  */
2684                (eq_attr "alternative" "7")
2685                  (if_then_else
2686                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2687                        (const_int 0))
2688                    (const_string "V2DF")
2689                    (const_string "DF"))]
2690                (const_string "DF")))])
2692 (define_split
2693   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2694         (match_operand:DF 1 "general_operand" ""))]
2695   "reload_completed
2696    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2697    && ! (ANY_FP_REG_P (operands[0]) || 
2698          (GET_CODE (operands[0]) == SUBREG
2699           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2700    && ! (ANY_FP_REG_P (operands[1]) || 
2701          (GET_CODE (operands[1]) == SUBREG
2702           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2703   [(const_int 0)]
2704   "ix86_split_long_move (operands); DONE;")
2706 (define_insn "*swapdf"
2707   [(set (match_operand:DF 0 "register_operand" "+f")
2708         (match_operand:DF 1 "register_operand" "+f"))
2709    (set (match_dup 1)
2710         (match_dup 0))]
2711   "reload_completed || !TARGET_SSE2"
2713   if (STACK_TOP_P (operands[0]))
2714     return "fxch\t%1";
2715   else
2716     return "fxch\t%0";
2718   [(set_attr "type" "fxch")
2719    (set_attr "mode" "DF")])
2721 (define_expand "movxf"
2722   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2723         (match_operand:XF 1 "general_operand" ""))]
2724   ""
2725   "ix86_expand_move (XFmode, operands); DONE;")
2727 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2728 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2729 ;; Pushing using integer instructions is longer except for constants
2730 ;; and direct memory references.
2731 ;; (assuming that any given constant is pushed only once, but this ought to be
2732 ;;  handled elsewhere).
2734 (define_insn "*pushxf_nointeger"
2735   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2736         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2737   "optimize_size"
2739   /* This insn should be already split before reg-stack.  */
2740   abort ();
2742   [(set_attr "type" "multi")
2743    (set_attr "mode" "XF,SI,SI")])
2745 (define_insn "*pushxf_integer"
2746   [(set (match_operand:XF 0 "push_operand" "=<,<")
2747         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2748   "!optimize_size"
2750   /* This insn should be already split before reg-stack.  */
2751   abort ();
2753   [(set_attr "type" "multi")
2754    (set_attr "mode" "XF,SI")])
2756 (define_split
2757   [(set (match_operand 0 "push_operand" "")
2758         (match_operand 1 "general_operand" ""))]
2759   "reload_completed
2760    && (GET_MODE (operands[0]) == XFmode
2761        || GET_MODE (operands[0]) == DFmode)
2762    && !ANY_FP_REG_P (operands[1])"
2763   [(const_int 0)]
2764   "ix86_split_long_move (operands); DONE;")
2766 (define_split
2767   [(set (match_operand:XF 0 "push_operand" "")
2768         (match_operand:XF 1 "any_fp_register_operand" ""))]
2769   "!TARGET_64BIT"
2770   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2771    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2772   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774 (define_split
2775   [(set (match_operand:XF 0 "push_operand" "")
2776         (match_operand:XF 1 "any_fp_register_operand" ""))]
2777   "TARGET_64BIT"
2778   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2779    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2780   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2782 ;; Do not use integer registers when optimizing for size
2783 (define_insn "*movxf_nointeger"
2784   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2785         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2786   "optimize_size
2787    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2788    && (reload_in_progress || reload_completed
2789        || GET_CODE (operands[1]) != CONST_DOUBLE
2790        || memory_operand (operands[0], XFmode))" 
2792   switch (which_alternative)
2793     {
2794     case 0:
2795       return output_387_reg_move (insn, operands);
2797     case 1:
2798       /* There is no non-popping store to memory for XFmode.  So if
2799          we need one, follow the store with a load.  */
2800       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2801         return "fstp%z0\t%y0\;fld%z0\t%y0";
2802       else
2803         return "fstp%z0\t%y0";
2805     case 2:
2806       return standard_80387_constant_opcode (operands[1]);
2808     case 3: case 4:
2809       return "#";
2810     }
2811   abort();
2813   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2814    (set_attr "mode" "XF,XF,XF,SI,SI")])
2816 (define_insn "*movxf_integer"
2817   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2818         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2819   "!optimize_size
2820    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2821    && (reload_in_progress || reload_completed
2822        || GET_CODE (operands[1]) != CONST_DOUBLE
2823        || memory_operand (operands[0], XFmode))" 
2825   switch (which_alternative)
2826     {
2827     case 0:
2828       return output_387_reg_move (insn, operands);
2830     case 1:
2831       /* There is no non-popping store to memory for XFmode.  So if
2832          we need one, follow the store with a load.  */
2833       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2834         return "fstp%z0\t%y0\;fld%z0\t%y0";
2835       else
2836         return "fstp%z0\t%y0";
2838     case 2:
2839       return standard_80387_constant_opcode (operands[1]);
2841     case 3: case 4:
2842       return "#";
2843     }
2844   abort();
2846   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2847    (set_attr "mode" "XF,XF,XF,SI,SI")])
2849 (define_split
2850   [(set (match_operand 0 "nonimmediate_operand" "")
2851         (match_operand 1 "general_operand" ""))]
2852   "reload_completed
2853    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2854    && GET_MODE (operands[0]) == XFmode
2855    && ! (ANY_FP_REG_P (operands[0]) || 
2856          (GET_CODE (operands[0]) == SUBREG
2857           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2858    && ! (ANY_FP_REG_P (operands[1]) || 
2859          (GET_CODE (operands[1]) == SUBREG
2860           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2861   [(const_int 0)]
2862   "ix86_split_long_move (operands); DONE;")
2864 (define_split
2865   [(set (match_operand 0 "register_operand" "")
2866         (match_operand 1 "memory_operand" ""))]
2867   "reload_completed
2868    && GET_CODE (operands[1]) == MEM
2869    && (GET_MODE (operands[0]) == XFmode
2870        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2871    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2872    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2873   [(set (match_dup 0) (match_dup 1))]
2875   rtx c = get_pool_constant (XEXP (operands[1], 0));
2876   rtx r = operands[0];
2878   if (GET_CODE (r) == SUBREG)
2879     r = SUBREG_REG (r);
2881   if (SSE_REG_P (r))
2882     {
2883       if (!standard_sse_constant_p (c))
2884         FAIL;
2885     }
2886   else if (FP_REG_P (r))
2887     {
2888       if (!standard_80387_constant_p (c))
2889         FAIL;
2890     }
2891   else if (MMX_REG_P (r))
2892     FAIL;
2894   operands[1] = c;
2897 (define_insn "swapxf"
2898   [(set (match_operand:XF 0 "register_operand" "+f")
2899         (match_operand:XF 1 "register_operand" "+f"))
2900    (set (match_dup 1)
2901         (match_dup 0))]
2902   ""
2904   if (STACK_TOP_P (operands[0]))
2905     return "fxch\t%1";
2906   else
2907     return "fxch\t%0";
2909   [(set_attr "type" "fxch")
2910    (set_attr "mode" "XF")])
2912 ;; Zero extension instructions
2914 (define_expand "zero_extendhisi2"
2915   [(set (match_operand:SI 0 "register_operand" "")
2916      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2917   ""
2919   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2920     {
2921       operands[1] = force_reg (HImode, operands[1]);
2922       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2923       DONE;
2924     }
2927 (define_insn "zero_extendhisi2_and"
2928   [(set (match_operand:SI 0 "register_operand" "=r")
2929      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2930    (clobber (reg:CC FLAGS_REG))]
2931   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2932   "#"
2933   [(set_attr "type" "alu1")
2934    (set_attr "mode" "SI")])
2936 (define_split
2937   [(set (match_operand:SI 0 "register_operand" "")
2938         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2939    (clobber (reg:CC FLAGS_REG))]
2940   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2941   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2942               (clobber (reg:CC FLAGS_REG))])]
2943   "")
2945 (define_insn "*zero_extendhisi2_movzwl"
2946   [(set (match_operand:SI 0 "register_operand" "=r")
2947      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2948   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2949   "movz{wl|x}\t{%1, %0|%0, %1}"
2950   [(set_attr "type" "imovx")
2951    (set_attr "mode" "SI")])
2953 (define_expand "zero_extendqihi2"
2954   [(parallel
2955     [(set (match_operand:HI 0 "register_operand" "")
2956        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2957      (clobber (reg:CC FLAGS_REG))])]
2958   ""
2959   "")
2961 (define_insn "*zero_extendqihi2_and"
2962   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2963      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2964    (clobber (reg:CC FLAGS_REG))]
2965   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2966   "#"
2967   [(set_attr "type" "alu1")
2968    (set_attr "mode" "HI")])
2970 (define_insn "*zero_extendqihi2_movzbw_and"
2971   [(set (match_operand:HI 0 "register_operand" "=r,r")
2972      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2973    (clobber (reg:CC FLAGS_REG))]
2974   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2975   "#"
2976   [(set_attr "type" "imovx,alu1")
2977    (set_attr "mode" "HI")])
2979 (define_insn "*zero_extendqihi2_movzbw"
2980   [(set (match_operand:HI 0 "register_operand" "=r")
2981      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2982   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2983   "movz{bw|x}\t{%1, %0|%0, %1}"
2984   [(set_attr "type" "imovx")
2985    (set_attr "mode" "HI")])
2987 ;; For the movzbw case strip only the clobber
2988 (define_split
2989   [(set (match_operand:HI 0 "register_operand" "")
2990         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2991    (clobber (reg:CC FLAGS_REG))]
2992   "reload_completed 
2993    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2994    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2995   [(set (match_operand:HI 0 "register_operand" "")
2996         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2998 ;; When source and destination does not overlap, clear destination
2999 ;; first and then do the movb
3000 (define_split
3001   [(set (match_operand:HI 0 "register_operand" "")
3002         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3003    (clobber (reg:CC FLAGS_REG))]
3004   "reload_completed
3005    && ANY_QI_REG_P (operands[0])
3006    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3007    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3008   [(set (match_dup 0) (const_int 0))
3009    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3010   "operands[2] = gen_lowpart (QImode, operands[0]);")
3012 ;; Rest is handled by single and.
3013 (define_split
3014   [(set (match_operand:HI 0 "register_operand" "")
3015         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3016    (clobber (reg:CC FLAGS_REG))]
3017   "reload_completed
3018    && true_regnum (operands[0]) == true_regnum (operands[1])"
3019   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3020               (clobber (reg:CC FLAGS_REG))])]
3021   "")
3023 (define_expand "zero_extendqisi2"
3024   [(parallel
3025     [(set (match_operand:SI 0 "register_operand" "")
3026        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3027      (clobber (reg:CC FLAGS_REG))])]
3028   ""
3029   "")
3031 (define_insn "*zero_extendqisi2_and"
3032   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3033      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3034    (clobber (reg:CC FLAGS_REG))]
3035   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3036   "#"
3037   [(set_attr "type" "alu1")
3038    (set_attr "mode" "SI")])
3040 (define_insn "*zero_extendqisi2_movzbw_and"
3041   [(set (match_operand:SI 0 "register_operand" "=r,r")
3042      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3043    (clobber (reg:CC FLAGS_REG))]
3044   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3045   "#"
3046   [(set_attr "type" "imovx,alu1")
3047    (set_attr "mode" "SI")])
3049 (define_insn "*zero_extendqisi2_movzbw"
3050   [(set (match_operand:SI 0 "register_operand" "=r")
3051      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3052   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3053   "movz{bl|x}\t{%1, %0|%0, %1}"
3054   [(set_attr "type" "imovx")
3055    (set_attr "mode" "SI")])
3057 ;; For the movzbl case strip only the clobber
3058 (define_split
3059   [(set (match_operand:SI 0 "register_operand" "")
3060         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3061    (clobber (reg:CC FLAGS_REG))]
3062   "reload_completed 
3063    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3064    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3065   [(set (match_dup 0)
3066         (zero_extend:SI (match_dup 1)))])
3068 ;; When source and destination does not overlap, clear destination
3069 ;; first and then do the movb
3070 (define_split
3071   [(set (match_operand:SI 0 "register_operand" "")
3072         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3073    (clobber (reg:CC FLAGS_REG))]
3074   "reload_completed
3075    && ANY_QI_REG_P (operands[0])
3076    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3077    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3078    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3079   [(set (match_dup 0) (const_int 0))
3080    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3081   "operands[2] = gen_lowpart (QImode, operands[0]);")
3083 ;; Rest is handled by single and.
3084 (define_split
3085   [(set (match_operand:SI 0 "register_operand" "")
3086         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3087    (clobber (reg:CC FLAGS_REG))]
3088   "reload_completed
3089    && true_regnum (operands[0]) == true_regnum (operands[1])"
3090   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3091               (clobber (reg:CC FLAGS_REG))])]
3092   "")
3094 ;; %%% Kill me once multi-word ops are sane.
3095 (define_expand "zero_extendsidi2"
3096   [(set (match_operand:DI 0 "register_operand" "=r")
3097      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3098   ""
3099   "if (!TARGET_64BIT)
3100      {
3101        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3102        DONE;
3103      }
3104   ")
3106 (define_insn "zero_extendsidi2_32"
3107   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3108         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3109    (clobber (reg:CC FLAGS_REG))]
3110   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3111   "@
3112    #
3113    #
3114    #
3115    movd\t{%1, %0|%0, %1}
3116    movd\t{%1, %0|%0, %1}"
3117   [(set_attr "mode" "SI,SI,SI,DI,TI")
3118    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3120 (define_insn "*zero_extendsidi2_32_1"
3121   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3122         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3123    (clobber (reg:CC FLAGS_REG))]
3124   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3125   "@
3126    #
3127    #
3128    #
3129    movd\t{%1, %0|%0, %1}
3130    movd\t{%1, %0|%0, %1}"
3131   [(set_attr "mode" "SI,SI,SI,DI,TI")
3132    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3134 (define_insn "zero_extendsidi2_rex64"
3135   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3136      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3137   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3138   "@
3139    mov\t{%k1, %k0|%k0, %k1}
3140    #
3141    movd\t{%1, %0|%0, %1}
3142    movd\t{%1, %0|%0, %1}"
3143   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3144    (set_attr "mode" "SI,DI,DI,TI")])
3146 (define_insn "*zero_extendsidi2_rex64_1"
3147   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3148      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3149   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3150   "@
3151    mov\t{%k1, %k0|%k0, %k1}
3152    #
3153    movd\t{%1, %0|%0, %1}
3154    movd\t{%1, %0|%0, %1}"
3155   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3156    (set_attr "mode" "SI,DI,SI,SI")])
3158 (define_split
3159   [(set (match_operand:DI 0 "memory_operand" "")
3160      (zero_extend:DI (match_dup 0)))]
3161   "TARGET_64BIT"
3162   [(set (match_dup 4) (const_int 0))]
3163   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3165 (define_split 
3166   [(set (match_operand:DI 0 "register_operand" "")
3167         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3168    (clobber (reg:CC FLAGS_REG))]
3169   "!TARGET_64BIT && reload_completed
3170    && true_regnum (operands[0]) == true_regnum (operands[1])"
3171   [(set (match_dup 4) (const_int 0))]
3172   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3174 (define_split 
3175   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3176         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3177    (clobber (reg:CC FLAGS_REG))]
3178   "!TARGET_64BIT && reload_completed
3179    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3180   [(set (match_dup 3) (match_dup 1))
3181    (set (match_dup 4) (const_int 0))]
3182   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3184 (define_insn "zero_extendhidi2"
3185   [(set (match_operand:DI 0 "register_operand" "=r,r")
3186      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3187   "TARGET_64BIT"
3188   "@
3189    movz{wl|x}\t{%1, %k0|%k0, %1}
3190    movz{wq|x}\t{%1, %0|%0, %1}"
3191   [(set_attr "type" "imovx")
3192    (set_attr "mode" "SI,DI")])
3194 (define_insn "zero_extendqidi2"
3195   [(set (match_operand:DI 0 "register_operand" "=r,r")
3196      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3197   "TARGET_64BIT"
3198   "@
3199    movz{bl|x}\t{%1, %k0|%k0, %1}
3200    movz{bq|x}\t{%1, %0|%0, %1}"
3201   [(set_attr "type" "imovx")
3202    (set_attr "mode" "SI,DI")])
3204 ;; Sign extension instructions
3206 (define_expand "extendsidi2"
3207   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3208                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3209               (clobber (reg:CC FLAGS_REG))
3210               (clobber (match_scratch:SI 2 ""))])]
3211   ""
3213   if (TARGET_64BIT)
3214     {
3215       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3216       DONE;
3217     }
3220 (define_insn "*extendsidi2_1"
3221   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3222         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3223    (clobber (reg:CC FLAGS_REG))
3224    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3225   "!TARGET_64BIT"
3226   "#")
3228 (define_insn "extendsidi2_rex64"
3229   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3230         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3231   "TARGET_64BIT"
3232   "@
3233    {cltq|cdqe}
3234    movs{lq|x}\t{%1,%0|%0, %1}"
3235   [(set_attr "type" "imovx")
3236    (set_attr "mode" "DI")
3237    (set_attr "prefix_0f" "0")
3238    (set_attr "modrm" "0,1")])
3240 (define_insn "extendhidi2"
3241   [(set (match_operand:DI 0 "register_operand" "=r")
3242         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243   "TARGET_64BIT"
3244   "movs{wq|x}\t{%1,%0|%0, %1}"
3245   [(set_attr "type" "imovx")
3246    (set_attr "mode" "DI")])
3248 (define_insn "extendqidi2"
3249   [(set (match_operand:DI 0 "register_operand" "=r")
3250         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3251   "TARGET_64BIT"
3252   "movs{bq|x}\t{%1,%0|%0, %1}"
3253    [(set_attr "type" "imovx")
3254     (set_attr "mode" "DI")])
3256 ;; Extend to memory case when source register does die.
3257 (define_split 
3258   [(set (match_operand:DI 0 "memory_operand" "")
3259         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3260    (clobber (reg:CC FLAGS_REG))
3261    (clobber (match_operand:SI 2 "register_operand" ""))]
3262   "(reload_completed
3263     && dead_or_set_p (insn, operands[1])
3264     && !reg_mentioned_p (operands[1], operands[0]))"
3265   [(set (match_dup 3) (match_dup 1))
3266    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3267               (clobber (reg:CC FLAGS_REG))])
3268    (set (match_dup 4) (match_dup 1))]
3269   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3271 ;; Extend to memory case when source register does not die.
3272 (define_split 
3273   [(set (match_operand:DI 0 "memory_operand" "")
3274         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3275    (clobber (reg:CC FLAGS_REG))
3276    (clobber (match_operand:SI 2 "register_operand" ""))]
3277   "reload_completed"
3278   [(const_int 0)]
3280   split_di (&operands[0], 1, &operands[3], &operands[4]);
3282   emit_move_insn (operands[3], operands[1]);
3284   /* Generate a cltd if possible and doing so it profitable.  */
3285   if (true_regnum (operands[1]) == 0
3286       && true_regnum (operands[2]) == 1
3287       && (optimize_size || TARGET_USE_CLTD))
3288     {
3289       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3290     }
3291   else
3292     {
3293       emit_move_insn (operands[2], operands[1]);
3294       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3295     }
3296   emit_move_insn (operands[4], operands[2]);
3297   DONE;
3300 ;; Extend to register case.  Optimize case where source and destination
3301 ;; registers match and cases where we can use cltd.
3302 (define_split 
3303   [(set (match_operand:DI 0 "register_operand" "")
3304         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3305    (clobber (reg:CC FLAGS_REG))
3306    (clobber (match_scratch:SI 2 ""))]
3307   "reload_completed"
3308   [(const_int 0)]
3310   split_di (&operands[0], 1, &operands[3], &operands[4]);
3312   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3313     emit_move_insn (operands[3], operands[1]);
3315   /* Generate a cltd if possible and doing so it profitable.  */
3316   if (true_regnum (operands[3]) == 0
3317       && (optimize_size || TARGET_USE_CLTD))
3318     {
3319       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3320       DONE;
3321     }
3323   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3324     emit_move_insn (operands[4], operands[1]);
3326   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3327   DONE;
3330 (define_insn "extendhisi2"
3331   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3332         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3333   ""
3335   switch (get_attr_prefix_0f (insn))
3336     {
3337     case 0:
3338       return "{cwtl|cwde}";
3339     default:
3340       return "movs{wl|x}\t{%1,%0|%0, %1}";
3341     }
3343   [(set_attr "type" "imovx")
3344    (set_attr "mode" "SI")
3345    (set (attr "prefix_0f")
3346      ;; movsx is short decodable while cwtl is vector decoded.
3347      (if_then_else (and (eq_attr "cpu" "!k6")
3348                         (eq_attr "alternative" "0"))
3349         (const_string "0")
3350         (const_string "1")))
3351    (set (attr "modrm")
3352      (if_then_else (eq_attr "prefix_0f" "0")
3353         (const_string "0")
3354         (const_string "1")))])
3356 (define_insn "*extendhisi2_zext"
3357   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3358         (zero_extend:DI
3359           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3360   "TARGET_64BIT"
3362   switch (get_attr_prefix_0f (insn))
3363     {
3364     case 0:
3365       return "{cwtl|cwde}";
3366     default:
3367       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3368     }
3370   [(set_attr "type" "imovx")
3371    (set_attr "mode" "SI")
3372    (set (attr "prefix_0f")
3373      ;; movsx is short decodable while cwtl is vector decoded.
3374      (if_then_else (and (eq_attr "cpu" "!k6")
3375                         (eq_attr "alternative" "0"))
3376         (const_string "0")
3377         (const_string "1")))
3378    (set (attr "modrm")
3379      (if_then_else (eq_attr "prefix_0f" "0")
3380         (const_string "0")
3381         (const_string "1")))])
3383 (define_insn "extendqihi2"
3384   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3385         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3386   ""
3388   switch (get_attr_prefix_0f (insn))
3389     {
3390     case 0:
3391       return "{cbtw|cbw}";
3392     default:
3393       return "movs{bw|x}\t{%1,%0|%0, %1}";
3394     }
3396   [(set_attr "type" "imovx")
3397    (set_attr "mode" "HI")
3398    (set (attr "prefix_0f")
3399      ;; movsx is short decodable while cwtl is vector decoded.
3400      (if_then_else (and (eq_attr "cpu" "!k6")
3401                         (eq_attr "alternative" "0"))
3402         (const_string "0")
3403         (const_string "1")))
3404    (set (attr "modrm")
3405      (if_then_else (eq_attr "prefix_0f" "0")
3406         (const_string "0")
3407         (const_string "1")))])
3409 (define_insn "extendqisi2"
3410   [(set (match_operand:SI 0 "register_operand" "=r")
3411         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3412   ""
3413   "movs{bl|x}\t{%1,%0|%0, %1}"
3414    [(set_attr "type" "imovx")
3415     (set_attr "mode" "SI")])
3417 (define_insn "*extendqisi2_zext"
3418   [(set (match_operand:DI 0 "register_operand" "=r")
3419         (zero_extend:DI
3420           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3421   "TARGET_64BIT"
3422   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3423    [(set_attr "type" "imovx")
3424     (set_attr "mode" "SI")])
3426 ;; Conversions between float and double.
3428 ;; These are all no-ops in the model used for the 80387.  So just
3429 ;; emit moves.
3431 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3432 (define_insn "*dummy_extendsfdf2"
3433   [(set (match_operand:DF 0 "push_operand" "=<")
3434         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3435   "0"
3436   "#")
3438 (define_split
3439   [(set (match_operand:DF 0 "push_operand" "")
3440         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3441   "!TARGET_64BIT"
3442   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3443    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3445 (define_split
3446   [(set (match_operand:DF 0 "push_operand" "")
3447         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3448   "TARGET_64BIT"
3449   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3450    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3452 (define_insn "*dummy_extendsfxf2"
3453   [(set (match_operand:XF 0 "push_operand" "=<")
3454         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3455   "0"
3456   "#")
3458 (define_split
3459   [(set (match_operand:XF 0 "push_operand" "")
3460         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3461   ""
3462   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3463    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3464   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3466 (define_split
3467   [(set (match_operand:XF 0 "push_operand" "")
3468         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3469   "TARGET_64BIT"
3470   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3471    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3472   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3474 (define_split
3475   [(set (match_operand:XF 0 "push_operand" "")
3476         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3477   ""
3478   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3479    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3480   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3482 (define_split
3483   [(set (match_operand:XF 0 "push_operand" "")
3484         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3485   "TARGET_64BIT"
3486   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3487    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3488   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3490 (define_expand "extendsfdf2"
3491   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3492         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3493   "TARGET_80387 || TARGET_SSE2"
3495   /* ??? Needed for compress_float_constant since all fp constants
3496      are LEGITIMATE_CONSTANT_P.  */
3497   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3498     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3499   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3500     operands[1] = force_reg (SFmode, operands[1]);
3503 (define_insn "*extendsfdf2_1"
3504   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3505         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3506   "(TARGET_80387 || TARGET_SSE2)
3507    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3509   switch (which_alternative)
3510     {
3511     case 0:
3512       return output_387_reg_move (insn, operands);
3514     case 1:
3515       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3516         return "fstp%z0\t%y0";
3517       else
3518         return "fst%z0\t%y0";
3520     case 2:
3521       return "cvtss2sd\t{%1, %0|%0, %1}";
3523     default:
3524       abort ();
3525     }
3527   [(set_attr "type" "fmov,fmov,ssecvt")
3528    (set_attr "mode" "SF,XF,DF")])
3530 (define_insn "*extendsfdf2_1_sse_only"
3531   [(set (match_operand:DF 0 "register_operand" "=Y")
3532         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3533   "!TARGET_80387 && TARGET_SSE2
3534    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3535   "cvtss2sd\t{%1, %0|%0, %1}"
3536   [(set_attr "type" "ssecvt")
3537    (set_attr "mode" "DF")])
3539 (define_expand "extendsfxf2"
3540   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3541         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3542   "TARGET_80387"
3544   /* ??? Needed for compress_float_constant since all fp constants
3545      are LEGITIMATE_CONSTANT_P.  */
3546   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3547     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3548   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3549     operands[1] = force_reg (SFmode, operands[1]);
3552 (define_insn "*extendsfxf2_1"
3553   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3554         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3555   "TARGET_80387
3556    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3558   switch (which_alternative)
3559     {
3560     case 0:
3561       return output_387_reg_move (insn, operands);
3563     case 1:
3564       /* There is no non-popping store to memory for XFmode.  So if
3565          we need one, follow the store with a load.  */
3566       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3567         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3568       else
3569         return "fstp%z0\t%y0";
3571     default:
3572       abort ();
3573     }
3575   [(set_attr "type" "fmov")
3576    (set_attr "mode" "SF,XF")])
3578 (define_expand "extenddfxf2"
3579   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3580         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3581   "TARGET_80387"
3583   /* ??? Needed for compress_float_constant since all fp constants
3584      are LEGITIMATE_CONSTANT_P.  */
3585   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3586     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3587   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3588     operands[1] = force_reg (DFmode, operands[1]);
3591 (define_insn "*extenddfxf2_1"
3592   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3593         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3594   "TARGET_80387
3595    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3597   switch (which_alternative)
3598     {
3599     case 0:
3600       return output_387_reg_move (insn, operands);
3602     case 1:
3603       /* There is no non-popping store to memory for XFmode.  So if
3604          we need one, follow the store with a load.  */
3605       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3606         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3607       else
3608         return "fstp%z0\t%y0";
3610     default:
3611       abort ();
3612     }
3614   [(set_attr "type" "fmov")
3615    (set_attr "mode" "DF,XF")])
3617 ;; %%% This seems bad bad news.
3618 ;; This cannot output into an f-reg because there is no way to be sure
3619 ;; of truncating in that case.  Otherwise this is just like a simple move
3620 ;; insn.  So we pretend we can output to a reg in order to get better
3621 ;; register preferencing, but we really use a stack slot.
3623 (define_expand "truncdfsf2"
3624   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3625                    (float_truncate:SF
3626                     (match_operand:DF 1 "register_operand" "")))
3627               (clobber (match_dup 2))])]
3628   "TARGET_80387 || TARGET_SSE2"
3629   "
3630    if (!TARGET_80387)
3631      {
3632         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3633         DONE;
3634      }
3635    else if (flag_unsafe_math_optimizations)
3636      {
3637         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3638         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3639         if (reg != operands[0])
3640           emit_move_insn (operands[0], reg);
3641         DONE;
3642      }
3643    else
3644      operands[2] = assign_386_stack_local (SFmode, 0);
3647 (define_insn "truncdfsf2_noop"
3648   [(set (match_operand:SF 0 "register_operand" "=f")
3649         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3650   "TARGET_80387 && flag_unsafe_math_optimizations"
3652   return output_387_reg_move (insn, operands);
3654   [(set_attr "type" "fmov")
3655    (set_attr "mode" "SF")])
3657 (define_insn "*truncdfsf2_1"
3658   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3659         (float_truncate:SF
3660          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3661    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3662   "TARGET_80387 && !TARGET_SSE2"
3664   switch (which_alternative)
3665     {
3666     case 0:
3667       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3668         return "fstp%z0\t%y0";
3669       else
3670         return "fst%z0\t%y0";
3671     default:
3672       abort ();
3673     }
3675   [(set_attr "type" "fmov,multi,multi,multi")
3676    (set_attr "mode" "SF,SF,SF,SF")])
3678 (define_insn "*truncdfsf2_1_sse"
3679   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3680         (float_truncate:SF
3681          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3682    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3683   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3685   switch (which_alternative)
3686     {
3687     case 0:
3688       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689         return "fstp%z0\t%y0";
3690       else
3691         return "fst%z0\t%y0";
3692     case 4:
3693       return "#";
3694     default:
3695       abort ();
3696     }
3698   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3699    (set_attr "mode" "SF,SF,SF,SF,DF")])
3701 (define_insn "*truncdfsf2_1_sse_nooverlap"
3702   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3703         (float_truncate:SF
3704          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3705    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3706   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3708   switch (which_alternative)
3709     {
3710     case 0:
3711       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712         return "fstp%z0\t%y0";
3713       else
3714         return "fst%z0\t%y0";
3715     case 4:
3716       return "#";
3717     default:
3718       abort ();
3719     }
3721   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3722    (set_attr "mode" "SF,SF,SF,SF,DF")])
3724 (define_insn "*truncdfsf2_2"
3725   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3726         (float_truncate:SF
3727          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3728   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3729    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3731   switch (which_alternative)
3732     {
3733     case 0:
3734     case 1:
3735       return "cvtsd2ss\t{%1, %0|%0, %1}";
3736     case 2:
3737       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3738         return "fstp%z0\t%y0";
3739       else
3740         return "fst%z0\t%y0";
3741     default:
3742       abort ();
3743     }
3745   [(set_attr "type" "ssecvt,ssecvt,fmov")
3746    (set_attr "athlon_decode" "vector,double,*")
3747    (set_attr "mode" "SF,SF,SF")])
3749 (define_insn "*truncdfsf2_2_nooverlap"
3750   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3751         (float_truncate:SF
3752          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3753   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3754    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3756   switch (which_alternative)
3757     {
3758     case 0:
3759       return "#";
3760     case 1:
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,fmov")
3770    (set_attr "mode" "DF,SF")])
3772 (define_insn "*truncdfsf2_3"
3773   [(set (match_operand:SF 0 "memory_operand" "=m")
3774         (float_truncate:SF
3775          (match_operand:DF 1 "register_operand" "f")))]
3776   "TARGET_80387"
3778   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3779     return "fstp%z0\t%y0";
3780   else
3781     return "fst%z0\t%y0";
3783   [(set_attr "type" "fmov")
3784    (set_attr "mode" "SF")])
3786 (define_insn "truncdfsf2_sse_only"
3787   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3788         (float_truncate:SF
3789          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3790   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3791   "cvtsd2ss\t{%1, %0|%0, %1}"
3792   [(set_attr "type" "ssecvt")
3793    (set_attr "athlon_decode" "vector,double")
3794    (set_attr "mode" "SF")])
3796 (define_insn "*truncdfsf2_sse_only_nooverlap"
3797   [(set (match_operand:SF 0 "register_operand" "=&Y")
3798         (float_truncate:SF
3799          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3800   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3801   "#"
3802   [(set_attr "type" "ssecvt")
3803    (set_attr "mode" "DF")])
3805 (define_split
3806   [(set (match_operand:SF 0 "memory_operand" "")
3807         (float_truncate:SF
3808          (match_operand:DF 1 "register_operand" "")))
3809    (clobber (match_operand:SF 2 "memory_operand" ""))]
3810   "TARGET_80387"
3811   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3812   "")
3814 ; Avoid possible reformatting penalty on the destination by first
3815 ; zeroing it out
3816 (define_split
3817   [(set (match_operand:SF 0 "register_operand" "")
3818         (float_truncate:SF
3819          (match_operand:DF 1 "nonimmediate_operand" "")))
3820    (clobber (match_operand 2 "" ""))]
3821   "TARGET_80387 && reload_completed
3822    && SSE_REG_P (operands[0])
3823    && !STACK_REG_P (operands[1])"
3824   [(const_int 0)]
3826   rtx src, dest;
3827   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3828     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3829   else
3830     {
3831       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3832       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3833       /* simplify_gen_subreg refuses to widen memory references.  */
3834       if (GET_CODE (src) == SUBREG)
3835         alter_subreg (&src);
3836       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3837         abort ();
3838       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3839       emit_insn (gen_cvtsd2ss (dest, dest, src));
3840     }
3841   DONE;
3844 (define_split
3845   [(set (match_operand:SF 0 "register_operand" "")
3846         (float_truncate:SF
3847          (match_operand:DF 1 "nonimmediate_operand" "")))]
3848   "TARGET_80387 && reload_completed
3849    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3850   [(const_int 0)]
3852   rtx src, dest;
3853   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3854   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3855   /* simplify_gen_subreg refuses to widen memory references.  */
3856   if (GET_CODE (src) == SUBREG)
3857     alter_subreg (&src);
3858   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3859     abort ();
3860   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3861   emit_insn (gen_cvtsd2ss (dest, dest, src));
3862   DONE;
3865 (define_split
3866   [(set (match_operand:SF 0 "register_operand" "")
3867         (float_truncate:SF
3868          (match_operand:DF 1 "fp_register_operand" "")))
3869    (clobber (match_operand:SF 2 "memory_operand" ""))]
3870   "TARGET_80387 && reload_completed"
3871   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3872    (set (match_dup 0) (match_dup 2))]
3873   "")
3875 (define_expand "truncxfsf2"
3876   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3877                    (float_truncate:SF
3878                     (match_operand:XF 1 "register_operand" "")))
3879               (clobber (match_dup 2))])]
3880   "TARGET_80387"
3881   "
3882   if (flag_unsafe_math_optimizations)
3883     {
3884       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3885       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3886       if (reg != operands[0])
3887         emit_move_insn (operands[0], reg);
3888       DONE;
3889     }
3890   else
3891     operands[2] = assign_386_stack_local (SFmode, 0);
3892   ")
3894 (define_insn "truncxfsf2_noop"
3895   [(set (match_operand:SF 0 "register_operand" "=f")
3896         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3897   "TARGET_80387 && flag_unsafe_math_optimizations"
3899   return output_387_reg_move (insn, operands);
3901   [(set_attr "type" "fmov")
3902    (set_attr "mode" "SF")])
3904 (define_insn "*truncxfsf2_1"
3905   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3906         (float_truncate:SF
3907          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3908    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3909   "TARGET_80387"
3911   switch (which_alternative)
3912     {
3913     case 0:
3914       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3915         return "fstp%z0\t%y0";
3916       else
3917         return "fst%z0\t%y0";
3918     default:
3919       abort();
3920     }
3922   [(set_attr "type" "fmov,multi,multi,multi")
3923    (set_attr "mode" "SF")])
3925 (define_insn "*truncxfsf2_2"
3926   [(set (match_operand:SF 0 "memory_operand" "=m")
3927         (float_truncate:SF
3928          (match_operand:XF 1 "register_operand" "f")))]
3929   "TARGET_80387"
3931   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3932     return "fstp%z0\t%y0";
3933   else
3934     return "fst%z0\t%y0";
3936   [(set_attr "type" "fmov")
3937    (set_attr "mode" "SF")])
3939 (define_split
3940   [(set (match_operand:SF 0 "memory_operand" "")
3941         (float_truncate:SF
3942          (match_operand:XF 1 "register_operand" "")))
3943    (clobber (match_operand:SF 2 "memory_operand" ""))]
3944   "TARGET_80387"
3945   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3946   "")
3948 (define_split
3949   [(set (match_operand:SF 0 "register_operand" "")
3950         (float_truncate:SF
3951          (match_operand:XF 1 "register_operand" "")))
3952    (clobber (match_operand:SF 2 "memory_operand" ""))]
3953   "TARGET_80387 && reload_completed"
3954   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3955    (set (match_dup 0) (match_dup 2))]
3956   "")
3958 (define_expand "truncxfdf2"
3959   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3960                    (float_truncate:DF
3961                     (match_operand:XF 1 "register_operand" "")))
3962               (clobber (match_dup 2))])]
3963   "TARGET_80387"
3964   "
3965   if (flag_unsafe_math_optimizations)
3966     {
3967       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3968       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3969       if (reg != operands[0])
3970         emit_move_insn (operands[0], reg);
3971       DONE;
3972     }
3973   else
3974     operands[2] = assign_386_stack_local (DFmode, 0);
3975   ")
3977 (define_insn "truncxfdf2_noop"
3978   [(set (match_operand:DF 0 "register_operand" "=f")
3979         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3980   "TARGET_80387 && flag_unsafe_math_optimizations"
3982   return output_387_reg_move (insn, operands);
3984   [(set_attr "type" "fmov")
3985    (set_attr "mode" "DF")])
3987 (define_insn "*truncxfdf2_1"
3988   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3989         (float_truncate:DF
3990          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3991    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3992   "TARGET_80387"
3994   switch (which_alternative)
3995     {
3996     case 0:
3997       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3998         return "fstp%z0\t%y0";
3999       else
4000         return "fst%z0\t%y0";
4001     default:
4002       abort();
4003     }
4004   abort ();
4006   [(set_attr "type" "fmov,multi,multi,multi")
4007    (set_attr "mode" "DF")])
4009 (define_insn "*truncxfdf2_2"
4010   [(set (match_operand:DF 0 "memory_operand" "=m")
4011         (float_truncate:DF
4012           (match_operand:XF 1 "register_operand" "f")))]
4013   "TARGET_80387"
4015   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4016     return "fstp%z0\t%y0";
4017   else
4018     return "fst%z0\t%y0";
4020   [(set_attr "type" "fmov")
4021    (set_attr "mode" "DF")])
4023 (define_split
4024   [(set (match_operand:DF 0 "memory_operand" "")
4025         (float_truncate:DF
4026          (match_operand:XF 1 "register_operand" "")))
4027    (clobber (match_operand:DF 2 "memory_operand" ""))]
4028   "TARGET_80387"
4029   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4030   "")
4032 (define_split
4033   [(set (match_operand:DF 0 "register_operand" "")
4034         (float_truncate:DF
4035          (match_operand:XF 1 "register_operand" "")))
4036    (clobber (match_operand:DF 2 "memory_operand" ""))]
4037   "TARGET_80387 && reload_completed"
4038   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4039    (set (match_dup 0) (match_dup 2))]
4040   "")
4043 ;; %%% Break up all these bad boys.
4045 ;; Signed conversion to DImode.
4047 (define_expand "fix_truncxfdi2"
4048   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4049                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4050               (clobber (reg:CC FLAGS_REG))])]
4051   "TARGET_80387"
4052   "")
4054 (define_expand "fix_truncdfdi2"
4055   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4056                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4057               (clobber (reg:CC FLAGS_REG))])]
4058   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4060   if (TARGET_64BIT && TARGET_SSE2)
4061    {
4062      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4063      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4064      if (out != operands[0])
4065         emit_move_insn (operands[0], out);
4066      DONE;
4067    }
4070 (define_expand "fix_truncsfdi2"
4071   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4072                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4073               (clobber (reg:CC FLAGS_REG))])] 
4074   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4076   if (TARGET_SSE && TARGET_64BIT)
4077    {
4078      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4079      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4080      if (out != operands[0])
4081         emit_move_insn (operands[0], out);
4082      DONE;
4083    }
4086 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4087 ;; of the machinery.
4088 (define_insn_and_split "*fix_truncdi_1"
4089   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4090         (fix:DI (match_operand 1 "register_operand" "f,f")))
4091    (clobber (reg:CC FLAGS_REG))]
4092   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4093    && !reload_completed && !reload_in_progress
4094    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4095   "#"
4096   "&& 1"
4097   [(const_int 0)]
4099   ix86_optimize_mode_switching = 1;
4100   operands[2] = assign_386_stack_local (HImode, 1);
4101   operands[3] = assign_386_stack_local (HImode, 2);
4102   if (memory_operand (operands[0], VOIDmode))
4103     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4104                                        operands[2], operands[3]));
4105   else
4106     {
4107       operands[4] = assign_386_stack_local (DImode, 0);
4108       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4109                                            operands[2], operands[3],
4110                                            operands[4]));
4111     }
4112   DONE;
4114   [(set_attr "type" "fistp")
4115    (set_attr "i387_cw" "trunc")
4116    (set_attr "mode" "DI")])
4118 (define_insn "fix_truncdi_nomemory"
4119   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4120         (fix:DI (match_operand 1 "register_operand" "f,f")))
4121    (use (match_operand:HI 2 "memory_operand" "m,m"))
4122    (use (match_operand:HI 3 "memory_operand" "m,m"))
4123    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4124    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4125   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4126    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4127   "#"
4128   [(set_attr "type" "fistp")
4129    (set_attr "i387_cw" "trunc")
4130    (set_attr "mode" "DI")])
4132 (define_insn "fix_truncdi_memory"
4133   [(set (match_operand:DI 0 "memory_operand" "=m")
4134         (fix:DI (match_operand 1 "register_operand" "f")))
4135    (use (match_operand:HI 2 "memory_operand" "m"))
4136    (use (match_operand:HI 3 "memory_operand" "m"))
4137    (clobber (match_scratch:DF 4 "=&1f"))]
4138   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4139    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4140   "* return output_fix_trunc (insn, operands);"
4141   [(set_attr "type" "fistp")
4142    (set_attr "i387_cw" "trunc")
4143    (set_attr "mode" "DI")])
4145 (define_split 
4146   [(set (match_operand:DI 0 "register_operand" "")
4147         (fix:DI (match_operand 1 "register_operand" "")))
4148    (use (match_operand:HI 2 "memory_operand" ""))
4149    (use (match_operand:HI 3 "memory_operand" ""))
4150    (clobber (match_operand:DI 4 "memory_operand" ""))
4151    (clobber (match_scratch 5 ""))]
4152   "reload_completed"
4153   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4154               (use (match_dup 2))
4155               (use (match_dup 3))
4156               (clobber (match_dup 5))])
4157    (set (match_dup 0) (match_dup 4))]
4158   "")
4160 (define_split 
4161   [(set (match_operand:DI 0 "memory_operand" "")
4162         (fix:DI (match_operand 1 "register_operand" "")))
4163    (use (match_operand:HI 2 "memory_operand" ""))
4164    (use (match_operand:HI 3 "memory_operand" ""))
4165    (clobber (match_operand:DI 4 "memory_operand" ""))
4166    (clobber (match_scratch 5 ""))]
4167   "reload_completed"
4168   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4169               (use (match_dup 2))
4170               (use (match_dup 3))
4171               (clobber (match_dup 5))])]
4172   "")
4174 ;; When SSE available, it is always faster to use it!
4175 (define_insn "fix_truncsfdi_sse"
4176   [(set (match_operand:DI 0 "register_operand" "=r,r")
4177         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4178   "TARGET_64BIT && TARGET_SSE"
4179   "cvttss2si{q}\t{%1, %0|%0, %1}"
4180   [(set_attr "type" "sseicvt")
4181    (set_attr "mode" "SF")
4182    (set_attr "athlon_decode" "double,vector")])
4184 ;; Avoid vector decoded form of the instruction.
4185 (define_peephole2
4186   [(match_scratch:SF 2 "x")
4187    (set (match_operand:DI 0 "register_operand" "")
4188         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4189   "TARGET_K8 && !optimize_size"
4190   [(set (match_dup 2) (match_dup 1))
4191    (set (match_dup 0) (fix:DI (match_dup 2)))]
4192   "")
4194 (define_insn "fix_truncdfdi_sse"
4195   [(set (match_operand:DI 0 "register_operand" "=r,r")
4196         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4197   "TARGET_64BIT && TARGET_SSE2"
4198   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4199   [(set_attr "type" "sseicvt,sseicvt")
4200    (set_attr "mode" "DF")
4201    (set_attr "athlon_decode" "double,vector")])
4203 ;; Avoid vector decoded form of the instruction.
4204 (define_peephole2
4205   [(match_scratch:DF 2 "Y")
4206    (set (match_operand:DI 0 "register_operand" "")
4207         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4208   "TARGET_K8 && !optimize_size"
4209   [(set (match_dup 2) (match_dup 1))
4210    (set (match_dup 0) (fix:DI (match_dup 2)))]
4211   "")
4213 ;; Signed conversion to SImode.
4215 (define_expand "fix_truncxfsi2"
4216   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4217                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4218               (clobber (reg:CC FLAGS_REG))])]
4219   "TARGET_80387"
4220   "")
4222 (define_expand "fix_truncdfsi2"
4223   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4224                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4225               (clobber (reg:CC FLAGS_REG))])]
4226   "TARGET_80387 || TARGET_SSE2"
4228   if (TARGET_SSE2)
4229    {
4230      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4231      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4232      if (out != operands[0])
4233         emit_move_insn (operands[0], out);
4234      DONE;
4235    }
4238 (define_expand "fix_truncsfsi2"
4239   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4240                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4241               (clobber (reg:CC FLAGS_REG))])] 
4242   "TARGET_80387 || TARGET_SSE"
4244   if (TARGET_SSE)
4245    {
4246      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4247      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4248      if (out != operands[0])
4249         emit_move_insn (operands[0], out);
4250      DONE;
4251    }
4254 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4255 ;; of the machinery.
4256 (define_insn_and_split "*fix_truncsi_1"
4257   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4258         (fix:SI (match_operand 1 "register_operand" "f,f")))
4259    (clobber (reg:CC FLAGS_REG))]
4260   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4261    && !reload_completed && !reload_in_progress
4262    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4263   "#"
4264   "&& 1"
4265   [(const_int 0)]
4267   ix86_optimize_mode_switching = 1;
4268   operands[2] = assign_386_stack_local (HImode, 1);
4269   operands[3] = assign_386_stack_local (HImode, 2);
4270   if (memory_operand (operands[0], VOIDmode))
4271     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4272                                        operands[2], operands[3]));
4273   else
4274     {
4275       operands[4] = assign_386_stack_local (SImode, 0);
4276       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4277                                            operands[2], operands[3],
4278                                            operands[4]));
4279     }
4280   DONE;
4282   [(set_attr "type" "fistp")
4283    (set_attr "i387_cw" "trunc")
4284    (set_attr "mode" "SI")])
4286 (define_insn "fix_truncsi_nomemory"
4287   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4288         (fix:SI (match_operand 1 "register_operand" "f,f")))
4289    (use (match_operand:HI 2 "memory_operand" "m,m"))
4290    (use (match_operand:HI 3 "memory_operand" "m,m"))
4291    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4292   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4293    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4294   "#"
4295   [(set_attr "type" "fistp")
4296    (set_attr "i387_cw" "trunc")
4297    (set_attr "mode" "SI")])
4299 (define_insn "fix_truncsi_memory"
4300   [(set (match_operand:SI 0 "memory_operand" "=m")
4301         (fix:SI (match_operand 1 "register_operand" "f")))
4302    (use (match_operand:HI 2 "memory_operand" "m"))
4303    (use (match_operand:HI 3 "memory_operand" "m"))]
4304   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4305    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4306   "* return output_fix_trunc (insn, operands);"
4307   [(set_attr "type" "fistp")
4308    (set_attr "i387_cw" "trunc")
4309    (set_attr "mode" "SI")])
4311 ;; When SSE available, it is always faster to use it!
4312 (define_insn "fix_truncsfsi_sse"
4313   [(set (match_operand:SI 0 "register_operand" "=r,r")
4314         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4315   "TARGET_SSE"
4316   "cvttss2si\t{%1, %0|%0, %1}"
4317   [(set_attr "type" "sseicvt")
4318    (set_attr "mode" "DF")
4319    (set_attr "athlon_decode" "double,vector")])
4321 ;; Avoid vector decoded form of the instruction.
4322 (define_peephole2
4323   [(match_scratch:SF 2 "x")
4324    (set (match_operand:SI 0 "register_operand" "")
4325         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4326   "TARGET_K8 && !optimize_size"
4327   [(set (match_dup 2) (match_dup 1))
4328    (set (match_dup 0) (fix:SI (match_dup 2)))]
4329   "")
4331 (define_insn "fix_truncdfsi_sse"
4332   [(set (match_operand:SI 0 "register_operand" "=r,r")
4333         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4334   "TARGET_SSE2"
4335   "cvttsd2si\t{%1, %0|%0, %1}"
4336   [(set_attr "type" "sseicvt")
4337    (set_attr "mode" "DF")
4338    (set_attr "athlon_decode" "double,vector")])
4340 ;; Avoid vector decoded form of the instruction.
4341 (define_peephole2
4342   [(match_scratch:DF 2 "Y")
4343    (set (match_operand:SI 0 "register_operand" "")
4344         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4345   "TARGET_K8 && !optimize_size"
4346   [(set (match_dup 2) (match_dup 1))
4347    (set (match_dup 0) (fix:SI (match_dup 2)))]
4348   "")
4350 (define_split 
4351   [(set (match_operand:SI 0 "register_operand" "")
4352         (fix:SI (match_operand 1 "register_operand" "")))
4353    (use (match_operand:HI 2 "memory_operand" ""))
4354    (use (match_operand:HI 3 "memory_operand" ""))
4355    (clobber (match_operand:SI 4 "memory_operand" ""))]
4356   "reload_completed"
4357   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4358               (use (match_dup 2))
4359               (use (match_dup 3))])
4360    (set (match_dup 0) (match_dup 4))]
4361   "")
4363 (define_split 
4364   [(set (match_operand:SI 0 "memory_operand" "")
4365         (fix:SI (match_operand 1 "register_operand" "")))
4366    (use (match_operand:HI 2 "memory_operand" ""))
4367    (use (match_operand:HI 3 "memory_operand" ""))
4368    (clobber (match_operand:SI 4 "memory_operand" ""))]
4369   "reload_completed"
4370   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4371               (use (match_dup 2))
4372               (use (match_dup 3))])]
4373   "")
4375 ;; Signed conversion to HImode.
4377 (define_expand "fix_truncxfhi2"
4378   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4379                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4380               (clobber (reg:CC FLAGS_REG))])] 
4381   "TARGET_80387"
4382   "")
4384 (define_expand "fix_truncdfhi2"
4385   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4386                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4387               (clobber (reg:CC FLAGS_REG))])]
4388   "TARGET_80387 && !TARGET_SSE2"
4389   "")
4391 (define_expand "fix_truncsfhi2"
4392   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4393                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4394                (clobber (reg:CC FLAGS_REG))])]
4395   "TARGET_80387 && !TARGET_SSE"
4396   "")
4398 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4399 ;; of the machinery.
4400 (define_insn_and_split "*fix_trunchi_1"
4401   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4402         (fix:HI (match_operand 1 "register_operand" "f,f")))
4403    (clobber (reg:CC FLAGS_REG))]
4404   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4405    && !reload_completed && !reload_in_progress
4406    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4407   "#"
4408   "&& 1"
4409   [(const_int 0)]
4411   ix86_optimize_mode_switching = 1;
4412   operands[2] = assign_386_stack_local (HImode, 1);
4413   operands[3] = assign_386_stack_local (HImode, 2);
4414   if (memory_operand (operands[0], VOIDmode))
4415     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4416                                        operands[2], operands[3]));
4417   else
4418     {
4419       operands[4] = assign_386_stack_local (HImode, 0);
4420       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4421                                            operands[2], operands[3],
4422                                            operands[4]));
4423     }
4424   DONE;
4426   [(set_attr "type" "fistp")
4427    (set_attr "i387_cw" "trunc")
4428    (set_attr "mode" "HI")])
4430 (define_insn "fix_trunchi_nomemory"
4431   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4432         (fix:HI (match_operand 1 "register_operand" "f,f")))
4433    (use (match_operand:HI 2 "memory_operand" "m,m"))
4434    (use (match_operand:HI 3 "memory_operand" "m,m"))
4435    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4436   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4437    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4438   "#"
4439   [(set_attr "type" "fistp")
4440    (set_attr "i387_cw" "trunc")
4441    (set_attr "mode" "HI")])
4443 (define_insn "fix_trunchi_memory"
4444   [(set (match_operand:HI 0 "memory_operand" "=m")
4445         (fix:HI (match_operand 1 "register_operand" "f")))
4446    (use (match_operand:HI 2 "memory_operand" "m"))
4447    (use (match_operand:HI 3 "memory_operand" "m"))]
4448   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4449    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4450   "* return output_fix_trunc (insn, operands);"
4451   [(set_attr "type" "fistp")
4452    (set_attr "i387_cw" "trunc")
4453    (set_attr "mode" "HI")])
4455 (define_split 
4456   [(set (match_operand:HI 0 "memory_operand" "")
4457         (fix:HI (match_operand 1 "register_operand" "")))
4458    (use (match_operand:HI 2 "memory_operand" ""))
4459    (use (match_operand:HI 3 "memory_operand" ""))
4460    (clobber (match_operand:HI 4 "memory_operand" ""))]
4461   "reload_completed"
4462   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4463               (use (match_dup 2))
4464               (use (match_dup 3))])]
4465   "")
4467 (define_split 
4468   [(set (match_operand:HI 0 "register_operand" "")
4469         (fix:HI (match_operand 1 "register_operand" "")))
4470    (use (match_operand:HI 2 "memory_operand" ""))
4471    (use (match_operand:HI 3 "memory_operand" ""))
4472    (clobber (match_operand:HI 4 "memory_operand" ""))]
4473   "reload_completed"
4474   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4475               (use (match_dup 2))
4476               (use (match_dup 3))
4477               (clobber (match_dup 4))])
4478    (set (match_dup 0) (match_dup 4))]
4479   "")
4481 (define_insn "x86_fnstcw_1"
4482   [(set (match_operand:HI 0 "memory_operand" "=m")
4483         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4484   "TARGET_80387"
4485   "fnstcw\t%0"
4486   [(set_attr "length" "2")
4487    (set_attr "mode" "HI")
4488    (set_attr "unit" "i387")])
4490 (define_insn "x86_fldcw_1"
4491   [(set (reg:HI FPSR_REG)
4492         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4493   "TARGET_80387"
4494   "fldcw\t%0"
4495   [(set_attr "length" "2")
4496    (set_attr "mode" "HI")
4497    (set_attr "unit" "i387")
4498    (set_attr "athlon_decode" "vector")])
4500 ;; Conversion between fixed point and floating point.
4502 ;; Even though we only accept memory inputs, the backend _really_
4503 ;; wants to be able to do this between registers.
4505 (define_expand "floathisf2"
4506   [(set (match_operand:SF 0 "register_operand" "")
4507         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4508   "TARGET_SSE || TARGET_80387"
4510   if (TARGET_SSE && TARGET_SSE_MATH)
4511     {
4512       emit_insn (gen_floatsisf2 (operands[0],
4513                                  convert_to_mode (SImode, operands[1], 0)));
4514       DONE;
4515     }
4518 (define_insn "*floathisf2_1"
4519   [(set (match_operand:SF 0 "register_operand" "=f,f")
4520         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4521   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4522   "@
4523    fild%z1\t%1
4524    #"
4525   [(set_attr "type" "fmov,multi")
4526    (set_attr "mode" "SF")
4527    (set_attr "fp_int_src" "true")])
4529 (define_expand "floatsisf2"
4530   [(set (match_operand:SF 0 "register_operand" "")
4531         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4532   "TARGET_SSE || TARGET_80387"
4533   "")
4535 (define_insn "*floatsisf2_i387"
4536   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4537         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4538   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4539   "@
4540    fild%z1\t%1
4541    #
4542    cvtsi2ss\t{%1, %0|%0, %1}
4543    cvtsi2ss\t{%1, %0|%0, %1}"
4544   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4545    (set_attr "mode" "SF")
4546    (set_attr "athlon_decode" "*,*,vector,double")
4547    (set_attr "fp_int_src" "true")])
4549 (define_insn "*floatsisf2_sse"
4550   [(set (match_operand:SF 0 "register_operand" "=x,x")
4551         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4552   "TARGET_SSE"
4553   "cvtsi2ss\t{%1, %0|%0, %1}"
4554   [(set_attr "type" "sseicvt")
4555    (set_attr "mode" "SF")
4556    (set_attr "athlon_decode" "vector,double")
4557    (set_attr "fp_int_src" "true")])
4559 ; Avoid possible reformatting penalty on the destination by first
4560 ; zeroing it out
4561 (define_split
4562   [(set (match_operand:SF 0 "register_operand" "")
4563         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4564   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4565    && SSE_REG_P (operands[0])"
4566   [(const_int 0)]
4568   rtx dest;
4569   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4570   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4571   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4572   DONE;
4575 (define_expand "floatdisf2"
4576   [(set (match_operand:SF 0 "register_operand" "")
4577         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4578   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4579   "")
4581 (define_insn "*floatdisf2_i387_only"
4582   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4583         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4584   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4585   "@
4586    fild%z1\t%1
4587    #"
4588   [(set_attr "type" "fmov,multi")
4589    (set_attr "mode" "SF")
4590    (set_attr "fp_int_src" "true")])
4592 (define_insn "*floatdisf2_i387"
4593   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4594         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4595   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4596   "@
4597    fild%z1\t%1
4598    #
4599    cvtsi2ss{q}\t{%1, %0|%0, %1}
4600    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4601   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4602    (set_attr "mode" "SF")
4603    (set_attr "athlon_decode" "*,*,vector,double")
4604    (set_attr "fp_int_src" "true")])
4606 (define_insn "*floatdisf2_sse"
4607   [(set (match_operand:SF 0 "register_operand" "=x,x")
4608         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4609   "TARGET_64BIT && TARGET_SSE"
4610   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4611   [(set_attr "type" "sseicvt")
4612    (set_attr "mode" "SF")
4613    (set_attr "athlon_decode" "vector,double")
4614    (set_attr "fp_int_src" "true")])
4616 ; Avoid possible reformatting penalty on the destination by first
4617 ; zeroing it out
4618 (define_split
4619   [(set (match_operand:SF 0 "register_operand" "")
4620         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4621   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4622    && SSE_REG_P (operands[0])"
4623   [(const_int 0)]
4625   rtx dest;
4626   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4627   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4628   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4629   DONE;
4632 (define_expand "floathidf2"
4633   [(set (match_operand:DF 0 "register_operand" "")
4634         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4635   "TARGET_SSE2 || TARGET_80387"
4637   if (TARGET_SSE && TARGET_SSE_MATH)
4638     {
4639       emit_insn (gen_floatsidf2 (operands[0],
4640                                  convert_to_mode (SImode, operands[1], 0)));
4641       DONE;
4642     }
4645 (define_insn "*floathidf2_1"
4646   [(set (match_operand:DF 0 "register_operand" "=f,f")
4647         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4648   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4649   "@
4650    fild%z1\t%1
4651    #"
4652   [(set_attr "type" "fmov,multi")
4653    (set_attr "mode" "DF")
4654    (set_attr "fp_int_src" "true")])
4656 (define_expand "floatsidf2"
4657   [(set (match_operand:DF 0 "register_operand" "")
4658         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4659   "TARGET_80387 || TARGET_SSE2"
4660   "")
4662 (define_insn "*floatsidf2_i387"
4663   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4664         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4665   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4666   "@
4667    fild%z1\t%1
4668    #
4669    cvtsi2sd\t{%1, %0|%0, %1}
4670    cvtsi2sd\t{%1, %0|%0, %1}"
4671   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4672    (set_attr "mode" "DF")
4673    (set_attr "athlon_decode" "*,*,double,direct")
4674    (set_attr "fp_int_src" "true")])
4676 (define_insn "*floatsidf2_sse"
4677   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4678         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4679   "TARGET_SSE2"
4680   "cvtsi2sd\t{%1, %0|%0, %1}"
4681   [(set_attr "type" "sseicvt")
4682    (set_attr "mode" "DF")
4683    (set_attr "athlon_decode" "double,direct")
4684    (set_attr "fp_int_src" "true")])
4686 (define_expand "floatdidf2"
4687   [(set (match_operand:DF 0 "register_operand" "")
4688         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4689   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4690   "")
4692 (define_insn "*floatdidf2_i387_only"
4693   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4694         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4695   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4696   "@
4697    fild%z1\t%1
4698    #"
4699   [(set_attr "type" "fmov,multi")
4700    (set_attr "mode" "DF")
4701    (set_attr "fp_int_src" "true")])
4703 (define_insn "*floatdidf2_i387"
4704   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4705         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4706   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4707   "@
4708    fild%z1\t%1
4709    #
4710    cvtsi2sd{q}\t{%1, %0|%0, %1}
4711    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4712   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4713    (set_attr "mode" "DF")
4714    (set_attr "athlon_decode" "*,*,double,direct")
4715    (set_attr "fp_int_src" "true")])
4717 (define_insn "*floatdidf2_sse"
4718   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4719         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4720   "TARGET_SSE2"
4721   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4722   [(set_attr "type" "sseicvt")
4723    (set_attr "mode" "DF")
4724    (set_attr "athlon_decode" "double,direct")
4725    (set_attr "fp_int_src" "true")])
4727 (define_insn "floathixf2"
4728   [(set (match_operand:XF 0 "register_operand" "=f,f")
4729         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4730   "TARGET_80387"
4731   "@
4732    fild%z1\t%1
4733    #"
4734   [(set_attr "type" "fmov,multi")
4735    (set_attr "mode" "XF")
4736    (set_attr "fp_int_src" "true")])
4738 (define_insn "floatsixf2"
4739   [(set (match_operand:XF 0 "register_operand" "=f,f")
4740         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4741   "TARGET_80387"
4742   "@
4743    fild%z1\t%1
4744    #"
4745   [(set_attr "type" "fmov,multi")
4746    (set_attr "mode" "XF")
4747    (set_attr "fp_int_src" "true")])
4749 (define_insn "floatdixf2"
4750   [(set (match_operand:XF 0 "register_operand" "=f,f")
4751         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4752   "TARGET_80387"
4753   "@
4754    fild%z1\t%1
4755    #"
4756   [(set_attr "type" "fmov,multi")
4757    (set_attr "mode" "XF")
4758    (set_attr "fp_int_src" "true")])
4760 ;; %%% Kill these when reload knows how to do it.
4761 (define_split
4762   [(set (match_operand 0 "fp_register_operand" "")
4763         (float (match_operand 1 "register_operand" "")))]
4764   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4765   [(const_int 0)]
4767   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4768   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4769   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4770   ix86_free_from_memory (GET_MODE (operands[1]));
4771   DONE;
4774 (define_expand "floatunssisf2"
4775   [(use (match_operand:SF 0 "register_operand" ""))
4776    (use (match_operand:SI 1 "register_operand" ""))]
4777   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4778   "x86_emit_floatuns (operands); DONE;")
4780 (define_expand "floatunsdisf2"
4781   [(use (match_operand:SF 0 "register_operand" ""))
4782    (use (match_operand:DI 1 "register_operand" ""))]
4783   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4784   "x86_emit_floatuns (operands); DONE;")
4786 (define_expand "floatunsdidf2"
4787   [(use (match_operand:DF 0 "register_operand" ""))
4788    (use (match_operand:DI 1 "register_operand" ""))]
4789   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4790   "x86_emit_floatuns (operands); DONE;")
4792 ;; SSE extract/set expanders
4794 (define_expand "vec_setv2df"
4795   [(match_operand:V2DF 0 "register_operand" "")
4796    (match_operand:DF 1 "register_operand" "")
4797    (match_operand 2 "const_int_operand" "")]
4798   "TARGET_SSE2"
4800   switch (INTVAL (operands[2]))
4801     {
4802     case 0:
4803       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4804                                  simplify_gen_subreg (V2DFmode, operands[1],
4805                                                       DFmode, 0)));
4806       break;
4807     case 1:
4808       {
4809         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4811         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4812       }
4813       break;
4814     default:
4815       abort ();
4816     }
4817   DONE;
4820 (define_expand "vec_extractv2df"
4821   [(match_operand:DF 0 "register_operand" "")
4822    (match_operand:V2DF 1 "register_operand" "")
4823    (match_operand 2 "const_int_operand" "")]
4824   "TARGET_SSE2"
4826   switch (INTVAL (operands[2]))
4827     {
4828     case 0:
4829       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4830       break;
4831     case 1:
4832       {
4833         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4835         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4836       }
4837       break;
4838     default:
4839       abort ();
4840     }
4841   DONE;
4844 (define_expand "vec_initv2df"
4845   [(match_operand:V2DF 0 "register_operand" "")
4846    (match_operand 1 "" "")]
4847   "TARGET_SSE2"
4849   ix86_expand_vector_init (operands[0], operands[1]);
4850   DONE;
4853 (define_expand "vec_setv4sf"
4854   [(match_operand:V4SF 0 "register_operand" "")
4855    (match_operand:SF 1 "register_operand" "")
4856    (match_operand 2 "const_int_operand" "")]
4857   "TARGET_SSE"
4859   switch (INTVAL (operands[2]))
4860     {
4861     case 0:
4862       emit_insn (gen_sse_movss (operands[0], operands[0],
4863                                 simplify_gen_subreg (V4SFmode, operands[1],
4864                                                      SFmode, 0)));
4865       break;
4866     case 1:
4867       {
4868         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4869         rtx tmp = gen_reg_rtx (V4SFmode);
4871         emit_move_insn (tmp, operands[0]);
4872         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4873         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4874         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4875                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4876       }
4877       break;
4878     case 2:
4879       {
4880         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4881         rtx tmp = gen_reg_rtx (V4SFmode);
4883         emit_move_insn (tmp, operands[0]);
4884         emit_insn (gen_sse_movss (tmp, tmp, op1));
4885         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4886                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4887       }
4888       break;
4889     case 3:
4890       {
4891         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4892         rtx tmp = gen_reg_rtx (V4SFmode);
4894         emit_move_insn (tmp, operands[0]);
4895         emit_insn (gen_sse_movss (tmp, tmp, op1));
4896         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4897                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4898       }
4899       break;
4900     default:
4901       abort ();
4902     }
4903   DONE;
4906 (define_expand "vec_extractv4sf"
4907   [(match_operand:SF 0 "register_operand" "")
4908    (match_operand:V4SF 1 "register_operand" "")
4909    (match_operand 2 "const_int_operand" "")]
4910   "TARGET_SSE"
4912   switch (INTVAL (operands[2]))
4913     {
4914     case 0:
4915       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4916       break;
4917     case 1:
4918       {
4919         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4920         rtx tmp = gen_reg_rtx (V4SFmode);
4922         emit_move_insn (tmp, operands[1]);
4923         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4924                                    const1_rtx));
4925       }
4926       break;
4927     case 2:
4928       {
4929         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4930         rtx tmp = gen_reg_rtx (V4SFmode);
4932         emit_move_insn (tmp, operands[1]);
4933         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4934       }
4935       break;
4936     case 3:
4937       {
4938         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4939         rtx tmp = gen_reg_rtx (V4SFmode);
4941         emit_move_insn (tmp, operands[1]);
4942         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4943                                    GEN_INT (3)));
4944       }
4945       break;
4946     default:
4947       abort ();
4948     }
4949   DONE;
4952 (define_expand "vec_initv4sf"
4953   [(match_operand:V4SF 0 "register_operand" "")
4954    (match_operand 1 "" "")]
4955   "TARGET_SSE"
4957   ix86_expand_vector_init (operands[0], operands[1]);
4958   DONE;
4961 ;; Add instructions
4963 ;; %%% splits for addsidi3
4964 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4965 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4966 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4968 (define_expand "adddi3"
4969   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4970         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4971                  (match_operand:DI 2 "x86_64_general_operand" "")))
4972    (clobber (reg:CC FLAGS_REG))]
4973   ""
4974   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4976 (define_insn "*adddi3_1"
4977   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4978         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4979                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4980    (clobber (reg:CC FLAGS_REG))]
4981   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4982   "#")
4984 (define_split
4985   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4986         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4987                  (match_operand:DI 2 "general_operand" "")))
4988    (clobber (reg:CC FLAGS_REG))]
4989   "!TARGET_64BIT && reload_completed"
4990   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4991                                           UNSPEC_ADD_CARRY))
4992               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4993    (parallel [(set (match_dup 3)
4994                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4995                                      (match_dup 4))
4996                             (match_dup 5)))
4997               (clobber (reg:CC FLAGS_REG))])]
4998   "split_di (operands+0, 1, operands+0, operands+3);
4999    split_di (operands+1, 1, operands+1, operands+4);
5000    split_di (operands+2, 1, operands+2, operands+5);")
5002 (define_insn "adddi3_carry_rex64"
5003   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5004           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5005                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5006                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5007    (clobber (reg:CC FLAGS_REG))]
5008   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5009   "adc{q}\t{%2, %0|%0, %2}"
5010   [(set_attr "type" "alu")
5011    (set_attr "pent_pair" "pu")
5012    (set_attr "mode" "DI")])
5014 (define_insn "*adddi3_cc_rex64"
5015   [(set (reg:CC FLAGS_REG)
5016         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5017                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5018                    UNSPEC_ADD_CARRY))
5019    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5020         (plus:DI (match_dup 1) (match_dup 2)))]
5021   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5022   "add{q}\t{%2, %0|%0, %2}"
5023   [(set_attr "type" "alu")
5024    (set_attr "mode" "DI")])
5026 (define_insn "addqi3_carry"
5027   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5028           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5029                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5030                    (match_operand:QI 2 "general_operand" "qi,qm")))
5031    (clobber (reg:CC FLAGS_REG))]
5032   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5033   "adc{b}\t{%2, %0|%0, %2}"
5034   [(set_attr "type" "alu")
5035    (set_attr "pent_pair" "pu")
5036    (set_attr "mode" "QI")])
5038 (define_insn "addhi3_carry"
5039   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5040           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5041                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5042                    (match_operand:HI 2 "general_operand" "ri,rm")))
5043    (clobber (reg:CC FLAGS_REG))]
5044   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5045   "adc{w}\t{%2, %0|%0, %2}"
5046   [(set_attr "type" "alu")
5047    (set_attr "pent_pair" "pu")
5048    (set_attr "mode" "HI")])
5050 (define_insn "addsi3_carry"
5051   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5052           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5053                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5054                    (match_operand:SI 2 "general_operand" "ri,rm")))
5055    (clobber (reg:CC FLAGS_REG))]
5056   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5057   "adc{l}\t{%2, %0|%0, %2}"
5058   [(set_attr "type" "alu")
5059    (set_attr "pent_pair" "pu")
5060    (set_attr "mode" "SI")])
5062 (define_insn "*addsi3_carry_zext"
5063   [(set (match_operand:DI 0 "register_operand" "=r")
5064           (zero_extend:DI 
5065             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5066                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5067                      (match_operand:SI 2 "general_operand" "rim"))))
5068    (clobber (reg:CC FLAGS_REG))]
5069   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5070   "adc{l}\t{%2, %k0|%k0, %2}"
5071   [(set_attr "type" "alu")
5072    (set_attr "pent_pair" "pu")
5073    (set_attr "mode" "SI")])
5075 (define_insn "*addsi3_cc"
5076   [(set (reg:CC FLAGS_REG)
5077         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5078                     (match_operand:SI 2 "general_operand" "ri,rm")]
5079                    UNSPEC_ADD_CARRY))
5080    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5081         (plus:SI (match_dup 1) (match_dup 2)))]
5082   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5083   "add{l}\t{%2, %0|%0, %2}"
5084   [(set_attr "type" "alu")
5085    (set_attr "mode" "SI")])
5087 (define_insn "addqi3_cc"
5088   [(set (reg:CC FLAGS_REG)
5089         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5090                     (match_operand:QI 2 "general_operand" "qi,qm")]
5091                    UNSPEC_ADD_CARRY))
5092    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5093         (plus:QI (match_dup 1) (match_dup 2)))]
5094   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5095   "add{b}\t{%2, %0|%0, %2}"
5096   [(set_attr "type" "alu")
5097    (set_attr "mode" "QI")])
5099 (define_expand "addsi3"
5100   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5101                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5102                             (match_operand:SI 2 "general_operand" "")))
5103               (clobber (reg:CC FLAGS_REG))])]
5104   ""
5105   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5107 (define_insn "*lea_1"
5108   [(set (match_operand:SI 0 "register_operand" "=r")
5109         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5110   "!TARGET_64BIT"
5111   "lea{l}\t{%a1, %0|%0, %a1}"
5112   [(set_attr "type" "lea")
5113    (set_attr "mode" "SI")])
5115 (define_insn "*lea_1_rex64"
5116   [(set (match_operand:SI 0 "register_operand" "=r")
5117         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5118   "TARGET_64BIT"
5119   "lea{l}\t{%a1, %0|%0, %a1}"
5120   [(set_attr "type" "lea")
5121    (set_attr "mode" "SI")])
5123 (define_insn "*lea_1_zext"
5124   [(set (match_operand:DI 0 "register_operand" "=r")
5125         (zero_extend:DI
5126          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5127   "TARGET_64BIT"
5128   "lea{l}\t{%a1, %k0|%k0, %a1}"
5129   [(set_attr "type" "lea")
5130    (set_attr "mode" "SI")])
5132 (define_insn "*lea_2_rex64"
5133   [(set (match_operand:DI 0 "register_operand" "=r")
5134         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5135   "TARGET_64BIT"
5136   "lea{q}\t{%a1, %0|%0, %a1}"
5137   [(set_attr "type" "lea")
5138    (set_attr "mode" "DI")])
5140 ;; The lea patterns for non-Pmodes needs to be matched by several
5141 ;; insns converted to real lea by splitters.
5143 (define_insn_and_split "*lea_general_1"
5144   [(set (match_operand 0 "register_operand" "=r")
5145         (plus (plus (match_operand 1 "index_register_operand" "r")
5146                     (match_operand 2 "register_operand" "r"))
5147               (match_operand 3 "immediate_operand" "i")))]
5148   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5149     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5150    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5151    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5152    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5153    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5154        || GET_MODE (operands[3]) == VOIDmode)"
5155   "#"
5156   "&& reload_completed"
5157   [(const_int 0)]
5159   rtx pat;
5160   operands[0] = gen_lowpart (SImode, operands[0]);
5161   operands[1] = gen_lowpart (Pmode, operands[1]);
5162   operands[2] = gen_lowpart (Pmode, operands[2]);
5163   operands[3] = gen_lowpart (Pmode, operands[3]);
5164   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5165                       operands[3]);
5166   if (Pmode != SImode)
5167     pat = gen_rtx_SUBREG (SImode, pat, 0);
5168   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5169   DONE;
5171   [(set_attr "type" "lea")
5172    (set_attr "mode" "SI")])
5174 (define_insn_and_split "*lea_general_1_zext"
5175   [(set (match_operand:DI 0 "register_operand" "=r")
5176         (zero_extend:DI
5177           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5178                             (match_operand:SI 2 "register_operand" "r"))
5179                    (match_operand:SI 3 "immediate_operand" "i"))))]
5180   "TARGET_64BIT"
5181   "#"
5182   "&& reload_completed"
5183   [(set (match_dup 0)
5184         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5185                                                      (match_dup 2))
5186                                             (match_dup 3)) 0)))]
5188   operands[1] = gen_lowpart (Pmode, operands[1]);
5189   operands[2] = gen_lowpart (Pmode, operands[2]);
5190   operands[3] = gen_lowpart (Pmode, operands[3]);
5192   [(set_attr "type" "lea")
5193    (set_attr "mode" "SI")])
5195 (define_insn_and_split "*lea_general_2"
5196   [(set (match_operand 0 "register_operand" "=r")
5197         (plus (mult (match_operand 1 "index_register_operand" "r")
5198                     (match_operand 2 "const248_operand" "i"))
5199               (match_operand 3 "nonmemory_operand" "ri")))]
5200   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5201     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5202    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5203    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5204    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5205        || GET_MODE (operands[3]) == VOIDmode)"
5206   "#"
5207   "&& reload_completed"
5208   [(const_int 0)]
5210   rtx pat;
5211   operands[0] = gen_lowpart (SImode, operands[0]);
5212   operands[1] = gen_lowpart (Pmode, operands[1]);
5213   operands[3] = gen_lowpart (Pmode, operands[3]);
5214   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5215                       operands[3]);
5216   if (Pmode != SImode)
5217     pat = gen_rtx_SUBREG (SImode, pat, 0);
5218   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5219   DONE;
5221   [(set_attr "type" "lea")
5222    (set_attr "mode" "SI")])
5224 (define_insn_and_split "*lea_general_2_zext"
5225   [(set (match_operand:DI 0 "register_operand" "=r")
5226         (zero_extend:DI
5227           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5228                             (match_operand:SI 2 "const248_operand" "n"))
5229                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5230   "TARGET_64BIT"
5231   "#"
5232   "&& reload_completed"
5233   [(set (match_dup 0)
5234         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5235                                                      (match_dup 2))
5236                                             (match_dup 3)) 0)))]
5238   operands[1] = gen_lowpart (Pmode, operands[1]);
5239   operands[3] = gen_lowpart (Pmode, operands[3]);
5241   [(set_attr "type" "lea")
5242    (set_attr "mode" "SI")])
5244 (define_insn_and_split "*lea_general_3"
5245   [(set (match_operand 0 "register_operand" "=r")
5246         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5247                           (match_operand 2 "const248_operand" "i"))
5248                     (match_operand 3 "register_operand" "r"))
5249               (match_operand 4 "immediate_operand" "i")))]
5250   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5251     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5252    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5253    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5254    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5255   "#"
5256   "&& reload_completed"
5257   [(const_int 0)]
5259   rtx pat;
5260   operands[0] = gen_lowpart (SImode, operands[0]);
5261   operands[1] = gen_lowpart (Pmode, operands[1]);
5262   operands[3] = gen_lowpart (Pmode, operands[3]);
5263   operands[4] = gen_lowpart (Pmode, operands[4]);
5264   pat = gen_rtx_PLUS (Pmode,
5265                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5266                                                          operands[2]),
5267                                     operands[3]),
5268                       operands[4]);
5269   if (Pmode != SImode)
5270     pat = gen_rtx_SUBREG (SImode, pat, 0);
5271   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5272   DONE;
5274   [(set_attr "type" "lea")
5275    (set_attr "mode" "SI")])
5277 (define_insn_and_split "*lea_general_3_zext"
5278   [(set (match_operand:DI 0 "register_operand" "=r")
5279         (zero_extend:DI
5280           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5281                                      (match_operand:SI 2 "const248_operand" "n"))
5282                             (match_operand:SI 3 "register_operand" "r"))
5283                    (match_operand:SI 4 "immediate_operand" "i"))))]
5284   "TARGET_64BIT"
5285   "#"
5286   "&& reload_completed"
5287   [(set (match_dup 0)
5288         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5289                                                               (match_dup 2))
5290                                                      (match_dup 3))
5291                                             (match_dup 4)) 0)))]
5293   operands[1] = gen_lowpart (Pmode, operands[1]);
5294   operands[3] = gen_lowpart (Pmode, operands[3]);
5295   operands[4] = gen_lowpart (Pmode, operands[4]);
5297   [(set_attr "type" "lea")
5298    (set_attr "mode" "SI")])
5300 (define_insn "*adddi_1_rex64"
5301   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5302         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5303                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5304    (clobber (reg:CC FLAGS_REG))]
5305   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5307   switch (get_attr_type (insn))
5308     {
5309     case TYPE_LEA:
5310       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5311       return "lea{q}\t{%a2, %0|%0, %a2}";
5313     case TYPE_INCDEC:
5314       if (! rtx_equal_p (operands[0], operands[1]))
5315         abort ();
5316       if (operands[2] == const1_rtx)
5317         return "inc{q}\t%0";
5318       else if (operands[2] == constm1_rtx)
5319         return "dec{q}\t%0";
5320       else
5321         abort ();
5323     default:
5324       if (! rtx_equal_p (operands[0], operands[1]))
5325         abort ();
5327       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5328          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5329       if (GET_CODE (operands[2]) == CONST_INT
5330           /* Avoid overflows.  */
5331           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5332           && (INTVAL (operands[2]) == 128
5333               || (INTVAL (operands[2]) < 0
5334                   && INTVAL (operands[2]) != -128)))
5335         {
5336           operands[2] = GEN_INT (-INTVAL (operands[2]));
5337           return "sub{q}\t{%2, %0|%0, %2}";
5338         }
5339       return "add{q}\t{%2, %0|%0, %2}";
5340     }
5342   [(set (attr "type")
5343      (cond [(eq_attr "alternative" "2")
5344               (const_string "lea")
5345             ; Current assemblers are broken and do not allow @GOTOFF in
5346             ; ought but a memory context.
5347             (match_operand:DI 2 "pic_symbolic_operand" "")
5348               (const_string "lea")
5349             (match_operand:DI 2 "incdec_operand" "")
5350               (const_string "incdec")
5351            ]
5352            (const_string "alu")))
5353    (set_attr "mode" "DI")])
5355 ;; Convert lea to the lea pattern to avoid flags dependency.
5356 (define_split
5357   [(set (match_operand:DI 0 "register_operand" "")
5358         (plus:DI (match_operand:DI 1 "register_operand" "")
5359                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5360    (clobber (reg:CC FLAGS_REG))]
5361   "TARGET_64BIT && reload_completed
5362    && true_regnum (operands[0]) != true_regnum (operands[1])"
5363   [(set (match_dup 0)
5364         (plus:DI (match_dup 1)
5365                  (match_dup 2)))]
5366   "")
5368 (define_insn "*adddi_2_rex64"
5369   [(set (reg 17)
5370         (compare
5371           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5372                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5373           (const_int 0)))                       
5374    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5375         (plus:DI (match_dup 1) (match_dup 2)))]
5376   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5377    && ix86_binary_operator_ok (PLUS, DImode, operands)
5378    /* Current assemblers are broken and do not allow @GOTOFF in
5379       ought but a memory context.  */
5380    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5382   switch (get_attr_type (insn))
5383     {
5384     case TYPE_INCDEC:
5385       if (! rtx_equal_p (operands[0], operands[1]))
5386         abort ();
5387       if (operands[2] == const1_rtx)
5388         return "inc{q}\t%0";
5389       else if (operands[2] == constm1_rtx)
5390         return "dec{q}\t%0";
5391       else
5392         abort ();
5394     default:
5395       if (! rtx_equal_p (operands[0], operands[1]))
5396         abort ();
5397       /* ???? We ought to handle there the 32bit case too
5398          - do we need new constraint?  */
5399       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5400          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5401       if (GET_CODE (operands[2]) == CONST_INT
5402           /* Avoid overflows.  */
5403           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5404           && (INTVAL (operands[2]) == 128
5405               || (INTVAL (operands[2]) < 0
5406                   && INTVAL (operands[2]) != -128)))
5407         {
5408           operands[2] = GEN_INT (-INTVAL (operands[2]));
5409           return "sub{q}\t{%2, %0|%0, %2}";
5410         }
5411       return "add{q}\t{%2, %0|%0, %2}";
5412     }
5414   [(set (attr "type")
5415      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5416         (const_string "incdec")
5417         (const_string "alu")))
5418    (set_attr "mode" "DI")])
5420 (define_insn "*adddi_3_rex64"
5421   [(set (reg 17)
5422         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5423                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5424    (clobber (match_scratch:DI 0 "=r"))]
5425   "TARGET_64BIT
5426    && ix86_match_ccmode (insn, CCZmode)
5427    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5428    /* Current assemblers are broken and do not allow @GOTOFF in
5429       ought but a memory context.  */
5430    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5432   switch (get_attr_type (insn))
5433     {
5434     case TYPE_INCDEC:
5435       if (! rtx_equal_p (operands[0], operands[1]))
5436         abort ();
5437       if (operands[2] == const1_rtx)
5438         return "inc{q}\t%0";
5439       else if (operands[2] == constm1_rtx)
5440         return "dec{q}\t%0";
5441       else
5442         abort ();
5444     default:
5445       if (! rtx_equal_p (operands[0], operands[1]))
5446         abort ();
5447       /* ???? We ought to handle there the 32bit case too
5448          - do we need new constraint?  */
5449       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5450          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5451       if (GET_CODE (operands[2]) == CONST_INT
5452           /* Avoid overflows.  */
5453           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5454           && (INTVAL (operands[2]) == 128
5455               || (INTVAL (operands[2]) < 0
5456                   && INTVAL (operands[2]) != -128)))
5457         {
5458           operands[2] = GEN_INT (-INTVAL (operands[2]));
5459           return "sub{q}\t{%2, %0|%0, %2}";
5460         }
5461       return "add{q}\t{%2, %0|%0, %2}";
5462     }
5464   [(set (attr "type")
5465      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5466         (const_string "incdec")
5467         (const_string "alu")))
5468    (set_attr "mode" "DI")])
5470 ; For comparisons against 1, -1 and 128, we may generate better code
5471 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5472 ; is matched then.  We can't accept general immediate, because for
5473 ; case of overflows,  the result is messed up.
5474 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5475 ; when negated.
5476 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5477 ; only for comparisons not depending on it.
5478 (define_insn "*adddi_4_rex64"
5479   [(set (reg 17)
5480         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5481                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5482    (clobber (match_scratch:DI 0 "=rm"))]
5483   "TARGET_64BIT
5484    &&  ix86_match_ccmode (insn, CCGCmode)"
5486   switch (get_attr_type (insn))
5487     {
5488     case TYPE_INCDEC:
5489       if (operands[2] == constm1_rtx)
5490         return "inc{q}\t%0";
5491       else if (operands[2] == const1_rtx)
5492         return "dec{q}\t%0";
5493       else
5494         abort();
5496     default:
5497       if (! rtx_equal_p (operands[0], operands[1]))
5498         abort ();
5499       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5500          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5501       if ((INTVAL (operands[2]) == -128
5502            || (INTVAL (operands[2]) > 0
5503                && INTVAL (operands[2]) != 128))
5504           /* Avoid overflows.  */
5505           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5506         return "sub{q}\t{%2, %0|%0, %2}";
5507       operands[2] = GEN_INT (-INTVAL (operands[2]));
5508       return "add{q}\t{%2, %0|%0, %2}";
5509     }
5511   [(set (attr "type")
5512      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5513         (const_string "incdec")
5514         (const_string "alu")))
5515    (set_attr "mode" "DI")])
5517 (define_insn "*adddi_5_rex64"
5518   [(set (reg 17)
5519         (compare
5520           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5521                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5522           (const_int 0)))                       
5523    (clobber (match_scratch:DI 0 "=r"))]
5524   "TARGET_64BIT
5525    && ix86_match_ccmode (insn, CCGOCmode)
5526    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5527    /* Current assemblers are broken and do not allow @GOTOFF in
5528       ought but a memory context.  */
5529    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5531   switch (get_attr_type (insn))
5532     {
5533     case TYPE_INCDEC:
5534       if (! rtx_equal_p (operands[0], operands[1]))
5535         abort ();
5536       if (operands[2] == const1_rtx)
5537         return "inc{q}\t%0";
5538       else if (operands[2] == constm1_rtx)
5539         return "dec{q}\t%0";
5540       else
5541         abort();
5543     default:
5544       if (! rtx_equal_p (operands[0], operands[1]))
5545         abort ();
5546       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5547          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5548       if (GET_CODE (operands[2]) == CONST_INT
5549           /* Avoid overflows.  */
5550           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5551           && (INTVAL (operands[2]) == 128
5552               || (INTVAL (operands[2]) < 0
5553                   && INTVAL (operands[2]) != -128)))
5554         {
5555           operands[2] = GEN_INT (-INTVAL (operands[2]));
5556           return "sub{q}\t{%2, %0|%0, %2}";
5557         }
5558       return "add{q}\t{%2, %0|%0, %2}";
5559     }
5561   [(set (attr "type")
5562      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5563         (const_string "incdec")
5564         (const_string "alu")))
5565    (set_attr "mode" "DI")])
5568 (define_insn "*addsi_1"
5569   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5570         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5571                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5572    (clobber (reg:CC FLAGS_REG))]
5573   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5575   switch (get_attr_type (insn))
5576     {
5577     case TYPE_LEA:
5578       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5579       return "lea{l}\t{%a2, %0|%0, %a2}";
5581     case TYPE_INCDEC:
5582       if (! rtx_equal_p (operands[0], operands[1]))
5583         abort ();
5584       if (operands[2] == const1_rtx)
5585         return "inc{l}\t%0";
5586       else if (operands[2] == constm1_rtx)
5587         return "dec{l}\t%0";
5588       else
5589         abort();
5591     default:
5592       if (! rtx_equal_p (operands[0], operands[1]))
5593         abort ();
5595       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5596          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5597       if (GET_CODE (operands[2]) == CONST_INT
5598           && (INTVAL (operands[2]) == 128
5599               || (INTVAL (operands[2]) < 0
5600                   && INTVAL (operands[2]) != -128)))
5601         {
5602           operands[2] = GEN_INT (-INTVAL (operands[2]));
5603           return "sub{l}\t{%2, %0|%0, %2}";
5604         }
5605       return "add{l}\t{%2, %0|%0, %2}";
5606     }
5608   [(set (attr "type")
5609      (cond [(eq_attr "alternative" "2")
5610               (const_string "lea")
5611             ; Current assemblers are broken and do not allow @GOTOFF in
5612             ; ought but a memory context.
5613             (match_operand:SI 2 "pic_symbolic_operand" "")
5614               (const_string "lea")
5615             (match_operand:SI 2 "incdec_operand" "")
5616               (const_string "incdec")
5617            ]
5618            (const_string "alu")))
5619    (set_attr "mode" "SI")])
5621 ;; Convert lea to the lea pattern to avoid flags dependency.
5622 (define_split
5623   [(set (match_operand 0 "register_operand" "")
5624         (plus (match_operand 1 "register_operand" "")
5625               (match_operand 2 "nonmemory_operand" "")))
5626    (clobber (reg:CC FLAGS_REG))]
5627   "reload_completed
5628    && true_regnum (operands[0]) != true_regnum (operands[1])"
5629   [(const_int 0)]
5631   rtx pat;
5632   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5633      may confuse gen_lowpart.  */
5634   if (GET_MODE (operands[0]) != Pmode)
5635     {
5636       operands[1] = gen_lowpart (Pmode, operands[1]);
5637       operands[2] = gen_lowpart (Pmode, operands[2]);
5638     }
5639   operands[0] = gen_lowpart (SImode, operands[0]);
5640   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5641   if (Pmode != SImode)
5642     pat = gen_rtx_SUBREG (SImode, pat, 0);
5643   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5644   DONE;
5647 ;; It may seem that nonimmediate operand is proper one for operand 1.
5648 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5649 ;; we take care in ix86_binary_operator_ok to not allow two memory
5650 ;; operands so proper swapping will be done in reload.  This allow
5651 ;; patterns constructed from addsi_1 to match.
5652 (define_insn "addsi_1_zext"
5653   [(set (match_operand:DI 0 "register_operand" "=r,r")
5654         (zero_extend:DI
5655           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5656                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5657    (clobber (reg:CC FLAGS_REG))]
5658   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5660   switch (get_attr_type (insn))
5661     {
5662     case TYPE_LEA:
5663       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5664       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5666     case TYPE_INCDEC:
5667       if (operands[2] == const1_rtx)
5668         return "inc{l}\t%k0";
5669       else if (operands[2] == constm1_rtx)
5670         return "dec{l}\t%k0";
5671       else
5672         abort();
5674     default:
5675       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5676          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5677       if (GET_CODE (operands[2]) == CONST_INT
5678           && (INTVAL (operands[2]) == 128
5679               || (INTVAL (operands[2]) < 0
5680                   && INTVAL (operands[2]) != -128)))
5681         {
5682           operands[2] = GEN_INT (-INTVAL (operands[2]));
5683           return "sub{l}\t{%2, %k0|%k0, %2}";
5684         }
5685       return "add{l}\t{%2, %k0|%k0, %2}";
5686     }
5688   [(set (attr "type")
5689      (cond [(eq_attr "alternative" "1")
5690               (const_string "lea")
5691             ; Current assemblers are broken and do not allow @GOTOFF in
5692             ; ought but a memory context.
5693             (match_operand:SI 2 "pic_symbolic_operand" "")
5694               (const_string "lea")
5695             (match_operand:SI 2 "incdec_operand" "")
5696               (const_string "incdec")
5697            ]
5698            (const_string "alu")))
5699    (set_attr "mode" "SI")])
5701 ;; Convert lea to the lea pattern to avoid flags dependency.
5702 (define_split
5703   [(set (match_operand:DI 0 "register_operand" "")
5704         (zero_extend:DI
5705           (plus:SI (match_operand:SI 1 "register_operand" "")
5706                    (match_operand:SI 2 "nonmemory_operand" ""))))
5707    (clobber (reg:CC FLAGS_REG))]
5708   "TARGET_64BIT && reload_completed
5709    && true_regnum (operands[0]) != true_regnum (operands[1])"
5710   [(set (match_dup 0)
5711         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5713   operands[1] = gen_lowpart (Pmode, operands[1]);
5714   operands[2] = gen_lowpart (Pmode, operands[2]);
5717 (define_insn "*addsi_2"
5718   [(set (reg 17)
5719         (compare
5720           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5721                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5722           (const_int 0)))                       
5723    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5724         (plus:SI (match_dup 1) (match_dup 2)))]
5725   "ix86_match_ccmode (insn, CCGOCmode)
5726    && ix86_binary_operator_ok (PLUS, SImode, operands)
5727    /* Current assemblers are broken and do not allow @GOTOFF in
5728       ought but a memory context.  */
5729    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731   switch (get_attr_type (insn))
5732     {
5733     case TYPE_INCDEC:
5734       if (! rtx_equal_p (operands[0], operands[1]))
5735         abort ();
5736       if (operands[2] == const1_rtx)
5737         return "inc{l}\t%0";
5738       else if (operands[2] == constm1_rtx)
5739         return "dec{l}\t%0";
5740       else
5741         abort();
5743     default:
5744       if (! rtx_equal_p (operands[0], operands[1]))
5745         abort ();
5746       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5747          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5748       if (GET_CODE (operands[2]) == CONST_INT
5749           && (INTVAL (operands[2]) == 128
5750               || (INTVAL (operands[2]) < 0
5751                   && INTVAL (operands[2]) != -128)))
5752         {
5753           operands[2] = GEN_INT (-INTVAL (operands[2]));
5754           return "sub{l}\t{%2, %0|%0, %2}";
5755         }
5756       return "add{l}\t{%2, %0|%0, %2}";
5757     }
5759   [(set (attr "type")
5760      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5761         (const_string "incdec")
5762         (const_string "alu")))
5763    (set_attr "mode" "SI")])
5765 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5766 (define_insn "*addsi_2_zext"
5767   [(set (reg 17)
5768         (compare
5769           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5770                    (match_operand:SI 2 "general_operand" "rmni"))
5771           (const_int 0)))                       
5772    (set (match_operand:DI 0 "register_operand" "=r")
5773         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5774   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5775    && ix86_binary_operator_ok (PLUS, SImode, operands)
5776    /* Current assemblers are broken and do not allow @GOTOFF in
5777       ought but a memory context.  */
5778    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5780   switch (get_attr_type (insn))
5781     {
5782     case TYPE_INCDEC:
5783       if (operands[2] == const1_rtx)
5784         return "inc{l}\t%k0";
5785       else if (operands[2] == constm1_rtx)
5786         return "dec{l}\t%k0";
5787       else
5788         abort();
5790     default:
5791       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5792          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5793       if (GET_CODE (operands[2]) == CONST_INT
5794           && (INTVAL (operands[2]) == 128
5795               || (INTVAL (operands[2]) < 0
5796                   && INTVAL (operands[2]) != -128)))
5797         {
5798           operands[2] = GEN_INT (-INTVAL (operands[2]));
5799           return "sub{l}\t{%2, %k0|%k0, %2}";
5800         }
5801       return "add{l}\t{%2, %k0|%k0, %2}";
5802     }
5804   [(set (attr "type")
5805      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5806         (const_string "incdec")
5807         (const_string "alu")))
5808    (set_attr "mode" "SI")])
5810 (define_insn "*addsi_3"
5811   [(set (reg 17)
5812         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5813                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5814    (clobber (match_scratch:SI 0 "=r"))]
5815   "ix86_match_ccmode (insn, CCZmode)
5816    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5817    /* Current assemblers are broken and do not allow @GOTOFF in
5818       ought but a memory context.  */
5819    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5821   switch (get_attr_type (insn))
5822     {
5823     case TYPE_INCDEC:
5824       if (! rtx_equal_p (operands[0], operands[1]))
5825         abort ();
5826       if (operands[2] == const1_rtx)
5827         return "inc{l}\t%0";
5828       else if (operands[2] == constm1_rtx)
5829         return "dec{l}\t%0";
5830       else
5831         abort();
5833     default:
5834       if (! rtx_equal_p (operands[0], operands[1]))
5835         abort ();
5836       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5837          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5838       if (GET_CODE (operands[2]) == CONST_INT
5839           && (INTVAL (operands[2]) == 128
5840               || (INTVAL (operands[2]) < 0
5841                   && INTVAL (operands[2]) != -128)))
5842         {
5843           operands[2] = GEN_INT (-INTVAL (operands[2]));
5844           return "sub{l}\t{%2, %0|%0, %2}";
5845         }
5846       return "add{l}\t{%2, %0|%0, %2}";
5847     }
5849   [(set (attr "type")
5850      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5851         (const_string "incdec")
5852         (const_string "alu")))
5853    (set_attr "mode" "SI")])
5855 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5856 (define_insn "*addsi_3_zext"
5857   [(set (reg 17)
5858         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5859                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5860    (set (match_operand:DI 0 "register_operand" "=r")
5861         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5862   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5863    && ix86_binary_operator_ok (PLUS, SImode, operands)
5864    /* Current assemblers are broken and do not allow @GOTOFF in
5865       ought but a memory context.  */
5866    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5868   switch (get_attr_type (insn))
5869     {
5870     case TYPE_INCDEC:
5871       if (operands[2] == const1_rtx)
5872         return "inc{l}\t%k0";
5873       else if (operands[2] == constm1_rtx)
5874         return "dec{l}\t%k0";
5875       else
5876         abort();
5878     default:
5879       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5880          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5881       if (GET_CODE (operands[2]) == CONST_INT
5882           && (INTVAL (operands[2]) == 128
5883               || (INTVAL (operands[2]) < 0
5884                   && INTVAL (operands[2]) != -128)))
5885         {
5886           operands[2] = GEN_INT (-INTVAL (operands[2]));
5887           return "sub{l}\t{%2, %k0|%k0, %2}";
5888         }
5889       return "add{l}\t{%2, %k0|%k0, %2}";
5890     }
5892   [(set (attr "type")
5893      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5894         (const_string "incdec")
5895         (const_string "alu")))
5896    (set_attr "mode" "SI")])
5898 ; For comparisons against 1, -1 and 128, we may generate better code
5899 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5900 ; is matched then.  We can't accept general immediate, because for
5901 ; case of overflows,  the result is messed up.
5902 ; This pattern also don't hold of 0x80000000, since the value overflows
5903 ; when negated.
5904 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5905 ; only for comparisons not depending on it.
5906 (define_insn "*addsi_4"
5907   [(set (reg 17)
5908         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5909                  (match_operand:SI 2 "const_int_operand" "n")))
5910    (clobber (match_scratch:SI 0 "=rm"))]
5911   "ix86_match_ccmode (insn, CCGCmode)
5912    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5914   switch (get_attr_type (insn))
5915     {
5916     case TYPE_INCDEC:
5917       if (operands[2] == constm1_rtx)
5918         return "inc{l}\t%0";
5919       else if (operands[2] == const1_rtx)
5920         return "dec{l}\t%0";
5921       else
5922         abort();
5924     default:
5925       if (! rtx_equal_p (operands[0], operands[1]))
5926         abort ();
5927       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5928          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5929       if ((INTVAL (operands[2]) == -128
5930            || (INTVAL (operands[2]) > 0
5931                && INTVAL (operands[2]) != 128)))
5932         return "sub{l}\t{%2, %0|%0, %2}";
5933       operands[2] = GEN_INT (-INTVAL (operands[2]));
5934       return "add{l}\t{%2, %0|%0, %2}";
5935     }
5937   [(set (attr "type")
5938      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5939         (const_string "incdec")
5940         (const_string "alu")))
5941    (set_attr "mode" "SI")])
5943 (define_insn "*addsi_5"
5944   [(set (reg 17)
5945         (compare
5946           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5947                    (match_operand:SI 2 "general_operand" "rmni"))
5948           (const_int 0)))                       
5949    (clobber (match_scratch:SI 0 "=r"))]
5950   "ix86_match_ccmode (insn, CCGOCmode)
5951    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5952    /* Current assemblers are broken and do not allow @GOTOFF in
5953       ought but a memory context.  */
5954    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5956   switch (get_attr_type (insn))
5957     {
5958     case TYPE_INCDEC:
5959       if (! rtx_equal_p (operands[0], operands[1]))
5960         abort ();
5961       if (operands[2] == const1_rtx)
5962         return "inc{l}\t%0";
5963       else if (operands[2] == constm1_rtx)
5964         return "dec{l}\t%0";
5965       else
5966         abort();
5968     default:
5969       if (! rtx_equal_p (operands[0], operands[1]))
5970         abort ();
5971       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5972          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5973       if (GET_CODE (operands[2]) == CONST_INT
5974           && (INTVAL (operands[2]) == 128
5975               || (INTVAL (operands[2]) < 0
5976                   && INTVAL (operands[2]) != -128)))
5977         {
5978           operands[2] = GEN_INT (-INTVAL (operands[2]));
5979           return "sub{l}\t{%2, %0|%0, %2}";
5980         }
5981       return "add{l}\t{%2, %0|%0, %2}";
5982     }
5984   [(set (attr "type")
5985      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5986         (const_string "incdec")
5987         (const_string "alu")))
5988    (set_attr "mode" "SI")])
5990 (define_expand "addhi3"
5991   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5992                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5993                             (match_operand:HI 2 "general_operand" "")))
5994               (clobber (reg:CC FLAGS_REG))])]
5995   "TARGET_HIMODE_MATH"
5996   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5998 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5999 ;; type optimizations enabled by define-splits.  This is not important
6000 ;; for PII, and in fact harmful because of partial register stalls.
6002 (define_insn "*addhi_1_lea"
6003   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6004         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6005                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6006    (clobber (reg:CC FLAGS_REG))]
6007   "!TARGET_PARTIAL_REG_STALL
6008    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6010   switch (get_attr_type (insn))
6011     {
6012     case TYPE_LEA:
6013       return "#";
6014     case TYPE_INCDEC:
6015       if (operands[2] == const1_rtx)
6016         return "inc{w}\t%0";
6017       else if (operands[2] == constm1_rtx)
6018         return "dec{w}\t%0";
6019       abort();
6021     default:
6022       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6023          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6024       if (GET_CODE (operands[2]) == CONST_INT
6025           && (INTVAL (operands[2]) == 128
6026               || (INTVAL (operands[2]) < 0
6027                   && INTVAL (operands[2]) != -128)))
6028         {
6029           operands[2] = GEN_INT (-INTVAL (operands[2]));
6030           return "sub{w}\t{%2, %0|%0, %2}";
6031         }
6032       return "add{w}\t{%2, %0|%0, %2}";
6033     }
6035   [(set (attr "type")
6036      (if_then_else (eq_attr "alternative" "2")
6037         (const_string "lea")
6038         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6039            (const_string "incdec")
6040            (const_string "alu"))))
6041    (set_attr "mode" "HI,HI,SI")])
6043 (define_insn "*addhi_1"
6044   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6045         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6046                  (match_operand:HI 2 "general_operand" "ri,rm")))
6047    (clobber (reg:CC FLAGS_REG))]
6048   "TARGET_PARTIAL_REG_STALL
6049    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6051   switch (get_attr_type (insn))
6052     {
6053     case TYPE_INCDEC:
6054       if (operands[2] == const1_rtx)
6055         return "inc{w}\t%0";
6056       else if (operands[2] == constm1_rtx)
6057         return "dec{w}\t%0";
6058       abort();
6060     default:
6061       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6062          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6063       if (GET_CODE (operands[2]) == CONST_INT
6064           && (INTVAL (operands[2]) == 128
6065               || (INTVAL (operands[2]) < 0
6066                   && INTVAL (operands[2]) != -128)))
6067         {
6068           operands[2] = GEN_INT (-INTVAL (operands[2]));
6069           return "sub{w}\t{%2, %0|%0, %2}";
6070         }
6071       return "add{w}\t{%2, %0|%0, %2}";
6072     }
6074   [(set (attr "type")
6075      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6076         (const_string "incdec")
6077         (const_string "alu")))
6078    (set_attr "mode" "HI")])
6080 (define_insn "*addhi_2"
6081   [(set (reg 17)
6082         (compare
6083           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6084                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6085           (const_int 0)))                       
6086    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6087         (plus:HI (match_dup 1) (match_dup 2)))]
6088   "ix86_match_ccmode (insn, CCGOCmode)
6089    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6091   switch (get_attr_type (insn))
6092     {
6093     case TYPE_INCDEC:
6094       if (operands[2] == const1_rtx)
6095         return "inc{w}\t%0";
6096       else if (operands[2] == constm1_rtx)
6097         return "dec{w}\t%0";
6098       abort();
6100     default:
6101       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6102          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6103       if (GET_CODE (operands[2]) == CONST_INT
6104           && (INTVAL (operands[2]) == 128
6105               || (INTVAL (operands[2]) < 0
6106                   && INTVAL (operands[2]) != -128)))
6107         {
6108           operands[2] = GEN_INT (-INTVAL (operands[2]));
6109           return "sub{w}\t{%2, %0|%0, %2}";
6110         }
6111       return "add{w}\t{%2, %0|%0, %2}";
6112     }
6114   [(set (attr "type")
6115      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6116         (const_string "incdec")
6117         (const_string "alu")))
6118    (set_attr "mode" "HI")])
6120 (define_insn "*addhi_3"
6121   [(set (reg 17)
6122         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6123                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6124    (clobber (match_scratch:HI 0 "=r"))]
6125   "ix86_match_ccmode (insn, CCZmode)
6126    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6128   switch (get_attr_type (insn))
6129     {
6130     case TYPE_INCDEC:
6131       if (operands[2] == const1_rtx)
6132         return "inc{w}\t%0";
6133       else if (operands[2] == constm1_rtx)
6134         return "dec{w}\t%0";
6135       abort();
6137     default:
6138       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6139          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6140       if (GET_CODE (operands[2]) == CONST_INT
6141           && (INTVAL (operands[2]) == 128
6142               || (INTVAL (operands[2]) < 0
6143                   && INTVAL (operands[2]) != -128)))
6144         {
6145           operands[2] = GEN_INT (-INTVAL (operands[2]));
6146           return "sub{w}\t{%2, %0|%0, %2}";
6147         }
6148       return "add{w}\t{%2, %0|%0, %2}";
6149     }
6151   [(set (attr "type")
6152      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6153         (const_string "incdec")
6154         (const_string "alu")))
6155    (set_attr "mode" "HI")])
6157 ; See comments above addsi_3_imm for details.
6158 (define_insn "*addhi_4"
6159   [(set (reg 17)
6160         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6161                  (match_operand:HI 2 "const_int_operand" "n")))
6162    (clobber (match_scratch:HI 0 "=rm"))]
6163   "ix86_match_ccmode (insn, CCGCmode)
6164    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6166   switch (get_attr_type (insn))
6167     {
6168     case TYPE_INCDEC:
6169       if (operands[2] == constm1_rtx)
6170         return "inc{w}\t%0";
6171       else if (operands[2] == const1_rtx)
6172         return "dec{w}\t%0";
6173       else
6174         abort();
6176     default:
6177       if (! rtx_equal_p (operands[0], operands[1]))
6178         abort ();
6179       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6180          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6181       if ((INTVAL (operands[2]) == -128
6182            || (INTVAL (operands[2]) > 0
6183                && INTVAL (operands[2]) != 128)))
6184         return "sub{w}\t{%2, %0|%0, %2}";
6185       operands[2] = GEN_INT (-INTVAL (operands[2]));
6186       return "add{w}\t{%2, %0|%0, %2}";
6187     }
6189   [(set (attr "type")
6190      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6191         (const_string "incdec")
6192         (const_string "alu")))
6193    (set_attr "mode" "SI")])
6196 (define_insn "*addhi_5"
6197   [(set (reg 17)
6198         (compare
6199           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6200                    (match_operand:HI 2 "general_operand" "rmni"))
6201           (const_int 0)))                       
6202    (clobber (match_scratch:HI 0 "=r"))]
6203   "ix86_match_ccmode (insn, CCGOCmode)
6204    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6206   switch (get_attr_type (insn))
6207     {
6208     case TYPE_INCDEC:
6209       if (operands[2] == const1_rtx)
6210         return "inc{w}\t%0";
6211       else if (operands[2] == constm1_rtx)
6212         return "dec{w}\t%0";
6213       abort();
6215     default:
6216       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6217          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6218       if (GET_CODE (operands[2]) == CONST_INT
6219           && (INTVAL (operands[2]) == 128
6220               || (INTVAL (operands[2]) < 0
6221                   && INTVAL (operands[2]) != -128)))
6222         {
6223           operands[2] = GEN_INT (-INTVAL (operands[2]));
6224           return "sub{w}\t{%2, %0|%0, %2}";
6225         }
6226       return "add{w}\t{%2, %0|%0, %2}";
6227     }
6229   [(set (attr "type")
6230      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6231         (const_string "incdec")
6232         (const_string "alu")))
6233    (set_attr "mode" "HI")])
6235 (define_expand "addqi3"
6236   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6237                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6238                             (match_operand:QI 2 "general_operand" "")))
6239               (clobber (reg:CC FLAGS_REG))])]
6240   "TARGET_QIMODE_MATH"
6241   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6243 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6244 (define_insn "*addqi_1_lea"
6245   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6246         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6247                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6248    (clobber (reg:CC FLAGS_REG))]
6249   "!TARGET_PARTIAL_REG_STALL
6250    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6252   int widen = (which_alternative == 2);
6253   switch (get_attr_type (insn))
6254     {
6255     case TYPE_LEA:
6256       return "#";
6257     case TYPE_INCDEC:
6258       if (operands[2] == const1_rtx)
6259         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6260       else if (operands[2] == constm1_rtx)
6261         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6262       abort();
6264     default:
6265       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6266          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6267       if (GET_CODE (operands[2]) == CONST_INT
6268           && (INTVAL (operands[2]) == 128
6269               || (INTVAL (operands[2]) < 0
6270                   && INTVAL (operands[2]) != -128)))
6271         {
6272           operands[2] = GEN_INT (-INTVAL (operands[2]));
6273           if (widen)
6274             return "sub{l}\t{%2, %k0|%k0, %2}";
6275           else
6276             return "sub{b}\t{%2, %0|%0, %2}";
6277         }
6278       if (widen)
6279         return "add{l}\t{%k2, %k0|%k0, %k2}";
6280       else
6281         return "add{b}\t{%2, %0|%0, %2}";
6282     }
6284   [(set (attr "type")
6285      (if_then_else (eq_attr "alternative" "3")
6286         (const_string "lea")
6287         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6288            (const_string "incdec")
6289            (const_string "alu"))))
6290    (set_attr "mode" "QI,QI,SI,SI")])
6292 (define_insn "*addqi_1"
6293   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6294         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6295                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6296    (clobber (reg:CC FLAGS_REG))]
6297   "TARGET_PARTIAL_REG_STALL
6298    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6300   int widen = (which_alternative == 2);
6301   switch (get_attr_type (insn))
6302     {
6303     case TYPE_INCDEC:
6304       if (operands[2] == const1_rtx)
6305         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6306       else if (operands[2] == constm1_rtx)
6307         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6308       abort();
6310     default:
6311       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6312          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6313       if (GET_CODE (operands[2]) == CONST_INT
6314           && (INTVAL (operands[2]) == 128
6315               || (INTVAL (operands[2]) < 0
6316                   && INTVAL (operands[2]) != -128)))
6317         {
6318           operands[2] = GEN_INT (-INTVAL (operands[2]));
6319           if (widen)
6320             return "sub{l}\t{%2, %k0|%k0, %2}";
6321           else
6322             return "sub{b}\t{%2, %0|%0, %2}";
6323         }
6324       if (widen)
6325         return "add{l}\t{%k2, %k0|%k0, %k2}";
6326       else
6327         return "add{b}\t{%2, %0|%0, %2}";
6328     }
6330   [(set (attr "type")
6331      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6332         (const_string "incdec")
6333         (const_string "alu")))
6334    (set_attr "mode" "QI,QI,SI")])
6336 (define_insn "*addqi_1_slp"
6337   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6338         (plus:QI (match_dup 0)
6339                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6340    (clobber (reg:CC FLAGS_REG))]
6341   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6342    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6344   switch (get_attr_type (insn))
6345     {
6346     case TYPE_INCDEC:
6347       if (operands[1] == const1_rtx)
6348         return "inc{b}\t%0";
6349       else if (operands[1] == constm1_rtx)
6350         return "dec{b}\t%0";
6351       abort();
6353     default:
6354       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6355       if (GET_CODE (operands[1]) == CONST_INT
6356           && INTVAL (operands[1]) < 0)
6357         {
6358           operands[1] = GEN_INT (-INTVAL (operands[1]));
6359           return "sub{b}\t{%1, %0|%0, %1}";
6360         }
6361       return "add{b}\t{%1, %0|%0, %1}";
6362     }
6364   [(set (attr "type")
6365      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6366         (const_string "incdec")
6367         (const_string "alu1")))
6368    (set_attr "mode" "QI")])
6370 (define_insn "*addqi_2"
6371   [(set (reg 17)
6372         (compare
6373           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6374                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6375           (const_int 0)))
6376    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6377         (plus:QI (match_dup 1) (match_dup 2)))]
6378   "ix86_match_ccmode (insn, CCGOCmode)
6379    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6381   switch (get_attr_type (insn))
6382     {
6383     case TYPE_INCDEC:
6384       if (operands[2] == const1_rtx)
6385         return "inc{b}\t%0";
6386       else if (operands[2] == constm1_rtx
6387                || (GET_CODE (operands[2]) == CONST_INT
6388                    && INTVAL (operands[2]) == 255))
6389         return "dec{b}\t%0";
6390       abort();
6392     default:
6393       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6394       if (GET_CODE (operands[2]) == CONST_INT
6395           && INTVAL (operands[2]) < 0)
6396         {
6397           operands[2] = GEN_INT (-INTVAL (operands[2]));
6398           return "sub{b}\t{%2, %0|%0, %2}";
6399         }
6400       return "add{b}\t{%2, %0|%0, %2}";
6401     }
6403   [(set (attr "type")
6404      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6405         (const_string "incdec")
6406         (const_string "alu")))
6407    (set_attr "mode" "QI")])
6409 (define_insn "*addqi_3"
6410   [(set (reg 17)
6411         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6412                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6413    (clobber (match_scratch:QI 0 "=q"))]
6414   "ix86_match_ccmode (insn, CCZmode)
6415    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6417   switch (get_attr_type (insn))
6418     {
6419     case TYPE_INCDEC:
6420       if (operands[2] == const1_rtx)
6421         return "inc{b}\t%0";
6422       else if (operands[2] == constm1_rtx
6423                || (GET_CODE (operands[2]) == CONST_INT
6424                    && INTVAL (operands[2]) == 255))
6425         return "dec{b}\t%0";
6426       abort();
6428     default:
6429       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6430       if (GET_CODE (operands[2]) == CONST_INT
6431           && INTVAL (operands[2]) < 0)
6432         {
6433           operands[2] = GEN_INT (-INTVAL (operands[2]));
6434           return "sub{b}\t{%2, %0|%0, %2}";
6435         }
6436       return "add{b}\t{%2, %0|%0, %2}";
6437     }
6439   [(set (attr "type")
6440      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6441         (const_string "incdec")
6442         (const_string "alu")))
6443    (set_attr "mode" "QI")])
6445 ; See comments above addsi_3_imm for details.
6446 (define_insn "*addqi_4"
6447   [(set (reg 17)
6448         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6449                  (match_operand:QI 2 "const_int_operand" "n")))
6450    (clobber (match_scratch:QI 0 "=qm"))]
6451   "ix86_match_ccmode (insn, CCGCmode)
6452    && (INTVAL (operands[2]) & 0xff) != 0x80"
6454   switch (get_attr_type (insn))
6455     {
6456     case TYPE_INCDEC:
6457       if (operands[2] == constm1_rtx
6458           || (GET_CODE (operands[2]) == CONST_INT
6459               && INTVAL (operands[2]) == 255))
6460         return "inc{b}\t%0";
6461       else if (operands[2] == const1_rtx)
6462         return "dec{b}\t%0";
6463       else
6464         abort();
6466     default:
6467       if (! rtx_equal_p (operands[0], operands[1]))
6468         abort ();
6469       if (INTVAL (operands[2]) < 0)
6470         {
6471           operands[2] = GEN_INT (-INTVAL (operands[2]));
6472           return "add{b}\t{%2, %0|%0, %2}";
6473         }
6474       return "sub{b}\t{%2, %0|%0, %2}";
6475     }
6477   [(set (attr "type")
6478      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6479         (const_string "incdec")
6480         (const_string "alu")))
6481    (set_attr "mode" "QI")])
6484 (define_insn "*addqi_5"
6485   [(set (reg 17)
6486         (compare
6487           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6488                    (match_operand:QI 2 "general_operand" "qmni"))
6489           (const_int 0)))
6490    (clobber (match_scratch:QI 0 "=q"))]
6491   "ix86_match_ccmode (insn, CCGOCmode)
6492    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6494   switch (get_attr_type (insn))
6495     {
6496     case TYPE_INCDEC:
6497       if (operands[2] == const1_rtx)
6498         return "inc{b}\t%0";
6499       else if (operands[2] == constm1_rtx
6500                || (GET_CODE (operands[2]) == CONST_INT
6501                    && INTVAL (operands[2]) == 255))
6502         return "dec{b}\t%0";
6503       abort();
6505     default:
6506       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6507       if (GET_CODE (operands[2]) == CONST_INT
6508           && INTVAL (operands[2]) < 0)
6509         {
6510           operands[2] = GEN_INT (-INTVAL (operands[2]));
6511           return "sub{b}\t{%2, %0|%0, %2}";
6512         }
6513       return "add{b}\t{%2, %0|%0, %2}";
6514     }
6516   [(set (attr "type")
6517      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6518         (const_string "incdec")
6519         (const_string "alu")))
6520    (set_attr "mode" "QI")])
6523 (define_insn "addqi_ext_1"
6524   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6525                          (const_int 8)
6526                          (const_int 8))
6527         (plus:SI
6528           (zero_extract:SI
6529             (match_operand 1 "ext_register_operand" "0")
6530             (const_int 8)
6531             (const_int 8))
6532           (match_operand:QI 2 "general_operand" "Qmn")))
6533    (clobber (reg:CC FLAGS_REG))]
6534   "!TARGET_64BIT"
6536   switch (get_attr_type (insn))
6537     {
6538     case TYPE_INCDEC:
6539       if (operands[2] == const1_rtx)
6540         return "inc{b}\t%h0";
6541       else if (operands[2] == constm1_rtx
6542                || (GET_CODE (operands[2]) == CONST_INT
6543                    && INTVAL (operands[2]) == 255))
6544         return "dec{b}\t%h0";
6545       abort();
6547     default:
6548       return "add{b}\t{%2, %h0|%h0, %2}";
6549     }
6551   [(set (attr "type")
6552      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6553         (const_string "incdec")
6554         (const_string "alu")))
6555    (set_attr "mode" "QI")])
6557 (define_insn "*addqi_ext_1_rex64"
6558   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6559                          (const_int 8)
6560                          (const_int 8))
6561         (plus:SI
6562           (zero_extract:SI
6563             (match_operand 1 "ext_register_operand" "0")
6564             (const_int 8)
6565             (const_int 8))
6566           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6567    (clobber (reg:CC FLAGS_REG))]
6568   "TARGET_64BIT"
6570   switch (get_attr_type (insn))
6571     {
6572     case TYPE_INCDEC:
6573       if (operands[2] == const1_rtx)
6574         return "inc{b}\t%h0";
6575       else if (operands[2] == constm1_rtx
6576                || (GET_CODE (operands[2]) == CONST_INT
6577                    && INTVAL (operands[2]) == 255))
6578         return "dec{b}\t%h0";
6579       abort();
6581     default:
6582       return "add{b}\t{%2, %h0|%h0, %2}";
6583     }
6585   [(set (attr "type")
6586      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6587         (const_string "incdec")
6588         (const_string "alu")))
6589    (set_attr "mode" "QI")])
6591 (define_insn "*addqi_ext_2"
6592   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6593                          (const_int 8)
6594                          (const_int 8))
6595         (plus:SI
6596           (zero_extract:SI
6597             (match_operand 1 "ext_register_operand" "%0")
6598             (const_int 8)
6599             (const_int 8))
6600           (zero_extract:SI
6601             (match_operand 2 "ext_register_operand" "Q")
6602             (const_int 8)
6603             (const_int 8))))
6604    (clobber (reg:CC FLAGS_REG))]
6605   ""
6606   "add{b}\t{%h2, %h0|%h0, %h2}"
6607   [(set_attr "type" "alu")
6608    (set_attr "mode" "QI")])
6610 ;; The patterns that match these are at the end of this file.
6612 (define_expand "addxf3"
6613   [(set (match_operand:XF 0 "register_operand" "")
6614         (plus:XF (match_operand:XF 1 "register_operand" "")
6615                  (match_operand:XF 2 "register_operand" "")))]
6616   "TARGET_80387"
6617   "")
6619 (define_expand "adddf3"
6620   [(set (match_operand:DF 0 "register_operand" "")
6621         (plus:DF (match_operand:DF 1 "register_operand" "")
6622                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6623   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6624   "")
6626 (define_expand "addsf3"
6627   [(set (match_operand:SF 0 "register_operand" "")
6628         (plus:SF (match_operand:SF 1 "register_operand" "")
6629                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6630   "TARGET_80387 || TARGET_SSE_MATH"
6631   "")
6633 ;; Subtract instructions
6635 ;; %%% splits for subsidi3
6637 (define_expand "subdi3"
6638   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6639                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6640                              (match_operand:DI 2 "x86_64_general_operand" "")))
6641               (clobber (reg:CC FLAGS_REG))])]
6642   ""
6643   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6645 (define_insn "*subdi3_1"
6646   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6647         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6648                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6649    (clobber (reg:CC FLAGS_REG))]
6650   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6651   "#")
6653 (define_split
6654   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6655         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6656                   (match_operand:DI 2 "general_operand" "")))
6657    (clobber (reg:CC FLAGS_REG))]
6658   "!TARGET_64BIT && reload_completed"
6659   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6660               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6661    (parallel [(set (match_dup 3)
6662                    (minus:SI (match_dup 4)
6663                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6664                                       (match_dup 5))))
6665               (clobber (reg:CC FLAGS_REG))])]
6666   "split_di (operands+0, 1, operands+0, operands+3);
6667    split_di (operands+1, 1, operands+1, operands+4);
6668    split_di (operands+2, 1, operands+2, operands+5);")
6670 (define_insn "subdi3_carry_rex64"
6671   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6672           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6673             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6674                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6675    (clobber (reg:CC FLAGS_REG))]
6676   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6677   "sbb{q}\t{%2, %0|%0, %2}"
6678   [(set_attr "type" "alu")
6679    (set_attr "pent_pair" "pu")
6680    (set_attr "mode" "DI")])
6682 (define_insn "*subdi_1_rex64"
6683   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6684         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6685                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6686    (clobber (reg:CC FLAGS_REG))]
6687   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6688   "sub{q}\t{%2, %0|%0, %2}"
6689   [(set_attr "type" "alu")
6690    (set_attr "mode" "DI")])
6692 (define_insn "*subdi_2_rex64"
6693   [(set (reg 17)
6694         (compare
6695           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6696                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6697           (const_int 0)))
6698    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6699         (minus:DI (match_dup 1) (match_dup 2)))]
6700   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6701    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6702   "sub{q}\t{%2, %0|%0, %2}"
6703   [(set_attr "type" "alu")
6704    (set_attr "mode" "DI")])
6706 (define_insn "*subdi_3_rex63"
6707   [(set (reg 17)
6708         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6709                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6710    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6711         (minus:DI (match_dup 1) (match_dup 2)))]
6712   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6713    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6714   "sub{q}\t{%2, %0|%0, %2}"
6715   [(set_attr "type" "alu")
6716    (set_attr "mode" "DI")])
6718 (define_insn "subqi3_carry"
6719   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6720           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6721             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6722                (match_operand:QI 2 "general_operand" "qi,qm"))))
6723    (clobber (reg:CC FLAGS_REG))]
6724   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6725   "sbb{b}\t{%2, %0|%0, %2}"
6726   [(set_attr "type" "alu")
6727    (set_attr "pent_pair" "pu")
6728    (set_attr "mode" "QI")])
6730 (define_insn "subhi3_carry"
6731   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6732           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6733             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6734                (match_operand:HI 2 "general_operand" "ri,rm"))))
6735    (clobber (reg:CC FLAGS_REG))]
6736   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6737   "sbb{w}\t{%2, %0|%0, %2}"
6738   [(set_attr "type" "alu")
6739    (set_attr "pent_pair" "pu")
6740    (set_attr "mode" "HI")])
6742 (define_insn "subsi3_carry"
6743   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6744           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6745             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6746                (match_operand:SI 2 "general_operand" "ri,rm"))))
6747    (clobber (reg:CC FLAGS_REG))]
6748   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6749   "sbb{l}\t{%2, %0|%0, %2}"
6750   [(set_attr "type" "alu")
6751    (set_attr "pent_pair" "pu")
6752    (set_attr "mode" "SI")])
6754 (define_insn "subsi3_carry_zext"
6755   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6756           (zero_extend:DI
6757             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6758               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6759                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6760    (clobber (reg:CC FLAGS_REG))]
6761   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6762   "sbb{l}\t{%2, %k0|%k0, %2}"
6763   [(set_attr "type" "alu")
6764    (set_attr "pent_pair" "pu")
6765    (set_attr "mode" "SI")])
6767 (define_expand "subsi3"
6768   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6769                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6770                              (match_operand:SI 2 "general_operand" "")))
6771               (clobber (reg:CC FLAGS_REG))])]
6772   ""
6773   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6775 (define_insn "*subsi_1"
6776   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6777         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6778                   (match_operand:SI 2 "general_operand" "ri,rm")))
6779    (clobber (reg:CC FLAGS_REG))]
6780   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6781   "sub{l}\t{%2, %0|%0, %2}"
6782   [(set_attr "type" "alu")
6783    (set_attr "mode" "SI")])
6785 (define_insn "*subsi_1_zext"
6786   [(set (match_operand:DI 0 "register_operand" "=r")
6787         (zero_extend:DI
6788           (minus:SI (match_operand:SI 1 "register_operand" "0")
6789                     (match_operand:SI 2 "general_operand" "rim"))))
6790    (clobber (reg:CC FLAGS_REG))]
6791   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6792   "sub{l}\t{%2, %k0|%k0, %2}"
6793   [(set_attr "type" "alu")
6794    (set_attr "mode" "SI")])
6796 (define_insn "*subsi_2"
6797   [(set (reg 17)
6798         (compare
6799           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6800                     (match_operand:SI 2 "general_operand" "ri,rm"))
6801           (const_int 0)))
6802    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6803         (minus:SI (match_dup 1) (match_dup 2)))]
6804   "ix86_match_ccmode (insn, CCGOCmode)
6805    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6806   "sub{l}\t{%2, %0|%0, %2}"
6807   [(set_attr "type" "alu")
6808    (set_attr "mode" "SI")])
6810 (define_insn "*subsi_2_zext"
6811   [(set (reg 17)
6812         (compare
6813           (minus:SI (match_operand:SI 1 "register_operand" "0")
6814                     (match_operand:SI 2 "general_operand" "rim"))
6815           (const_int 0)))
6816    (set (match_operand:DI 0 "register_operand" "=r")
6817         (zero_extend:DI
6818           (minus:SI (match_dup 1)
6819                     (match_dup 2))))]
6820   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6821    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6822   "sub{l}\t{%2, %k0|%k0, %2}"
6823   [(set_attr "type" "alu")
6824    (set_attr "mode" "SI")])
6826 (define_insn "*subsi_3"
6827   [(set (reg 17)
6828         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6829                  (match_operand:SI 2 "general_operand" "ri,rm")))
6830    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6831         (minus:SI (match_dup 1) (match_dup 2)))]
6832   "ix86_match_ccmode (insn, CCmode)
6833    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6834   "sub{l}\t{%2, %0|%0, %2}"
6835   [(set_attr "type" "alu")
6836    (set_attr "mode" "SI")])
6838 (define_insn "*subsi_3_zext"
6839   [(set (reg 17)
6840         (compare (match_operand:SI 1 "register_operand" "0")
6841                  (match_operand:SI 2 "general_operand" "rim")))
6842    (set (match_operand:DI 0 "register_operand" "=r")
6843         (zero_extend:DI
6844           (minus:SI (match_dup 1)
6845                     (match_dup 2))))]
6846   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6847    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6848   "sub{q}\t{%2, %0|%0, %2}"
6849   [(set_attr "type" "alu")
6850    (set_attr "mode" "DI")])
6852 (define_expand "subhi3"
6853   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6854                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6855                              (match_operand:HI 2 "general_operand" "")))
6856               (clobber (reg:CC FLAGS_REG))])]
6857   "TARGET_HIMODE_MATH"
6858   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6860 (define_insn "*subhi_1"
6861   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6862         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6863                   (match_operand:HI 2 "general_operand" "ri,rm")))
6864    (clobber (reg:CC FLAGS_REG))]
6865   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6866   "sub{w}\t{%2, %0|%0, %2}"
6867   [(set_attr "type" "alu")
6868    (set_attr "mode" "HI")])
6870 (define_insn "*subhi_2"
6871   [(set (reg 17)
6872         (compare
6873           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6874                     (match_operand:HI 2 "general_operand" "ri,rm"))
6875           (const_int 0)))
6876    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6877         (minus:HI (match_dup 1) (match_dup 2)))]
6878   "ix86_match_ccmode (insn, CCGOCmode)
6879    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6880   "sub{w}\t{%2, %0|%0, %2}"
6881   [(set_attr "type" "alu")
6882    (set_attr "mode" "HI")])
6884 (define_insn "*subhi_3"
6885   [(set (reg 17)
6886         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6887                  (match_operand:HI 2 "general_operand" "ri,rm")))
6888    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6889         (minus:HI (match_dup 1) (match_dup 2)))]
6890   "ix86_match_ccmode (insn, CCmode)
6891    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6892   "sub{w}\t{%2, %0|%0, %2}"
6893   [(set_attr "type" "alu")
6894    (set_attr "mode" "HI")])
6896 (define_expand "subqi3"
6897   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6898                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6899                              (match_operand:QI 2 "general_operand" "")))
6900               (clobber (reg:CC FLAGS_REG))])]
6901   "TARGET_QIMODE_MATH"
6902   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6904 (define_insn "*subqi_1"
6905   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6906         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6907                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6908    (clobber (reg:CC FLAGS_REG))]
6909   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6910   "sub{b}\t{%2, %0|%0, %2}"
6911   [(set_attr "type" "alu")
6912    (set_attr "mode" "QI")])
6914 (define_insn "*subqi_1_slp"
6915   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6916         (minus:QI (match_dup 0)
6917                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6918    (clobber (reg:CC FLAGS_REG))]
6919   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6921   "sub{b}\t{%1, %0|%0, %1}"
6922   [(set_attr "type" "alu1")
6923    (set_attr "mode" "QI")])
6925 (define_insn "*subqi_2"
6926   [(set (reg 17)
6927         (compare
6928           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6929                     (match_operand:QI 2 "general_operand" "qi,qm"))
6930           (const_int 0)))
6931    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6932         (minus:HI (match_dup 1) (match_dup 2)))]
6933   "ix86_match_ccmode (insn, CCGOCmode)
6934    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6935   "sub{b}\t{%2, %0|%0, %2}"
6936   [(set_attr "type" "alu")
6937    (set_attr "mode" "QI")])
6939 (define_insn "*subqi_3"
6940   [(set (reg 17)
6941         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6942                  (match_operand:QI 2 "general_operand" "qi,qm")))
6943    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6944         (minus:HI (match_dup 1) (match_dup 2)))]
6945   "ix86_match_ccmode (insn, CCmode)
6946    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6947   "sub{b}\t{%2, %0|%0, %2}"
6948   [(set_attr "type" "alu")
6949    (set_attr "mode" "QI")])
6951 ;; The patterns that match these are at the end of this file.
6953 (define_expand "subxf3"
6954   [(set (match_operand:XF 0 "register_operand" "")
6955         (minus:XF (match_operand:XF 1 "register_operand" "")
6956                   (match_operand:XF 2 "register_operand" "")))]
6957   "TARGET_80387"
6958   "")
6960 (define_expand "subdf3"
6961   [(set (match_operand:DF 0 "register_operand" "")
6962         (minus:DF (match_operand:DF 1 "register_operand" "")
6963                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6964   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6965   "")
6967 (define_expand "subsf3"
6968   [(set (match_operand:SF 0 "register_operand" "")
6969         (minus:SF (match_operand:SF 1 "register_operand" "")
6970                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6971   "TARGET_80387 || TARGET_SSE_MATH"
6972   "")
6974 ;; Multiply instructions
6976 (define_expand "muldi3"
6977   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6978                    (mult:DI (match_operand:DI 1 "register_operand" "")
6979                             (match_operand:DI 2 "x86_64_general_operand" "")))
6980               (clobber (reg:CC FLAGS_REG))])]
6981   "TARGET_64BIT"
6982   "")
6984 (define_insn "*muldi3_1_rex64"
6985   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6986         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6987                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6988    (clobber (reg:CC FLAGS_REG))]
6989   "TARGET_64BIT
6990    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6991   "@
6992    imul{q}\t{%2, %1, %0|%0, %1, %2}
6993    imul{q}\t{%2, %1, %0|%0, %1, %2}
6994    imul{q}\t{%2, %0|%0, %2}"
6995   [(set_attr "type" "imul")
6996    (set_attr "prefix_0f" "0,0,1")
6997    (set (attr "athlon_decode")
6998         (cond [(eq_attr "cpu" "athlon")
6999                   (const_string "vector")
7000                (eq_attr "alternative" "1")
7001                   (const_string "vector")
7002                (and (eq_attr "alternative" "2")
7003                     (match_operand 1 "memory_operand" ""))
7004                   (const_string "vector")]
7005               (const_string "direct")))
7006    (set_attr "mode" "DI")])
7008 (define_expand "mulsi3"
7009   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7010                    (mult:SI (match_operand:SI 1 "register_operand" "")
7011                             (match_operand:SI 2 "general_operand" "")))
7012               (clobber (reg:CC FLAGS_REG))])]
7013   ""
7014   "")
7016 (define_insn "*mulsi3_1"
7017   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7018         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7019                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7020    (clobber (reg:CC FLAGS_REG))]
7021   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7022   "@
7023    imul{l}\t{%2, %1, %0|%0, %1, %2}
7024    imul{l}\t{%2, %1, %0|%0, %1, %2}
7025    imul{l}\t{%2, %0|%0, %2}"
7026   [(set_attr "type" "imul")
7027    (set_attr "prefix_0f" "0,0,1")
7028    (set (attr "athlon_decode")
7029         (cond [(eq_attr "cpu" "athlon")
7030                   (const_string "vector")
7031                (eq_attr "alternative" "1")
7032                   (const_string "vector")
7033                (and (eq_attr "alternative" "2")
7034                     (match_operand 1 "memory_operand" ""))
7035                   (const_string "vector")]
7036               (const_string "direct")))
7037    (set_attr "mode" "SI")])
7039 (define_insn "*mulsi3_1_zext"
7040   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7041         (zero_extend:DI
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   "TARGET_64BIT
7046    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7047   "@
7048    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7049    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7050    imul{l}\t{%2, %k0|%k0, %2}"
7051   [(set_attr "type" "imul")
7052    (set_attr "prefix_0f" "0,0,1")
7053    (set (attr "athlon_decode")
7054         (cond [(eq_attr "cpu" "athlon")
7055                   (const_string "vector")
7056                (eq_attr "alternative" "1")
7057                   (const_string "vector")
7058                (and (eq_attr "alternative" "2")
7059                     (match_operand 1 "memory_operand" ""))
7060                   (const_string "vector")]
7061               (const_string "direct")))
7062    (set_attr "mode" "SI")])
7064 (define_expand "mulhi3"
7065   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7066                    (mult:HI (match_operand:HI 1 "register_operand" "")
7067                             (match_operand:HI 2 "general_operand" "")))
7068               (clobber (reg:CC FLAGS_REG))])]
7069   "TARGET_HIMODE_MATH"
7070   "")
7072 (define_insn "*mulhi3_1"
7073   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7074         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7075                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7076    (clobber (reg:CC FLAGS_REG))]
7077   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7078   "@
7079    imul{w}\t{%2, %1, %0|%0, %1, %2}
7080    imul{w}\t{%2, %1, %0|%0, %1, %2}
7081    imul{w}\t{%2, %0|%0, %2}"
7082   [(set_attr "type" "imul")
7083    (set_attr "prefix_0f" "0,0,1")
7084    (set (attr "athlon_decode")
7085         (cond [(eq_attr "cpu" "athlon")
7086                   (const_string "vector")
7087                (eq_attr "alternative" "1,2")
7088                   (const_string "vector")]
7089               (const_string "direct")))
7090    (set_attr "mode" "HI")])
7092 (define_expand "mulqi3"
7093   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7094                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7095                             (match_operand:QI 2 "register_operand" "")))
7096               (clobber (reg:CC FLAGS_REG))])]
7097   "TARGET_QIMODE_MATH"
7098   "")
7100 (define_insn "*mulqi3_1"
7101   [(set (match_operand:QI 0 "register_operand" "=a")
7102         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7103                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7104    (clobber (reg:CC FLAGS_REG))]
7105   "TARGET_QIMODE_MATH
7106    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7107   "mul{b}\t%2"
7108   [(set_attr "type" "imul")
7109    (set_attr "length_immediate" "0")
7110    (set (attr "athlon_decode")
7111      (if_then_else (eq_attr "cpu" "athlon")
7112         (const_string "vector")
7113         (const_string "direct")))
7114    (set_attr "mode" "QI")])
7116 (define_expand "umulqihi3"
7117   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7118                    (mult:HI (zero_extend:HI
7119                               (match_operand:QI 1 "nonimmediate_operand" ""))
7120                             (zero_extend:HI
7121                               (match_operand:QI 2 "register_operand" ""))))
7122               (clobber (reg:CC FLAGS_REG))])]
7123   "TARGET_QIMODE_MATH"
7124   "")
7126 (define_insn "*umulqihi3_1"
7127   [(set (match_operand:HI 0 "register_operand" "=a")
7128         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7129                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7130    (clobber (reg:CC FLAGS_REG))]
7131   "TARGET_QIMODE_MATH
7132    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7133   "mul{b}\t%2"
7134   [(set_attr "type" "imul")
7135    (set_attr "length_immediate" "0")
7136    (set (attr "athlon_decode")
7137      (if_then_else (eq_attr "cpu" "athlon")
7138         (const_string "vector")
7139         (const_string "direct")))
7140    (set_attr "mode" "QI")])
7142 (define_expand "mulqihi3"
7143   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7144                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7145                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7146               (clobber (reg:CC FLAGS_REG))])]
7147   "TARGET_QIMODE_MATH"
7148   "")
7150 (define_insn "*mulqihi3_insn"
7151   [(set (match_operand:HI 0 "register_operand" "=a")
7152         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7153                  (sign_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   "imul{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 "umulditi3"
7167   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7168                    (mult:TI (zero_extend:TI
7169                               (match_operand:DI 1 "nonimmediate_operand" ""))
7170                             (zero_extend:TI
7171                               (match_operand:DI 2 "register_operand" ""))))
7172               (clobber (reg:CC FLAGS_REG))])]
7173   "TARGET_64BIT"
7174   "")
7176 (define_insn "*umulditi3_insn"
7177   [(set (match_operand:TI 0 "register_operand" "=A")
7178         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7179                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7180    (clobber (reg:CC FLAGS_REG))]
7181   "TARGET_64BIT
7182    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7183   "mul{q}\t%2"
7184   [(set_attr "type" "imul")
7185    (set_attr "length_immediate" "0")
7186    (set (attr "athlon_decode")
7187      (if_then_else (eq_attr "cpu" "athlon")
7188         (const_string "vector")
7189         (const_string "double")))
7190    (set_attr "mode" "DI")])
7192 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7193 (define_expand "umulsidi3"
7194   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7195                    (mult:DI (zero_extend:DI
7196                               (match_operand:SI 1 "nonimmediate_operand" ""))
7197                             (zero_extend:DI
7198                               (match_operand:SI 2 "register_operand" ""))))
7199               (clobber (reg:CC FLAGS_REG))])]
7200   "!TARGET_64BIT"
7201   "")
7203 (define_insn "*umulsidi3_insn"
7204   [(set (match_operand:DI 0 "register_operand" "=A")
7205         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7206                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7207    (clobber (reg:CC FLAGS_REG))]
7208   "!TARGET_64BIT
7209    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7210   "mul{l}\t%2"
7211   [(set_attr "type" "imul")
7212    (set_attr "length_immediate" "0")
7213    (set (attr "athlon_decode")
7214      (if_then_else (eq_attr "cpu" "athlon")
7215         (const_string "vector")
7216         (const_string "double")))
7217    (set_attr "mode" "SI")])
7219 (define_expand "mulditi3"
7220   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7221                    (mult:TI (sign_extend:TI
7222                               (match_operand:DI 1 "nonimmediate_operand" ""))
7223                             (sign_extend:TI
7224                               (match_operand:DI 2 "register_operand" ""))))
7225               (clobber (reg:CC FLAGS_REG))])]
7226   "TARGET_64BIT"
7227   "")
7229 (define_insn "*mulditi3_insn"
7230   [(set (match_operand:TI 0 "register_operand" "=A")
7231         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7232                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7233    (clobber (reg:CC FLAGS_REG))]
7234   "TARGET_64BIT
7235    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7236   "imul{q}\t%2"
7237   [(set_attr "type" "imul")
7238    (set_attr "length_immediate" "0")
7239    (set (attr "athlon_decode")
7240      (if_then_else (eq_attr "cpu" "athlon")
7241         (const_string "vector")
7242         (const_string "double")))
7243    (set_attr "mode" "DI")])
7245 (define_expand "mulsidi3"
7246   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7247                    (mult:DI (sign_extend:DI
7248                               (match_operand:SI 1 "nonimmediate_operand" ""))
7249                             (sign_extend:DI
7250                               (match_operand:SI 2 "register_operand" ""))))
7251               (clobber (reg:CC FLAGS_REG))])]
7252   "!TARGET_64BIT"
7253   "")
7255 (define_insn "*mulsidi3_insn"
7256   [(set (match_operand:DI 0 "register_operand" "=A")
7257         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7258                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7259    (clobber (reg:CC FLAGS_REG))]
7260   "!TARGET_64BIT
7261    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7262   "imul{l}\t%2"
7263   [(set_attr "type" "imul")
7264    (set_attr "length_immediate" "0")
7265    (set (attr "athlon_decode")
7266      (if_then_else (eq_attr "cpu" "athlon")
7267         (const_string "vector")
7268         (const_string "double")))
7269    (set_attr "mode" "SI")])
7271 (define_expand "umuldi3_highpart"
7272   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7273                    (truncate:DI
7274                      (lshiftrt:TI
7275                        (mult:TI (zero_extend:TI
7276                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7277                                 (zero_extend:TI
7278                                   (match_operand:DI 2 "register_operand" "")))
7279                        (const_int 64))))
7280               (clobber (match_scratch:DI 3 ""))
7281               (clobber (reg:CC FLAGS_REG))])]
7282   "TARGET_64BIT"
7283   "")
7285 (define_insn "*umuldi3_highpart_rex64"
7286   [(set (match_operand:DI 0 "register_operand" "=d")
7287         (truncate:DI
7288           (lshiftrt:TI
7289             (mult:TI (zero_extend:TI
7290                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7291                      (zero_extend:TI
7292                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7293             (const_int 64))))
7294    (clobber (match_scratch:DI 3 "=1"))
7295    (clobber (reg:CC FLAGS_REG))]
7296   "TARGET_64BIT
7297    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7298   "mul{q}\t%2"
7299   [(set_attr "type" "imul")
7300    (set_attr "length_immediate" "0")
7301    (set (attr "athlon_decode")
7302      (if_then_else (eq_attr "cpu" "athlon")
7303         (const_string "vector")
7304         (const_string "double")))
7305    (set_attr "mode" "DI")])
7307 (define_expand "umulsi3_highpart"
7308   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7309                    (truncate:SI
7310                      (lshiftrt:DI
7311                        (mult:DI (zero_extend:DI
7312                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7313                                 (zero_extend:DI
7314                                   (match_operand:SI 2 "register_operand" "")))
7315                        (const_int 32))))
7316               (clobber (match_scratch:SI 3 ""))
7317               (clobber (reg:CC FLAGS_REG))])]
7318   ""
7319   "")
7321 (define_insn "*umulsi3_highpart_insn"
7322   [(set (match_operand:SI 0 "register_operand" "=d")
7323         (truncate:SI
7324           (lshiftrt:DI
7325             (mult:DI (zero_extend:DI
7326                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7327                      (zero_extend:DI
7328                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7329             (const_int 32))))
7330    (clobber (match_scratch:SI 3 "=1"))
7331    (clobber (reg:CC FLAGS_REG))]
7332   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7333   "mul{l}\t%2"
7334   [(set_attr "type" "imul")
7335    (set_attr "length_immediate" "0")
7336    (set (attr "athlon_decode")
7337      (if_then_else (eq_attr "cpu" "athlon")
7338         (const_string "vector")
7339         (const_string "double")))
7340    (set_attr "mode" "SI")])
7342 (define_insn "*umulsi3_highpart_zext"
7343   [(set (match_operand:DI 0 "register_operand" "=d")
7344         (zero_extend:DI (truncate:SI
7345           (lshiftrt:DI
7346             (mult:DI (zero_extend:DI
7347                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7348                      (zero_extend:DI
7349                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7350             (const_int 32)))))
7351    (clobber (match_scratch:SI 3 "=1"))
7352    (clobber (reg:CC FLAGS_REG))]
7353   "TARGET_64BIT
7354    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7355   "mul{l}\t%2"
7356   [(set_attr "type" "imul")
7357    (set_attr "length_immediate" "0")
7358    (set (attr "athlon_decode")
7359      (if_then_else (eq_attr "cpu" "athlon")
7360         (const_string "vector")
7361         (const_string "double")))
7362    (set_attr "mode" "SI")])
7364 (define_expand "smuldi3_highpart"
7365   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7366                    (truncate:DI
7367                      (lshiftrt:TI
7368                        (mult:TI (sign_extend:TI
7369                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7370                                 (sign_extend:TI
7371                                   (match_operand:DI 2 "register_operand" "")))
7372                        (const_int 64))))
7373               (clobber (match_scratch:DI 3 ""))
7374               (clobber (reg:CC FLAGS_REG))])]
7375   "TARGET_64BIT"
7376   "")
7378 (define_insn "*smuldi3_highpart_rex64"
7379   [(set (match_operand:DI 0 "register_operand" "=d")
7380         (truncate:DI
7381           (lshiftrt:TI
7382             (mult:TI (sign_extend:TI
7383                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7384                      (sign_extend:TI
7385                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7386             (const_int 64))))
7387    (clobber (match_scratch:DI 3 "=1"))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "TARGET_64BIT
7390    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7391   "imul{q}\t%2"
7392   [(set_attr "type" "imul")
7393    (set (attr "athlon_decode")
7394      (if_then_else (eq_attr "cpu" "athlon")
7395         (const_string "vector")
7396         (const_string "double")))
7397    (set_attr "mode" "DI")])
7399 (define_expand "smulsi3_highpart"
7400   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7401                    (truncate:SI
7402                      (lshiftrt:DI
7403                        (mult:DI (sign_extend:DI
7404                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7405                                 (sign_extend:DI
7406                                   (match_operand:SI 2 "register_operand" "")))
7407                        (const_int 32))))
7408               (clobber (match_scratch:SI 3 ""))
7409               (clobber (reg:CC FLAGS_REG))])]
7410   ""
7411   "")
7413 (define_insn "*smulsi3_highpart_insn"
7414   [(set (match_operand:SI 0 "register_operand" "=d")
7415         (truncate:SI
7416           (lshiftrt:DI
7417             (mult:DI (sign_extend:DI
7418                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7419                      (sign_extend:DI
7420                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7421             (const_int 32))))
7422    (clobber (match_scratch:SI 3 "=1"))
7423    (clobber (reg:CC FLAGS_REG))]
7424   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7425   "imul{l}\t%2"
7426   [(set_attr "type" "imul")
7427    (set (attr "athlon_decode")
7428      (if_then_else (eq_attr "cpu" "athlon")
7429         (const_string "vector")
7430         (const_string "double")))
7431    (set_attr "mode" "SI")])
7433 (define_insn "*smulsi3_highpart_zext"
7434   [(set (match_operand:DI 0 "register_operand" "=d")
7435         (zero_extend:DI (truncate:SI
7436           (lshiftrt:DI
7437             (mult:DI (sign_extend:DI
7438                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7439                      (sign_extend:DI
7440                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7441             (const_int 32)))))
7442    (clobber (match_scratch:SI 3 "=1"))
7443    (clobber (reg:CC FLAGS_REG))]
7444   "TARGET_64BIT
7445    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7446   "imul{l}\t%2"
7447   [(set_attr "type" "imul")
7448    (set (attr "athlon_decode")
7449      (if_then_else (eq_attr "cpu" "athlon")
7450         (const_string "vector")
7451         (const_string "double")))
7452    (set_attr "mode" "SI")])
7454 ;; The patterns that match these are at the end of this file.
7456 (define_expand "mulxf3"
7457   [(set (match_operand:XF 0 "register_operand" "")
7458         (mult:XF (match_operand:XF 1 "register_operand" "")
7459                  (match_operand:XF 2 "register_operand" "")))]
7460   "TARGET_80387"
7461   "")
7463 (define_expand "muldf3"
7464   [(set (match_operand:DF 0 "register_operand" "")
7465         (mult:DF (match_operand:DF 1 "register_operand" "")
7466                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7467   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7468   "")
7470 (define_expand "mulsf3"
7471   [(set (match_operand:SF 0 "register_operand" "")
7472         (mult:SF (match_operand:SF 1 "register_operand" "")
7473                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7474   "TARGET_80387 || TARGET_SSE_MATH"
7475   "")
7477 ;; Divide instructions
7479 (define_insn "divqi3"
7480   [(set (match_operand:QI 0 "register_operand" "=a")
7481         (div:QI (match_operand:HI 1 "register_operand" "0")
7482                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7483    (clobber (reg:CC FLAGS_REG))]
7484   "TARGET_QIMODE_MATH"
7485   "idiv{b}\t%2"
7486   [(set_attr "type" "idiv")
7487    (set_attr "mode" "QI")])
7489 (define_insn "udivqi3"
7490   [(set (match_operand:QI 0 "register_operand" "=a")
7491         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7492                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7493    (clobber (reg:CC FLAGS_REG))]
7494   "TARGET_QIMODE_MATH"
7495   "div{b}\t%2"
7496   [(set_attr "type" "idiv")
7497    (set_attr "mode" "QI")])
7499 ;; The patterns that match these are at the end of this file.
7501 (define_expand "divxf3"
7502   [(set (match_operand:XF 0 "register_operand" "")
7503         (div:XF (match_operand:XF 1 "register_operand" "")
7504                 (match_operand:XF 2 "register_operand" "")))]
7505   "TARGET_80387"
7506   "")
7508 (define_expand "divdf3"
7509   [(set (match_operand:DF 0 "register_operand" "")
7510         (div:DF (match_operand:DF 1 "register_operand" "")
7511                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7512    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7513    "")
7515 (define_expand "divsf3"
7516   [(set (match_operand:SF 0 "register_operand" "")
7517         (div:SF (match_operand:SF 1 "register_operand" "")
7518                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7519   "TARGET_80387 || TARGET_SSE_MATH"
7520   "")
7522 ;; Remainder instructions.
7524 (define_expand "divmoddi4"
7525   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7526                    (div:DI (match_operand:DI 1 "register_operand" "")
7527                            (match_operand:DI 2 "nonimmediate_operand" "")))
7528               (set (match_operand:DI 3 "register_operand" "")
7529                    (mod:DI (match_dup 1) (match_dup 2)))
7530               (clobber (reg:CC FLAGS_REG))])]
7531   "TARGET_64BIT"
7532   "")
7534 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7535 ;; Penalize eax case slightly because it results in worse scheduling
7536 ;; of code.
7537 (define_insn "*divmoddi4_nocltd_rex64"
7538   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7539         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7540                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7541    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7542         (mod:DI (match_dup 2) (match_dup 3)))
7543    (clobber (reg:CC FLAGS_REG))]
7544   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7545   "#"
7546   [(set_attr "type" "multi")])
7548 (define_insn "*divmoddi4_cltd_rex64"
7549   [(set (match_operand:DI 0 "register_operand" "=a")
7550         (div:DI (match_operand:DI 2 "register_operand" "a")
7551                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7552    (set (match_operand:DI 1 "register_operand" "=&d")
7553         (mod:DI (match_dup 2) (match_dup 3)))
7554    (clobber (reg:CC FLAGS_REG))]
7555   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7556   "#"
7557   [(set_attr "type" "multi")])
7559 (define_insn "*divmoddi_noext_rex64"
7560   [(set (match_operand:DI 0 "register_operand" "=a")
7561         (div:DI (match_operand:DI 1 "register_operand" "0")
7562                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7563    (set (match_operand:DI 3 "register_operand" "=d")
7564         (mod:DI (match_dup 1) (match_dup 2)))
7565    (use (match_operand:DI 4 "register_operand" "3"))
7566    (clobber (reg:CC FLAGS_REG))]
7567   "TARGET_64BIT"
7568   "idiv{q}\t%2"
7569   [(set_attr "type" "idiv")
7570    (set_attr "mode" "DI")])
7572 (define_split
7573   [(set (match_operand:DI 0 "register_operand" "")
7574         (div:DI (match_operand:DI 1 "register_operand" "")
7575                 (match_operand:DI 2 "nonimmediate_operand" "")))
7576    (set (match_operand:DI 3 "register_operand" "")
7577         (mod:DI (match_dup 1) (match_dup 2)))
7578    (clobber (reg:CC FLAGS_REG))]
7579   "TARGET_64BIT && reload_completed"
7580   [(parallel [(set (match_dup 3)
7581                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7582               (clobber (reg:CC FLAGS_REG))])
7583    (parallel [(set (match_dup 0)
7584                    (div:DI (reg:DI 0) (match_dup 2)))
7585               (set (match_dup 3)
7586                    (mod:DI (reg:DI 0) (match_dup 2)))
7587               (use (match_dup 3))
7588               (clobber (reg:CC FLAGS_REG))])]
7590   /* Avoid use of cltd in favor of a mov+shift.  */
7591   if (!TARGET_USE_CLTD && !optimize_size)
7592     {
7593       if (true_regnum (operands[1]))
7594         emit_move_insn (operands[0], operands[1]);
7595       else
7596         emit_move_insn (operands[3], operands[1]);
7597       operands[4] = operands[3];
7598     }
7599   else
7600     {
7601       if (true_regnum (operands[1]))
7602         abort();
7603       operands[4] = operands[1];
7604     }
7608 (define_expand "divmodsi4"
7609   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7610                    (div:SI (match_operand:SI 1 "register_operand" "")
7611                            (match_operand:SI 2 "nonimmediate_operand" "")))
7612               (set (match_operand:SI 3 "register_operand" "")
7613                    (mod:SI (match_dup 1) (match_dup 2)))
7614               (clobber (reg:CC FLAGS_REG))])]
7615   ""
7616   "")
7618 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7619 ;; Penalize eax case slightly because it results in worse scheduling
7620 ;; of code.
7621 (define_insn "*divmodsi4_nocltd"
7622   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7623         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7624                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7625    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7626         (mod:SI (match_dup 2) (match_dup 3)))
7627    (clobber (reg:CC FLAGS_REG))]
7628   "!optimize_size && !TARGET_USE_CLTD"
7629   "#"
7630   [(set_attr "type" "multi")])
7632 (define_insn "*divmodsi4_cltd"
7633   [(set (match_operand:SI 0 "register_operand" "=a")
7634         (div:SI (match_operand:SI 2 "register_operand" "a")
7635                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7636    (set (match_operand:SI 1 "register_operand" "=&d")
7637         (mod:SI (match_dup 2) (match_dup 3)))
7638    (clobber (reg:CC FLAGS_REG))]
7639   "optimize_size || TARGET_USE_CLTD"
7640   "#"
7641   [(set_attr "type" "multi")])
7643 (define_insn "*divmodsi_noext"
7644   [(set (match_operand:SI 0 "register_operand" "=a")
7645         (div:SI (match_operand:SI 1 "register_operand" "0")
7646                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7647    (set (match_operand:SI 3 "register_operand" "=d")
7648         (mod:SI (match_dup 1) (match_dup 2)))
7649    (use (match_operand:SI 4 "register_operand" "3"))
7650    (clobber (reg:CC FLAGS_REG))]
7651   ""
7652   "idiv{l}\t%2"
7653   [(set_attr "type" "idiv")
7654    (set_attr "mode" "SI")])
7656 (define_split
7657   [(set (match_operand:SI 0 "register_operand" "")
7658         (div:SI (match_operand:SI 1 "register_operand" "")
7659                 (match_operand:SI 2 "nonimmediate_operand" "")))
7660    (set (match_operand:SI 3 "register_operand" "")
7661         (mod:SI (match_dup 1) (match_dup 2)))
7662    (clobber (reg:CC FLAGS_REG))]
7663   "reload_completed"
7664   [(parallel [(set (match_dup 3)
7665                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7666               (clobber (reg:CC FLAGS_REG))])
7667    (parallel [(set (match_dup 0)
7668                    (div:SI (reg:SI 0) (match_dup 2)))
7669               (set (match_dup 3)
7670                    (mod:SI (reg:SI 0) (match_dup 2)))
7671               (use (match_dup 3))
7672               (clobber (reg:CC FLAGS_REG))])]
7674   /* Avoid use of cltd in favor of a mov+shift.  */
7675   if (!TARGET_USE_CLTD && !optimize_size)
7676     {
7677       if (true_regnum (operands[1]))
7678         emit_move_insn (operands[0], operands[1]);
7679       else
7680         emit_move_insn (operands[3], operands[1]);
7681       operands[4] = operands[3];
7682     }
7683   else
7684     {
7685       if (true_regnum (operands[1]))
7686         abort();
7687       operands[4] = operands[1];
7688     }
7690 ;; %%% Split me.
7691 (define_insn "divmodhi4"
7692   [(set (match_operand:HI 0 "register_operand" "=a")
7693         (div:HI (match_operand:HI 1 "register_operand" "0")
7694                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7695    (set (match_operand:HI 3 "register_operand" "=&d")
7696         (mod:HI (match_dup 1) (match_dup 2)))
7697    (clobber (reg:CC FLAGS_REG))]
7698   "TARGET_HIMODE_MATH"
7699   "cwtd\;idiv{w}\t%2"
7700   [(set_attr "type" "multi")
7701    (set_attr "length_immediate" "0")
7702    (set_attr "mode" "SI")])
7704 (define_insn "udivmoddi4"
7705   [(set (match_operand:DI 0 "register_operand" "=a")
7706         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7707                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7708    (set (match_operand:DI 3 "register_operand" "=&d")
7709         (umod:DI (match_dup 1) (match_dup 2)))
7710    (clobber (reg:CC FLAGS_REG))]
7711   "TARGET_64BIT"
7712   "xor{q}\t%3, %3\;div{q}\t%2"
7713   [(set_attr "type" "multi")
7714    (set_attr "length_immediate" "0")
7715    (set_attr "mode" "DI")])
7717 (define_insn "*udivmoddi4_noext"
7718   [(set (match_operand:DI 0 "register_operand" "=a")
7719         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7720                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7721    (set (match_operand:DI 3 "register_operand" "=d")
7722         (umod:DI (match_dup 1) (match_dup 2)))
7723    (use (match_dup 3))
7724    (clobber (reg:CC FLAGS_REG))]
7725   "TARGET_64BIT"
7726   "div{q}\t%2"
7727   [(set_attr "type" "idiv")
7728    (set_attr "mode" "DI")])
7730 (define_split
7731   [(set (match_operand:DI 0 "register_operand" "")
7732         (udiv:DI (match_operand:DI 1 "register_operand" "")
7733                  (match_operand:DI 2 "nonimmediate_operand" "")))
7734    (set (match_operand:DI 3 "register_operand" "")
7735         (umod:DI (match_dup 1) (match_dup 2)))
7736    (clobber (reg:CC FLAGS_REG))]
7737   "TARGET_64BIT && reload_completed"
7738   [(set (match_dup 3) (const_int 0))
7739    (parallel [(set (match_dup 0)
7740                    (udiv:DI (match_dup 1) (match_dup 2)))
7741               (set (match_dup 3)
7742                    (umod:DI (match_dup 1) (match_dup 2)))
7743               (use (match_dup 3))
7744               (clobber (reg:CC FLAGS_REG))])]
7745   "")
7747 (define_insn "udivmodsi4"
7748   [(set (match_operand:SI 0 "register_operand" "=a")
7749         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7750                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7751    (set (match_operand:SI 3 "register_operand" "=&d")
7752         (umod:SI (match_dup 1) (match_dup 2)))
7753    (clobber (reg:CC FLAGS_REG))]
7754   ""
7755   "xor{l}\t%3, %3\;div{l}\t%2"
7756   [(set_attr "type" "multi")
7757    (set_attr "length_immediate" "0")
7758    (set_attr "mode" "SI")])
7760 (define_insn "*udivmodsi4_noext"
7761   [(set (match_operand:SI 0 "register_operand" "=a")
7762         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7763                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7764    (set (match_operand:SI 3 "register_operand" "=d")
7765         (umod:SI (match_dup 1) (match_dup 2)))
7766    (use (match_dup 3))
7767    (clobber (reg:CC FLAGS_REG))]
7768   ""
7769   "div{l}\t%2"
7770   [(set_attr "type" "idiv")
7771    (set_attr "mode" "SI")])
7773 (define_split
7774   [(set (match_operand:SI 0 "register_operand" "")
7775         (udiv:SI (match_operand:SI 1 "register_operand" "")
7776                  (match_operand:SI 2 "nonimmediate_operand" "")))
7777    (set (match_operand:SI 3 "register_operand" "")
7778         (umod:SI (match_dup 1) (match_dup 2)))
7779    (clobber (reg:CC FLAGS_REG))]
7780   "reload_completed"
7781   [(set (match_dup 3) (const_int 0))
7782    (parallel [(set (match_dup 0)
7783                    (udiv:SI (match_dup 1) (match_dup 2)))
7784               (set (match_dup 3)
7785                    (umod:SI (match_dup 1) (match_dup 2)))
7786               (use (match_dup 3))
7787               (clobber (reg:CC FLAGS_REG))])]
7788   "")
7790 (define_expand "udivmodhi4"
7791   [(set (match_dup 4) (const_int 0))
7792    (parallel [(set (match_operand:HI 0 "register_operand" "")
7793                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7794                             (match_operand:HI 2 "nonimmediate_operand" "")))
7795               (set (match_operand:HI 3 "register_operand" "")
7796                    (umod:HI (match_dup 1) (match_dup 2)))
7797               (use (match_dup 4))
7798               (clobber (reg:CC FLAGS_REG))])]
7799   "TARGET_HIMODE_MATH"
7800   "operands[4] = gen_reg_rtx (HImode);")
7802 (define_insn "*udivmodhi_noext"
7803   [(set (match_operand:HI 0 "register_operand" "=a")
7804         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7805                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7806    (set (match_operand:HI 3 "register_operand" "=d")
7807         (umod:HI (match_dup 1) (match_dup 2)))
7808    (use (match_operand:HI 4 "register_operand" "3"))
7809    (clobber (reg:CC FLAGS_REG))]
7810   ""
7811   "div{w}\t%2"
7812   [(set_attr "type" "idiv")
7813    (set_attr "mode" "HI")])
7815 ;; We cannot use div/idiv for double division, because it causes
7816 ;; "division by zero" on the overflow and that's not what we expect
7817 ;; from truncate.  Because true (non truncating) double division is
7818 ;; never generated, we can't create this insn anyway.
7820 ;(define_insn ""
7821 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7822 ;       (truncate:SI
7823 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7824 ;                  (zero_extend:DI
7825 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7826 ;   (set (match_operand:SI 3 "register_operand" "=d")
7827 ;       (truncate:SI
7828 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7829 ;   (clobber (reg:CC FLAGS_REG))]
7830 ;  ""
7831 ;  "div{l}\t{%2, %0|%0, %2}"
7832 ;  [(set_attr "type" "idiv")])
7834 ;;- Logical AND instructions
7836 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7837 ;; Note that this excludes ah.
7839 (define_insn "*testdi_1_rex64"
7840   [(set (reg 17)
7841         (compare
7842           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7843                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7844           (const_int 0)))]
7845   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7846    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7847   "@
7848    test{l}\t{%k1, %k0|%k0, %k1}
7849    test{l}\t{%k1, %k0|%k0, %k1}
7850    test{q}\t{%1, %0|%0, %1}
7851    test{q}\t{%1, %0|%0, %1}
7852    test{q}\t{%1, %0|%0, %1}"
7853   [(set_attr "type" "test")
7854    (set_attr "modrm" "0,1,0,1,1")
7855    (set_attr "mode" "SI,SI,DI,DI,DI")
7856    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7858 (define_insn "testsi_1"
7859   [(set (reg 17)
7860         (compare
7861           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7862                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7863           (const_int 0)))]
7864   "ix86_match_ccmode (insn, CCNOmode)
7865    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7866   "test{l}\t{%1, %0|%0, %1}"
7867   [(set_attr "type" "test")
7868    (set_attr "modrm" "0,1,1")
7869    (set_attr "mode" "SI")
7870    (set_attr "pent_pair" "uv,np,uv")])
7872 (define_expand "testsi_ccno_1"
7873   [(set (reg:CCNO FLAGS_REG)
7874         (compare:CCNO
7875           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7876                   (match_operand:SI 1 "nonmemory_operand" ""))
7877           (const_int 0)))]
7878   ""
7879   "")
7881 (define_insn "*testhi_1"
7882   [(set (reg 17)
7883         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7884                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7885                  (const_int 0)))]
7886   "ix86_match_ccmode (insn, CCNOmode)
7887    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7888   "test{w}\t{%1, %0|%0, %1}"
7889   [(set_attr "type" "test")
7890    (set_attr "modrm" "0,1,1")
7891    (set_attr "mode" "HI")
7892    (set_attr "pent_pair" "uv,np,uv")])
7894 (define_expand "testqi_ccz_1"
7895   [(set (reg:CCZ FLAGS_REG)
7896         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7897                              (match_operand:QI 1 "nonmemory_operand" ""))
7898                  (const_int 0)))]
7899   ""
7900   "")
7902 (define_insn "*testqi_1"
7903   [(set (reg FLAGS_REG)
7904         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7905                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7906                  (const_int 0)))]
7907   "ix86_match_ccmode (insn, CCNOmode)
7908    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7910   if (which_alternative == 3)
7911     {
7912       if (GET_CODE (operands[1]) == CONST_INT
7913           && (INTVAL (operands[1]) & 0xffffff00))
7914         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7915       return "test{l}\t{%1, %k0|%k0, %1}";
7916     }
7917   return "test{b}\t{%1, %0|%0, %1}";
7919   [(set_attr "type" "test")
7920    (set_attr "modrm" "0,1,1,1")
7921    (set_attr "mode" "QI,QI,QI,SI")
7922    (set_attr "pent_pair" "uv,np,uv,np")])
7924 (define_expand "testqi_ext_ccno_0"
7925   [(set (reg:CCNO FLAGS_REG)
7926         (compare:CCNO
7927           (and:SI
7928             (zero_extract:SI
7929               (match_operand 0 "ext_register_operand" "")
7930               (const_int 8)
7931               (const_int 8))
7932             (match_operand 1 "const_int_operand" ""))
7933           (const_int 0)))]
7934   ""
7935   "")
7937 (define_insn "*testqi_ext_0"
7938   [(set (reg 17)
7939         (compare
7940           (and:SI
7941             (zero_extract:SI
7942               (match_operand 0 "ext_register_operand" "Q")
7943               (const_int 8)
7944               (const_int 8))
7945             (match_operand 1 "const_int_operand" "n"))
7946           (const_int 0)))]
7947   "ix86_match_ccmode (insn, CCNOmode)"
7948   "test{b}\t{%1, %h0|%h0, %1}"
7949   [(set_attr "type" "test")
7950    (set_attr "mode" "QI")
7951    (set_attr "length_immediate" "1")
7952    (set_attr "pent_pair" "np")])
7954 (define_insn "*testqi_ext_1"
7955   [(set (reg 17)
7956         (compare
7957           (and:SI
7958             (zero_extract:SI
7959               (match_operand 0 "ext_register_operand" "Q")
7960               (const_int 8)
7961               (const_int 8))
7962             (zero_extend:SI
7963               (match_operand:QI 1 "general_operand" "Qm")))
7964           (const_int 0)))]
7965   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7966    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7967   "test{b}\t{%1, %h0|%h0, %1}"
7968   [(set_attr "type" "test")
7969    (set_attr "mode" "QI")])
7971 (define_insn "*testqi_ext_1_rex64"
7972   [(set (reg 17)
7973         (compare
7974           (and:SI
7975             (zero_extract:SI
7976               (match_operand 0 "ext_register_operand" "Q")
7977               (const_int 8)
7978               (const_int 8))
7979             (zero_extend:SI
7980               (match_operand:QI 1 "register_operand" "Q")))
7981           (const_int 0)))]
7982   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7983   "test{b}\t{%1, %h0|%h0, %1}"
7984   [(set_attr "type" "test")
7985    (set_attr "mode" "QI")])
7987 (define_insn "*testqi_ext_2"
7988   [(set (reg 17)
7989         (compare
7990           (and:SI
7991             (zero_extract:SI
7992               (match_operand 0 "ext_register_operand" "Q")
7993               (const_int 8)
7994               (const_int 8))
7995             (zero_extract:SI
7996               (match_operand 1 "ext_register_operand" "Q")
7997               (const_int 8)
7998               (const_int 8)))
7999           (const_int 0)))]
8000   "ix86_match_ccmode (insn, CCNOmode)"
8001   "test{b}\t{%h1, %h0|%h0, %h1}"
8002   [(set_attr "type" "test")
8003    (set_attr "mode" "QI")])
8005 ;; Combine likes to form bit extractions for some tests.  Humor it.
8006 (define_insn "*testqi_ext_3"
8007   [(set (reg 17)
8008         (compare (zero_extract:SI
8009                    (match_operand 0 "nonimmediate_operand" "rm")
8010                    (match_operand:SI 1 "const_int_operand" "")
8011                    (match_operand:SI 2 "const_int_operand" ""))
8012                  (const_int 0)))]
8013   "ix86_match_ccmode (insn, CCNOmode)
8014    && (GET_MODE (operands[0]) == SImode
8015        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8016        || GET_MODE (operands[0]) == HImode
8017        || GET_MODE (operands[0]) == QImode)"
8018   "#")
8020 (define_insn "*testqi_ext_3_rex64"
8021   [(set (reg 17)
8022         (compare (zero_extract:DI
8023                    (match_operand 0 "nonimmediate_operand" "rm")
8024                    (match_operand:DI 1 "const_int_operand" "")
8025                    (match_operand:DI 2 "const_int_operand" ""))
8026                  (const_int 0)))]
8027   "TARGET_64BIT
8028    && ix86_match_ccmode (insn, CCNOmode)
8029    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8030    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8031    /* Ensure that resulting mask is zero or sign extended operand.  */
8032    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8033        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8034            && INTVAL (operands[1]) > 32))
8035    && (GET_MODE (operands[0]) == SImode
8036        || GET_MODE (operands[0]) == DImode
8037        || GET_MODE (operands[0]) == HImode
8038        || GET_MODE (operands[0]) == QImode)"
8039   "#")
8041 (define_split
8042   [(set (reg 17)
8043         (compare (zero_extract
8044                    (match_operand 0 "nonimmediate_operand" "")
8045                    (match_operand 1 "const_int_operand" "")
8046                    (match_operand 2 "const_int_operand" ""))
8047                  (const_int 0)))]
8048   "ix86_match_ccmode (insn, CCNOmode)"
8049   [(set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
8051   HOST_WIDE_INT len = INTVAL (operands[1]);
8052   HOST_WIDE_INT pos = INTVAL (operands[2]);
8053   HOST_WIDE_INT mask;
8054   enum machine_mode mode, submode;
8056   mode = GET_MODE (operands[0]);
8057   if (GET_CODE (operands[0]) == MEM)
8058     {
8059       /* ??? Combine likes to put non-volatile mem extractions in QImode
8060          no matter the size of the test.  So find a mode that works.  */
8061       if (! MEM_VOLATILE_P (operands[0]))
8062         {
8063           mode = smallest_mode_for_size (pos + len, MODE_INT);
8064           operands[0] = adjust_address (operands[0], mode, 0);
8065         }
8066     }
8067   else if (GET_CODE (operands[0]) == SUBREG
8068            && (submode = GET_MODE (SUBREG_REG (operands[0])),
8069                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8070            && pos + len <= GET_MODE_BITSIZE (submode))
8071     {
8072       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8073       mode = submode;
8074       operands[0] = SUBREG_REG (operands[0]);
8075     }
8076   else if (mode == HImode && pos + len <= 8)
8077     {
8078       /* Small HImode tests can be converted to QImode.  */
8079       mode = QImode;
8080       operands[0] = gen_lowpart (QImode, operands[0]);
8081     }
8083   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8084   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8086   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8089 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8090 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8091 ;; this is relatively important trick.
8092 ;; Do the conversion only post-reload to avoid limiting of the register class
8093 ;; to QI regs.
8094 (define_split
8095   [(set (reg 17)
8096         (compare
8097           (and (match_operand 0 "register_operand" "")
8098                (match_operand 1 "const_int_operand" ""))
8099           (const_int 0)))]
8100    "reload_completed
8101     && QI_REG_P (operands[0])
8102     && ((ix86_match_ccmode (insn, CCZmode)
8103          && !(INTVAL (operands[1]) & ~(255 << 8)))
8104         || (ix86_match_ccmode (insn, CCNOmode)
8105             && !(INTVAL (operands[1]) & ~(127 << 8))))
8106     && GET_MODE (operands[0]) != QImode"
8107   [(set (reg:CCNO FLAGS_REG)
8108         (compare:CCNO
8109           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8110                   (match_dup 1))
8111           (const_int 0)))]
8112   "operands[0] = gen_lowpart (SImode, operands[0]);
8113    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8115 (define_split
8116   [(set (reg 17)
8117         (compare
8118           (and (match_operand 0 "nonimmediate_operand" "")
8119                (match_operand 1 "const_int_operand" ""))
8120           (const_int 0)))]
8121    "reload_completed
8122     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8123     && ((ix86_match_ccmode (insn, CCZmode)
8124          && !(INTVAL (operands[1]) & ~255))
8125         || (ix86_match_ccmode (insn, CCNOmode)
8126             && !(INTVAL (operands[1]) & ~127)))
8127     && GET_MODE (operands[0]) != QImode"
8128   [(set (reg:CCNO FLAGS_REG)
8129         (compare:CCNO
8130           (and:QI (match_dup 0)
8131                   (match_dup 1))
8132           (const_int 0)))]
8133   "operands[0] = gen_lowpart (QImode, operands[0]);
8134    operands[1] = gen_lowpart (QImode, operands[1]);")
8137 ;; %%% This used to optimize known byte-wide and operations to memory,
8138 ;; and sometimes to QImode registers.  If this is considered useful,
8139 ;; it should be done with splitters.
8141 (define_expand "anddi3"
8142   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8143         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8144                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8145    (clobber (reg:CC FLAGS_REG))]
8146   "TARGET_64BIT"
8147   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8149 (define_insn "*anddi_1_rex64"
8150   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8151         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8152                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8153    (clobber (reg:CC FLAGS_REG))]
8154   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8156   switch (get_attr_type (insn))
8157     {
8158     case TYPE_IMOVX:
8159       {
8160         enum machine_mode mode;
8162         if (GET_CODE (operands[2]) != CONST_INT)
8163           abort ();
8164         if (INTVAL (operands[2]) == 0xff)
8165           mode = QImode;
8166         else if (INTVAL (operands[2]) == 0xffff)
8167           mode = HImode;
8168         else
8169           abort ();
8170         
8171         operands[1] = gen_lowpart (mode, operands[1]);
8172         if (mode == QImode)
8173           return "movz{bq|x}\t{%1,%0|%0, %1}";
8174         else
8175           return "movz{wq|x}\t{%1,%0|%0, %1}";
8176       }
8178     default:
8179       if (! rtx_equal_p (operands[0], operands[1]))
8180         abort ();
8181       if (get_attr_mode (insn) == MODE_SI)
8182         return "and{l}\t{%k2, %k0|%k0, %k2}";
8183       else
8184         return "and{q}\t{%2, %0|%0, %2}";
8185     }
8187   [(set_attr "type" "alu,alu,alu,imovx")
8188    (set_attr "length_immediate" "*,*,*,0")
8189    (set_attr "mode" "SI,DI,DI,DI")])
8191 (define_insn "*anddi_2"
8192   [(set (reg 17)
8193         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8194                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8195                  (const_int 0)))
8196    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8197         (and:DI (match_dup 1) (match_dup 2)))]
8198   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8199    && ix86_binary_operator_ok (AND, DImode, operands)"
8200   "@
8201    and{l}\t{%k2, %k0|%k0, %k2}
8202    and{q}\t{%2, %0|%0, %2}
8203    and{q}\t{%2, %0|%0, %2}"
8204   [(set_attr "type" "alu")
8205    (set_attr "mode" "SI,DI,DI")])
8207 (define_expand "andsi3"
8208   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8209         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8210                 (match_operand:SI 2 "general_operand" "")))
8211    (clobber (reg:CC FLAGS_REG))]
8212   ""
8213   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8215 (define_insn "*andsi_1"
8216   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8217         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8218                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8219    (clobber (reg:CC FLAGS_REG))]
8220   "ix86_binary_operator_ok (AND, SImode, operands)"
8222   switch (get_attr_type (insn))
8223     {
8224     case TYPE_IMOVX:
8225       {
8226         enum machine_mode mode;
8228         if (GET_CODE (operands[2]) != CONST_INT)
8229           abort ();
8230         if (INTVAL (operands[2]) == 0xff)
8231           mode = QImode;
8232         else if (INTVAL (operands[2]) == 0xffff)
8233           mode = HImode;
8234         else
8235           abort ();
8236         
8237         operands[1] = gen_lowpart (mode, operands[1]);
8238         if (mode == QImode)
8239           return "movz{bl|x}\t{%1,%0|%0, %1}";
8240         else
8241           return "movz{wl|x}\t{%1,%0|%0, %1}";
8242       }
8244     default:
8245       if (! rtx_equal_p (operands[0], operands[1]))
8246         abort ();
8247       return "and{l}\t{%2, %0|%0, %2}";
8248     }
8250   [(set_attr "type" "alu,alu,imovx")
8251    (set_attr "length_immediate" "*,*,0")
8252    (set_attr "mode" "SI")])
8254 (define_split
8255   [(set (match_operand 0 "register_operand" "")
8256         (and (match_dup 0)
8257              (const_int -65536)))
8258    (clobber (reg:CC FLAGS_REG))]
8259   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8260   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8261   "operands[1] = gen_lowpart (HImode, operands[0]);")
8263 (define_split
8264   [(set (match_operand 0 "ext_register_operand" "")
8265         (and (match_dup 0)
8266              (const_int -256)))
8267    (clobber (reg:CC FLAGS_REG))]
8268   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8269   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8270   "operands[1] = gen_lowpart (QImode, operands[0]);")
8272 (define_split
8273   [(set (match_operand 0 "ext_register_operand" "")
8274         (and (match_dup 0)
8275              (const_int -65281)))
8276    (clobber (reg:CC FLAGS_REG))]
8277   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8278   [(parallel [(set (zero_extract:SI (match_dup 0)
8279                                     (const_int 8)
8280                                     (const_int 8))
8281                    (xor:SI 
8282                      (zero_extract:SI (match_dup 0)
8283                                       (const_int 8)
8284                                       (const_int 8))
8285                      (zero_extract:SI (match_dup 0)
8286                                       (const_int 8)
8287                                       (const_int 8))))
8288               (clobber (reg:CC FLAGS_REG))])]
8289   "operands[0] = gen_lowpart (SImode, operands[0]);")
8291 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8292 (define_insn "*andsi_1_zext"
8293   [(set (match_operand:DI 0 "register_operand" "=r")
8294         (zero_extend:DI
8295           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8296                   (match_operand:SI 2 "general_operand" "rim"))))
8297    (clobber (reg:CC FLAGS_REG))]
8298   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8299   "and{l}\t{%2, %k0|%k0, %2}"
8300   [(set_attr "type" "alu")
8301    (set_attr "mode" "SI")])
8303 (define_insn "*andsi_2"
8304   [(set (reg 17)
8305         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8306                          (match_operand:SI 2 "general_operand" "rim,ri"))
8307                  (const_int 0)))
8308    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8309         (and:SI (match_dup 1) (match_dup 2)))]
8310   "ix86_match_ccmode (insn, CCNOmode)
8311    && ix86_binary_operator_ok (AND, SImode, operands)"
8312   "and{l}\t{%2, %0|%0, %2}"
8313   [(set_attr "type" "alu")
8314    (set_attr "mode" "SI")])
8316 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8317 (define_insn "*andsi_2_zext"
8318   [(set (reg 17)
8319         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8320                          (match_operand:SI 2 "general_operand" "rim"))
8321                  (const_int 0)))
8322    (set (match_operand:DI 0 "register_operand" "=r")
8323         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8324   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8325    && ix86_binary_operator_ok (AND, SImode, operands)"
8326   "and{l}\t{%2, %k0|%k0, %2}"
8327   [(set_attr "type" "alu")
8328    (set_attr "mode" "SI")])
8330 (define_expand "andhi3"
8331   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8332         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8333                 (match_operand:HI 2 "general_operand" "")))
8334    (clobber (reg:CC FLAGS_REG))]
8335   "TARGET_HIMODE_MATH"
8336   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8338 (define_insn "*andhi_1"
8339   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8340         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8341                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8342    (clobber (reg:CC FLAGS_REG))]
8343   "ix86_binary_operator_ok (AND, HImode, operands)"
8345   switch (get_attr_type (insn))
8346     {
8347     case TYPE_IMOVX:
8348       if (GET_CODE (operands[2]) != CONST_INT)
8349         abort ();
8350       if (INTVAL (operands[2]) == 0xff)
8351         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8352       abort ();
8354     default:
8355       if (! rtx_equal_p (operands[0], operands[1]))
8356         abort ();
8358       return "and{w}\t{%2, %0|%0, %2}";
8359     }
8361   [(set_attr "type" "alu,alu,imovx")
8362    (set_attr "length_immediate" "*,*,0")
8363    (set_attr "mode" "HI,HI,SI")])
8365 (define_insn "*andhi_2"
8366   [(set (reg 17)
8367         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8368                          (match_operand:HI 2 "general_operand" "rim,ri"))
8369                  (const_int 0)))
8370    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8371         (and:HI (match_dup 1) (match_dup 2)))]
8372   "ix86_match_ccmode (insn, CCNOmode)
8373    && ix86_binary_operator_ok (AND, HImode, operands)"
8374   "and{w}\t{%2, %0|%0, %2}"
8375   [(set_attr "type" "alu")
8376    (set_attr "mode" "HI")])
8378 (define_expand "andqi3"
8379   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8380         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8381                 (match_operand:QI 2 "general_operand" "")))
8382    (clobber (reg:CC FLAGS_REG))]
8383   "TARGET_QIMODE_MATH"
8384   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8386 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8387 (define_insn "*andqi_1"
8388   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8389         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8390                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8391    (clobber (reg:CC FLAGS_REG))]
8392   "ix86_binary_operator_ok (AND, QImode, operands)"
8393   "@
8394    and{b}\t{%2, %0|%0, %2}
8395    and{b}\t{%2, %0|%0, %2}
8396    and{l}\t{%k2, %k0|%k0, %k2}"
8397   [(set_attr "type" "alu")
8398    (set_attr "mode" "QI,QI,SI")])
8400 (define_insn "*andqi_1_slp"
8401   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8402         (and:QI (match_dup 0)
8403                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8404    (clobber (reg:CC FLAGS_REG))]
8405   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8406    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8407   "and{b}\t{%1, %0|%0, %1}"
8408   [(set_attr "type" "alu1")
8409    (set_attr "mode" "QI")])
8411 (define_insn "*andqi_2"
8412   [(set (reg 17)
8413         (compare (and:QI
8414                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8415                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8416                  (const_int 0)))
8417    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8418         (and:QI (match_dup 1) (match_dup 2)))]
8419   "ix86_match_ccmode (insn, CCNOmode)
8420    && ix86_binary_operator_ok (AND, QImode, operands)"
8422   if (which_alternative == 2)
8423     {
8424       if (GET_CODE (operands[2]) == CONST_INT
8425           && (INTVAL (operands[2]) & 0xffffff00))
8426         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8427       return "and{l}\t{%2, %k0|%k0, %2}";
8428     }
8429   return "and{b}\t{%2, %0|%0, %2}";
8431   [(set_attr "type" "alu")
8432    (set_attr "mode" "QI,QI,SI")])
8434 (define_insn "*andqi_2_slp"
8435   [(set (reg 17)
8436         (compare (and:QI
8437                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8438                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8439                  (const_int 0)))
8440    (set (strict_low_part (match_dup 0))
8441         (and:QI (match_dup 0) (match_dup 1)))]
8442   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8443    && ix86_match_ccmode (insn, CCNOmode)
8444    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8445   "and{b}\t{%1, %0|%0, %1}"
8446   [(set_attr "type" "alu1")
8447    (set_attr "mode" "QI")])
8449 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8450 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8451 ;; for a QImode operand, which of course failed.
8453 (define_insn "andqi_ext_0"
8454   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8455                          (const_int 8)
8456                          (const_int 8))
8457         (and:SI 
8458           (zero_extract:SI
8459             (match_operand 1 "ext_register_operand" "0")
8460             (const_int 8)
8461             (const_int 8))
8462           (match_operand 2 "const_int_operand" "n")))
8463    (clobber (reg:CC FLAGS_REG))]
8464   ""
8465   "and{b}\t{%2, %h0|%h0, %2}"
8466   [(set_attr "type" "alu")
8467    (set_attr "length_immediate" "1")
8468    (set_attr "mode" "QI")])
8470 ;; Generated by peephole translating test to and.  This shows up
8471 ;; often in fp comparisons.
8473 (define_insn "*andqi_ext_0_cc"
8474   [(set (reg 17)
8475         (compare
8476           (and:SI
8477             (zero_extract:SI
8478               (match_operand 1 "ext_register_operand" "0")
8479               (const_int 8)
8480               (const_int 8))
8481             (match_operand 2 "const_int_operand" "n"))
8482           (const_int 0)))
8483    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8484                          (const_int 8)
8485                          (const_int 8))
8486         (and:SI 
8487           (zero_extract:SI
8488             (match_dup 1)
8489             (const_int 8)
8490             (const_int 8))
8491           (match_dup 2)))]
8492   "ix86_match_ccmode (insn, CCNOmode)"
8493   "and{b}\t{%2, %h0|%h0, %2}"
8494   [(set_attr "type" "alu")
8495    (set_attr "length_immediate" "1")
8496    (set_attr "mode" "QI")])
8498 (define_insn "*andqi_ext_1"
8499   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8500                          (const_int 8)
8501                          (const_int 8))
8502         (and:SI 
8503           (zero_extract:SI
8504             (match_operand 1 "ext_register_operand" "0")
8505             (const_int 8)
8506             (const_int 8))
8507           (zero_extend:SI
8508             (match_operand:QI 2 "general_operand" "Qm"))))
8509    (clobber (reg:CC FLAGS_REG))]
8510   "!TARGET_64BIT"
8511   "and{b}\t{%2, %h0|%h0, %2}"
8512   [(set_attr "type" "alu")
8513    (set_attr "length_immediate" "0")
8514    (set_attr "mode" "QI")])
8516 (define_insn "*andqi_ext_1_rex64"
8517   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8518                          (const_int 8)
8519                          (const_int 8))
8520         (and:SI 
8521           (zero_extract:SI
8522             (match_operand 1 "ext_register_operand" "0")
8523             (const_int 8)
8524             (const_int 8))
8525           (zero_extend:SI
8526             (match_operand 2 "ext_register_operand" "Q"))))
8527    (clobber (reg:CC FLAGS_REG))]
8528   "TARGET_64BIT"
8529   "and{b}\t{%2, %h0|%h0, %2}"
8530   [(set_attr "type" "alu")
8531    (set_attr "length_immediate" "0")
8532    (set_attr "mode" "QI")])
8534 (define_insn "*andqi_ext_2"
8535   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8536                          (const_int 8)
8537                          (const_int 8))
8538         (and:SI
8539           (zero_extract:SI
8540             (match_operand 1 "ext_register_operand" "%0")
8541             (const_int 8)
8542             (const_int 8))
8543           (zero_extract:SI
8544             (match_operand 2 "ext_register_operand" "Q")
8545             (const_int 8)
8546             (const_int 8))))
8547    (clobber (reg:CC FLAGS_REG))]
8548   ""
8549   "and{b}\t{%h2, %h0|%h0, %h2}"
8550   [(set_attr "type" "alu")
8551    (set_attr "length_immediate" "0")
8552    (set_attr "mode" "QI")])
8554 ;; Convert wide AND instructions with immediate operand to shorter QImode
8555 ;; equivalents when possible.
8556 ;; Don't do the splitting with memory operands, since it introduces risk
8557 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8558 ;; for size, but that can (should?) be handled by generic code instead.
8559 (define_split
8560   [(set (match_operand 0 "register_operand" "")
8561         (and (match_operand 1 "register_operand" "")
8562              (match_operand 2 "const_int_operand" "")))
8563    (clobber (reg:CC FLAGS_REG))]
8564    "reload_completed
8565     && QI_REG_P (operands[0])
8566     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8567     && !(~INTVAL (operands[2]) & ~(255 << 8))
8568     && GET_MODE (operands[0]) != QImode"
8569   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8570                    (and:SI (zero_extract:SI (match_dup 1)
8571                                             (const_int 8) (const_int 8))
8572                            (match_dup 2)))
8573               (clobber (reg:CC FLAGS_REG))])]
8574   "operands[0] = gen_lowpart (SImode, operands[0]);
8575    operands[1] = gen_lowpart (SImode, operands[1]);
8576    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8578 ;; Since AND can be encoded with sign extended immediate, this is only
8579 ;; profitable when 7th bit is not set.
8580 (define_split
8581   [(set (match_operand 0 "register_operand" "")
8582         (and (match_operand 1 "general_operand" "")
8583              (match_operand 2 "const_int_operand" "")))
8584    (clobber (reg:CC FLAGS_REG))]
8585    "reload_completed
8586     && ANY_QI_REG_P (operands[0])
8587     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8588     && !(~INTVAL (operands[2]) & ~255)
8589     && !(INTVAL (operands[2]) & 128)
8590     && GET_MODE (operands[0]) != QImode"
8591   [(parallel [(set (strict_low_part (match_dup 0))
8592                    (and:QI (match_dup 1)
8593                            (match_dup 2)))
8594               (clobber (reg:CC FLAGS_REG))])]
8595   "operands[0] = gen_lowpart (QImode, operands[0]);
8596    operands[1] = gen_lowpart (QImode, operands[1]);
8597    operands[2] = gen_lowpart (QImode, operands[2]);")
8599 ;; Logical inclusive OR instructions
8601 ;; %%% This used to optimize known byte-wide and operations to memory.
8602 ;; If this is considered useful, it should be done with splitters.
8604 (define_expand "iordi3"
8605   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8606         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8607                 (match_operand:DI 2 "x86_64_general_operand" "")))
8608    (clobber (reg:CC FLAGS_REG))]
8609   "TARGET_64BIT"
8610   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8612 (define_insn "*iordi_1_rex64"
8613   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8614         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8615                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8616    (clobber (reg:CC FLAGS_REG))]
8617   "TARGET_64BIT
8618    && ix86_binary_operator_ok (IOR, DImode, operands)"
8619   "or{q}\t{%2, %0|%0, %2}"
8620   [(set_attr "type" "alu")
8621    (set_attr "mode" "DI")])
8623 (define_insn "*iordi_2_rex64"
8624   [(set (reg 17)
8625         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8626                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8627                  (const_int 0)))
8628    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8629         (ior:DI (match_dup 1) (match_dup 2)))]
8630   "TARGET_64BIT
8631    && ix86_match_ccmode (insn, CCNOmode)
8632    && ix86_binary_operator_ok (IOR, DImode, operands)"
8633   "or{q}\t{%2, %0|%0, %2}"
8634   [(set_attr "type" "alu")
8635    (set_attr "mode" "DI")])
8637 (define_insn "*iordi_3_rex64"
8638   [(set (reg 17)
8639         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8640                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8641                  (const_int 0)))
8642    (clobber (match_scratch:DI 0 "=r"))]
8643   "TARGET_64BIT
8644    && ix86_match_ccmode (insn, CCNOmode)
8645    && ix86_binary_operator_ok (IOR, DImode, operands)"
8646   "or{q}\t{%2, %0|%0, %2}"
8647   [(set_attr "type" "alu")
8648    (set_attr "mode" "DI")])
8651 (define_expand "iorsi3"
8652   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8653         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8654                 (match_operand:SI 2 "general_operand" "")))
8655    (clobber (reg:CC FLAGS_REG))]
8656   ""
8657   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8659 (define_insn "*iorsi_1"
8660   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8661         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8662                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8663    (clobber (reg:CC FLAGS_REG))]
8664   "ix86_binary_operator_ok (IOR, SImode, operands)"
8665   "or{l}\t{%2, %0|%0, %2}"
8666   [(set_attr "type" "alu")
8667    (set_attr "mode" "SI")])
8669 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8670 (define_insn "*iorsi_1_zext"
8671   [(set (match_operand:DI 0 "register_operand" "=rm")
8672         (zero_extend:DI
8673           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8674                   (match_operand:SI 2 "general_operand" "rim"))))
8675    (clobber (reg:CC FLAGS_REG))]
8676   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8677   "or{l}\t{%2, %k0|%k0, %2}"
8678   [(set_attr "type" "alu")
8679    (set_attr "mode" "SI")])
8681 (define_insn "*iorsi_1_zext_imm"
8682   [(set (match_operand:DI 0 "register_operand" "=rm")
8683         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8684                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8685    (clobber (reg:CC FLAGS_REG))]
8686   "TARGET_64BIT"
8687   "or{l}\t{%2, %k0|%k0, %2}"
8688   [(set_attr "type" "alu")
8689    (set_attr "mode" "SI")])
8691 (define_insn "*iorsi_2"
8692   [(set (reg 17)
8693         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8694                          (match_operand:SI 2 "general_operand" "rim,ri"))
8695                  (const_int 0)))
8696    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8697         (ior:SI (match_dup 1) (match_dup 2)))]
8698   "ix86_match_ccmode (insn, CCNOmode)
8699    && ix86_binary_operator_ok (IOR, SImode, operands)"
8700   "or{l}\t{%2, %0|%0, %2}"
8701   [(set_attr "type" "alu")
8702    (set_attr "mode" "SI")])
8704 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8705 ;; ??? Special case for immediate operand is missing - it is tricky.
8706 (define_insn "*iorsi_2_zext"
8707   [(set (reg 17)
8708         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8709                          (match_operand:SI 2 "general_operand" "rim"))
8710                  (const_int 0)))
8711    (set (match_operand:DI 0 "register_operand" "=r")
8712         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8713   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8714    && ix86_binary_operator_ok (IOR, SImode, operands)"
8715   "or{l}\t{%2, %k0|%k0, %2}"
8716   [(set_attr "type" "alu")
8717    (set_attr "mode" "SI")])
8719 (define_insn "*iorsi_2_zext_imm"
8720   [(set (reg 17)
8721         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8722                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8723                  (const_int 0)))
8724    (set (match_operand:DI 0 "register_operand" "=r")
8725         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8726   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8727    && ix86_binary_operator_ok (IOR, SImode, operands)"
8728   "or{l}\t{%2, %k0|%k0, %2}"
8729   [(set_attr "type" "alu")
8730    (set_attr "mode" "SI")])
8732 (define_insn "*iorsi_3"
8733   [(set (reg 17)
8734         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8735                          (match_operand:SI 2 "general_operand" "rim"))
8736                  (const_int 0)))
8737    (clobber (match_scratch:SI 0 "=r"))]
8738   "ix86_match_ccmode (insn, CCNOmode)
8739    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8740   "or{l}\t{%2, %0|%0, %2}"
8741   [(set_attr "type" "alu")
8742    (set_attr "mode" "SI")])
8744 (define_expand "iorhi3"
8745   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8746         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8747                 (match_operand:HI 2 "general_operand" "")))
8748    (clobber (reg:CC FLAGS_REG))]
8749   "TARGET_HIMODE_MATH"
8750   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8752 (define_insn "*iorhi_1"
8753   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8754         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8755                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8756    (clobber (reg:CC FLAGS_REG))]
8757   "ix86_binary_operator_ok (IOR, HImode, operands)"
8758   "or{w}\t{%2, %0|%0, %2}"
8759   [(set_attr "type" "alu")
8760    (set_attr "mode" "HI")])
8762 (define_insn "*iorhi_2"
8763   [(set (reg 17)
8764         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8765                          (match_operand:HI 2 "general_operand" "rim,ri"))
8766                  (const_int 0)))
8767    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8768         (ior:HI (match_dup 1) (match_dup 2)))]
8769   "ix86_match_ccmode (insn, CCNOmode)
8770    && ix86_binary_operator_ok (IOR, HImode, operands)"
8771   "or{w}\t{%2, %0|%0, %2}"
8772   [(set_attr "type" "alu")
8773    (set_attr "mode" "HI")])
8775 (define_insn "*iorhi_3"
8776   [(set (reg 17)
8777         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8778                          (match_operand:HI 2 "general_operand" "rim"))
8779                  (const_int 0)))
8780    (clobber (match_scratch:HI 0 "=r"))]
8781   "ix86_match_ccmode (insn, CCNOmode)
8782    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8783   "or{w}\t{%2, %0|%0, %2}"
8784   [(set_attr "type" "alu")
8785    (set_attr "mode" "HI")])
8787 (define_expand "iorqi3"
8788   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8789         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8790                 (match_operand:QI 2 "general_operand" "")))
8791    (clobber (reg:CC FLAGS_REG))]
8792   "TARGET_QIMODE_MATH"
8793   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8795 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8796 (define_insn "*iorqi_1"
8797   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8798         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8799                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8800    (clobber (reg:CC FLAGS_REG))]
8801   "ix86_binary_operator_ok (IOR, QImode, operands)"
8802   "@
8803    or{b}\t{%2, %0|%0, %2}
8804    or{b}\t{%2, %0|%0, %2}
8805    or{l}\t{%k2, %k0|%k0, %k2}"
8806   [(set_attr "type" "alu")
8807    (set_attr "mode" "QI,QI,SI")])
8809 (define_insn "*iorqi_1_slp"
8810   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8811         (ior:QI (match_dup 0)
8812                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8813    (clobber (reg:CC FLAGS_REG))]
8814   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8815    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8816   "or{b}\t{%1, %0|%0, %1}"
8817   [(set_attr "type" "alu1")
8818    (set_attr "mode" "QI")])
8820 (define_insn "*iorqi_2"
8821   [(set (reg 17)
8822         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8823                          (match_operand:QI 2 "general_operand" "qim,qi"))
8824                  (const_int 0)))
8825    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8826         (ior:QI (match_dup 1) (match_dup 2)))]
8827   "ix86_match_ccmode (insn, CCNOmode)
8828    && ix86_binary_operator_ok (IOR, QImode, operands)"
8829   "or{b}\t{%2, %0|%0, %2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "mode" "QI")])
8833 (define_insn "*iorqi_2_slp"
8834   [(set (reg 17)
8835         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8836                          (match_operand:QI 1 "general_operand" "qim,qi"))
8837                  (const_int 0)))
8838    (set (strict_low_part (match_dup 0))
8839         (ior:QI (match_dup 0) (match_dup 1)))]
8840   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8841    && ix86_match_ccmode (insn, CCNOmode)
8842    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8843   "or{b}\t{%1, %0|%0, %1}"
8844   [(set_attr "type" "alu1")
8845    (set_attr "mode" "QI")])
8847 (define_insn "*iorqi_3"
8848   [(set (reg 17)
8849         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8850                          (match_operand:QI 2 "general_operand" "qim"))
8851                  (const_int 0)))
8852    (clobber (match_scratch:QI 0 "=q"))]
8853   "ix86_match_ccmode (insn, CCNOmode)
8854    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8855   "or{b}\t{%2, %0|%0, %2}"
8856   [(set_attr "type" "alu")
8857    (set_attr "mode" "QI")])
8859 (define_insn "iorqi_ext_0"
8860   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8861                          (const_int 8)
8862                          (const_int 8))
8863         (ior:SI 
8864           (zero_extract:SI
8865             (match_operand 1 "ext_register_operand" "0")
8866             (const_int 8)
8867             (const_int 8))
8868           (match_operand 2 "const_int_operand" "n")))
8869    (clobber (reg:CC FLAGS_REG))]
8870   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8871   "or{b}\t{%2, %h0|%h0, %2}"
8872   [(set_attr "type" "alu")
8873    (set_attr "length_immediate" "1")
8874    (set_attr "mode" "QI")])
8876 (define_insn "*iorqi_ext_1"
8877   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8878                          (const_int 8)
8879                          (const_int 8))
8880         (ior:SI 
8881           (zero_extract:SI
8882             (match_operand 1 "ext_register_operand" "0")
8883             (const_int 8)
8884             (const_int 8))
8885           (zero_extend:SI
8886             (match_operand:QI 2 "general_operand" "Qm"))))
8887    (clobber (reg:CC FLAGS_REG))]
8888   "!TARGET_64BIT
8889    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8890   "or{b}\t{%2, %h0|%h0, %2}"
8891   [(set_attr "type" "alu")
8892    (set_attr "length_immediate" "0")
8893    (set_attr "mode" "QI")])
8895 (define_insn "*iorqi_ext_1_rex64"
8896   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8897                          (const_int 8)
8898                          (const_int 8))
8899         (ior:SI 
8900           (zero_extract:SI
8901             (match_operand 1 "ext_register_operand" "0")
8902             (const_int 8)
8903             (const_int 8))
8904           (zero_extend:SI
8905             (match_operand 2 "ext_register_operand" "Q"))))
8906    (clobber (reg:CC FLAGS_REG))]
8907   "TARGET_64BIT
8908    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8909   "or{b}\t{%2, %h0|%h0, %2}"
8910   [(set_attr "type" "alu")
8911    (set_attr "length_immediate" "0")
8912    (set_attr "mode" "QI")])
8914 (define_insn "*iorqi_ext_2"
8915   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8916                          (const_int 8)
8917                          (const_int 8))
8918         (ior:SI 
8919           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8920                            (const_int 8)
8921                            (const_int 8))
8922           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8923                            (const_int 8)
8924                            (const_int 8))))
8925    (clobber (reg:CC FLAGS_REG))]
8926   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8927   "ior{b}\t{%h2, %h0|%h0, %h2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "length_immediate" "0")
8930    (set_attr "mode" "QI")])
8932 (define_split
8933   [(set (match_operand 0 "register_operand" "")
8934         (ior (match_operand 1 "register_operand" "")
8935              (match_operand 2 "const_int_operand" "")))
8936    (clobber (reg:CC FLAGS_REG))]
8937    "reload_completed
8938     && QI_REG_P (operands[0])
8939     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8940     && !(INTVAL (operands[2]) & ~(255 << 8))
8941     && GET_MODE (operands[0]) != QImode"
8942   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8943                    (ior:SI (zero_extract:SI (match_dup 1)
8944                                             (const_int 8) (const_int 8))
8945                            (match_dup 2)))
8946               (clobber (reg:CC FLAGS_REG))])]
8947   "operands[0] = gen_lowpart (SImode, operands[0]);
8948    operands[1] = gen_lowpart (SImode, operands[1]);
8949    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8951 ;; Since OR can be encoded with sign extended immediate, this is only
8952 ;; profitable when 7th bit is set.
8953 (define_split
8954   [(set (match_operand 0 "register_operand" "")
8955         (ior (match_operand 1 "general_operand" "")
8956              (match_operand 2 "const_int_operand" "")))
8957    (clobber (reg:CC FLAGS_REG))]
8958    "reload_completed
8959     && ANY_QI_REG_P (operands[0])
8960     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8961     && !(INTVAL (operands[2]) & ~255)
8962     && (INTVAL (operands[2]) & 128)
8963     && GET_MODE (operands[0]) != QImode"
8964   [(parallel [(set (strict_low_part (match_dup 0))
8965                    (ior:QI (match_dup 1)
8966                            (match_dup 2)))
8967               (clobber (reg:CC FLAGS_REG))])]
8968   "operands[0] = gen_lowpart (QImode, operands[0]);
8969    operands[1] = gen_lowpart (QImode, operands[1]);
8970    operands[2] = gen_lowpart (QImode, operands[2]);")
8972 ;; Logical XOR instructions
8974 ;; %%% This used to optimize known byte-wide and operations to memory.
8975 ;; If this is considered useful, it should be done with splitters.
8977 (define_expand "xordi3"
8978   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8979         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8980                 (match_operand:DI 2 "x86_64_general_operand" "")))
8981    (clobber (reg:CC FLAGS_REG))]
8982   "TARGET_64BIT"
8983   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8985 (define_insn "*xordi_1_rex64"
8986   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8987         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8988                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   "TARGET_64BIT
8991    && ix86_binary_operator_ok (XOR, DImode, operands)"
8992   "@
8993    xor{q}\t{%2, %0|%0, %2}
8994    xor{q}\t{%2, %0|%0, %2}"
8995   [(set_attr "type" "alu")
8996    (set_attr "mode" "DI,DI")])
8998 (define_insn "*xordi_2_rex64"
8999   [(set (reg 17)
9000         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9001                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9002                  (const_int 0)))
9003    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9004         (xor:DI (match_dup 1) (match_dup 2)))]
9005   "TARGET_64BIT
9006    && ix86_match_ccmode (insn, CCNOmode)
9007    && ix86_binary_operator_ok (XOR, DImode, operands)"
9008   "@
9009    xor{q}\t{%2, %0|%0, %2}
9010    xor{q}\t{%2, %0|%0, %2}"
9011   [(set_attr "type" "alu")
9012    (set_attr "mode" "DI,DI")])
9014 (define_insn "*xordi_3_rex64"
9015   [(set (reg 17)
9016         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9017                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9018                  (const_int 0)))
9019    (clobber (match_scratch:DI 0 "=r"))]
9020   "TARGET_64BIT
9021    && ix86_match_ccmode (insn, CCNOmode)
9022    && ix86_binary_operator_ok (XOR, DImode, operands)"
9023   "xor{q}\t{%2, %0|%0, %2}"
9024   [(set_attr "type" "alu")
9025    (set_attr "mode" "DI")])
9027 (define_expand "xorsi3"
9028   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9029         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9030                 (match_operand:SI 2 "general_operand" "")))
9031    (clobber (reg:CC FLAGS_REG))]
9032   ""
9033   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9035 (define_insn "*xorsi_1"
9036   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9037         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9038                 (match_operand:SI 2 "general_operand" "ri,rm")))
9039    (clobber (reg:CC FLAGS_REG))]
9040   "ix86_binary_operator_ok (XOR, SImode, operands)"
9041   "xor{l}\t{%2, %0|%0, %2}"
9042   [(set_attr "type" "alu")
9043    (set_attr "mode" "SI")])
9045 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9046 ;; Add speccase for immediates
9047 (define_insn "*xorsi_1_zext"
9048   [(set (match_operand:DI 0 "register_operand" "=r")
9049         (zero_extend:DI
9050           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9051                   (match_operand:SI 2 "general_operand" "rim"))))
9052    (clobber (reg:CC FLAGS_REG))]
9053   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9054   "xor{l}\t{%2, %k0|%k0, %2}"
9055   [(set_attr "type" "alu")
9056    (set_attr "mode" "SI")])
9058 (define_insn "*xorsi_1_zext_imm"
9059   [(set (match_operand:DI 0 "register_operand" "=r")
9060         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9061                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9062    (clobber (reg:CC FLAGS_REG))]
9063   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9064   "xor{l}\t{%2, %k0|%k0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "mode" "SI")])
9068 (define_insn "*xorsi_2"
9069   [(set (reg 17)
9070         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9071                          (match_operand:SI 2 "general_operand" "rim,ri"))
9072                  (const_int 0)))
9073    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9074         (xor:SI (match_dup 1) (match_dup 2)))]
9075   "ix86_match_ccmode (insn, CCNOmode)
9076    && ix86_binary_operator_ok (XOR, SImode, operands)"
9077   "xor{l}\t{%2, %0|%0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "mode" "SI")])
9081 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9082 ;; ??? Special case for immediate operand is missing - it is tricky.
9083 (define_insn "*xorsi_2_zext"
9084   [(set (reg 17)
9085         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9086                          (match_operand:SI 2 "general_operand" "rim"))
9087                  (const_int 0)))
9088    (set (match_operand:DI 0 "register_operand" "=r")
9089         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9090   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9091    && ix86_binary_operator_ok (XOR, SImode, operands)"
9092   "xor{l}\t{%2, %k0|%k0, %2}"
9093   [(set_attr "type" "alu")
9094    (set_attr "mode" "SI")])
9096 (define_insn "*xorsi_2_zext_imm"
9097   [(set (reg 17)
9098         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9099                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9100                  (const_int 0)))
9101    (set (match_operand:DI 0 "register_operand" "=r")
9102         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9103   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9104    && ix86_binary_operator_ok (XOR, SImode, operands)"
9105   "xor{l}\t{%2, %k0|%k0, %2}"
9106   [(set_attr "type" "alu")
9107    (set_attr "mode" "SI")])
9109 (define_insn "*xorsi_3"
9110   [(set (reg 17)
9111         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9112                          (match_operand:SI 2 "general_operand" "rim"))
9113                  (const_int 0)))
9114    (clobber (match_scratch:SI 0 "=r"))]
9115   "ix86_match_ccmode (insn, CCNOmode)
9116    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9117   "xor{l}\t{%2, %0|%0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "mode" "SI")])
9121 (define_expand "xorhi3"
9122   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9123         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9124                 (match_operand:HI 2 "general_operand" "")))
9125    (clobber (reg:CC FLAGS_REG))]
9126   "TARGET_HIMODE_MATH"
9127   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9129 (define_insn "*xorhi_1"
9130   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9131         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9132                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9133    (clobber (reg:CC FLAGS_REG))]
9134   "ix86_binary_operator_ok (XOR, HImode, operands)"
9135   "xor{w}\t{%2, %0|%0, %2}"
9136   [(set_attr "type" "alu")
9137    (set_attr "mode" "HI")])
9139 (define_insn "*xorhi_2"
9140   [(set (reg 17)
9141         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9142                          (match_operand:HI 2 "general_operand" "rim,ri"))
9143                  (const_int 0)))
9144    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9145         (xor:HI (match_dup 1) (match_dup 2)))]
9146   "ix86_match_ccmode (insn, CCNOmode)
9147    && ix86_binary_operator_ok (XOR, HImode, operands)"
9148   "xor{w}\t{%2, %0|%0, %2}"
9149   [(set_attr "type" "alu")
9150    (set_attr "mode" "HI")])
9152 (define_insn "*xorhi_3"
9153   [(set (reg 17)
9154         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9155                          (match_operand:HI 2 "general_operand" "rim"))
9156                  (const_int 0)))
9157    (clobber (match_scratch:HI 0 "=r"))]
9158   "ix86_match_ccmode (insn, CCNOmode)
9159    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9160   "xor{w}\t{%2, %0|%0, %2}"
9161   [(set_attr "type" "alu")
9162    (set_attr "mode" "HI")])
9164 (define_expand "xorqi3"
9165   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9166         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9167                 (match_operand:QI 2 "general_operand" "")))
9168    (clobber (reg:CC FLAGS_REG))]
9169   "TARGET_QIMODE_MATH"
9170   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9172 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9173 (define_insn "*xorqi_1"
9174   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9175         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9176                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9177    (clobber (reg:CC FLAGS_REG))]
9178   "ix86_binary_operator_ok (XOR, QImode, operands)"
9179   "@
9180    xor{b}\t{%2, %0|%0, %2}
9181    xor{b}\t{%2, %0|%0, %2}
9182    xor{l}\t{%k2, %k0|%k0, %k2}"
9183   [(set_attr "type" "alu")
9184    (set_attr "mode" "QI,QI,SI")])
9186 (define_insn "*xorqi_1_slp"
9187   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9188         (xor:QI (match_dup 0)
9189                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9190    (clobber (reg:CC FLAGS_REG))]
9191   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9192    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9193   "xor{b}\t{%1, %0|%0, %1}"
9194   [(set_attr "type" "alu1")
9195    (set_attr "mode" "QI")])
9197 (define_insn "xorqi_ext_0"
9198   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9199                          (const_int 8)
9200                          (const_int 8))
9201         (xor:SI 
9202           (zero_extract:SI
9203             (match_operand 1 "ext_register_operand" "0")
9204             (const_int 8)
9205             (const_int 8))
9206           (match_operand 2 "const_int_operand" "n")))
9207    (clobber (reg:CC FLAGS_REG))]
9208   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9209   "xor{b}\t{%2, %h0|%h0, %2}"
9210   [(set_attr "type" "alu")
9211    (set_attr "length_immediate" "1")
9212    (set_attr "mode" "QI")])
9214 (define_insn "*xorqi_ext_1"
9215   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9216                          (const_int 8)
9217                          (const_int 8))
9218         (xor:SI 
9219           (zero_extract:SI
9220             (match_operand 1 "ext_register_operand" "0")
9221             (const_int 8)
9222             (const_int 8))
9223           (zero_extend:SI
9224             (match_operand:QI 2 "general_operand" "Qm"))))
9225    (clobber (reg:CC FLAGS_REG))]
9226   "!TARGET_64BIT
9227    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9228   "xor{b}\t{%2, %h0|%h0, %2}"
9229   [(set_attr "type" "alu")
9230    (set_attr "length_immediate" "0")
9231    (set_attr "mode" "QI")])
9233 (define_insn "*xorqi_ext_1_rex64"
9234   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9235                          (const_int 8)
9236                          (const_int 8))
9237         (xor:SI 
9238           (zero_extract:SI
9239             (match_operand 1 "ext_register_operand" "0")
9240             (const_int 8)
9241             (const_int 8))
9242           (zero_extend:SI
9243             (match_operand 2 "ext_register_operand" "Q"))))
9244    (clobber (reg:CC FLAGS_REG))]
9245   "TARGET_64BIT
9246    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9247   "xor{b}\t{%2, %h0|%h0, %2}"
9248   [(set_attr "type" "alu")
9249    (set_attr "length_immediate" "0")
9250    (set_attr "mode" "QI")])
9252 (define_insn "*xorqi_ext_2"
9253   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9254                          (const_int 8)
9255                          (const_int 8))
9256         (xor:SI 
9257           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9258                            (const_int 8)
9259                            (const_int 8))
9260           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9261                            (const_int 8)
9262                            (const_int 8))))
9263    (clobber (reg:CC FLAGS_REG))]
9264   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9265   "xor{b}\t{%h2, %h0|%h0, %h2}"
9266   [(set_attr "type" "alu")
9267    (set_attr "length_immediate" "0")
9268    (set_attr "mode" "QI")])
9270 (define_insn "*xorqi_cc_1"
9271   [(set (reg 17)
9272         (compare
9273           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9274                   (match_operand:QI 2 "general_operand" "qim,qi"))
9275           (const_int 0)))
9276    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9277         (xor:QI (match_dup 1) (match_dup 2)))]
9278   "ix86_match_ccmode (insn, CCNOmode)
9279    && ix86_binary_operator_ok (XOR, QImode, operands)"
9280   "xor{b}\t{%2, %0|%0, %2}"
9281   [(set_attr "type" "alu")
9282    (set_attr "mode" "QI")])
9284 (define_insn "*xorqi_2_slp"
9285   [(set (reg 17)
9286         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9287                          (match_operand:QI 1 "general_operand" "qim,qi"))
9288                  (const_int 0)))
9289    (set (strict_low_part (match_dup 0))
9290         (xor:QI (match_dup 0) (match_dup 1)))]
9291   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9292    && ix86_match_ccmode (insn, CCNOmode)
9293    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9294   "xor{b}\t{%1, %0|%0, %1}"
9295   [(set_attr "type" "alu1")
9296    (set_attr "mode" "QI")])
9298 (define_insn "*xorqi_cc_2"
9299   [(set (reg 17)
9300         (compare
9301           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9302                   (match_operand:QI 2 "general_operand" "qim"))
9303           (const_int 0)))
9304    (clobber (match_scratch:QI 0 "=q"))]
9305   "ix86_match_ccmode (insn, CCNOmode)
9306    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9307   "xor{b}\t{%2, %0|%0, %2}"
9308   [(set_attr "type" "alu")
9309    (set_attr "mode" "QI")])
9311 (define_insn "*xorqi_cc_ext_1"
9312   [(set (reg 17)
9313         (compare
9314           (xor:SI
9315             (zero_extract:SI
9316               (match_operand 1 "ext_register_operand" "0")
9317               (const_int 8)
9318               (const_int 8))
9319             (match_operand:QI 2 "general_operand" "qmn"))
9320           (const_int 0)))
9321    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9322                          (const_int 8)
9323                          (const_int 8))
9324         (xor:SI 
9325           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9326           (match_dup 2)))]
9327   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9328   "xor{b}\t{%2, %h0|%h0, %2}"
9329   [(set_attr "type" "alu")
9330    (set_attr "mode" "QI")])
9332 (define_insn "*xorqi_cc_ext_1_rex64"
9333   [(set (reg 17)
9334         (compare
9335           (xor:SI
9336             (zero_extract:SI
9337               (match_operand 1 "ext_register_operand" "0")
9338               (const_int 8)
9339               (const_int 8))
9340             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9341           (const_int 0)))
9342    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9343                          (const_int 8)
9344                          (const_int 8))
9345         (xor:SI 
9346           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9347           (match_dup 2)))]
9348   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9349   "xor{b}\t{%2, %h0|%h0, %2}"
9350   [(set_attr "type" "alu")
9351    (set_attr "mode" "QI")])
9353 (define_expand "xorqi_cc_ext_1"
9354   [(parallel [
9355      (set (reg:CCNO FLAGS_REG)
9356           (compare:CCNO
9357             (xor:SI
9358               (zero_extract:SI
9359                 (match_operand 1 "ext_register_operand" "")
9360                 (const_int 8)
9361                 (const_int 8))
9362               (match_operand:QI 2 "general_operand" ""))
9363             (const_int 0)))
9364      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9365                            (const_int 8)
9366                            (const_int 8))
9367           (xor:SI 
9368             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9369             (match_dup 2)))])]
9370   ""
9371   "")
9373 (define_split
9374   [(set (match_operand 0 "register_operand" "")
9375         (xor (match_operand 1 "register_operand" "")
9376              (match_operand 2 "const_int_operand" "")))
9377    (clobber (reg:CC FLAGS_REG))]
9378    "reload_completed
9379     && QI_REG_P (operands[0])
9380     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9381     && !(INTVAL (operands[2]) & ~(255 << 8))
9382     && GET_MODE (operands[0]) != QImode"
9383   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9384                    (xor:SI (zero_extract:SI (match_dup 1)
9385                                             (const_int 8) (const_int 8))
9386                            (match_dup 2)))
9387               (clobber (reg:CC FLAGS_REG))])]
9388   "operands[0] = gen_lowpart (SImode, operands[0]);
9389    operands[1] = gen_lowpart (SImode, operands[1]);
9390    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9392 ;; Since XOR can be encoded with sign extended immediate, this is only
9393 ;; profitable when 7th bit is set.
9394 (define_split
9395   [(set (match_operand 0 "register_operand" "")
9396         (xor (match_operand 1 "general_operand" "")
9397              (match_operand 2 "const_int_operand" "")))
9398    (clobber (reg:CC FLAGS_REG))]
9399    "reload_completed
9400     && ANY_QI_REG_P (operands[0])
9401     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9402     && !(INTVAL (operands[2]) & ~255)
9403     && (INTVAL (operands[2]) & 128)
9404     && GET_MODE (operands[0]) != QImode"
9405   [(parallel [(set (strict_low_part (match_dup 0))
9406                    (xor:QI (match_dup 1)
9407                            (match_dup 2)))
9408               (clobber (reg:CC FLAGS_REG))])]
9409   "operands[0] = gen_lowpart (QImode, operands[0]);
9410    operands[1] = gen_lowpart (QImode, operands[1]);
9411    operands[2] = gen_lowpart (QImode, operands[2]);")
9413 ;; Negation instructions
9415 (define_expand "negdi2"
9416   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9417                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9418               (clobber (reg:CC FLAGS_REG))])]
9419   ""
9420   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9422 (define_insn "*negdi2_1"
9423   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9424         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9425    (clobber (reg:CC FLAGS_REG))]
9426   "!TARGET_64BIT
9427    && ix86_unary_operator_ok (NEG, DImode, operands)"
9428   "#")
9430 (define_split
9431   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9432         (neg:DI (match_operand:DI 1 "general_operand" "")))
9433    (clobber (reg:CC FLAGS_REG))]
9434   "!TARGET_64BIT && reload_completed"
9435   [(parallel
9436     [(set (reg:CCZ FLAGS_REG)
9437           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9438      (set (match_dup 0) (neg:SI (match_dup 2)))])
9439    (parallel
9440     [(set (match_dup 1)
9441           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9442                             (match_dup 3))
9443                    (const_int 0)))
9444      (clobber (reg:CC FLAGS_REG))])
9445    (parallel
9446     [(set (match_dup 1)
9447           (neg:SI (match_dup 1)))
9448      (clobber (reg:CC FLAGS_REG))])]
9449   "split_di (operands+1, 1, operands+2, operands+3);
9450    split_di (operands+0, 1, operands+0, operands+1);")
9452 (define_insn "*negdi2_1_rex64"
9453   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9454         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9455    (clobber (reg:CC FLAGS_REG))]
9456   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9457   "neg{q}\t%0"
9458   [(set_attr "type" "negnot")
9459    (set_attr "mode" "DI")])
9461 ;; The problem with neg is that it does not perform (compare x 0),
9462 ;; it really performs (compare 0 x), which leaves us with the zero
9463 ;; flag being the only useful item.
9465 (define_insn "*negdi2_cmpz_rex64"
9466   [(set (reg:CCZ FLAGS_REG)
9467         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9468                      (const_int 0)))
9469    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9470         (neg:DI (match_dup 1)))]
9471   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9472   "neg{q}\t%0"
9473   [(set_attr "type" "negnot")
9474    (set_attr "mode" "DI")])
9477 (define_expand "negsi2"
9478   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9479                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9480               (clobber (reg:CC FLAGS_REG))])]
9481   ""
9482   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9484 (define_insn "*negsi2_1"
9485   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9486         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9487    (clobber (reg:CC FLAGS_REG))]
9488   "ix86_unary_operator_ok (NEG, SImode, operands)"
9489   "neg{l}\t%0"
9490   [(set_attr "type" "negnot")
9491    (set_attr "mode" "SI")])
9493 ;; Combine is quite creative about this pattern.
9494 (define_insn "*negsi2_1_zext"
9495   [(set (match_operand:DI 0 "register_operand" "=r")
9496         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9497                                         (const_int 32)))
9498                      (const_int 32)))
9499    (clobber (reg:CC FLAGS_REG))]
9500   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9501   "neg{l}\t%k0"
9502   [(set_attr "type" "negnot")
9503    (set_attr "mode" "SI")])
9505 ;; The problem with neg is that it does not perform (compare x 0),
9506 ;; it really performs (compare 0 x), which leaves us with the zero
9507 ;; flag being the only useful item.
9509 (define_insn "*negsi2_cmpz"
9510   [(set (reg:CCZ FLAGS_REG)
9511         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9512                      (const_int 0)))
9513    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9514         (neg:SI (match_dup 1)))]
9515   "ix86_unary_operator_ok (NEG, SImode, operands)"
9516   "neg{l}\t%0"
9517   [(set_attr "type" "negnot")
9518    (set_attr "mode" "SI")])
9520 (define_insn "*negsi2_cmpz_zext"
9521   [(set (reg:CCZ FLAGS_REG)
9522         (compare:CCZ (lshiftrt:DI
9523                        (neg:DI (ashift:DI
9524                                  (match_operand:DI 1 "register_operand" "0")
9525                                  (const_int 32)))
9526                        (const_int 32))
9527                      (const_int 0)))
9528    (set (match_operand:DI 0 "register_operand" "=r")
9529         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9530                                         (const_int 32)))
9531                      (const_int 32)))]
9532   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9533   "neg{l}\t%k0"
9534   [(set_attr "type" "negnot")
9535    (set_attr "mode" "SI")])
9537 (define_expand "neghi2"
9538   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9539                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9540               (clobber (reg:CC FLAGS_REG))])]
9541   "TARGET_HIMODE_MATH"
9542   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9544 (define_insn "*neghi2_1"
9545   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9546         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9547    (clobber (reg:CC FLAGS_REG))]
9548   "ix86_unary_operator_ok (NEG, HImode, operands)"
9549   "neg{w}\t%0"
9550   [(set_attr "type" "negnot")
9551    (set_attr "mode" "HI")])
9553 (define_insn "*neghi2_cmpz"
9554   [(set (reg:CCZ FLAGS_REG)
9555         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9556                      (const_int 0)))
9557    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9558         (neg:HI (match_dup 1)))]
9559   "ix86_unary_operator_ok (NEG, HImode, operands)"
9560   "neg{w}\t%0"
9561   [(set_attr "type" "negnot")
9562    (set_attr "mode" "HI")])
9564 (define_expand "negqi2"
9565   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9566                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9567               (clobber (reg:CC FLAGS_REG))])]
9568   "TARGET_QIMODE_MATH"
9569   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9571 (define_insn "*negqi2_1"
9572   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9573         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9574    (clobber (reg:CC FLAGS_REG))]
9575   "ix86_unary_operator_ok (NEG, QImode, operands)"
9576   "neg{b}\t%0"
9577   [(set_attr "type" "negnot")
9578    (set_attr "mode" "QI")])
9580 (define_insn "*negqi2_cmpz"
9581   [(set (reg:CCZ FLAGS_REG)
9582         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9583                      (const_int 0)))
9584    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9585         (neg:QI (match_dup 1)))]
9586   "ix86_unary_operator_ok (NEG, QImode, operands)"
9587   "neg{b}\t%0"
9588   [(set_attr "type" "negnot")
9589    (set_attr "mode" "QI")])
9591 ;; Changing of sign for FP values is doable using integer unit too.
9593 (define_expand "negsf2"
9594   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9595                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9596               (clobber (reg:CC FLAGS_REG))])]
9597   "TARGET_80387"
9598   "if (TARGET_SSE)
9599      {
9600        /* In case operand is in memory,  we will not use SSE.  */
9601        if (memory_operand (operands[0], VOIDmode)
9602            && rtx_equal_p (operands[0], operands[1]))
9603          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9604        else
9605         {
9606           /* Using SSE is tricky, since we need bitwise negation of -0
9607              in register.  */
9608           rtx reg = gen_reg_rtx (SFmode);
9609           rtx dest = operands[0];
9610           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9612           operands[1] = force_reg (SFmode, operands[1]);
9613           operands[0] = force_reg (SFmode, operands[0]);
9614           reg = force_reg (V4SFmode,
9615                            gen_rtx_CONST_VECTOR (V4SFmode,
9616                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9617                                         CONST0_RTX (SFmode),
9618                                         CONST0_RTX (SFmode))));
9619           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9620           if (dest != operands[0])
9621             emit_move_insn (dest, operands[0]);
9622         }
9623        DONE;
9624      }
9625    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9627 (define_insn "negsf2_memory"
9628   [(set (match_operand:SF 0 "memory_operand" "=m")
9629         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9630    (clobber (reg:CC FLAGS_REG))]
9631   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9632   "#")
9634 (define_insn "negsf2_ifs"
9635   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9636         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9637    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9638    (clobber (reg:CC FLAGS_REG))]
9639   "TARGET_SSE
9640    && (reload_in_progress || reload_completed
9641        || (register_operand (operands[0], VOIDmode)
9642            && register_operand (operands[1], VOIDmode)))"
9643   "#")
9645 (define_split
9646   [(set (match_operand:SF 0 "memory_operand" "")
9647         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9648    (use (match_operand:SF 2 "" ""))
9649    (clobber (reg:CC FLAGS_REG))]
9650   ""
9651   [(parallel [(set (match_dup 0)
9652                    (neg:SF (match_dup 1)))
9653               (clobber (reg:CC FLAGS_REG))])])
9655 (define_split
9656   [(set (match_operand:SF 0 "register_operand" "")
9657         (neg:SF (match_operand:SF 1 "register_operand" "")))
9658    (use (match_operand:V4SF 2 "" ""))
9659    (clobber (reg:CC FLAGS_REG))]
9660   "reload_completed && !SSE_REG_P (operands[0])"
9661   [(parallel [(set (match_dup 0)
9662                    (neg:SF (match_dup 1)))
9663               (clobber (reg:CC FLAGS_REG))])])
9665 (define_split
9666   [(set (match_operand:SF 0 "register_operand" "")
9667         (neg:SF (match_operand:SF 1 "register_operand" "")))
9668    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9669    (clobber (reg:CC FLAGS_REG))]
9670   "reload_completed && SSE_REG_P (operands[0])"
9671   [(set (match_dup 0)
9672         (xor:V4SF (match_dup 1)
9673                   (match_dup 2)))]
9675   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9676   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9677   if (operands_match_p (operands[0], operands[2]))
9678     {
9679       rtx tmp;
9680       tmp = operands[1];
9681       operands[1] = operands[2];
9682       operands[2] = tmp;
9683     }
9687 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9688 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9689 ;; to itself.
9690 (define_insn "*negsf2_if"
9691   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9692         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9693    (clobber (reg:CC FLAGS_REG))]
9694   "TARGET_80387 && !TARGET_SSE
9695    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9696   "#")
9698 (define_split
9699   [(set (match_operand:SF 0 "fp_register_operand" "")
9700         (neg:SF (match_operand:SF 1 "register_operand" "")))
9701    (clobber (reg:CC FLAGS_REG))]
9702   "TARGET_80387 && reload_completed"
9703   [(set (match_dup 0)
9704         (neg:SF (match_dup 1)))]
9705   "")
9707 (define_split
9708   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9709         (neg:SF (match_operand:SF 1 "register_operand" "")))
9710    (clobber (reg:CC FLAGS_REG))]
9711   "TARGET_80387 && reload_completed"
9712   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9713               (clobber (reg:CC FLAGS_REG))])]
9714   "operands[1] = gen_int_mode (0x80000000, SImode);
9715    operands[0] = gen_lowpart (SImode, operands[0]);")
9717 (define_split
9718   [(set (match_operand 0 "memory_operand" "")
9719         (neg (match_operand 1 "memory_operand" "")))
9720    (clobber (reg:CC FLAGS_REG))]
9721   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9722   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9723               (clobber (reg:CC FLAGS_REG))])]
9725   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9727   if (GET_MODE (operands[1]) == XFmode)
9728     size = 10;
9729   operands[0] = adjust_address (operands[0], QImode, size - 1);
9730   operands[1] = gen_int_mode (0x80, QImode);
9733 (define_expand "negdf2"
9734   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9735                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9736               (clobber (reg:CC FLAGS_REG))])]
9737   "TARGET_80387"
9738   "if (TARGET_SSE2)
9739      {
9740        /* In case operand is in memory,  we will not use SSE.  */
9741        if (memory_operand (operands[0], VOIDmode)
9742            && rtx_equal_p (operands[0], operands[1]))
9743          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9744        else
9745         {
9746           /* Using SSE is tricky, since we need bitwise negation of -0
9747              in register.  */
9748           rtx reg;
9749 #if HOST_BITS_PER_WIDE_INT >= 64
9750           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9751 #else
9752           rtx imm = immed_double_const (0, 0x80000000, DImode);
9753 #endif
9754           rtx dest = operands[0];
9756           operands[1] = force_reg (DFmode, operands[1]);
9757           operands[0] = force_reg (DFmode, operands[0]);
9758           imm = gen_lowpart (DFmode, imm);
9759           reg = force_reg (V2DFmode,
9760                            gen_rtx_CONST_VECTOR (V2DFmode,
9761                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9762           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9763           if (dest != operands[0])
9764             emit_move_insn (dest, operands[0]);
9765         }
9766        DONE;
9767      }
9768    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9770 (define_insn "negdf2_memory"
9771   [(set (match_operand:DF 0 "memory_operand" "=m")
9772         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9773    (clobber (reg:CC FLAGS_REG))]
9774   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9775   "#")
9777 (define_insn "negdf2_ifs"
9778   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9779         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9780    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9781    (clobber (reg:CC FLAGS_REG))]
9782   "!TARGET_64BIT && TARGET_SSE2
9783    && (reload_in_progress || reload_completed
9784        || (register_operand (operands[0], VOIDmode)
9785            && register_operand (operands[1], VOIDmode)))"
9786   "#")
9788 (define_insn "*negdf2_ifs_rex64"
9789   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9790         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9791    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9792    (clobber (reg:CC FLAGS_REG))]
9793   "TARGET_64BIT && TARGET_SSE2
9794    && (reload_in_progress || reload_completed
9795        || (register_operand (operands[0], VOIDmode)
9796            && register_operand (operands[1], VOIDmode)))"
9797   "#")
9799 (define_split
9800   [(set (match_operand:DF 0 "memory_operand" "")
9801         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9802    (use (match_operand:V2DF 2 "" ""))
9803    (clobber (reg:CC FLAGS_REG))]
9804   ""
9805   [(parallel [(set (match_dup 0)
9806                    (neg:DF (match_dup 1)))
9807               (clobber (reg:CC FLAGS_REG))])])
9809 (define_split
9810   [(set (match_operand:DF 0 "register_operand" "")
9811         (neg:DF (match_operand:DF 1 "register_operand" "")))
9812    (use (match_operand:V2DF 2 "" ""))
9813    (clobber (reg:CC FLAGS_REG))]
9814   "reload_completed && !SSE_REG_P (operands[0])
9815    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9816   [(parallel [(set (match_dup 0)
9817                    (neg:DF (match_dup 1)))
9818               (clobber (reg:CC FLAGS_REG))])])
9820 (define_split
9821   [(set (match_operand:DF 0 "register_operand" "")
9822         (neg:DF (match_operand:DF 1 "register_operand" "")))
9823    (use (match_operand:V2DF 2 "" ""))
9824    (clobber (reg:CC FLAGS_REG))]
9825   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9826   [(parallel [(set (match_dup 0)
9827                    (xor:DI (match_dup 1) (match_dup 2)))
9828               (clobber (reg:CC FLAGS_REG))])]
9829    "operands[0] = gen_lowpart (DImode, operands[0]);
9830     operands[1] = gen_lowpart (DImode, operands[1]);
9831     operands[2] = gen_lowpart (DImode, operands[2]);")
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 "nonimmediate_operand" ""))
9837    (clobber (reg:CC FLAGS_REG))]
9838   "reload_completed && SSE_REG_P (operands[0])"
9839   [(set (match_dup 0)
9840         (xor:V2DF (match_dup 1)
9841                   (match_dup 2)))]
9843   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9844   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9845   /* Avoid possible reformatting on the operands.  */
9846   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9847     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9848   if (operands_match_p (operands[0], operands[2]))
9849     {
9850       rtx tmp;
9851       tmp = operands[1];
9852       operands[1] = operands[2];
9853       operands[2] = tmp;
9854     }
9857 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9858 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9859 ;; to itself.
9860 (define_insn "*negdf2_if"
9861   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9862         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9863    (clobber (reg:CC FLAGS_REG))]
9864   "!TARGET_64BIT && TARGET_80387
9865    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9866   "#")
9868 ;; FIXME: We should to allow integer registers here.  Problem is that
9869 ;; we need another scratch register to get constant from.
9870 ;; Forcing constant to mem if no register available in peep2 should be
9871 ;; safe even for PIC mode, because of RIP relative addressing.
9872 (define_insn "*negdf2_if_rex64"
9873   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9874         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9875    (clobber (reg:CC FLAGS_REG))]
9876   "TARGET_64BIT && TARGET_80387
9877    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9878   "#")
9880 (define_split
9881   [(set (match_operand:DF 0 "fp_register_operand" "")
9882         (neg:DF (match_operand:DF 1 "register_operand" "")))
9883    (clobber (reg:CC FLAGS_REG))]
9884   "TARGET_80387 && reload_completed"
9885   [(set (match_dup 0)
9886         (neg:DF (match_dup 1)))]
9887   "")
9889 (define_split
9890   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9891         (neg:DF (match_operand:DF 1 "register_operand" "")))
9892    (clobber (reg:CC FLAGS_REG))]
9893   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9894   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9895               (clobber (reg:CC FLAGS_REG))])]
9896   "operands[4] = gen_int_mode (0x80000000, SImode);
9897    split_di (operands+0, 1, operands+2, operands+3);")
9899 (define_expand "negxf2"
9900   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9901                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9902               (clobber (reg:CC FLAGS_REG))])]
9903   "TARGET_80387"
9904   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9906 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9907 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9908 ;; to itself.
9909 (define_insn "*negxf2_if"
9910   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9911         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9912    (clobber (reg:CC FLAGS_REG))]
9913   "TARGET_80387
9914    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9915   "#")
9917 (define_split
9918   [(set (match_operand:XF 0 "fp_register_operand" "")
9919         (neg:XF (match_operand:XF 1 "register_operand" "")))
9920    (clobber (reg:CC FLAGS_REG))]
9921   "TARGET_80387 && reload_completed"
9922   [(set (match_dup 0)
9923         (neg:XF (match_dup 1)))]
9924   "")
9926 (define_split
9927   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9928         (neg:XF (match_operand:XF 1 "register_operand" "")))
9929    (clobber (reg:CC FLAGS_REG))]
9930   "TARGET_80387 && reload_completed"
9931   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9932               (clobber (reg:CC FLAGS_REG))])]
9933   "operands[1] = GEN_INT (0x8000);
9934    operands[0] = gen_rtx_REG (SImode,
9935                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9937 ;; Conditionalize these after reload. If they matches before reload, we 
9938 ;; lose the clobber and ability to use integer instructions.
9940 (define_insn "*negsf2_1"
9941   [(set (match_operand:SF 0 "register_operand" "=f")
9942         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9943   "TARGET_80387 && reload_completed"
9944   "fchs"
9945   [(set_attr "type" "fsgn")
9946    (set_attr "mode" "SF")])
9948 (define_insn "*negdf2_1"
9949   [(set (match_operand:DF 0 "register_operand" "=f")
9950         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9951   "TARGET_80387 && reload_completed"
9952   "fchs"
9953   [(set_attr "type" "fsgn")
9954    (set_attr "mode" "DF")])
9956 (define_insn "*negextendsfdf2"
9957   [(set (match_operand:DF 0 "register_operand" "=f")
9958         (neg:DF (float_extend:DF
9959                   (match_operand:SF 1 "register_operand" "0"))))]
9960   "TARGET_80387"
9961   "fchs"
9962   [(set_attr "type" "fsgn")
9963    (set_attr "mode" "DF")])
9965 (define_insn "*negxf2_1"
9966   [(set (match_operand:XF 0 "register_operand" "=f")
9967         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9968   "TARGET_80387 && reload_completed"
9969   "fchs"
9970   [(set_attr "type" "fsgn")
9971    (set_attr "mode" "XF")])
9973 (define_insn "*negextenddfxf2"
9974   [(set (match_operand:XF 0 "register_operand" "=f")
9975         (neg:XF (float_extend:XF
9976                   (match_operand:DF 1 "register_operand" "0"))))]
9977   "TARGET_80387"
9978   "fchs"
9979   [(set_attr "type" "fsgn")
9980    (set_attr "mode" "XF")])
9982 (define_insn "*negextendsfxf2"
9983   [(set (match_operand:XF 0 "register_operand" "=f")
9984         (neg:XF (float_extend:XF
9985                   (match_operand:SF 1 "register_operand" "0"))))]
9986   "TARGET_80387"
9987   "fchs"
9988   [(set_attr "type" "fsgn")
9989    (set_attr "mode" "XF")])
9991 ;; Absolute value instructions
9993 (define_expand "abssf2"
9994   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9995                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9996               (clobber (reg:CC FLAGS_REG))])]
9997   "TARGET_80387"
9998   "if (TARGET_SSE)
9999      {
10000        /* In case operand is in memory,  we will not use SSE.  */
10001        if (memory_operand (operands[0], VOIDmode)
10002            && rtx_equal_p (operands[0], operands[1]))
10003          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10004        else
10005         {
10006           /* Using SSE is tricky, since we need bitwise negation of -0
10007              in register.  */
10008           rtx reg = gen_reg_rtx (V4SFmode);
10009           rtx dest = operands[0];
10010           rtx imm;
10012           operands[1] = force_reg (SFmode, operands[1]);
10013           operands[0] = force_reg (SFmode, operands[0]);
10014           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10015           reg = force_reg (V4SFmode,
10016                            gen_rtx_CONST_VECTOR (V4SFmode,
10017                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
10018                                       CONST0_RTX (SFmode),
10019                                       CONST0_RTX (SFmode))));
10020           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10021           if (dest != operands[0])
10022             emit_move_insn (dest, operands[0]);
10023         }
10024        DONE;
10025      }
10026    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10028 (define_insn "abssf2_memory"
10029   [(set (match_operand:SF 0 "memory_operand" "=m")
10030         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10031    (clobber (reg:CC FLAGS_REG))]
10032   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10033   "#")
10035 (define_insn "abssf2_ifs"
10036   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10037         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10038    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10039    (clobber (reg:CC FLAGS_REG))]
10040   "TARGET_SSE
10041    && (reload_in_progress || reload_completed
10042        || (register_operand (operands[0], VOIDmode)
10043             && register_operand (operands[1], VOIDmode)))"
10044   "#")
10046 (define_split
10047   [(set (match_operand:SF 0 "memory_operand" "")
10048         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10049    (use (match_operand:V4SF 2 "" ""))
10050    (clobber (reg:CC FLAGS_REG))]
10051   ""
10052   [(parallel [(set (match_dup 0)
10053                    (abs:SF (match_dup 1)))
10054               (clobber (reg:CC FLAGS_REG))])])
10056 (define_split
10057   [(set (match_operand:SF 0 "register_operand" "")
10058         (abs:SF (match_operand:SF 1 "register_operand" "")))
10059    (use (match_operand:V4SF 2 "" ""))
10060    (clobber (reg:CC FLAGS_REG))]
10061   "reload_completed && !SSE_REG_P (operands[0])"
10062   [(parallel [(set (match_dup 0)
10063                    (abs:SF (match_dup 1)))
10064               (clobber (reg:CC FLAGS_REG))])])
10066 (define_split
10067   [(set (match_operand:SF 0 "register_operand" "")
10068         (abs:SF (match_operand:SF 1 "register_operand" "")))
10069    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10070    (clobber (reg:CC FLAGS_REG))]
10071   "reload_completed && SSE_REG_P (operands[0])"
10072   [(set (match_dup 0)
10073         (and:V4SF (match_dup 1)
10074                   (match_dup 2)))]
10076   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10077   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10078   if (operands_match_p (operands[0], operands[2]))
10079     {
10080       rtx tmp;
10081       tmp = operands[1];
10082       operands[1] = operands[2];
10083       operands[2] = tmp;
10084     }
10087 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10088 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10089 ;; to itself.
10090 (define_insn "*abssf2_if"
10091   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10092         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10093    (clobber (reg:CC FLAGS_REG))]
10094   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10095   "#")
10097 (define_split
10098   [(set (match_operand:SF 0 "fp_register_operand" "")
10099         (abs:SF (match_operand:SF 1 "register_operand" "")))
10100    (clobber (reg:CC FLAGS_REG))]
10101   "TARGET_80387 && reload_completed"
10102   [(set (match_dup 0)
10103         (abs:SF (match_dup 1)))]
10104   "")
10106 (define_split
10107   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10108         (abs:SF (match_operand:SF 1 "register_operand" "")))
10109    (clobber (reg:CC FLAGS_REG))]
10110   "TARGET_80387 && reload_completed"
10111   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10112               (clobber (reg:CC FLAGS_REG))])]
10113   "operands[1] = gen_int_mode (~0x80000000, SImode);
10114    operands[0] = gen_lowpart (SImode, operands[0]);")
10116 (define_split
10117   [(set (match_operand 0 "memory_operand" "")
10118         (abs (match_operand 1 "memory_operand" "")))
10119    (clobber (reg:CC FLAGS_REG))]
10120   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10121   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10122               (clobber (reg:CC FLAGS_REG))])]
10124   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10126   if (GET_MODE (operands[1]) == XFmode)
10127     size = 10;
10128   operands[0] = adjust_address (operands[0], QImode, size - 1);
10129   operands[1] = gen_int_mode (~0x80, QImode);
10132 (define_expand "absdf2"
10133   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10134                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10135               (clobber (reg:CC FLAGS_REG))])]
10136   "TARGET_80387"
10137   "if (TARGET_SSE2)
10138      {
10139        /* In case operand is in memory,  we will not use SSE.  */
10140        if (memory_operand (operands[0], VOIDmode)
10141            && rtx_equal_p (operands[0], operands[1]))
10142          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10143        else
10144         {
10145           /* Using SSE is tricky, since we need bitwise negation of -0
10146              in register.  */
10147           rtx reg = gen_reg_rtx (V2DFmode);
10148 #if HOST_BITS_PER_WIDE_INT >= 64
10149           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10150 #else
10151           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10152 #endif
10153           rtx dest = operands[0];
10155           operands[1] = force_reg (DFmode, operands[1]);
10156           operands[0] = force_reg (DFmode, operands[0]);
10158           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10159           imm = gen_lowpart (DFmode, imm);
10160           reg = force_reg (V2DFmode,
10161                            gen_rtx_CONST_VECTOR (V2DFmode,
10162                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10163           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10164           if (dest != operands[0])
10165             emit_move_insn (dest, operands[0]);
10166         }
10167        DONE;
10168      }
10169    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10171 (define_insn "absdf2_memory"
10172   [(set (match_operand:DF 0 "memory_operand" "=m")
10173         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10174    (clobber (reg:CC FLAGS_REG))]
10175   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10176   "#")
10178 (define_insn "absdf2_ifs"
10179   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10180         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10181    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10182    (clobber (reg:CC FLAGS_REG))]
10183   "!TARGET_64BIT && TARGET_SSE2
10184    && (reload_in_progress || reload_completed
10185        || (register_operand (operands[0], VOIDmode)
10186            && register_operand (operands[1], VOIDmode)))"
10187   "#")
10189 (define_insn "*absdf2_ifs_rex64"
10190   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10191         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10192    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10193    (clobber (reg:CC FLAGS_REG))]
10194   "TARGET_64BIT && TARGET_SSE2
10195    && (reload_in_progress || reload_completed
10196        || (register_operand (operands[0], VOIDmode)
10197            && register_operand (operands[1], VOIDmode)))"
10198   "#")
10200 (define_split
10201   [(set (match_operand:DF 0 "memory_operand" "")
10202         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10203    (use (match_operand:V2DF 2 "" ""))
10204    (clobber (reg:CC FLAGS_REG))]
10205   ""
10206   [(parallel [(set (match_dup 0)
10207                    (abs:DF (match_dup 1)))
10208               (clobber (reg:CC FLAGS_REG))])])
10210 (define_split
10211   [(set (match_operand:DF 0 "register_operand" "")
10212         (abs:DF (match_operand:DF 1 "register_operand" "")))
10213    (use (match_operand:V2DF 2 "" ""))
10214    (clobber (reg:CC FLAGS_REG))]
10215   "reload_completed && !SSE_REG_P (operands[0])"
10216   [(parallel [(set (match_dup 0)
10217                    (abs:DF (match_dup 1)))
10218               (clobber (reg:CC FLAGS_REG))])])
10220 (define_split
10221   [(set (match_operand:DF 0 "register_operand" "")
10222         (abs:DF (match_operand:DF 1 "register_operand" "")))
10223    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10224    (clobber (reg:CC FLAGS_REG))]
10225   "reload_completed && SSE_REG_P (operands[0])"
10226   [(set (match_dup 0)
10227         (and:V2DF (match_dup 1)
10228                   (match_dup 2)))]
10230   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10231   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10232   /* Avoid possible reformatting on the operands.  */
10233   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10234     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10235   if (operands_match_p (operands[0], operands[2]))
10236     {
10237       rtx tmp;
10238       tmp = operands[1];
10239       operands[1] = operands[2];
10240       operands[2] = tmp;
10241     }
10245 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10246 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10247 ;; to itself.
10248 (define_insn "*absdf2_if"
10249   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10250         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10251    (clobber (reg:CC FLAGS_REG))]
10252   "!TARGET_64BIT && TARGET_80387
10253    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10254   "#")
10256 ;; FIXME: We should to allow integer registers here.  Problem is that
10257 ;; we need another scratch register to get constant from.
10258 ;; Forcing constant to mem if no register available in peep2 should be
10259 ;; safe even for PIC mode, because of RIP relative addressing.
10260 (define_insn "*absdf2_if_rex64"
10261   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10262         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10263    (clobber (reg:CC FLAGS_REG))]
10264   "TARGET_64BIT && TARGET_80387
10265    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10266   "#")
10268 (define_split
10269   [(set (match_operand:DF 0 "fp_register_operand" "")
10270         (abs:DF (match_operand:DF 1 "register_operand" "")))
10271    (clobber (reg:CC FLAGS_REG))]
10272   "TARGET_80387 && reload_completed"
10273   [(set (match_dup 0)
10274         (abs:DF (match_dup 1)))]
10275   "")
10277 (define_split
10278   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10279         (abs:DF (match_operand:DF 1 "register_operand" "")))
10280    (clobber (reg:CC FLAGS_REG))]
10281   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10282   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10283               (clobber (reg:CC FLAGS_REG))])]
10284   "operands[4] = gen_int_mode (~0x80000000, SImode);
10285    split_di (operands+0, 1, operands+2, operands+3);")
10287 (define_expand "absxf2"
10288   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10289                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10290               (clobber (reg:CC FLAGS_REG))])]
10291   "TARGET_80387"
10292   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10294 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10295 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10296 ;; to itself.
10297 (define_insn "*absxf2_if"
10298   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10299         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10300    (clobber (reg:CC FLAGS_REG))]
10301   "TARGET_80387
10302    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10303   "#")
10305 (define_split
10306   [(set (match_operand:XF 0 "fp_register_operand" "")
10307         (abs:XF (match_operand:XF 1 "register_operand" "")))
10308    (clobber (reg:CC FLAGS_REG))]
10309   "TARGET_80387 && reload_completed"
10310   [(set (match_dup 0)
10311         (abs:XF (match_dup 1)))]
10312   "")
10314 (define_split
10315   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10316         (abs:XF (match_operand:XF 1 "register_operand" "")))
10317    (clobber (reg:CC FLAGS_REG))]
10318   "TARGET_80387 && reload_completed"
10319   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10320               (clobber (reg:CC FLAGS_REG))])]
10321   "operands[1] = GEN_INT (~0x8000);
10322    operands[0] = gen_rtx_REG (SImode,
10323                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10325 (define_insn "*abssf2_1"
10326   [(set (match_operand:SF 0 "register_operand" "=f")
10327         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10328   "TARGET_80387 && reload_completed"
10329   "fabs"
10330   [(set_attr "type" "fsgn")
10331    (set_attr "mode" "SF")])
10333 (define_insn "*absdf2_1"
10334   [(set (match_operand:DF 0 "register_operand" "=f")
10335         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10336   "TARGET_80387 && reload_completed"
10337   "fabs"
10338   [(set_attr "type" "fsgn")
10339    (set_attr "mode" "DF")])
10341 (define_insn "*absextendsfdf2"
10342   [(set (match_operand:DF 0 "register_operand" "=f")
10343         (abs:DF (float_extend:DF
10344                   (match_operand:SF 1 "register_operand" "0"))))]
10345   "TARGET_80387"
10346   "fabs"
10347   [(set_attr "type" "fsgn")
10348    (set_attr "mode" "DF")])
10350 (define_insn "*absxf2_1"
10351   [(set (match_operand:XF 0 "register_operand" "=f")
10352         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10353   "TARGET_80387 && reload_completed"
10354   "fabs"
10355   [(set_attr "type" "fsgn")
10356    (set_attr "mode" "DF")])
10358 (define_insn "*absextenddfxf2"
10359   [(set (match_operand:XF 0 "register_operand" "=f")
10360         (abs:XF (float_extend:XF
10361           (match_operand:DF 1 "register_operand" "0"))))]
10362   "TARGET_80387"
10363   "fabs"
10364   [(set_attr "type" "fsgn")
10365    (set_attr "mode" "XF")])
10367 (define_insn "*absextendsfxf2"
10368   [(set (match_operand:XF 0 "register_operand" "=f")
10369         (abs:XF (float_extend:XF
10370           (match_operand:SF 1 "register_operand" "0"))))]
10371   "TARGET_80387"
10372   "fabs"
10373   [(set_attr "type" "fsgn")
10374    (set_attr "mode" "XF")])
10376 ;; One complement instructions
10378 (define_expand "one_cmpldi2"
10379   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10380         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10381   "TARGET_64BIT"
10382   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10384 (define_insn "*one_cmpldi2_1_rex64"
10385   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10386         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10387   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10388   "not{q}\t%0"
10389   [(set_attr "type" "negnot")
10390    (set_attr "mode" "DI")])
10392 (define_insn "*one_cmpldi2_2_rex64"
10393   [(set (reg 17)
10394         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10395                  (const_int 0)))
10396    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10397         (not:DI (match_dup 1)))]
10398   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10399    && ix86_unary_operator_ok (NOT, DImode, operands)"
10400   "#"
10401   [(set_attr "type" "alu1")
10402    (set_attr "mode" "DI")])
10404 (define_split
10405   [(set (reg 17)
10406         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10407                  (const_int 0)))
10408    (set (match_operand:DI 0 "nonimmediate_operand" "")
10409         (not:DI (match_dup 1)))]
10410   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10411   [(parallel [(set (reg:CCNO FLAGS_REG)
10412                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10413                                  (const_int 0)))
10414               (set (match_dup 0)
10415                    (xor:DI (match_dup 1) (const_int -1)))])]
10416   "")
10418 (define_expand "one_cmplsi2"
10419   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10420         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10421   ""
10422   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10424 (define_insn "*one_cmplsi2_1"
10425   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10426         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10427   "ix86_unary_operator_ok (NOT, SImode, operands)"
10428   "not{l}\t%0"
10429   [(set_attr "type" "negnot")
10430    (set_attr "mode" "SI")])
10432 ;; ??? Currently never generated - xor is used instead.
10433 (define_insn "*one_cmplsi2_1_zext"
10434   [(set (match_operand:DI 0 "register_operand" "=r")
10435         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10436   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10437   "not{l}\t%k0"
10438   [(set_attr "type" "negnot")
10439    (set_attr "mode" "SI")])
10441 (define_insn "*one_cmplsi2_2"
10442   [(set (reg 17)
10443         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10444                  (const_int 0)))
10445    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10446         (not:SI (match_dup 1)))]
10447   "ix86_match_ccmode (insn, CCNOmode)
10448    && ix86_unary_operator_ok (NOT, SImode, operands)"
10449   "#"
10450   [(set_attr "type" "alu1")
10451    (set_attr "mode" "SI")])
10453 (define_split
10454   [(set (reg 17)
10455         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10456                  (const_int 0)))
10457    (set (match_operand:SI 0 "nonimmediate_operand" "")
10458         (not:SI (match_dup 1)))]
10459   "ix86_match_ccmode (insn, CCNOmode)"
10460   [(parallel [(set (reg:CCNO FLAGS_REG)
10461                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10462                                  (const_int 0)))
10463               (set (match_dup 0)
10464                    (xor:SI (match_dup 1) (const_int -1)))])]
10465   "")
10467 ;; ??? Currently never generated - xor is used instead.
10468 (define_insn "*one_cmplsi2_2_zext"
10469   [(set (reg 17)
10470         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10471                  (const_int 0)))
10472    (set (match_operand:DI 0 "register_operand" "=r")
10473         (zero_extend:DI (not:SI (match_dup 1))))]
10474   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10475    && ix86_unary_operator_ok (NOT, SImode, operands)"
10476   "#"
10477   [(set_attr "type" "alu1")
10478    (set_attr "mode" "SI")])
10480 (define_split
10481   [(set (reg 17)
10482         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10483                  (const_int 0)))
10484    (set (match_operand:DI 0 "register_operand" "")
10485         (zero_extend:DI (not:SI (match_dup 1))))]
10486   "ix86_match_ccmode (insn, CCNOmode)"
10487   [(parallel [(set (reg:CCNO FLAGS_REG)
10488                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10489                                  (const_int 0)))
10490               (set (match_dup 0)
10491                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10492   "")
10494 (define_expand "one_cmplhi2"
10495   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10496         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10497   "TARGET_HIMODE_MATH"
10498   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10500 (define_insn "*one_cmplhi2_1"
10501   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10502         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10503   "ix86_unary_operator_ok (NOT, HImode, operands)"
10504   "not{w}\t%0"
10505   [(set_attr "type" "negnot")
10506    (set_attr "mode" "HI")])
10508 (define_insn "*one_cmplhi2_2"
10509   [(set (reg 17)
10510         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10511                  (const_int 0)))
10512    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10513         (not:HI (match_dup 1)))]
10514   "ix86_match_ccmode (insn, CCNOmode)
10515    && ix86_unary_operator_ok (NEG, HImode, operands)"
10516   "#"
10517   [(set_attr "type" "alu1")
10518    (set_attr "mode" "HI")])
10520 (define_split
10521   [(set (reg 17)
10522         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10523                  (const_int 0)))
10524    (set (match_operand:HI 0 "nonimmediate_operand" "")
10525         (not:HI (match_dup 1)))]
10526   "ix86_match_ccmode (insn, CCNOmode)"
10527   [(parallel [(set (reg:CCNO FLAGS_REG)
10528                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10529                                  (const_int 0)))
10530               (set (match_dup 0)
10531                    (xor:HI (match_dup 1) (const_int -1)))])]
10532   "")
10534 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10535 (define_expand "one_cmplqi2"
10536   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10537         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10538   "TARGET_QIMODE_MATH"
10539   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10541 (define_insn "*one_cmplqi2_1"
10542   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10543         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10544   "ix86_unary_operator_ok (NOT, QImode, operands)"
10545   "@
10546    not{b}\t%0
10547    not{l}\t%k0"
10548   [(set_attr "type" "negnot")
10549    (set_attr "mode" "QI,SI")])
10551 (define_insn "*one_cmplqi2_2"
10552   [(set (reg 17)
10553         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10554                  (const_int 0)))
10555    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10556         (not:QI (match_dup 1)))]
10557   "ix86_match_ccmode (insn, CCNOmode)
10558    && ix86_unary_operator_ok (NOT, QImode, operands)"
10559   "#"
10560   [(set_attr "type" "alu1")
10561    (set_attr "mode" "QI")])
10563 (define_split
10564   [(set (reg 17)
10565         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10566                  (const_int 0)))
10567    (set (match_operand:QI 0 "nonimmediate_operand" "")
10568         (not:QI (match_dup 1)))]
10569   "ix86_match_ccmode (insn, CCNOmode)"
10570   [(parallel [(set (reg:CCNO FLAGS_REG)
10571                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10572                                  (const_int 0)))
10573               (set (match_dup 0)
10574                    (xor:QI (match_dup 1) (const_int -1)))])]
10575   "")
10577 ;; Arithmetic shift instructions
10579 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10580 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10581 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10582 ;; from the assembler input.
10584 ;; This instruction shifts the target reg/mem as usual, but instead of
10585 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10586 ;; is a left shift double, bits are taken from the high order bits of
10587 ;; reg, else if the insn is a shift right double, bits are taken from the
10588 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10589 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10591 ;; Since sh[lr]d does not change the `reg' operand, that is done
10592 ;; separately, making all shifts emit pairs of shift double and normal
10593 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10594 ;; support a 63 bit shift, each shift where the count is in a reg expands
10595 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10597 ;; If the shift count is a constant, we need never emit more than one
10598 ;; shift pair, instead using moves and sign extension for counts greater
10599 ;; than 31.
10601 (define_expand "ashldi3"
10602   [(set (match_operand:DI 0 "shiftdi_operand" "")
10603         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10604                    (match_operand:QI 2 "nonmemory_operand" "")))]
10605   ""
10606   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10608 (define_insn "*ashldi3_1_rex64"
10609   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10610         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10611                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10612    (clobber (reg:CC FLAGS_REG))]
10613   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10615   switch (get_attr_type (insn))
10616     {
10617     case TYPE_ALU:
10618       if (operands[2] != const1_rtx)
10619         abort ();
10620       if (!rtx_equal_p (operands[0], operands[1]))
10621         abort ();
10622       return "add{q}\t{%0, %0|%0, %0}";
10624     case TYPE_LEA:
10625       if (GET_CODE (operands[2]) != CONST_INT
10626           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10627         abort ();
10628       operands[1] = gen_rtx_MULT (DImode, operands[1],
10629                                   GEN_INT (1 << INTVAL (operands[2])));
10630       return "lea{q}\t{%a1, %0|%0, %a1}";
10632     default:
10633       if (REG_P (operands[2]))
10634         return "sal{q}\t{%b2, %0|%0, %b2}";
10635       else if (operands[2] == const1_rtx
10636                && (TARGET_SHIFT1 || optimize_size))
10637         return "sal{q}\t%0";
10638       else
10639         return "sal{q}\t{%2, %0|%0, %2}";
10640     }
10642   [(set (attr "type")
10643      (cond [(eq_attr "alternative" "1")
10644               (const_string "lea")
10645             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10646                           (const_int 0))
10647                       (match_operand 0 "register_operand" ""))
10648                  (match_operand 2 "const1_operand" ""))
10649               (const_string "alu")
10650            ]
10651            (const_string "ishift")))
10652    (set_attr "mode" "DI")])
10654 ;; Convert lea to the lea pattern to avoid flags dependency.
10655 (define_split
10656   [(set (match_operand:DI 0 "register_operand" "")
10657         (ashift:DI (match_operand:DI 1 "register_operand" "")
10658                    (match_operand:QI 2 "immediate_operand" "")))
10659    (clobber (reg:CC FLAGS_REG))]
10660   "TARGET_64BIT && reload_completed
10661    && true_regnum (operands[0]) != true_regnum (operands[1])"
10662   [(set (match_dup 0)
10663         (mult:DI (match_dup 1)
10664                  (match_dup 2)))]
10665   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10667 ;; This pattern can't accept a variable shift count, since shifts by
10668 ;; zero don't affect the flags.  We assume that shifts by constant
10669 ;; zero are optimized away.
10670 (define_insn "*ashldi3_cmp_rex64"
10671   [(set (reg 17)
10672         (compare
10673           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10674                      (match_operand:QI 2 "immediate_operand" "e"))
10675           (const_int 0)))
10676    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10677         (ashift:DI (match_dup 1) (match_dup 2)))]
10678   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10679    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10681   switch (get_attr_type (insn))
10682     {
10683     case TYPE_ALU:
10684       if (operands[2] != const1_rtx)
10685         abort ();
10686       return "add{q}\t{%0, %0|%0, %0}";
10688     default:
10689       if (REG_P (operands[2]))
10690         return "sal{q}\t{%b2, %0|%0, %b2}";
10691       else if (operands[2] == const1_rtx
10692                && (TARGET_SHIFT1 || optimize_size))
10693         return "sal{q}\t%0";
10694       else
10695         return "sal{q}\t{%2, %0|%0, %2}";
10696     }
10698   [(set (attr "type")
10699      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10700                           (const_int 0))
10701                       (match_operand 0 "register_operand" ""))
10702                  (match_operand 2 "const1_operand" ""))
10703               (const_string "alu")
10704            ]
10705            (const_string "ishift")))
10706    (set_attr "mode" "DI")])
10708 (define_insn "*ashldi3_1"
10709   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10710         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10711                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10712    (clobber (reg:CC FLAGS_REG))]
10713   "!TARGET_64BIT"
10714   "#"
10715   [(set_attr "type" "multi")])
10717 ;; By default we don't ask for a scratch register, because when DImode
10718 ;; values are manipulated, registers are already at a premium.  But if
10719 ;; we have one handy, we won't turn it away.
10720 (define_peephole2
10721   [(match_scratch:SI 3 "r")
10722    (parallel [(set (match_operand:DI 0 "register_operand" "")
10723                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10724                               (match_operand:QI 2 "nonmemory_operand" "")))
10725               (clobber (reg:CC FLAGS_REG))])
10726    (match_dup 3)]
10727   "!TARGET_64BIT && TARGET_CMOVE"
10728   [(const_int 0)]
10729   "ix86_split_ashldi (operands, operands[3]); DONE;")
10731 (define_split
10732   [(set (match_operand:DI 0 "register_operand" "")
10733         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10734                    (match_operand:QI 2 "nonmemory_operand" "")))
10735    (clobber (reg:CC FLAGS_REG))]
10736   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10737   [(const_int 0)]
10738   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10740 (define_insn "x86_shld_1"
10741   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10742         (ior:SI (ashift:SI (match_dup 0)
10743                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10744                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10745                   (minus:QI (const_int 32) (match_dup 2)))))
10746    (clobber (reg:CC FLAGS_REG))]
10747   ""
10748   "@
10749    shld{l}\t{%2, %1, %0|%0, %1, %2}
10750    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10751   [(set_attr "type" "ishift")
10752    (set_attr "prefix_0f" "1")
10753    (set_attr "mode" "SI")
10754    (set_attr "pent_pair" "np")
10755    (set_attr "athlon_decode" "vector")])
10757 (define_expand "x86_shift_adj_1"
10758   [(set (reg:CCZ FLAGS_REG)
10759         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10760                              (const_int 32))
10761                      (const_int 0)))
10762    (set (match_operand:SI 0 "register_operand" "")
10763         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10764                          (match_operand:SI 1 "register_operand" "")
10765                          (match_dup 0)))
10766    (set (match_dup 1)
10767         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10768                          (match_operand:SI 3 "register_operand" "r")
10769                          (match_dup 1)))]
10770   "TARGET_CMOVE"
10771   "")
10773 (define_expand "x86_shift_adj_2"
10774   [(use (match_operand:SI 0 "register_operand" ""))
10775    (use (match_operand:SI 1 "register_operand" ""))
10776    (use (match_operand:QI 2 "register_operand" ""))]
10777   ""
10779   rtx label = gen_label_rtx ();
10780   rtx tmp;
10782   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10784   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10785   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10786   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10787                               gen_rtx_LABEL_REF (VOIDmode, label),
10788                               pc_rtx);
10789   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10790   JUMP_LABEL (tmp) = label;
10792   emit_move_insn (operands[0], operands[1]);
10793   ix86_expand_clear (operands[1]);
10795   emit_label (label);
10796   LABEL_NUSES (label) = 1;
10798   DONE;
10801 (define_expand "ashlsi3"
10802   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10803         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10804                    (match_operand:QI 2 "nonmemory_operand" "")))
10805    (clobber (reg:CC FLAGS_REG))]
10806   ""
10807   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10809 (define_insn "*ashlsi3_1"
10810   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10811         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10812                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10813    (clobber (reg:CC FLAGS_REG))]
10814   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10816   switch (get_attr_type (insn))
10817     {
10818     case TYPE_ALU:
10819       if (operands[2] != const1_rtx)
10820         abort ();
10821       if (!rtx_equal_p (operands[0], operands[1]))
10822         abort ();
10823       return "add{l}\t{%0, %0|%0, %0}";
10825     case TYPE_LEA:
10826       return "#";
10828     default:
10829       if (REG_P (operands[2]))
10830         return "sal{l}\t{%b2, %0|%0, %b2}";
10831       else if (operands[2] == const1_rtx
10832                && (TARGET_SHIFT1 || optimize_size))
10833         return "sal{l}\t%0";
10834       else
10835         return "sal{l}\t{%2, %0|%0, %2}";
10836     }
10838   [(set (attr "type")
10839      (cond [(eq_attr "alternative" "1")
10840               (const_string "lea")
10841             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10842                           (const_int 0))
10843                       (match_operand 0 "register_operand" ""))
10844                  (match_operand 2 "const1_operand" ""))
10845               (const_string "alu")
10846            ]
10847            (const_string "ishift")))
10848    (set_attr "mode" "SI")])
10850 ;; Convert lea to the lea pattern to avoid flags dependency.
10851 (define_split
10852   [(set (match_operand 0 "register_operand" "")
10853         (ashift (match_operand 1 "index_register_operand" "")
10854                 (match_operand:QI 2 "const_int_operand" "")))
10855    (clobber (reg:CC FLAGS_REG))]
10856   "reload_completed
10857    && true_regnum (operands[0]) != true_regnum (operands[1])"
10858   [(const_int 0)]
10860   rtx pat;
10861   operands[0] = gen_lowpart (SImode, operands[0]);
10862   operands[1] = gen_lowpart (Pmode, operands[1]);
10863   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10864   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10865   if (Pmode != SImode)
10866     pat = gen_rtx_SUBREG (SImode, pat, 0);
10867   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10868   DONE;
10871 ;; Rare case of shifting RSP is handled by generating move and shift
10872 (define_split
10873   [(set (match_operand 0 "register_operand" "")
10874         (ashift (match_operand 1 "register_operand" "")
10875                 (match_operand:QI 2 "const_int_operand" "")))
10876    (clobber (reg:CC FLAGS_REG))]
10877   "reload_completed
10878    && true_regnum (operands[0]) != true_regnum (operands[1])"
10879   [(const_int 0)]
10881   rtx pat, clob;
10882   emit_move_insn (operands[1], operands[0]);
10883   pat = gen_rtx_SET (VOIDmode, operands[0],
10884                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10885                                      operands[0], operands[2]));
10886   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10887   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10888   DONE;
10891 (define_insn "*ashlsi3_1_zext"
10892   [(set (match_operand:DI 0 "register_operand" "=r,r")
10893         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10894                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10895    (clobber (reg:CC FLAGS_REG))]
10896   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10898   switch (get_attr_type (insn))
10899     {
10900     case TYPE_ALU:
10901       if (operands[2] != const1_rtx)
10902         abort ();
10903       return "add{l}\t{%k0, %k0|%k0, %k0}";
10905     case TYPE_LEA:
10906       return "#";
10908     default:
10909       if (REG_P (operands[2]))
10910         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10911       else if (operands[2] == const1_rtx
10912                && (TARGET_SHIFT1 || optimize_size))
10913         return "sal{l}\t%k0";
10914       else
10915         return "sal{l}\t{%2, %k0|%k0, %2}";
10916     }
10918   [(set (attr "type")
10919      (cond [(eq_attr "alternative" "1")
10920               (const_string "lea")
10921             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10922                      (const_int 0))
10923                  (match_operand 2 "const1_operand" ""))
10924               (const_string "alu")
10925            ]
10926            (const_string "ishift")))
10927    (set_attr "mode" "SI")])
10929 ;; Convert lea to the lea pattern to avoid flags dependency.
10930 (define_split
10931   [(set (match_operand:DI 0 "register_operand" "")
10932         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10933                                 (match_operand:QI 2 "const_int_operand" ""))))
10934    (clobber (reg:CC FLAGS_REG))]
10935   "TARGET_64BIT && reload_completed
10936    && true_regnum (operands[0]) != true_regnum (operands[1])"
10937   [(set (match_dup 0) (zero_extend:DI
10938                         (subreg:SI (mult:SI (match_dup 1)
10939                                             (match_dup 2)) 0)))]
10941   operands[1] = gen_lowpart (Pmode, operands[1]);
10942   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10945 ;; This pattern can't accept a variable shift count, since shifts by
10946 ;; zero don't affect the flags.  We assume that shifts by constant
10947 ;; zero are optimized away.
10948 (define_insn "*ashlsi3_cmp"
10949   [(set (reg 17)
10950         (compare
10951           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10952                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10953           (const_int 0)))
10954    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10955         (ashift:SI (match_dup 1) (match_dup 2)))]
10956   "ix86_match_ccmode (insn, CCGOCmode)
10957    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10959   switch (get_attr_type (insn))
10960     {
10961     case TYPE_ALU:
10962       if (operands[2] != const1_rtx)
10963         abort ();
10964       return "add{l}\t{%0, %0|%0, %0}";
10966     default:
10967       if (REG_P (operands[2]))
10968         return "sal{l}\t{%b2, %0|%0, %b2}";
10969       else if (operands[2] == const1_rtx
10970                && (TARGET_SHIFT1 || optimize_size))
10971         return "sal{l}\t%0";
10972       else
10973         return "sal{l}\t{%2, %0|%0, %2}";
10974     }
10976   [(set (attr "type")
10977      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10978                           (const_int 0))
10979                       (match_operand 0 "register_operand" ""))
10980                  (match_operand 2 "const1_operand" ""))
10981               (const_string "alu")
10982            ]
10983            (const_string "ishift")))
10984    (set_attr "mode" "SI")])
10986 (define_insn "*ashlsi3_cmp_zext"
10987   [(set (reg 17)
10988         (compare
10989           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10990                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10991           (const_int 0)))
10992    (set (match_operand:DI 0 "register_operand" "=r")
10993         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10994   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10995    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10997   switch (get_attr_type (insn))
10998     {
10999     case TYPE_ALU:
11000       if (operands[2] != const1_rtx)
11001         abort ();
11002       return "add{l}\t{%k0, %k0|%k0, %k0}";
11004     default:
11005       if (REG_P (operands[2]))
11006         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11007       else if (operands[2] == const1_rtx
11008                && (TARGET_SHIFT1 || optimize_size))
11009         return "sal{l}\t%k0";
11010       else
11011         return "sal{l}\t{%2, %k0|%k0, %2}";
11012     }
11014   [(set (attr "type")
11015      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11016                      (const_int 0))
11017                  (match_operand 2 "const1_operand" ""))
11018               (const_string "alu")
11019            ]
11020            (const_string "ishift")))
11021    (set_attr "mode" "SI")])
11023 (define_expand "ashlhi3"
11024   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11025         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11026                    (match_operand:QI 2 "nonmemory_operand" "")))
11027    (clobber (reg:CC FLAGS_REG))]
11028   "TARGET_HIMODE_MATH"
11029   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11031 (define_insn "*ashlhi3_1_lea"
11032   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11033         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11034                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11035    (clobber (reg:CC FLAGS_REG))]
11036   "!TARGET_PARTIAL_REG_STALL
11037    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11039   switch (get_attr_type (insn))
11040     {
11041     case TYPE_LEA:
11042       return "#";
11043     case TYPE_ALU:
11044       if (operands[2] != const1_rtx)
11045         abort ();
11046       return "add{w}\t{%0, %0|%0, %0}";
11048     default:
11049       if (REG_P (operands[2]))
11050         return "sal{w}\t{%b2, %0|%0, %b2}";
11051       else if (operands[2] == const1_rtx
11052                && (TARGET_SHIFT1 || optimize_size))
11053         return "sal{w}\t%0";
11054       else
11055         return "sal{w}\t{%2, %0|%0, %2}";
11056     }
11058   [(set (attr "type")
11059      (cond [(eq_attr "alternative" "1")
11060               (const_string "lea")
11061             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11062                           (const_int 0))
11063                       (match_operand 0 "register_operand" ""))
11064                  (match_operand 2 "const1_operand" ""))
11065               (const_string "alu")
11066            ]
11067            (const_string "ishift")))
11068    (set_attr "mode" "HI,SI")])
11070 (define_insn "*ashlhi3_1"
11071   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11072         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11073                    (match_operand:QI 2 "nonmemory_operand" "cI")))
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_ALU:
11081       if (operands[2] != const1_rtx)
11082         abort ();
11083       return "add{w}\t{%0, %0|%0, %0}";
11085     default:
11086       if (REG_P (operands[2]))
11087         return "sal{w}\t{%b2, %0|%0, %b2}";
11088       else if (operands[2] == const1_rtx
11089                && (TARGET_SHIFT1 || optimize_size))
11090         return "sal{w}\t%0";
11091       else
11092         return "sal{w}\t{%2, %0|%0, %2}";
11093     }
11095   [(set (attr "type")
11096      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11097                           (const_int 0))
11098                       (match_operand 0 "register_operand" ""))
11099                  (match_operand 2 "const1_operand" ""))
11100               (const_string "alu")
11101            ]
11102            (const_string "ishift")))
11103    (set_attr "mode" "HI")])
11105 ;; This pattern can't accept a variable shift count, since shifts by
11106 ;; zero don't affect the flags.  We assume that shifts by constant
11107 ;; zero are optimized away.
11108 (define_insn "*ashlhi3_cmp"
11109   [(set (reg 17)
11110         (compare
11111           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11112                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11113           (const_int 0)))
11114    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11115         (ashift:HI (match_dup 1) (match_dup 2)))]
11116   "ix86_match_ccmode (insn, CCGOCmode)
11117    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11119   switch (get_attr_type (insn))
11120     {
11121     case TYPE_ALU:
11122       if (operands[2] != const1_rtx)
11123         abort ();
11124       return "add{w}\t{%0, %0|%0, %0}";
11126     default:
11127       if (REG_P (operands[2]))
11128         return "sal{w}\t{%b2, %0|%0, %b2}";
11129       else if (operands[2] == const1_rtx
11130                && (TARGET_SHIFT1 || optimize_size))
11131         return "sal{w}\t%0";
11132       else
11133         return "sal{w}\t{%2, %0|%0, %2}";
11134     }
11136   [(set (attr "type")
11137      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11138                           (const_int 0))
11139                       (match_operand 0 "register_operand" ""))
11140                  (match_operand 2 "const1_operand" ""))
11141               (const_string "alu")
11142            ]
11143            (const_string "ishift")))
11144    (set_attr "mode" "HI")])
11146 (define_expand "ashlqi3"
11147   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11148         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11149                    (match_operand:QI 2 "nonmemory_operand" "")))
11150    (clobber (reg:CC FLAGS_REG))]
11151   "TARGET_QIMODE_MATH"
11152   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11154 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11156 (define_insn "*ashlqi3_1_lea"
11157   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11158         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11159                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11160    (clobber (reg:CC FLAGS_REG))]
11161   "!TARGET_PARTIAL_REG_STALL
11162    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11164   switch (get_attr_type (insn))
11165     {
11166     case TYPE_LEA:
11167       return "#";
11168     case TYPE_ALU:
11169       if (operands[2] != const1_rtx)
11170         abort ();
11171       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11172         return "add{l}\t{%k0, %k0|%k0, %k0}";
11173       else
11174         return "add{b}\t{%0, %0|%0, %0}";
11176     default:
11177       if (REG_P (operands[2]))
11178         {
11179           if (get_attr_mode (insn) == MODE_SI)
11180             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11181           else
11182             return "sal{b}\t{%b2, %0|%0, %b2}";
11183         }
11184       else if (operands[2] == const1_rtx
11185                && (TARGET_SHIFT1 || optimize_size))
11186         {
11187           if (get_attr_mode (insn) == MODE_SI)
11188             return "sal{l}\t%0";
11189           else
11190             return "sal{b}\t%0";
11191         }
11192       else
11193         {
11194           if (get_attr_mode (insn) == MODE_SI)
11195             return "sal{l}\t{%2, %k0|%k0, %2}";
11196           else
11197             return "sal{b}\t{%2, %0|%0, %2}";
11198         }
11199     }
11201   [(set (attr "type")
11202      (cond [(eq_attr "alternative" "2")
11203               (const_string "lea")
11204             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11205                           (const_int 0))
11206                       (match_operand 0 "register_operand" ""))
11207                  (match_operand 2 "const1_operand" ""))
11208               (const_string "alu")
11209            ]
11210            (const_string "ishift")))
11211    (set_attr "mode" "QI,SI,SI")])
11213 (define_insn "*ashlqi3_1"
11214   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11215         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11216                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11217    (clobber (reg:CC FLAGS_REG))]
11218   "TARGET_PARTIAL_REG_STALL
11219    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11221   switch (get_attr_type (insn))
11222     {
11223     case TYPE_ALU:
11224       if (operands[2] != const1_rtx)
11225         abort ();
11226       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11227         return "add{l}\t{%k0, %k0|%k0, %k0}";
11228       else
11229         return "add{b}\t{%0, %0|%0, %0}";
11231     default:
11232       if (REG_P (operands[2]))
11233         {
11234           if (get_attr_mode (insn) == MODE_SI)
11235             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11236           else
11237             return "sal{b}\t{%b2, %0|%0, %b2}";
11238         }
11239       else if (operands[2] == const1_rtx
11240                && (TARGET_SHIFT1 || optimize_size))
11241         {
11242           if (get_attr_mode (insn) == MODE_SI)
11243             return "sal{l}\t%0";
11244           else
11245             return "sal{b}\t%0";
11246         }
11247       else
11248         {
11249           if (get_attr_mode (insn) == MODE_SI)
11250             return "sal{l}\t{%2, %k0|%k0, %2}";
11251           else
11252             return "sal{b}\t{%2, %0|%0, %2}";
11253         }
11254     }
11256   [(set (attr "type")
11257      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11258                           (const_int 0))
11259                       (match_operand 0 "register_operand" ""))
11260                  (match_operand 2 "const1_operand" ""))
11261               (const_string "alu")
11262            ]
11263            (const_string "ishift")))
11264    (set_attr "mode" "QI,SI")])
11266 ;; This pattern can't accept a variable shift count, since shifts by
11267 ;; zero don't affect the flags.  We assume that shifts by constant
11268 ;; zero are optimized away.
11269 (define_insn "*ashlqi3_cmp"
11270   [(set (reg 17)
11271         (compare
11272           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11273                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11274           (const_int 0)))
11275    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11276         (ashift:QI (match_dup 1) (match_dup 2)))]
11277   "ix86_match_ccmode (insn, CCGOCmode)
11278    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11280   switch (get_attr_type (insn))
11281     {
11282     case TYPE_ALU:
11283       if (operands[2] != const1_rtx)
11284         abort ();
11285       return "add{b}\t{%0, %0|%0, %0}";
11287     default:
11288       if (REG_P (operands[2]))
11289         return "sal{b}\t{%b2, %0|%0, %b2}";
11290       else if (operands[2] == const1_rtx
11291                && (TARGET_SHIFT1 || optimize_size))
11292         return "sal{b}\t%0";
11293       else
11294         return "sal{b}\t{%2, %0|%0, %2}";
11295     }
11297   [(set (attr "type")
11298      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11299                           (const_int 0))
11300                       (match_operand 0 "register_operand" ""))
11301                  (match_operand 2 "const1_operand" ""))
11302               (const_string "alu")
11303            ]
11304            (const_string "ishift")))
11305    (set_attr "mode" "QI")])
11307 ;; See comment above `ashldi3' about how this works.
11309 (define_expand "ashrdi3"
11310   [(set (match_operand:DI 0 "shiftdi_operand" "")
11311         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11312                      (match_operand:QI 2 "nonmemory_operand" "")))]
11313   ""
11314   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11316 (define_insn "*ashrdi3_63_rex64"
11317   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11318         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11319                      (match_operand:DI 2 "const_int_operand" "i,i")))
11320    (clobber (reg:CC FLAGS_REG))]
11321   "TARGET_64BIT && INTVAL (operands[2]) == 63
11322    && (TARGET_USE_CLTD || optimize_size)
11323    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11324   "@
11325    {cqto|cqo}
11326    sar{q}\t{%2, %0|%0, %2}"
11327   [(set_attr "type" "imovx,ishift")
11328    (set_attr "prefix_0f" "0,*")
11329    (set_attr "length_immediate" "0,*")
11330    (set_attr "modrm" "0,1")
11331    (set_attr "mode" "DI")])
11333 (define_insn "*ashrdi3_1_one_bit_rex64"
11334   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11335         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11336                      (match_operand:QI 2 "const1_operand" "")))
11337    (clobber (reg:CC FLAGS_REG))]
11338   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11339    && (TARGET_SHIFT1 || optimize_size)"
11340   "sar{q}\t%0"
11341   [(set_attr "type" "ishift")
11342    (set (attr "length") 
11343      (if_then_else (match_operand:DI 0 "register_operand" "") 
11344         (const_string "2")
11345         (const_string "*")))])
11347 (define_insn "*ashrdi3_1_rex64"
11348   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11349         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11350                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11351    (clobber (reg:CC FLAGS_REG))]
11352   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11353   "@
11354    sar{q}\t{%2, %0|%0, %2}
11355    sar{q}\t{%b2, %0|%0, %b2}"
11356   [(set_attr "type" "ishift")
11357    (set_attr "mode" "DI")])
11359 ;; This pattern can't accept a variable shift count, since shifts by
11360 ;; zero don't affect the flags.  We assume that shifts by constant
11361 ;; zero are optimized away.
11362 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11363   [(set (reg 17)
11364         (compare
11365           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11366                        (match_operand:QI 2 "const1_operand" ""))
11367           (const_int 0)))
11368    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11369         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11370   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11371    && (TARGET_SHIFT1 || optimize_size)
11372    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11373   "sar{q}\t%0"
11374   [(set_attr "type" "ishift")
11375    (set (attr "length") 
11376      (if_then_else (match_operand:DI 0 "register_operand" "") 
11377         (const_string "2")
11378         (const_string "*")))])
11380 ;; This pattern can't accept a variable shift count, since shifts by
11381 ;; zero don't affect the flags.  We assume that shifts by constant
11382 ;; zero are optimized away.
11383 (define_insn "*ashrdi3_cmp_rex64"
11384   [(set (reg 17)
11385         (compare
11386           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11387                        (match_operand:QI 2 "const_int_operand" "n"))
11388           (const_int 0)))
11389    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11390         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11391   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11392    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11393   "sar{q}\t{%2, %0|%0, %2}"
11394   [(set_attr "type" "ishift")
11395    (set_attr "mode" "DI")])
11397 (define_insn "*ashrdi3_1"
11398   [(set (match_operand:DI 0 "register_operand" "=r")
11399         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11400                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "!TARGET_64BIT"
11403   "#"
11404   [(set_attr "type" "multi")])
11406 ;; By default we don't ask for a scratch register, because when DImode
11407 ;; values are manipulated, registers are already at a premium.  But if
11408 ;; we have one handy, we won't turn it away.
11409 (define_peephole2
11410   [(match_scratch:SI 3 "r")
11411    (parallel [(set (match_operand:DI 0 "register_operand" "")
11412                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11413                                 (match_operand:QI 2 "nonmemory_operand" "")))
11414               (clobber (reg:CC FLAGS_REG))])
11415    (match_dup 3)]
11416   "!TARGET_64BIT && TARGET_CMOVE"
11417   [(const_int 0)]
11418   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11420 (define_split
11421   [(set (match_operand:DI 0 "register_operand" "")
11422         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11423                      (match_operand:QI 2 "nonmemory_operand" "")))
11424    (clobber (reg:CC FLAGS_REG))]
11425   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11426   [(const_int 0)]
11427   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11429 (define_insn "x86_shrd_1"
11430   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11431         (ior:SI (ashiftrt:SI (match_dup 0)
11432                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11433                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11434                   (minus:QI (const_int 32) (match_dup 2)))))
11435    (clobber (reg:CC FLAGS_REG))]
11436   ""
11437   "@
11438    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11439    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11440   [(set_attr "type" "ishift")
11441    (set_attr "prefix_0f" "1")
11442    (set_attr "pent_pair" "np")
11443    (set_attr "mode" "SI")])
11445 (define_expand "x86_shift_adj_3"
11446   [(use (match_operand:SI 0 "register_operand" ""))
11447    (use (match_operand:SI 1 "register_operand" ""))
11448    (use (match_operand:QI 2 "register_operand" ""))]
11449   ""
11451   rtx label = gen_label_rtx ();
11452   rtx tmp;
11454   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11456   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11457   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11458   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11459                               gen_rtx_LABEL_REF (VOIDmode, label),
11460                               pc_rtx);
11461   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11462   JUMP_LABEL (tmp) = label;
11464   emit_move_insn (operands[0], operands[1]);
11465   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11467   emit_label (label);
11468   LABEL_NUSES (label) = 1;
11470   DONE;
11473 (define_insn "ashrsi3_31"
11474   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11475         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11476                      (match_operand:SI 2 "const_int_operand" "i,i")))
11477    (clobber (reg:CC FLAGS_REG))]
11478   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11479    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11480   "@
11481    {cltd|cdq}
11482    sar{l}\t{%2, %0|%0, %2}"
11483   [(set_attr "type" "imovx,ishift")
11484    (set_attr "prefix_0f" "0,*")
11485    (set_attr "length_immediate" "0,*")
11486    (set_attr "modrm" "0,1")
11487    (set_attr "mode" "SI")])
11489 (define_insn "*ashrsi3_31_zext"
11490   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11491         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11492                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11493    (clobber (reg:CC FLAGS_REG))]
11494   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11495    && INTVAL (operands[2]) == 31
11496    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11497   "@
11498    {cltd|cdq}
11499    sar{l}\t{%2, %k0|%k0, %2}"
11500   [(set_attr "type" "imovx,ishift")
11501    (set_attr "prefix_0f" "0,*")
11502    (set_attr "length_immediate" "0,*")
11503    (set_attr "modrm" "0,1")
11504    (set_attr "mode" "SI")])
11506 (define_expand "ashrsi3"
11507   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11508         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11509                      (match_operand:QI 2 "nonmemory_operand" "")))
11510    (clobber (reg:CC FLAGS_REG))]
11511   ""
11512   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11514 (define_insn "*ashrsi3_1_one_bit"
11515   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11516         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11517                      (match_operand:QI 2 "const1_operand" "")))
11518    (clobber (reg:CC FLAGS_REG))]
11519   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11520    && (TARGET_SHIFT1 || optimize_size)"
11521   "sar{l}\t%0"
11522   [(set_attr "type" "ishift")
11523    (set (attr "length") 
11524      (if_then_else (match_operand:SI 0 "register_operand" "") 
11525         (const_string "2")
11526         (const_string "*")))])
11528 (define_insn "*ashrsi3_1_one_bit_zext"
11529   [(set (match_operand:DI 0 "register_operand" "=r")
11530         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11531                                      (match_operand:QI 2 "const1_operand" ""))))
11532    (clobber (reg:CC FLAGS_REG))]
11533   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11534    && (TARGET_SHIFT1 || optimize_size)"
11535   "sar{l}\t%k0"
11536   [(set_attr "type" "ishift")
11537    (set_attr "length" "2")])
11539 (define_insn "*ashrsi3_1"
11540   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11541         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11542                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11543    (clobber (reg:CC FLAGS_REG))]
11544   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11545   "@
11546    sar{l}\t{%2, %0|%0, %2}
11547    sar{l}\t{%b2, %0|%0, %b2}"
11548   [(set_attr "type" "ishift")
11549    (set_attr "mode" "SI")])
11551 (define_insn "*ashrsi3_1_zext"
11552   [(set (match_operand:DI 0 "register_operand" "=r,r")
11553         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11554                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11555    (clobber (reg:CC FLAGS_REG))]
11556   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11557   "@
11558    sar{l}\t{%2, %k0|%k0, %2}
11559    sar{l}\t{%b2, %k0|%k0, %b2}"
11560   [(set_attr "type" "ishift")
11561    (set_attr "mode" "SI")])
11563 ;; This pattern can't accept a variable shift count, since shifts by
11564 ;; zero don't affect the flags.  We assume that shifts by constant
11565 ;; zero are optimized away.
11566 (define_insn "*ashrsi3_one_bit_cmp"
11567   [(set (reg 17)
11568         (compare
11569           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11570                        (match_operand:QI 2 "const1_operand" ""))
11571           (const_int 0)))
11572    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11573         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11574   "ix86_match_ccmode (insn, CCGOCmode)
11575    && (TARGET_SHIFT1 || optimize_size)
11576    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11577   "sar{l}\t%0"
11578   [(set_attr "type" "ishift")
11579    (set (attr "length") 
11580      (if_then_else (match_operand:SI 0 "register_operand" "") 
11581         (const_string "2")
11582         (const_string "*")))])
11584 (define_insn "*ashrsi3_one_bit_cmp_zext"
11585   [(set (reg 17)
11586         (compare
11587           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11588                        (match_operand:QI 2 "const1_operand" ""))
11589           (const_int 0)))
11590    (set (match_operand:DI 0 "register_operand" "=r")
11591         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11592   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11593    && (TARGET_SHIFT1 || optimize_size)
11594    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11595   "sar{l}\t%k0"
11596   [(set_attr "type" "ishift")
11597    (set_attr "length" "2")])
11599 ;; This pattern can't accept a variable shift count, since shifts by
11600 ;; zero don't affect the flags.  We assume that shifts by constant
11601 ;; zero are optimized away.
11602 (define_insn "*ashrsi3_cmp"
11603   [(set (reg 17)
11604         (compare
11605           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11606                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11607           (const_int 0)))
11608    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11609         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11610   "ix86_match_ccmode (insn, CCGOCmode)
11611    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11612   "sar{l}\t{%2, %0|%0, %2}"
11613   [(set_attr "type" "ishift")
11614    (set_attr "mode" "SI")])
11616 (define_insn "*ashrsi3_cmp_zext"
11617   [(set (reg 17)
11618         (compare
11619           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11620                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11621           (const_int 0)))
11622    (set (match_operand:DI 0 "register_operand" "=r")
11623         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11624   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11625    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11626   "sar{l}\t{%2, %k0|%k0, %2}"
11627   [(set_attr "type" "ishift")
11628    (set_attr "mode" "SI")])
11630 (define_expand "ashrhi3"
11631   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11632         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11633                      (match_operand:QI 2 "nonmemory_operand" "")))
11634    (clobber (reg:CC FLAGS_REG))]
11635   "TARGET_HIMODE_MATH"
11636   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11638 (define_insn "*ashrhi3_1_one_bit"
11639   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11640         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11641                      (match_operand:QI 2 "const1_operand" "")))
11642    (clobber (reg:CC FLAGS_REG))]
11643   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11644    && (TARGET_SHIFT1 || optimize_size)"
11645   "sar{w}\t%0"
11646   [(set_attr "type" "ishift")
11647    (set (attr "length") 
11648      (if_then_else (match_operand 0 "register_operand" "") 
11649         (const_string "2")
11650         (const_string "*")))])
11652 (define_insn "*ashrhi3_1"
11653   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11654         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11655                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11656    (clobber (reg:CC FLAGS_REG))]
11657   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11658   "@
11659    sar{w}\t{%2, %0|%0, %2}
11660    sar{w}\t{%b2, %0|%0, %b2}"
11661   [(set_attr "type" "ishift")
11662    (set_attr "mode" "HI")])
11664 ;; This pattern can't accept a variable shift count, since shifts by
11665 ;; zero don't affect the flags.  We assume that shifts by constant
11666 ;; zero are optimized away.
11667 (define_insn "*ashrhi3_one_bit_cmp"
11668   [(set (reg 17)
11669         (compare
11670           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11671                        (match_operand:QI 2 "const1_operand" ""))
11672           (const_int 0)))
11673    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11674         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11675   "ix86_match_ccmode (insn, CCGOCmode)
11676    && (TARGET_SHIFT1 || optimize_size)
11677    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11678   "sar{w}\t%0"
11679   [(set_attr "type" "ishift")
11680    (set (attr "length") 
11681      (if_then_else (match_operand 0 "register_operand" "") 
11682         (const_string "2")
11683         (const_string "*")))])
11685 ;; This pattern can't accept a variable shift count, since shifts by
11686 ;; zero don't affect the flags.  We assume that shifts by constant
11687 ;; zero are optimized away.
11688 (define_insn "*ashrhi3_cmp"
11689   [(set (reg 17)
11690         (compare
11691           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11692                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11693           (const_int 0)))
11694    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11695         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11696   "ix86_match_ccmode (insn, CCGOCmode)
11697    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11698   "sar{w}\t{%2, %0|%0, %2}"
11699   [(set_attr "type" "ishift")
11700    (set_attr "mode" "HI")])
11702 (define_expand "ashrqi3"
11703   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11704         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11705                      (match_operand:QI 2 "nonmemory_operand" "")))
11706    (clobber (reg:CC FLAGS_REG))]
11707   "TARGET_QIMODE_MATH"
11708   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11710 (define_insn "*ashrqi3_1_one_bit"
11711   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11712         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11713                      (match_operand:QI 2 "const1_operand" "")))
11714    (clobber (reg:CC FLAGS_REG))]
11715   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11716    && (TARGET_SHIFT1 || optimize_size)"
11717   "sar{b}\t%0"
11718   [(set_attr "type" "ishift")
11719    (set (attr "length") 
11720      (if_then_else (match_operand 0 "register_operand" "") 
11721         (const_string "2")
11722         (const_string "*")))])
11724 (define_insn "*ashrqi3_1_one_bit_slp"
11725   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11726         (ashiftrt:QI (match_dup 0)
11727                      (match_operand:QI 1 "const1_operand" "")))
11728    (clobber (reg:CC FLAGS_REG))]
11729   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11730    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11731    && (TARGET_SHIFT1 || optimize_size)"
11732   "sar{b}\t%0"
11733   [(set_attr "type" "ishift1")
11734    (set (attr "length") 
11735      (if_then_else (match_operand 0 "register_operand" "") 
11736         (const_string "2")
11737         (const_string "*")))])
11739 (define_insn "*ashrqi3_1"
11740   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11741         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11742                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11743    (clobber (reg:CC FLAGS_REG))]
11744   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11745   "@
11746    sar{b}\t{%2, %0|%0, %2}
11747    sar{b}\t{%b2, %0|%0, %b2}"
11748   [(set_attr "type" "ishift")
11749    (set_attr "mode" "QI")])
11751 (define_insn "*ashrqi3_1_slp"
11752   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11753         (ashiftrt:QI (match_dup 0)
11754                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11755    (clobber (reg:CC FLAGS_REG))]
11756   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11757    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11758   "@
11759    sar{b}\t{%1, %0|%0, %1}
11760    sar{b}\t{%b1, %0|%0, %b1}"
11761   [(set_attr "type" "ishift1")
11762    (set_attr "mode" "QI")])
11764 ;; This pattern can't accept a variable shift count, since shifts by
11765 ;; zero don't affect the flags.  We assume that shifts by constant
11766 ;; zero are optimized away.
11767 (define_insn "*ashrqi3_one_bit_cmp"
11768   [(set (reg 17)
11769         (compare
11770           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11771                        (match_operand:QI 2 "const1_operand" "I"))
11772           (const_int 0)))
11773    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11774         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11775   "ix86_match_ccmode (insn, CCGOCmode)
11776    && (TARGET_SHIFT1 || optimize_size)
11777    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11778   "sar{b}\t%0"
11779   [(set_attr "type" "ishift")
11780    (set (attr "length") 
11781      (if_then_else (match_operand 0 "register_operand" "") 
11782         (const_string "2")
11783         (const_string "*")))])
11785 ;; This pattern can't accept a variable shift count, since shifts by
11786 ;; zero don't affect the flags.  We assume that shifts by constant
11787 ;; zero are optimized away.
11788 (define_insn "*ashrqi3_cmp"
11789   [(set (reg 17)
11790         (compare
11791           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11792                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11793           (const_int 0)))
11794    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11795         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11796   "ix86_match_ccmode (insn, CCGOCmode)
11797    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11798   "sar{b}\t{%2, %0|%0, %2}"
11799   [(set_attr "type" "ishift")
11800    (set_attr "mode" "QI")])
11802 ;; Logical shift instructions
11804 ;; See comment above `ashldi3' about how this works.
11806 (define_expand "lshrdi3"
11807   [(set (match_operand:DI 0 "shiftdi_operand" "")
11808         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11809                      (match_operand:QI 2 "nonmemory_operand" "")))]
11810   ""
11811   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11813 (define_insn "*lshrdi3_1_one_bit_rex64"
11814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11815         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11816                      (match_operand:QI 2 "const1_operand" "")))
11817    (clobber (reg:CC FLAGS_REG))]
11818   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11819    && (TARGET_SHIFT1 || optimize_size)"
11820   "shr{q}\t%0"
11821   [(set_attr "type" "ishift")
11822    (set (attr "length") 
11823      (if_then_else (match_operand:DI 0 "register_operand" "") 
11824         (const_string "2")
11825         (const_string "*")))])
11827 (define_insn "*lshrdi3_1_rex64"
11828   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11829         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11830                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11833   "@
11834    shr{q}\t{%2, %0|%0, %2}
11835    shr{q}\t{%b2, %0|%0, %b2}"
11836   [(set_attr "type" "ishift")
11837    (set_attr "mode" "DI")])
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 "*lshrdi3_cmp_one_bit_rex64"
11843   [(set (reg 17)
11844         (compare
11845           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11846                        (match_operand:QI 2 "const1_operand" ""))
11847           (const_int 0)))
11848    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11849         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11850   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11851    && (TARGET_SHIFT1 || optimize_size)
11852    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11853   "shr{q}\t%0"
11854   [(set_attr "type" "ishift")
11855    (set (attr "length") 
11856      (if_then_else (match_operand:DI 0 "register_operand" "") 
11857         (const_string "2")
11858         (const_string "*")))])
11860 ;; This pattern can't accept a variable shift count, since shifts by
11861 ;; zero don't affect the flags.  We assume that shifts by constant
11862 ;; zero are optimized away.
11863 (define_insn "*lshrdi3_cmp_rex64"
11864   [(set (reg 17)
11865         (compare
11866           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11867                        (match_operand:QI 2 "const_int_operand" "e"))
11868           (const_int 0)))
11869    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11870         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11871   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11872    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11873   "shr{q}\t{%2, %0|%0, %2}"
11874   [(set_attr "type" "ishift")
11875    (set_attr "mode" "DI")])
11877 (define_insn "*lshrdi3_1"
11878   [(set (match_operand:DI 0 "register_operand" "=r")
11879         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11880                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11881    (clobber (reg:CC FLAGS_REG))]
11882   "!TARGET_64BIT"
11883   "#"
11884   [(set_attr "type" "multi")])
11886 ;; By default we don't ask for a scratch register, because when DImode
11887 ;; values are manipulated, registers are already at a premium.  But if
11888 ;; we have one handy, we won't turn it away.
11889 (define_peephole2
11890   [(match_scratch:SI 3 "r")
11891    (parallel [(set (match_operand:DI 0 "register_operand" "")
11892                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11893                                 (match_operand:QI 2 "nonmemory_operand" "")))
11894               (clobber (reg:CC FLAGS_REG))])
11895    (match_dup 3)]
11896   "!TARGET_64BIT && TARGET_CMOVE"
11897   [(const_int 0)]
11898   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11900 (define_split 
11901   [(set (match_operand:DI 0 "register_operand" "")
11902         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11903                      (match_operand:QI 2 "nonmemory_operand" "")))
11904    (clobber (reg:CC FLAGS_REG))]
11905   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11906   [(const_int 0)]
11907   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11909 (define_expand "lshrsi3"
11910   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11911         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11912                      (match_operand:QI 2 "nonmemory_operand" "")))
11913    (clobber (reg:CC FLAGS_REG))]
11914   ""
11915   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11917 (define_insn "*lshrsi3_1_one_bit"
11918   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11919         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11920                      (match_operand:QI 2 "const1_operand" "")))
11921    (clobber (reg:CC FLAGS_REG))]
11922   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11923    && (TARGET_SHIFT1 || optimize_size)"
11924   "shr{l}\t%0"
11925   [(set_attr "type" "ishift")
11926    (set (attr "length") 
11927      (if_then_else (match_operand:SI 0 "register_operand" "") 
11928         (const_string "2")
11929         (const_string "*")))])
11931 (define_insn "*lshrsi3_1_one_bit_zext"
11932   [(set (match_operand:DI 0 "register_operand" "=r")
11933         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11934                      (match_operand:QI 2 "const1_operand" "")))
11935    (clobber (reg:CC FLAGS_REG))]
11936   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11937    && (TARGET_SHIFT1 || optimize_size)"
11938   "shr{l}\t%k0"
11939   [(set_attr "type" "ishift")
11940    (set_attr "length" "2")])
11942 (define_insn "*lshrsi3_1"
11943   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11944         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11945                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11946    (clobber (reg:CC FLAGS_REG))]
11947   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11948   "@
11949    shr{l}\t{%2, %0|%0, %2}
11950    shr{l}\t{%b2, %0|%0, %b2}"
11951   [(set_attr "type" "ishift")
11952    (set_attr "mode" "SI")])
11954 (define_insn "*lshrsi3_1_zext"
11955   [(set (match_operand:DI 0 "register_operand" "=r,r")
11956         (zero_extend:DI
11957           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11958                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11959    (clobber (reg:CC FLAGS_REG))]
11960   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11961   "@
11962    shr{l}\t{%2, %k0|%k0, %2}
11963    shr{l}\t{%b2, %k0|%k0, %b2}"
11964   [(set_attr "type" "ishift")
11965    (set_attr "mode" "SI")])
11967 ;; This pattern can't accept a variable shift count, since shifts by
11968 ;; zero don't affect the flags.  We assume that shifts by constant
11969 ;; zero are optimized away.
11970 (define_insn "*lshrsi3_one_bit_cmp"
11971   [(set (reg 17)
11972         (compare
11973           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11974                        (match_operand:QI 2 "const1_operand" ""))
11975           (const_int 0)))
11976    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11977         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11978   "ix86_match_ccmode (insn, CCGOCmode)
11979    && (TARGET_SHIFT1 || optimize_size)
11980    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11981   "shr{l}\t%0"
11982   [(set_attr "type" "ishift")
11983    (set (attr "length") 
11984      (if_then_else (match_operand:SI 0 "register_operand" "") 
11985         (const_string "2")
11986         (const_string "*")))])
11988 (define_insn "*lshrsi3_cmp_one_bit_zext"
11989   [(set (reg 17)
11990         (compare
11991           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11992                        (match_operand:QI 2 "const1_operand" ""))
11993           (const_int 0)))
11994    (set (match_operand:DI 0 "register_operand" "=r")
11995         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11996   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11997    && (TARGET_SHIFT1 || optimize_size)
11998    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11999   "shr{l}\t%k0"
12000   [(set_attr "type" "ishift")
12001    (set_attr "length" "2")])
12003 ;; This pattern can't accept a variable shift count, since shifts by
12004 ;; zero don't affect the flags.  We assume that shifts by constant
12005 ;; zero are optimized away.
12006 (define_insn "*lshrsi3_cmp"
12007   [(set (reg 17)
12008         (compare
12009           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12010                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12011           (const_int 0)))
12012    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12013         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12014   "ix86_match_ccmode (insn, CCGOCmode)
12015    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12016   "shr{l}\t{%2, %0|%0, %2}"
12017   [(set_attr "type" "ishift")
12018    (set_attr "mode" "SI")])
12020 (define_insn "*lshrsi3_cmp_zext"
12021   [(set (reg 17)
12022         (compare
12023           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12024                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12025           (const_int 0)))
12026    (set (match_operand:DI 0 "register_operand" "=r")
12027         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12028   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12029    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12030   "shr{l}\t{%2, %k0|%k0, %2}"
12031   [(set_attr "type" "ishift")
12032    (set_attr "mode" "SI")])
12034 (define_expand "lshrhi3"
12035   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12036         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12037                      (match_operand:QI 2 "nonmemory_operand" "")))
12038    (clobber (reg:CC FLAGS_REG))]
12039   "TARGET_HIMODE_MATH"
12040   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12042 (define_insn "*lshrhi3_1_one_bit"
12043   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12044         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12045                      (match_operand:QI 2 "const1_operand" "")))
12046    (clobber (reg:CC FLAGS_REG))]
12047   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12048    && (TARGET_SHIFT1 || optimize_size)"
12049   "shr{w}\t%0"
12050   [(set_attr "type" "ishift")
12051    (set (attr "length") 
12052      (if_then_else (match_operand 0 "register_operand" "") 
12053         (const_string "2")
12054         (const_string "*")))])
12056 (define_insn "*lshrhi3_1"
12057   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12058         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12059                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12060    (clobber (reg:CC FLAGS_REG))]
12061   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12062   "@
12063    shr{w}\t{%2, %0|%0, %2}
12064    shr{w}\t{%b2, %0|%0, %b2}"
12065   [(set_attr "type" "ishift")
12066    (set_attr "mode" "HI")])
12068 ;; This pattern can't accept a variable shift count, since shifts by
12069 ;; zero don't affect the flags.  We assume that shifts by constant
12070 ;; zero are optimized away.
12071 (define_insn "*lshrhi3_one_bit_cmp"
12072   [(set (reg 17)
12073         (compare
12074           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12075                        (match_operand:QI 2 "const1_operand" ""))
12076           (const_int 0)))
12077    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12078         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12079   "ix86_match_ccmode (insn, CCGOCmode)
12080    && (TARGET_SHIFT1 || optimize_size)
12081    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12082   "shr{w}\t%0"
12083   [(set_attr "type" "ishift")
12084    (set (attr "length") 
12085      (if_then_else (match_operand:SI 0 "register_operand" "") 
12086         (const_string "2")
12087         (const_string "*")))])
12089 ;; This pattern can't accept a variable shift count, since shifts by
12090 ;; zero don't affect the flags.  We assume that shifts by constant
12091 ;; zero are optimized away.
12092 (define_insn "*lshrhi3_cmp"
12093   [(set (reg 17)
12094         (compare
12095           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12096                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12097           (const_int 0)))
12098    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12099         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12100   "ix86_match_ccmode (insn, CCGOCmode)
12101    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12102   "shr{w}\t{%2, %0|%0, %2}"
12103   [(set_attr "type" "ishift")
12104    (set_attr "mode" "HI")])
12106 (define_expand "lshrqi3"
12107   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12108         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12109                      (match_operand:QI 2 "nonmemory_operand" "")))
12110    (clobber (reg:CC FLAGS_REG))]
12111   "TARGET_QIMODE_MATH"
12112   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12114 (define_insn "*lshrqi3_1_one_bit"
12115   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12116         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12117                      (match_operand:QI 2 "const1_operand" "")))
12118    (clobber (reg:CC FLAGS_REG))]
12119   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12120    && (TARGET_SHIFT1 || optimize_size)"
12121   "shr{b}\t%0"
12122   [(set_attr "type" "ishift")
12123    (set (attr "length") 
12124      (if_then_else (match_operand 0 "register_operand" "") 
12125         (const_string "2")
12126         (const_string "*")))])
12128 (define_insn "*lshrqi3_1_one_bit_slp"
12129   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12130         (lshiftrt:QI (match_dup 0)
12131                      (match_operand:QI 1 "const1_operand" "")))
12132    (clobber (reg:CC FLAGS_REG))]
12133   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12134    && (TARGET_SHIFT1 || optimize_size)"
12135   "shr{b}\t%0"
12136   [(set_attr "type" "ishift1")
12137    (set (attr "length") 
12138      (if_then_else (match_operand 0 "register_operand" "") 
12139         (const_string "2")
12140         (const_string "*")))])
12142 (define_insn "*lshrqi3_1"
12143   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12144         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12145                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12148   "@
12149    shr{b}\t{%2, %0|%0, %2}
12150    shr{b}\t{%b2, %0|%0, %b2}"
12151   [(set_attr "type" "ishift")
12152    (set_attr "mode" "QI")])
12154 (define_insn "*lshrqi3_1_slp"
12155   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12156         (lshiftrt:QI (match_dup 0)
12157                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12158    (clobber (reg:CC FLAGS_REG))]
12159   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12160    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12161   "@
12162    shr{b}\t{%1, %0|%0, %1}
12163    shr{b}\t{%b1, %0|%0, %b1}"
12164   [(set_attr "type" "ishift1")
12165    (set_attr "mode" "QI")])
12167 ;; This pattern can't accept a variable shift count, since shifts by
12168 ;; zero don't affect the flags.  We assume that shifts by constant
12169 ;; zero are optimized away.
12170 (define_insn "*lshrqi2_one_bit_cmp"
12171   [(set (reg 17)
12172         (compare
12173           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12174                        (match_operand:QI 2 "const1_operand" ""))
12175           (const_int 0)))
12176    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12177         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12178   "ix86_match_ccmode (insn, CCGOCmode)
12179    && (TARGET_SHIFT1 || optimize_size)
12180    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12181   "shr{b}\t%0"
12182   [(set_attr "type" "ishift")
12183    (set (attr "length") 
12184      (if_then_else (match_operand:SI 0 "register_operand" "") 
12185         (const_string "2")
12186         (const_string "*")))])
12188 ;; This pattern can't accept a variable shift count, since shifts by
12189 ;; zero don't affect the flags.  We assume that shifts by constant
12190 ;; zero are optimized away.
12191 (define_insn "*lshrqi2_cmp"
12192   [(set (reg 17)
12193         (compare
12194           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12195                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12196           (const_int 0)))
12197    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12198         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12199   "ix86_match_ccmode (insn, CCGOCmode)
12200    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12201   "shr{b}\t{%2, %0|%0, %2}"
12202   [(set_attr "type" "ishift")
12203    (set_attr "mode" "QI")])
12205 ;; Rotate instructions
12207 (define_expand "rotldi3"
12208   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12209         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12210                    (match_operand:QI 2 "nonmemory_operand" "")))
12211    (clobber (reg:CC FLAGS_REG))]
12212   "TARGET_64BIT"
12213   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12215 (define_insn "*rotlsi3_1_one_bit_rex64"
12216   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12217         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12218                    (match_operand:QI 2 "const1_operand" "")))
12219    (clobber (reg:CC FLAGS_REG))]
12220   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12221    && (TARGET_SHIFT1 || optimize_size)"
12222   "rol{q}\t%0"
12223   [(set_attr "type" "rotate")
12224    (set (attr "length") 
12225      (if_then_else (match_operand:DI 0 "register_operand" "") 
12226         (const_string "2")
12227         (const_string "*")))])
12229 (define_insn "*rotldi3_1_rex64"
12230   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12231         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12232                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12233    (clobber (reg:CC FLAGS_REG))]
12234   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12235   "@
12236    rol{q}\t{%2, %0|%0, %2}
12237    rol{q}\t{%b2, %0|%0, %b2}"
12238   [(set_attr "type" "rotate")
12239    (set_attr "mode" "DI")])
12241 (define_expand "rotlsi3"
12242   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12243         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12244                    (match_operand:QI 2 "nonmemory_operand" "")))
12245    (clobber (reg:CC FLAGS_REG))]
12246   ""
12247   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12249 (define_insn "*rotlsi3_1_one_bit"
12250   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12251         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12252                    (match_operand:QI 2 "const1_operand" "")))
12253    (clobber (reg:CC FLAGS_REG))]
12254   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12255    && (TARGET_SHIFT1 || optimize_size)"
12256   "rol{l}\t%0"
12257   [(set_attr "type" "rotate")
12258    (set (attr "length") 
12259      (if_then_else (match_operand:SI 0 "register_operand" "") 
12260         (const_string "2")
12261         (const_string "*")))])
12263 (define_insn "*rotlsi3_1_one_bit_zext"
12264   [(set (match_operand:DI 0 "register_operand" "=r")
12265         (zero_extend:DI
12266           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12267                      (match_operand:QI 2 "const1_operand" ""))))
12268    (clobber (reg:CC FLAGS_REG))]
12269   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12270    && (TARGET_SHIFT1 || optimize_size)"
12271   "rol{l}\t%k0"
12272   [(set_attr "type" "rotate")
12273    (set_attr "length" "2")])
12275 (define_insn "*rotlsi3_1"
12276   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12277         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12278                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12279    (clobber (reg:CC FLAGS_REG))]
12280   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12281   "@
12282    rol{l}\t{%2, %0|%0, %2}
12283    rol{l}\t{%b2, %0|%0, %b2}"
12284   [(set_attr "type" "rotate")
12285    (set_attr "mode" "SI")])
12287 (define_insn "*rotlsi3_1_zext"
12288   [(set (match_operand:DI 0 "register_operand" "=r,r")
12289         (zero_extend:DI
12290           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12291                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12292    (clobber (reg:CC FLAGS_REG))]
12293   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12294   "@
12295    rol{l}\t{%2, %k0|%k0, %2}
12296    rol{l}\t{%b2, %k0|%k0, %b2}"
12297   [(set_attr "type" "rotate")
12298    (set_attr "mode" "SI")])
12300 (define_expand "rotlhi3"
12301   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12302         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12303                    (match_operand:QI 2 "nonmemory_operand" "")))
12304    (clobber (reg:CC FLAGS_REG))]
12305   "TARGET_HIMODE_MATH"
12306   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12308 (define_insn "*rotlhi3_1_one_bit"
12309   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12310         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12311                    (match_operand:QI 2 "const1_operand" "")))
12312    (clobber (reg:CC FLAGS_REG))]
12313   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12314    && (TARGET_SHIFT1 || optimize_size)"
12315   "rol{w}\t%0"
12316   [(set_attr "type" "rotate")
12317    (set (attr "length") 
12318      (if_then_else (match_operand 0 "register_operand" "") 
12319         (const_string "2")
12320         (const_string "*")))])
12322 (define_insn "*rotlhi3_1"
12323   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12324         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12325                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12326    (clobber (reg:CC FLAGS_REG))]
12327   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12328   "@
12329    rol{w}\t{%2, %0|%0, %2}
12330    rol{w}\t{%b2, %0|%0, %b2}"
12331   [(set_attr "type" "rotate")
12332    (set_attr "mode" "HI")])
12334 (define_expand "rotlqi3"
12335   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12336         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12337                    (match_operand:QI 2 "nonmemory_operand" "")))
12338    (clobber (reg:CC FLAGS_REG))]
12339   "TARGET_QIMODE_MATH"
12340   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12342 (define_insn "*rotlqi3_1_one_bit_slp"
12343   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12344         (rotate:QI (match_dup 0)
12345                    (match_operand:QI 1 "const1_operand" "")))
12346    (clobber (reg:CC FLAGS_REG))]
12347   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12348    && (TARGET_SHIFT1 || optimize_size)"
12349   "rol{b}\t%0"
12350   [(set_attr "type" "rotate1")
12351    (set (attr "length") 
12352      (if_then_else (match_operand 0 "register_operand" "") 
12353         (const_string "2")
12354         (const_string "*")))])
12356 (define_insn "*rotlqi3_1_one_bit"
12357   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12358         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12359                    (match_operand:QI 2 "const1_operand" "")))
12360    (clobber (reg:CC FLAGS_REG))]
12361   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12362    && (TARGET_SHIFT1 || optimize_size)"
12363   "rol{b}\t%0"
12364   [(set_attr "type" "rotate")
12365    (set (attr "length") 
12366      (if_then_else (match_operand 0 "register_operand" "") 
12367         (const_string "2")
12368         (const_string "*")))])
12370 (define_insn "*rotlqi3_1_slp"
12371   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12372         (rotate:QI (match_dup 0)
12373                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12374    (clobber (reg:CC FLAGS_REG))]
12375   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12376    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12377   "@
12378    rol{b}\t{%1, %0|%0, %1}
12379    rol{b}\t{%b1, %0|%0, %b1}"
12380   [(set_attr "type" "rotate1")
12381    (set_attr "mode" "QI")])
12383 (define_insn "*rotlqi3_1"
12384   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12385         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12386                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12387    (clobber (reg:CC FLAGS_REG))]
12388   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12389   "@
12390    rol{b}\t{%2, %0|%0, %2}
12391    rol{b}\t{%b2, %0|%0, %b2}"
12392   [(set_attr "type" "rotate")
12393    (set_attr "mode" "QI")])
12395 (define_expand "rotrdi3"
12396   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12397         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12398                      (match_operand:QI 2 "nonmemory_operand" "")))
12399    (clobber (reg:CC FLAGS_REG))]
12400   "TARGET_64BIT"
12401   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12403 (define_insn "*rotrdi3_1_one_bit_rex64"
12404   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12405         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12406                      (match_operand:QI 2 "const1_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12409    && (TARGET_SHIFT1 || optimize_size)"
12410   "ror{q}\t%0"
12411   [(set_attr "type" "rotate")
12412    (set (attr "length") 
12413      (if_then_else (match_operand:DI 0 "register_operand" "") 
12414         (const_string "2")
12415         (const_string "*")))])
12417 (define_insn "*rotrdi3_1_rex64"
12418   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12419         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12420                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12421    (clobber (reg:CC FLAGS_REG))]
12422   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12423   "@
12424    ror{q}\t{%2, %0|%0, %2}
12425    ror{q}\t{%b2, %0|%0, %b2}"
12426   [(set_attr "type" "rotate")
12427    (set_attr "mode" "DI")])
12429 (define_expand "rotrsi3"
12430   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12431         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12432                      (match_operand:QI 2 "nonmemory_operand" "")))
12433    (clobber (reg:CC FLAGS_REG))]
12434   ""
12435   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12437 (define_insn "*rotrsi3_1_one_bit"
12438   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12439         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12440                      (match_operand:QI 2 "const1_operand" "")))
12441    (clobber (reg:CC FLAGS_REG))]
12442   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12443    && (TARGET_SHIFT1 || optimize_size)"
12444   "ror{l}\t%0"
12445   [(set_attr "type" "rotate")
12446    (set (attr "length") 
12447      (if_then_else (match_operand:SI 0 "register_operand" "") 
12448         (const_string "2")
12449         (const_string "*")))])
12451 (define_insn "*rotrsi3_1_one_bit_zext"
12452   [(set (match_operand:DI 0 "register_operand" "=r")
12453         (zero_extend:DI
12454           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12455                        (match_operand:QI 2 "const1_operand" ""))))
12456    (clobber (reg:CC FLAGS_REG))]
12457   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12458    && (TARGET_SHIFT1 || optimize_size)"
12459   "ror{l}\t%k0"
12460   [(set_attr "type" "rotate")
12461    (set (attr "length") 
12462      (if_then_else (match_operand:SI 0 "register_operand" "") 
12463         (const_string "2")
12464         (const_string "*")))])
12466 (define_insn "*rotrsi3_1"
12467   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12468         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12469                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12470    (clobber (reg:CC FLAGS_REG))]
12471   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12472   "@
12473    ror{l}\t{%2, %0|%0, %2}
12474    ror{l}\t{%b2, %0|%0, %b2}"
12475   [(set_attr "type" "rotate")
12476    (set_attr "mode" "SI")])
12478 (define_insn "*rotrsi3_1_zext"
12479   [(set (match_operand:DI 0 "register_operand" "=r,r")
12480         (zero_extend:DI
12481           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12482                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12483    (clobber (reg:CC FLAGS_REG))]
12484   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12485   "@
12486    ror{l}\t{%2, %k0|%k0, %2}
12487    ror{l}\t{%b2, %k0|%k0, %b2}"
12488   [(set_attr "type" "rotate")
12489    (set_attr "mode" "SI")])
12491 (define_expand "rotrhi3"
12492   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12493         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12494                      (match_operand:QI 2 "nonmemory_operand" "")))
12495    (clobber (reg:CC FLAGS_REG))]
12496   "TARGET_HIMODE_MATH"
12497   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12499 (define_insn "*rotrhi3_one_bit"
12500   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12501         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12502                      (match_operand:QI 2 "const1_operand" "")))
12503    (clobber (reg:CC FLAGS_REG))]
12504   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12505    && (TARGET_SHIFT1 || optimize_size)"
12506   "ror{w}\t%0"
12507   [(set_attr "type" "rotate")
12508    (set (attr "length") 
12509      (if_then_else (match_operand 0 "register_operand" "") 
12510         (const_string "2")
12511         (const_string "*")))])
12513 (define_insn "*rotrhi3"
12514   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12515         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12516                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12517    (clobber (reg:CC FLAGS_REG))]
12518   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12519   "@
12520    ror{w}\t{%2, %0|%0, %2}
12521    ror{w}\t{%b2, %0|%0, %b2}"
12522   [(set_attr "type" "rotate")
12523    (set_attr "mode" "HI")])
12525 (define_expand "rotrqi3"
12526   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12527         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12528                      (match_operand:QI 2 "nonmemory_operand" "")))
12529    (clobber (reg:CC FLAGS_REG))]
12530   "TARGET_QIMODE_MATH"
12531   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12533 (define_insn "*rotrqi3_1_one_bit"
12534   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12535         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12536                      (match_operand:QI 2 "const1_operand" "")))
12537    (clobber (reg:CC FLAGS_REG))]
12538   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12539    && (TARGET_SHIFT1 || optimize_size)"
12540   "ror{b}\t%0"
12541   [(set_attr "type" "rotate")
12542    (set (attr "length") 
12543      (if_then_else (match_operand 0 "register_operand" "") 
12544         (const_string "2")
12545         (const_string "*")))])
12547 (define_insn "*rotrqi3_1_one_bit_slp"
12548   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12549         (rotatert:QI (match_dup 0)
12550                      (match_operand:QI 1 "const1_operand" "")))
12551    (clobber (reg:CC FLAGS_REG))]
12552   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12553    && (TARGET_SHIFT1 || optimize_size)"
12554   "ror{b}\t%0"
12555   [(set_attr "type" "rotate1")
12556    (set (attr "length") 
12557      (if_then_else (match_operand 0 "register_operand" "") 
12558         (const_string "2")
12559         (const_string "*")))])
12561 (define_insn "*rotrqi3_1"
12562   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12563         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12564                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12565    (clobber (reg:CC FLAGS_REG))]
12566   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12567   "@
12568    ror{b}\t{%2, %0|%0, %2}
12569    ror{b}\t{%b2, %0|%0, %b2}"
12570   [(set_attr "type" "rotate")
12571    (set_attr "mode" "QI")])
12573 (define_insn "*rotrqi3_1_slp"
12574   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12575         (rotatert:QI (match_dup 0)
12576                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12577    (clobber (reg:CC FLAGS_REG))]
12578   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12579    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12580   "@
12581    ror{b}\t{%1, %0|%0, %1}
12582    ror{b}\t{%b1, %0|%0, %b1}"
12583   [(set_attr "type" "rotate1")
12584    (set_attr "mode" "QI")])
12586 ;; Bit set / bit test instructions
12588 (define_expand "extv"
12589   [(set (match_operand:SI 0 "register_operand" "")
12590         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12591                          (match_operand:SI 2 "immediate_operand" "")
12592                          (match_operand:SI 3 "immediate_operand" "")))]
12593   ""
12595   /* Handle extractions from %ah et al.  */
12596   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12597     FAIL;
12599   /* From mips.md: extract_bit_field doesn't verify that our source
12600      matches the predicate, so check it again here.  */
12601   if (! register_operand (operands[1], VOIDmode))
12602     FAIL;
12605 (define_expand "extzv"
12606   [(set (match_operand:SI 0 "register_operand" "")
12607         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12608                          (match_operand:SI 2 "immediate_operand" "")
12609                          (match_operand:SI 3 "immediate_operand" "")))]
12610   ""
12612   /* Handle extractions from %ah et al.  */
12613   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12614     FAIL;
12616   /* From mips.md: extract_bit_field doesn't verify that our source
12617      matches the predicate, so check it again here.  */
12618   if (! register_operand (operands[1], VOIDmode))
12619     FAIL;
12622 (define_expand "insv"
12623   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12624                       (match_operand 1 "immediate_operand" "")
12625                       (match_operand 2 "immediate_operand" ""))
12626         (match_operand 3 "register_operand" ""))]
12627   ""
12629   /* Handle extractions from %ah et al.  */
12630   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12631     FAIL;
12633   /* From mips.md: insert_bit_field doesn't verify that our source
12634      matches the predicate, so check it again here.  */
12635   if (! register_operand (operands[0], VOIDmode))
12636     FAIL;
12638   if (TARGET_64BIT)
12639     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12640   else
12641     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12643   DONE;
12646 ;; %%% bts, btr, btc, bt.
12648 ;; Store-flag instructions.
12650 ;; For all sCOND expanders, also expand the compare or test insn that
12651 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12653 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12654 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12655 ;; way, which can later delete the movzx if only QImode is needed.
12657 (define_expand "seq"
12658   [(set (match_operand:QI 0 "register_operand" "")
12659         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12660   ""
12661   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12663 (define_expand "sne"
12664   [(set (match_operand:QI 0 "register_operand" "")
12665         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12666   ""
12667   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12669 (define_expand "sgt"
12670   [(set (match_operand:QI 0 "register_operand" "")
12671         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12672   ""
12673   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12675 (define_expand "sgtu"
12676   [(set (match_operand:QI 0 "register_operand" "")
12677         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12678   ""
12679   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12681 (define_expand "slt"
12682   [(set (match_operand:QI 0 "register_operand" "")
12683         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12684   ""
12685   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12687 (define_expand "sltu"
12688   [(set (match_operand:QI 0 "register_operand" "")
12689         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12690   ""
12691   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12693 (define_expand "sge"
12694   [(set (match_operand:QI 0 "register_operand" "")
12695         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12696   ""
12697   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12699 (define_expand "sgeu"
12700   [(set (match_operand:QI 0 "register_operand" "")
12701         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12702   ""
12703   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12705 (define_expand "sle"
12706   [(set (match_operand:QI 0 "register_operand" "")
12707         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12708   ""
12709   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12711 (define_expand "sleu"
12712   [(set (match_operand:QI 0 "register_operand" "")
12713         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12714   ""
12715   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12717 (define_expand "sunordered"
12718   [(set (match_operand:QI 0 "register_operand" "")
12719         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12720   "TARGET_80387 || TARGET_SSE"
12721   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12723 (define_expand "sordered"
12724   [(set (match_operand:QI 0 "register_operand" "")
12725         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12726   "TARGET_80387"
12727   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12729 (define_expand "suneq"
12730   [(set (match_operand:QI 0 "register_operand" "")
12731         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12732   "TARGET_80387 || TARGET_SSE"
12733   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12735 (define_expand "sunge"
12736   [(set (match_operand:QI 0 "register_operand" "")
12737         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12738   "TARGET_80387 || TARGET_SSE"
12739   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12741 (define_expand "sungt"
12742   [(set (match_operand:QI 0 "register_operand" "")
12743         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744   "TARGET_80387 || TARGET_SSE"
12745   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12747 (define_expand "sunle"
12748   [(set (match_operand:QI 0 "register_operand" "")
12749         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750   "TARGET_80387 || TARGET_SSE"
12751   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12753 (define_expand "sunlt"
12754   [(set (match_operand:QI 0 "register_operand" "")
12755         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756   "TARGET_80387 || TARGET_SSE"
12757   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12759 (define_expand "sltgt"
12760   [(set (match_operand:QI 0 "register_operand" "")
12761         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762   "TARGET_80387 || TARGET_SSE"
12763   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12765 (define_insn "*setcc_1"
12766   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12767         (match_operator:QI 1 "ix86_comparison_operator"
12768           [(reg 17) (const_int 0)]))]
12769   ""
12770   "set%C1\t%0"
12771   [(set_attr "type" "setcc")
12772    (set_attr "mode" "QI")])
12774 (define_insn "*setcc_2"
12775   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12776         (match_operator:QI 1 "ix86_comparison_operator"
12777           [(reg 17) (const_int 0)]))]
12778   ""
12779   "set%C1\t%0"
12780   [(set_attr "type" "setcc")
12781    (set_attr "mode" "QI")])
12783 ;; In general it is not safe to assume too much about CCmode registers,
12784 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12785 ;; conditions this is safe on x86, so help combine not create
12787 ;;      seta    %al
12788 ;;      testb   %al, %al
12789 ;;      sete    %al
12791 (define_split 
12792   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12793         (ne:QI (match_operator 1 "ix86_comparison_operator"
12794                  [(reg 17) (const_int 0)])
12795             (const_int 0)))]
12796   ""
12797   [(set (match_dup 0) (match_dup 1))]
12799   PUT_MODE (operands[1], QImode);
12802 (define_split 
12803   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12804         (ne:QI (match_operator 1 "ix86_comparison_operator"
12805                  [(reg 17) (const_int 0)])
12806             (const_int 0)))]
12807   ""
12808   [(set (match_dup 0) (match_dup 1))]
12810   PUT_MODE (operands[1], QImode);
12813 (define_split 
12814   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12815         (eq:QI (match_operator 1 "ix86_comparison_operator"
12816                  [(reg 17) (const_int 0)])
12817             (const_int 0)))]
12818   ""
12819   [(set (match_dup 0) (match_dup 1))]
12821   rtx new_op1 = copy_rtx (operands[1]);
12822   operands[1] = new_op1;
12823   PUT_MODE (new_op1, QImode);
12824   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12825                                              GET_MODE (XEXP (new_op1, 0))));
12827   /* Make sure that (a) the CCmode we have for the flags is strong
12828      enough for the reversed compare or (b) we have a valid FP compare.  */
12829   if (! ix86_comparison_operator (new_op1, VOIDmode))
12830     FAIL;
12833 (define_split 
12834   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12835         (eq:QI (match_operator 1 "ix86_comparison_operator"
12836                  [(reg 17) (const_int 0)])
12837             (const_int 0)))]
12838   ""
12839   [(set (match_dup 0) (match_dup 1))]
12841   rtx new_op1 = copy_rtx (operands[1]);
12842   operands[1] = new_op1;
12843   PUT_MODE (new_op1, QImode);
12844   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12845                                              GET_MODE (XEXP (new_op1, 0))));
12847   /* Make sure that (a) the CCmode we have for the flags is strong
12848      enough for the reversed compare or (b) we have a valid FP compare.  */
12849   if (! ix86_comparison_operator (new_op1, VOIDmode))
12850     FAIL;
12853 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12854 ;; subsequent logical operations are used to imitate conditional moves.
12855 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12856 ;; it directly.  Further holding this value in pseudo register might bring
12857 ;; problem in implicit normalization in spill code.
12858 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12859 ;; instructions after reload by splitting the conditional move patterns.
12861 (define_insn "*sse_setccsf"
12862   [(set (match_operand:SF 0 "register_operand" "=x")
12863         (match_operator:SF 1 "sse_comparison_operator"
12864           [(match_operand:SF 2 "register_operand" "0")
12865            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12866   "TARGET_SSE && reload_completed"
12867   "cmp%D1ss\t{%3, %0|%0, %3}"
12868   [(set_attr "type" "ssecmp")
12869    (set_attr "mode" "SF")])
12871 (define_insn "*sse_setccdf"
12872   [(set (match_operand:DF 0 "register_operand" "=Y")
12873         (match_operator:DF 1 "sse_comparison_operator"
12874           [(match_operand:DF 2 "register_operand" "0")
12875            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12876   "TARGET_SSE2 && reload_completed"
12877   "cmp%D1sd\t{%3, %0|%0, %3}"
12878   [(set_attr "type" "ssecmp")
12879    (set_attr "mode" "DF")])
12881 ;; Basic conditional jump instructions.
12882 ;; We ignore the overflow flag for signed branch instructions.
12884 ;; For all bCOND expanders, also expand the compare or test insn that
12885 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12887 (define_expand "beq"
12888   [(set (pc)
12889         (if_then_else (match_dup 1)
12890                       (label_ref (match_operand 0 "" ""))
12891                       (pc)))]
12892   ""
12893   "ix86_expand_branch (EQ, operands[0]); DONE;")
12895 (define_expand "bne"
12896   [(set (pc)
12897         (if_then_else (match_dup 1)
12898                       (label_ref (match_operand 0 "" ""))
12899                       (pc)))]
12900   ""
12901   "ix86_expand_branch (NE, operands[0]); DONE;")
12903 (define_expand "bgt"
12904   [(set (pc)
12905         (if_then_else (match_dup 1)
12906                       (label_ref (match_operand 0 "" ""))
12907                       (pc)))]
12908   ""
12909   "ix86_expand_branch (GT, operands[0]); DONE;")
12911 (define_expand "bgtu"
12912   [(set (pc)
12913         (if_then_else (match_dup 1)
12914                       (label_ref (match_operand 0 "" ""))
12915                       (pc)))]
12916   ""
12917   "ix86_expand_branch (GTU, operands[0]); DONE;")
12919 (define_expand "blt"
12920   [(set (pc)
12921         (if_then_else (match_dup 1)
12922                       (label_ref (match_operand 0 "" ""))
12923                       (pc)))]
12924   ""
12925   "ix86_expand_branch (LT, operands[0]); DONE;")
12927 (define_expand "bltu"
12928   [(set (pc)
12929         (if_then_else (match_dup 1)
12930                       (label_ref (match_operand 0 "" ""))
12931                       (pc)))]
12932   ""
12933   "ix86_expand_branch (LTU, operands[0]); DONE;")
12935 (define_expand "bge"
12936   [(set (pc)
12937         (if_then_else (match_dup 1)
12938                       (label_ref (match_operand 0 "" ""))
12939                       (pc)))]
12940   ""
12941   "ix86_expand_branch (GE, operands[0]); DONE;")
12943 (define_expand "bgeu"
12944   [(set (pc)
12945         (if_then_else (match_dup 1)
12946                       (label_ref (match_operand 0 "" ""))
12947                       (pc)))]
12948   ""
12949   "ix86_expand_branch (GEU, operands[0]); DONE;")
12951 (define_expand "ble"
12952   [(set (pc)
12953         (if_then_else (match_dup 1)
12954                       (label_ref (match_operand 0 "" ""))
12955                       (pc)))]
12956   ""
12957   "ix86_expand_branch (LE, operands[0]); DONE;")
12959 (define_expand "bleu"
12960   [(set (pc)
12961         (if_then_else (match_dup 1)
12962                       (label_ref (match_operand 0 "" ""))
12963                       (pc)))]
12964   ""
12965   "ix86_expand_branch (LEU, operands[0]); DONE;")
12967 (define_expand "bunordered"
12968   [(set (pc)
12969         (if_then_else (match_dup 1)
12970                       (label_ref (match_operand 0 "" ""))
12971                       (pc)))]
12972   "TARGET_80387 || TARGET_SSE"
12973   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12975 (define_expand "bordered"
12976   [(set (pc)
12977         (if_then_else (match_dup 1)
12978                       (label_ref (match_operand 0 "" ""))
12979                       (pc)))]
12980   "TARGET_80387 || TARGET_SSE"
12981   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12983 (define_expand "buneq"
12984   [(set (pc)
12985         (if_then_else (match_dup 1)
12986                       (label_ref (match_operand 0 "" ""))
12987                       (pc)))]
12988   "TARGET_80387 || TARGET_SSE"
12989   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12991 (define_expand "bunge"
12992   [(set (pc)
12993         (if_then_else (match_dup 1)
12994                       (label_ref (match_operand 0 "" ""))
12995                       (pc)))]
12996   "TARGET_80387 || TARGET_SSE"
12997   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12999 (define_expand "bungt"
13000   [(set (pc)
13001         (if_then_else (match_dup 1)
13002                       (label_ref (match_operand 0 "" ""))
13003                       (pc)))]
13004   "TARGET_80387 || TARGET_SSE"
13005   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13007 (define_expand "bunle"
13008   [(set (pc)
13009         (if_then_else (match_dup 1)
13010                       (label_ref (match_operand 0 "" ""))
13011                       (pc)))]
13012   "TARGET_80387 || TARGET_SSE"
13013   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13015 (define_expand "bunlt"
13016   [(set (pc)
13017         (if_then_else (match_dup 1)
13018                       (label_ref (match_operand 0 "" ""))
13019                       (pc)))]
13020   "TARGET_80387 || TARGET_SSE"
13021   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13023 (define_expand "bltgt"
13024   [(set (pc)
13025         (if_then_else (match_dup 1)
13026                       (label_ref (match_operand 0 "" ""))
13027                       (pc)))]
13028   "TARGET_80387 || TARGET_SSE"
13029   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13031 (define_insn "*jcc_1"
13032   [(set (pc)
13033         (if_then_else (match_operator 1 "ix86_comparison_operator"
13034                                       [(reg 17) (const_int 0)])
13035                       (label_ref (match_operand 0 "" ""))
13036                       (pc)))]
13037   ""
13038   "%+j%C1\t%l0"
13039   [(set_attr "type" "ibr")
13040    (set_attr "modrm" "0")
13041    (set (attr "length")
13042            (if_then_else (and (ge (minus (match_dup 0) (pc))
13043                                   (const_int -126))
13044                               (lt (minus (match_dup 0) (pc))
13045                                   (const_int 128)))
13046              (const_int 2)
13047              (const_int 6)))])
13049 (define_insn "*jcc_2"
13050   [(set (pc)
13051         (if_then_else (match_operator 1 "ix86_comparison_operator"
13052                                       [(reg 17) (const_int 0)])
13053                       (pc)
13054                       (label_ref (match_operand 0 "" ""))))]
13055   ""
13056   "%+j%c1\t%l0"
13057   [(set_attr "type" "ibr")
13058    (set_attr "modrm" "0")
13059    (set (attr "length")
13060            (if_then_else (and (ge (minus (match_dup 0) (pc))
13061                                   (const_int -126))
13062                               (lt (minus (match_dup 0) (pc))
13063                                   (const_int 128)))
13064              (const_int 2)
13065              (const_int 6)))])
13067 ;; In general it is not safe to assume too much about CCmode registers,
13068 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13069 ;; conditions this is safe on x86, so help combine not create
13071 ;;      seta    %al
13072 ;;      testb   %al, %al
13073 ;;      je      Lfoo
13075 (define_split 
13076   [(set (pc)
13077         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13078                                       [(reg 17) (const_int 0)])
13079                           (const_int 0))
13080                       (label_ref (match_operand 1 "" ""))
13081                       (pc)))]
13082   ""
13083   [(set (pc)
13084         (if_then_else (match_dup 0)
13085                       (label_ref (match_dup 1))
13086                       (pc)))]
13088   PUT_MODE (operands[0], VOIDmode);
13090   
13091 (define_split 
13092   [(set (pc)
13093         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13094                                       [(reg 17) (const_int 0)])
13095                           (const_int 0))
13096                       (label_ref (match_operand 1 "" ""))
13097                       (pc)))]
13098   ""
13099   [(set (pc)
13100         (if_then_else (match_dup 0)
13101                       (label_ref (match_dup 1))
13102                       (pc)))]
13104   rtx new_op0 = copy_rtx (operands[0]);
13105   operands[0] = new_op0;
13106   PUT_MODE (new_op0, VOIDmode);
13107   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13108                                              GET_MODE (XEXP (new_op0, 0))));
13110   /* Make sure that (a) the CCmode we have for the flags is strong
13111      enough for the reversed compare or (b) we have a valid FP compare.  */
13112   if (! ix86_comparison_operator (new_op0, VOIDmode))
13113     FAIL;
13116 ;; Define combination compare-and-branch fp compare instructions to use
13117 ;; during early optimization.  Splitting the operation apart early makes
13118 ;; for bad code when we want to reverse the operation.
13120 (define_insn "*fp_jcc_1"
13121   [(set (pc)
13122         (if_then_else (match_operator 0 "comparison_operator"
13123                         [(match_operand 1 "register_operand" "f")
13124                          (match_operand 2 "register_operand" "f")])
13125           (label_ref (match_operand 3 "" ""))
13126           (pc)))
13127    (clobber (reg:CCFP FPSR_REG))
13128    (clobber (reg:CCFP FLAGS_REG))]
13129   "TARGET_CMOVE && TARGET_80387
13130    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13131    && FLOAT_MODE_P (GET_MODE (operands[1]))
13132    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13133    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13134   "#")
13136 (define_insn "*fp_jcc_1_sse"
13137   [(set (pc)
13138         (if_then_else (match_operator 0 "comparison_operator"
13139                         [(match_operand 1 "register_operand" "f#x,x#f")
13140                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13141           (label_ref (match_operand 3 "" ""))
13142           (pc)))
13143    (clobber (reg:CCFP FPSR_REG))
13144    (clobber (reg:CCFP FLAGS_REG))]
13145   "TARGET_80387
13146    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13147    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13148    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13149   "#")
13151 (define_insn "*fp_jcc_1_sse_only"
13152   [(set (pc)
13153         (if_then_else (match_operator 0 "comparison_operator"
13154                         [(match_operand 1 "register_operand" "x")
13155                          (match_operand 2 "nonimmediate_operand" "xm")])
13156           (label_ref (match_operand 3 "" ""))
13157           (pc)))
13158    (clobber (reg:CCFP FPSR_REG))
13159    (clobber (reg:CCFP FLAGS_REG))]
13160   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13161    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13162    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13163   "#")
13165 (define_insn "*fp_jcc_2"
13166   [(set (pc)
13167         (if_then_else (match_operator 0 "comparison_operator"
13168                         [(match_operand 1 "register_operand" "f")
13169                          (match_operand 2 "register_operand" "f")])
13170           (pc)
13171           (label_ref (match_operand 3 "" ""))))
13172    (clobber (reg:CCFP FPSR_REG))
13173    (clobber (reg:CCFP FLAGS_REG))]
13174   "TARGET_CMOVE && TARGET_80387
13175    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13176    && FLOAT_MODE_P (GET_MODE (operands[1]))
13177    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13178    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13179   "#")
13181 (define_insn "*fp_jcc_2_sse"
13182   [(set (pc)
13183         (if_then_else (match_operator 0 "comparison_operator"
13184                         [(match_operand 1 "register_operand" "f#x,x#f")
13185                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13186           (pc)
13187           (label_ref (match_operand 3 "" ""))))
13188    (clobber (reg:CCFP FPSR_REG))
13189    (clobber (reg:CCFP FLAGS_REG))]
13190   "TARGET_80387
13191    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13192    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13193    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13194   "#")
13196 (define_insn "*fp_jcc_2_sse_only"
13197   [(set (pc)
13198         (if_then_else (match_operator 0 "comparison_operator"
13199                         [(match_operand 1 "register_operand" "x")
13200                          (match_operand 2 "nonimmediate_operand" "xm")])
13201           (pc)
13202           (label_ref (match_operand 3 "" ""))))
13203    (clobber (reg:CCFP FPSR_REG))
13204    (clobber (reg:CCFP FLAGS_REG))]
13205   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13206    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13207    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13208   "#")
13210 (define_insn "*fp_jcc_3"
13211   [(set (pc)
13212         (if_then_else (match_operator 0 "comparison_operator"
13213                         [(match_operand 1 "register_operand" "f")
13214                          (match_operand 2 "nonimmediate_operand" "fm")])
13215           (label_ref (match_operand 3 "" ""))
13216           (pc)))
13217    (clobber (reg:CCFP FPSR_REG))
13218    (clobber (reg:CCFP FLAGS_REG))
13219    (clobber (match_scratch:HI 4 "=a"))]
13220   "TARGET_80387
13221    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13222    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13223    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13224    && SELECT_CC_MODE (GET_CODE (operands[0]),
13225                       operands[1], operands[2]) == CCFPmode
13226    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13227   "#")
13229 (define_insn "*fp_jcc_4"
13230   [(set (pc)
13231         (if_then_else (match_operator 0 "comparison_operator"
13232                         [(match_operand 1 "register_operand" "f")
13233                          (match_operand 2 "nonimmediate_operand" "fm")])
13234           (pc)
13235           (label_ref (match_operand 3 "" ""))))
13236    (clobber (reg:CCFP FPSR_REG))
13237    (clobber (reg:CCFP FLAGS_REG))
13238    (clobber (match_scratch:HI 4 "=a"))]
13239   "TARGET_80387
13240    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13241    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13243    && SELECT_CC_MODE (GET_CODE (operands[0]),
13244                       operands[1], operands[2]) == CCFPmode
13245    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13246   "#")
13248 (define_insn "*fp_jcc_5"
13249   [(set (pc)
13250         (if_then_else (match_operator 0 "comparison_operator"
13251                         [(match_operand 1 "register_operand" "f")
13252                          (match_operand 2 "register_operand" "f")])
13253           (label_ref (match_operand 3 "" ""))
13254           (pc)))
13255    (clobber (reg:CCFP FPSR_REG))
13256    (clobber (reg:CCFP FLAGS_REG))
13257    (clobber (match_scratch:HI 4 "=a"))]
13258   "TARGET_80387
13259    && FLOAT_MODE_P (GET_MODE (operands[1]))
13260    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13261    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13262   "#")
13264 (define_insn "*fp_jcc_6"
13265   [(set (pc)
13266         (if_then_else (match_operator 0 "comparison_operator"
13267                         [(match_operand 1 "register_operand" "f")
13268                          (match_operand 2 "register_operand" "f")])
13269           (pc)
13270           (label_ref (match_operand 3 "" ""))))
13271    (clobber (reg:CCFP FPSR_REG))
13272    (clobber (reg:CCFP FLAGS_REG))
13273    (clobber (match_scratch:HI 4 "=a"))]
13274   "TARGET_80387
13275    && FLOAT_MODE_P (GET_MODE (operands[1]))
13276    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13277    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13278   "#")
13280 (define_insn "*fp_jcc_7"
13281   [(set (pc)
13282         (if_then_else (match_operator 0 "comparison_operator"
13283                         [(match_operand 1 "register_operand" "f")
13284                          (match_operand 2 "const_double_operand" "C")])
13285           (label_ref (match_operand 3 "" ""))
13286           (pc)))
13287    (clobber (reg:CCFP FPSR_REG))
13288    (clobber (reg:CCFP FLAGS_REG))
13289    (clobber (match_scratch:HI 4 "=a"))]
13290   "TARGET_80387
13291    && FLOAT_MODE_P (GET_MODE (operands[1]))
13292    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13293    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13294    && SELECT_CC_MODE (GET_CODE (operands[0]),
13295                       operands[1], operands[2]) == CCFPmode
13296    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13297   "#")
13299 (define_split
13300   [(set (pc)
13301         (if_then_else (match_operator 0 "comparison_operator"
13302                         [(match_operand 1 "register_operand" "")
13303                          (match_operand 2 "nonimmediate_operand" "")])
13304           (match_operand 3 "" "")
13305           (match_operand 4 "" "")))
13306    (clobber (reg:CCFP FPSR_REG))
13307    (clobber (reg:CCFP FLAGS_REG))]
13308   "reload_completed"
13309   [(const_int 0)]
13311   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13312                         operands[3], operands[4], NULL_RTX);
13313   DONE;
13316 (define_split
13317   [(set (pc)
13318         (if_then_else (match_operator 0 "comparison_operator"
13319                         [(match_operand 1 "register_operand" "")
13320                          (match_operand 2 "general_operand" "")])
13321           (match_operand 3 "" "")
13322           (match_operand 4 "" "")))
13323    (clobber (reg:CCFP FPSR_REG))
13324    (clobber (reg:CCFP FLAGS_REG))
13325    (clobber (match_scratch:HI 5 "=a"))]
13326   "reload_completed"
13327   [(const_int 0)]
13329   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13330                         operands[3], operands[4], operands[5]);
13331   DONE;
13334 ;; Unconditional and other jump instructions
13336 (define_insn "jump"
13337   [(set (pc)
13338         (label_ref (match_operand 0 "" "")))]
13339   ""
13340   "jmp\t%l0"
13341   [(set_attr "type" "ibr")
13342    (set (attr "length")
13343            (if_then_else (and (ge (minus (match_dup 0) (pc))
13344                                   (const_int -126))
13345                               (lt (minus (match_dup 0) (pc))
13346                                   (const_int 128)))
13347              (const_int 2)
13348              (const_int 5)))
13349    (set_attr "modrm" "0")])
13351 (define_expand "indirect_jump"
13352   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13353   ""
13354   "")
13356 (define_insn "*indirect_jump"
13357   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13358   "!TARGET_64BIT"
13359   "jmp\t%A0"
13360   [(set_attr "type" "ibr")
13361    (set_attr "length_immediate" "0")])
13363 (define_insn "*indirect_jump_rtx64"
13364   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13365   "TARGET_64BIT"
13366   "jmp\t%A0"
13367   [(set_attr "type" "ibr")
13368    (set_attr "length_immediate" "0")])
13370 (define_expand "tablejump"
13371   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13372               (use (label_ref (match_operand 1 "" "")))])]
13373   ""
13375   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13376      relative.  Convert the relative address to an absolute address.  */
13377   if (flag_pic)
13378     {
13379       rtx op0, op1;
13380       enum rtx_code code;
13382       if (TARGET_64BIT)
13383         {
13384           code = PLUS;
13385           op0 = operands[0];
13386           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13387         }
13388       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13389         {
13390           code = PLUS;
13391           op0 = operands[0];
13392           op1 = pic_offset_table_rtx;
13393         }
13394       else
13395         {
13396           code = MINUS;
13397           op0 = pic_offset_table_rtx;
13398           op1 = operands[0];
13399         }
13401       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13402                                          OPTAB_DIRECT);
13403     }
13406 (define_insn "*tablejump_1"
13407   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13408    (use (label_ref (match_operand 1 "" "")))]
13409   "!TARGET_64BIT"
13410   "jmp\t%A0"
13411   [(set_attr "type" "ibr")
13412    (set_attr "length_immediate" "0")])
13414 (define_insn "*tablejump_1_rtx64"
13415   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13416    (use (label_ref (match_operand 1 "" "")))]
13417   "TARGET_64BIT"
13418   "jmp\t%A0"
13419   [(set_attr "type" "ibr")
13420    (set_attr "length_immediate" "0")])
13422 ;; Loop instruction
13424 ;; This is all complicated by the fact that since this is a jump insn
13425 ;; we must handle our own reloads.
13427 (define_expand "doloop_end"
13428   [(use (match_operand 0 "" ""))        ; loop pseudo
13429    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13430    (use (match_operand 2 "" ""))        ; max iterations
13431    (use (match_operand 3 "" ""))        ; loop level 
13432    (use (match_operand 4 "" ""))]       ; label
13433   "!TARGET_64BIT && TARGET_USE_LOOP"
13434   "                                 
13436   /* Only use cloop on innermost loops.  */
13437   if (INTVAL (operands[3]) > 1)
13438     FAIL;
13439   if (GET_MODE (operands[0]) != SImode)
13440     FAIL;
13441   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13442                                            operands[0]));
13443   DONE;
13446 (define_insn "doloop_end_internal"
13447   [(set (pc)
13448         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13449                           (const_int 1))
13450                       (label_ref (match_operand 0 "" ""))
13451                       (pc)))
13452    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13453         (plus:SI (match_dup 1)
13454                  (const_int -1)))
13455    (clobber (match_scratch:SI 3 "=X,X,r"))
13456    (clobber (reg:CC FLAGS_REG))]
13457   "!TARGET_64BIT && TARGET_USE_LOOP
13458    && (reload_in_progress || reload_completed
13459        || register_operand (operands[2], VOIDmode))"
13461   if (which_alternative != 0)
13462     return "#";
13463   if (get_attr_length (insn) == 2)
13464     return "%+loop\t%l0";
13465   else
13466     return "dec{l}\t%1\;%+jne\t%l0";
13468   [(set (attr "length")
13469         (if_then_else (and (eq_attr "alternative" "0")
13470                            (and (ge (minus (match_dup 0) (pc))
13471                                     (const_int -126))
13472                                 (lt (minus (match_dup 0) (pc))
13473                                     (const_int 128))))
13474                       (const_int 2)
13475                       (const_int 16)))
13476    ;; We don't know the type before shorten branches.  Optimistically expect
13477    ;; the loop instruction to match.
13478    (set (attr "type") (const_string "ibr"))])
13480 (define_split
13481   [(set (pc)
13482         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13483                           (const_int 1))
13484                       (match_operand 0 "" "")
13485                       (pc)))
13486    (set (match_dup 1)
13487         (plus:SI (match_dup 1)
13488                  (const_int -1)))
13489    (clobber (match_scratch:SI 2 ""))
13490    (clobber (reg:CC FLAGS_REG))]
13491   "!TARGET_64BIT && TARGET_USE_LOOP
13492    && reload_completed
13493    && REGNO (operands[1]) != 2"
13494   [(parallel [(set (reg:CCZ FLAGS_REG)
13495                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13496                                  (const_int 0)))
13497               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13498    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13499                            (match_dup 0)
13500                            (pc)))]
13501   "")
13502   
13503 (define_split
13504   [(set (pc)
13505         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13506                           (const_int 1))
13507                       (match_operand 0 "" "")
13508                       (pc)))
13509    (set (match_operand:SI 2 "nonimmediate_operand" "")
13510         (plus:SI (match_dup 1)
13511                  (const_int -1)))
13512    (clobber (match_scratch:SI 3 ""))
13513    (clobber (reg:CC FLAGS_REG))]
13514   "!TARGET_64BIT && TARGET_USE_LOOP
13515    && reload_completed
13516    && (! REG_P (operands[2])
13517        || ! rtx_equal_p (operands[1], operands[2]))"
13518   [(set (match_dup 3) (match_dup 1))
13519    (parallel [(set (reg:CCZ FLAGS_REG)
13520                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13521                                 (const_int 0)))
13522               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13523    (set (match_dup 2) (match_dup 3))
13524    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13525                            (match_dup 0)
13526                            (pc)))]
13527   "")
13529 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13531 (define_peephole2
13532   [(set (reg 17) (match_operand 0 "" ""))
13533    (set (match_operand:QI 1 "register_operand" "")
13534         (match_operator:QI 2 "ix86_comparison_operator"
13535           [(reg 17) (const_int 0)]))
13536    (set (match_operand 3 "q_regs_operand" "")
13537         (zero_extend (match_dup 1)))]
13538   "(peep2_reg_dead_p (3, operands[1])
13539     || operands_match_p (operands[1], operands[3]))
13540    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13541   [(set (match_dup 4) (match_dup 0))
13542    (set (strict_low_part (match_dup 5))
13543         (match_dup 2))]
13545   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13546   operands[5] = gen_lowpart (QImode, operands[3]);
13547   ix86_expand_clear (operands[3]);
13550 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13552 (define_peephole2
13553   [(set (reg 17) (match_operand 0 "" ""))
13554    (set (match_operand:QI 1 "register_operand" "")
13555         (match_operator:QI 2 "ix86_comparison_operator"
13556           [(reg 17) (const_int 0)]))
13557    (parallel [(set (match_operand 3 "q_regs_operand" "")
13558                    (zero_extend (match_dup 1)))
13559               (clobber (reg:CC FLAGS_REG))])]
13560   "(peep2_reg_dead_p (3, operands[1])
13561     || operands_match_p (operands[1], operands[3]))
13562    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13563   [(set (match_dup 4) (match_dup 0))
13564    (set (strict_low_part (match_dup 5))
13565         (match_dup 2))]
13567   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13568   operands[5] = gen_lowpart (QImode, operands[3]);
13569   ix86_expand_clear (operands[3]);
13572 ;; Call instructions.
13574 ;; The predicates normally associated with named expanders are not properly
13575 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13576 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13578 ;; Call subroutine returning no value.
13580 (define_expand "call_pop"
13581   [(parallel [(call (match_operand:QI 0 "" "")
13582                     (match_operand:SI 1 "" ""))
13583               (set (reg:SI SP_REG)
13584                    (plus:SI (reg:SI SP_REG)
13585                             (match_operand:SI 3 "" "")))])]
13586   "!TARGET_64BIT"
13588   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13589   DONE;
13592 (define_insn "*call_pop_0"
13593   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13594          (match_operand:SI 1 "" ""))
13595    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13596                             (match_operand:SI 2 "immediate_operand" "")))]
13597   "!TARGET_64BIT"
13599   if (SIBLING_CALL_P (insn))
13600     return "jmp\t%P0";
13601   else
13602     return "call\t%P0";
13604   [(set_attr "type" "call")])
13605   
13606 (define_insn "*call_pop_1"
13607   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13608          (match_operand:SI 1 "" ""))
13609    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13610                             (match_operand:SI 2 "immediate_operand" "i")))]
13611   "!TARGET_64BIT"
13613   if (constant_call_address_operand (operands[0], Pmode))
13614     {
13615       if (SIBLING_CALL_P (insn))
13616         return "jmp\t%P0";
13617       else
13618         return "call\t%P0";
13619     }
13620   if (SIBLING_CALL_P (insn))
13621     return "jmp\t%A0";
13622   else
13623     return "call\t%A0";
13625   [(set_attr "type" "call")])
13627 (define_expand "call"
13628   [(call (match_operand:QI 0 "" "")
13629          (match_operand 1 "" ""))
13630    (use (match_operand 2 "" ""))]
13631   ""
13633   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13634   DONE;
13637 (define_expand "sibcall"
13638   [(call (match_operand:QI 0 "" "")
13639          (match_operand 1 "" ""))
13640    (use (match_operand 2 "" ""))]
13641   ""
13643   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13644   DONE;
13647 (define_insn "*call_0"
13648   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13649          (match_operand 1 "" ""))]
13650   ""
13652   if (SIBLING_CALL_P (insn))
13653     return "jmp\t%P0";
13654   else
13655     return "call\t%P0";
13657   [(set_attr "type" "call")])
13659 (define_insn "*call_1"
13660   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13661          (match_operand 1 "" ""))]
13662   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13664   if (constant_call_address_operand (operands[0], Pmode))
13665     return "call\t%P0";
13666   return "call\t%A0";
13668   [(set_attr "type" "call")])
13670 (define_insn "*sibcall_1"
13671   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13672          (match_operand 1 "" ""))]
13673   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13675   if (constant_call_address_operand (operands[0], Pmode))
13676     return "jmp\t%P0";
13677   return "jmp\t%A0";
13679   [(set_attr "type" "call")])
13681 (define_insn "*call_1_rex64"
13682   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13683          (match_operand 1 "" ""))]
13684   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13686   if (constant_call_address_operand (operands[0], Pmode))
13687     return "call\t%P0";
13688   return "call\t%A0";
13690   [(set_attr "type" "call")])
13692 (define_insn "*sibcall_1_rex64"
13693   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13694          (match_operand 1 "" ""))]
13695   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13696   "jmp\t%P0"
13697   [(set_attr "type" "call")])
13699 (define_insn "*sibcall_1_rex64_v"
13700   [(call (mem:QI (reg:DI 40))
13701          (match_operand 0 "" ""))]
13702   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13703   "jmp\t*%%r11"
13704   [(set_attr "type" "call")])
13707 ;; Call subroutine, returning value in operand 0
13709 (define_expand "call_value_pop"
13710   [(parallel [(set (match_operand 0 "" "")
13711                    (call (match_operand:QI 1 "" "")
13712                          (match_operand:SI 2 "" "")))
13713               (set (reg:SI SP_REG)
13714                    (plus:SI (reg:SI SP_REG)
13715                             (match_operand:SI 4 "" "")))])]
13716   "!TARGET_64BIT"
13718   ix86_expand_call (operands[0], operands[1], operands[2],
13719                     operands[3], operands[4], 0);
13720   DONE;
13723 (define_expand "call_value"
13724   [(set (match_operand 0 "" "")
13725         (call (match_operand:QI 1 "" "")
13726               (match_operand:SI 2 "" "")))
13727    (use (match_operand:SI 3 "" ""))]
13728   ;; Operand 2 not used on the i386.
13729   ""
13731   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13732   DONE;
13735 (define_expand "sibcall_value"
13736   [(set (match_operand 0 "" "")
13737         (call (match_operand:QI 1 "" "")
13738               (match_operand:SI 2 "" "")))
13739    (use (match_operand:SI 3 "" ""))]
13740   ;; Operand 2 not used on the i386.
13741   ""
13743   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13744   DONE;
13747 ;; Call subroutine returning any type.
13749 (define_expand "untyped_call"
13750   [(parallel [(call (match_operand 0 "" "")
13751                     (const_int 0))
13752               (match_operand 1 "" "")
13753               (match_operand 2 "" "")])]
13754   ""
13756   int i;
13758   /* In order to give reg-stack an easier job in validating two
13759      coprocessor registers as containing a possible return value,
13760      simply pretend the untyped call returns a complex long double
13761      value.  */
13763   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13764                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13765                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13766                     NULL, 0);
13768   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13769     {
13770       rtx set = XVECEXP (operands[2], 0, i);
13771       emit_move_insn (SET_DEST (set), SET_SRC (set));
13772     }
13774   /* The optimizer does not know that the call sets the function value
13775      registers we stored in the result block.  We avoid problems by
13776      claiming that all hard registers are used and clobbered at this
13777      point.  */
13778   emit_insn (gen_blockage (const0_rtx));
13780   DONE;
13783 ;; Prologue and epilogue instructions
13785 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13786 ;; all of memory.  This blocks insns from being moved across this point.
13788 (define_insn "blockage"
13789   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13790   ""
13791   ""
13792   [(set_attr "length" "0")])
13794 ;; Insn emitted into the body of a function to return from a function.
13795 ;; This is only done if the function's epilogue is known to be simple.
13796 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13798 (define_expand "return"
13799   [(return)]
13800   "ix86_can_use_return_insn_p ()"
13802   if (current_function_pops_args)
13803     {
13804       rtx popc = GEN_INT (current_function_pops_args);
13805       emit_jump_insn (gen_return_pop_internal (popc));
13806       DONE;
13807     }
13810 (define_insn "return_internal"
13811   [(return)]
13812   "reload_completed"
13813   "ret"
13814   [(set_attr "length" "1")
13815    (set_attr "length_immediate" "0")
13816    (set_attr "modrm" "0")])
13818 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13819 ;; instruction Athlon and K8 have.
13821 (define_insn "return_internal_long"
13822   [(return)
13823    (unspec [(const_int 0)] UNSPEC_REP)]
13824   "reload_completed"
13825   "rep {;} ret"
13826   [(set_attr "length" "1")
13827    (set_attr "length_immediate" "0")
13828    (set_attr "prefix_rep" "1")
13829    (set_attr "modrm" "0")])
13831 (define_insn "return_pop_internal"
13832   [(return)
13833    (use (match_operand:SI 0 "const_int_operand" ""))]
13834   "reload_completed"
13835   "ret\t%0"
13836   [(set_attr "length" "3")
13837    (set_attr "length_immediate" "2")
13838    (set_attr "modrm" "0")])
13840 (define_insn "return_indirect_internal"
13841   [(return)
13842    (use (match_operand:SI 0 "register_operand" "r"))]
13843   "reload_completed"
13844   "jmp\t%A0"
13845   [(set_attr "type" "ibr")
13846    (set_attr "length_immediate" "0")])
13848 (define_insn "nop"
13849   [(const_int 0)]
13850   ""
13851   "nop"
13852   [(set_attr "length" "1")
13853    (set_attr "length_immediate" "0")
13854    (set_attr "modrm" "0")])
13856 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13857 ;; branch prediction penalty for the third jump in a 16-byte
13858 ;; block on K8.
13860 (define_insn "align"
13861   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13862   ""
13864 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13865   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13866 #else
13867   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13868      The align insn is used to avoid 3 jump instructions in the row to improve
13869      branch prediction and the benefits hardly outweight the cost of extra 8
13870      nops on the average inserted by full alignment pseudo operation.  */
13871 #endif
13872   return "";
13874   [(set_attr "length" "16")])
13876 (define_expand "prologue"
13877   [(const_int 1)]
13878   ""
13879   "ix86_expand_prologue (); DONE;")
13881 (define_insn "set_got"
13882   [(set (match_operand:SI 0 "register_operand" "=r")
13883         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13884    (clobber (reg:CC FLAGS_REG))]
13885   "!TARGET_64BIT"
13886   { return output_set_got (operands[0]); }
13887   [(set_attr "type" "multi")
13888    (set_attr "length" "12")])
13890 (define_expand "epilogue"
13891   [(const_int 1)]
13892   ""
13893   "ix86_expand_epilogue (1); DONE;")
13895 (define_expand "sibcall_epilogue"
13896   [(const_int 1)]
13897   ""
13898   "ix86_expand_epilogue (0); DONE;")
13900 (define_expand "eh_return"
13901   [(use (match_operand 0 "register_operand" ""))]
13902   ""
13904   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13906   /* Tricky bit: we write the address of the handler to which we will
13907      be returning into someone else's stack frame, one word below the
13908      stack address we wish to restore.  */
13909   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13910   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13911   tmp = gen_rtx_MEM (Pmode, tmp);
13912   emit_move_insn (tmp, ra);
13914   if (Pmode == SImode)
13915     emit_jump_insn (gen_eh_return_si (sa));
13916   else
13917     emit_jump_insn (gen_eh_return_di (sa));
13918   emit_barrier ();
13919   DONE;
13922 (define_insn_and_split "eh_return_si"
13923   [(set (pc) 
13924         (unspec [(match_operand:SI 0 "register_operand" "c")]
13925                  UNSPEC_EH_RETURN))]
13926   "!TARGET_64BIT"
13927   "#"
13928   "reload_completed"
13929   [(const_int 1)]
13930   "ix86_expand_epilogue (2); DONE;")
13932 (define_insn_and_split "eh_return_di"
13933   [(set (pc) 
13934         (unspec [(match_operand:DI 0 "register_operand" "c")]
13935                  UNSPEC_EH_RETURN))]
13936   "TARGET_64BIT"
13937   "#"
13938   "reload_completed"
13939   [(const_int 1)]
13940   "ix86_expand_epilogue (2); DONE;")
13942 (define_insn "leave"
13943   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13944    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13945    (clobber (mem:BLK (scratch)))]
13946   "!TARGET_64BIT"
13947   "leave"
13948   [(set_attr "type" "leave")])
13950 (define_insn "leave_rex64"
13951   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13952    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13953    (clobber (mem:BLK (scratch)))]
13954   "TARGET_64BIT"
13955   "leave"
13956   [(set_attr "type" "leave")])
13958 (define_expand "ffssi2"
13959   [(parallel
13960      [(set (match_operand:SI 0 "register_operand" "") 
13961            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13962       (clobber (match_scratch:SI 2 ""))
13963       (clobber (reg:CC FLAGS_REG))])]
13964   ""
13965   "")
13967 (define_insn_and_split "*ffs_cmove"
13968   [(set (match_operand:SI 0 "register_operand" "=r") 
13969         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13970    (clobber (match_scratch:SI 2 "=&r"))
13971    (clobber (reg:CC FLAGS_REG))]
13972   "TARGET_CMOVE"
13973   "#"
13974   "&& reload_completed"
13975   [(set (match_dup 2) (const_int -1))
13976    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13977               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13978    (set (match_dup 0) (if_then_else:SI
13979                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13980                         (match_dup 2)
13981                         (match_dup 0)))
13982    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13983               (clobber (reg:CC FLAGS_REG))])]
13984   "")
13986 (define_insn_and_split "*ffs_no_cmove"
13987   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13988         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13989    (clobber (match_scratch:SI 2 "=&q"))
13990    (clobber (reg:CC FLAGS_REG))]
13991   ""
13992   "#"
13993   "reload_completed"
13994   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13995               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13996    (set (strict_low_part (match_dup 3))
13997         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13998    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13999               (clobber (reg:CC FLAGS_REG))])
14000    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14001               (clobber (reg:CC FLAGS_REG))])
14002    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14003               (clobber (reg:CC FLAGS_REG))])]
14005   operands[3] = gen_lowpart (QImode, operands[2]);
14006   ix86_expand_clear (operands[2]);
14009 (define_insn "*ffssi_1"
14010   [(set (reg:CCZ FLAGS_REG)
14011         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14012                      (const_int 0)))
14013    (set (match_operand:SI 0 "register_operand" "=r")
14014         (ctz:SI (match_dup 1)))]
14015   ""
14016   "bsf{l}\t{%1, %0|%0, %1}"
14017   [(set_attr "prefix_0f" "1")])
14019 (define_expand "ffsdi2"
14020   [(parallel
14021      [(set (match_operand:DI 0 "register_operand" "") 
14022            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14023       (clobber (match_scratch:DI 2 ""))
14024       (clobber (reg:CC 17))])]
14025   "TARGET_64BIT && TARGET_CMOVE"
14026   "")
14028 (define_insn_and_split "*ffs_rex64"
14029   [(set (match_operand:DI 0 "register_operand" "=r") 
14030         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14031    (clobber (match_scratch:DI 2 "=&r"))
14032    (clobber (reg:CC 17))]
14033   "TARGET_64BIT && TARGET_CMOVE"
14034   "#"
14035   "&& reload_completed"
14036   [(set (match_dup 2) (const_int -1))
14037    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14038               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14039    (set (match_dup 0) (if_then_else:DI
14040                         (eq (reg:CCZ 17) (const_int 0))
14041                         (match_dup 2)
14042                         (match_dup 0)))
14043    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14044               (clobber (reg:CC 17))])]
14045   "")
14047 (define_insn "*ffsdi_1"
14048   [(set (reg:CCZ 17)
14049         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14050                      (const_int 0)))
14051    (set (match_operand:DI 0 "register_operand" "=r")
14052         (ctz:DI (match_dup 1)))]
14053   "TARGET_64BIT"
14054   "bsf{q}\t{%1, %0|%0, %1}"
14055   [(set_attr "prefix_0f" "1")])
14057 (define_insn "ctzsi2"
14058   [(set (match_operand:SI 0 "register_operand" "=r")
14059         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14060    (clobber (reg:CC FLAGS_REG))]
14061   ""
14062   "bsf{l}\t{%1, %0|%0, %1}"
14063   [(set_attr "prefix_0f" "1")])
14065 (define_insn "ctzdi2"
14066   [(set (match_operand:DI 0 "register_operand" "=r")
14067         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14068    (clobber (reg:CC 17))]
14069   "TARGET_64BIT"
14070   "bsf{q}\t{%1, %0|%0, %1}"
14071   [(set_attr "prefix_0f" "1")])
14073 (define_expand "clzsi2"
14074   [(parallel
14075      [(set (match_operand:SI 0 "register_operand" "")
14076            (minus:SI (const_int 31)
14077                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14078       (clobber (reg:CC FLAGS_REG))])
14079    (parallel
14080      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14081       (clobber (reg:CC FLAGS_REG))])]
14082   ""
14083   "")
14085 (define_insn "*bsr"
14086   [(set (match_operand:SI 0 "register_operand" "=r")
14087         (minus:SI (const_int 31)
14088                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14089    (clobber (reg:CC FLAGS_REG))]
14090   ""
14091   "bsr{l}\t{%1, %0|%0, %1}"
14092   [(set_attr "prefix_0f" "1")])
14094 (define_expand "clzdi2"
14095   [(parallel
14096      [(set (match_operand:DI 0 "register_operand" "")
14097            (minus:DI (const_int 63)
14098                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14099       (clobber (reg:CC 17))])
14100    (parallel
14101      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14102       (clobber (reg:CC 17))])]
14103   "TARGET_64BIT"
14104   "")
14106 (define_insn "*bsr_rex64"
14107   [(set (match_operand:DI 0 "register_operand" "=r")
14108         (minus:DI (const_int 63)
14109                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14110    (clobber (reg:CC 17))]
14111   "TARGET_64BIT"
14112   "bsr{q}\t{%1, %0|%0, %1}"
14113   [(set_attr "prefix_0f" "1")])
14115 ;; Thread-local storage patterns for ELF.
14117 ;; Note that these code sequences must appear exactly as shown
14118 ;; in order to allow linker relaxation.
14120 (define_insn "*tls_global_dynamic_32_gnu"
14121   [(set (match_operand:SI 0 "register_operand" "=a")
14122         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14123                     (match_operand:SI 2 "tls_symbolic_operand" "")
14124                     (match_operand:SI 3 "call_insn_operand" "")]
14125                     UNSPEC_TLS_GD))
14126    (clobber (match_scratch:SI 4 "=d"))
14127    (clobber (match_scratch:SI 5 "=c"))
14128    (clobber (reg:CC FLAGS_REG))]
14129   "!TARGET_64BIT && TARGET_GNU_TLS"
14130   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14131   [(set_attr "type" "multi")
14132    (set_attr "length" "12")])
14134 (define_insn "*tls_global_dynamic_32_sun"
14135   [(set (match_operand:SI 0 "register_operand" "=a")
14136         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14137                     (match_operand:SI 2 "tls_symbolic_operand" "")
14138                     (match_operand:SI 3 "call_insn_operand" "")]
14139                     UNSPEC_TLS_GD))
14140    (clobber (match_scratch:SI 4 "=d"))
14141    (clobber (match_scratch:SI 5 "=c"))
14142    (clobber (reg:CC FLAGS_REG))]
14143   "!TARGET_64BIT && TARGET_SUN_TLS"
14144   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14145         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14146   [(set_attr "type" "multi")
14147    (set_attr "length" "14")])
14149 (define_expand "tls_global_dynamic_32"
14150   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14151                    (unspec:SI
14152                     [(match_dup 2)
14153                      (match_operand:SI 1 "tls_symbolic_operand" "")
14154                      (match_dup 3)]
14155                     UNSPEC_TLS_GD))
14156               (clobber (match_scratch:SI 4 ""))
14157               (clobber (match_scratch:SI 5 ""))
14158               (clobber (reg:CC FLAGS_REG))])]
14159   ""
14161   if (flag_pic)
14162     operands[2] = pic_offset_table_rtx;
14163   else
14164     {
14165       operands[2] = gen_reg_rtx (Pmode);
14166       emit_insn (gen_set_got (operands[2]));
14167     }
14168   operands[3] = ix86_tls_get_addr ();
14171 (define_insn "*tls_global_dynamic_64"
14172   [(set (match_operand:DI 0 "register_operand" "=a")
14173         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14174                       (match_operand:DI 3 "" "")))
14175    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14176               UNSPEC_TLS_GD)]
14177   "TARGET_64BIT"
14178   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14179   [(set_attr "type" "multi")
14180    (set_attr "length" "16")])
14182 (define_expand "tls_global_dynamic_64"
14183   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14184                    (call (mem:QI (match_dup 2)) (const_int 0)))
14185               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14186                          UNSPEC_TLS_GD)])]
14187   ""
14189   operands[2] = ix86_tls_get_addr ();
14192 (define_insn "*tls_local_dynamic_base_32_gnu"
14193   [(set (match_operand:SI 0 "register_operand" "=a")
14194         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14195                     (match_operand:SI 2 "call_insn_operand" "")]
14196                    UNSPEC_TLS_LD_BASE))
14197    (clobber (match_scratch:SI 3 "=d"))
14198    (clobber (match_scratch:SI 4 "=c"))
14199    (clobber (reg:CC FLAGS_REG))]
14200   "!TARGET_64BIT && TARGET_GNU_TLS"
14201   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14202   [(set_attr "type" "multi")
14203    (set_attr "length" "11")])
14205 (define_insn "*tls_local_dynamic_base_32_sun"
14206   [(set (match_operand:SI 0 "register_operand" "=a")
14207         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14208                     (match_operand:SI 2 "call_insn_operand" "")]
14209                    UNSPEC_TLS_LD_BASE))
14210    (clobber (match_scratch:SI 3 "=d"))
14211    (clobber (match_scratch:SI 4 "=c"))
14212    (clobber (reg:CC FLAGS_REG))]
14213   "!TARGET_64BIT && TARGET_SUN_TLS"
14214   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14215         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14216   [(set_attr "type" "multi")
14217    (set_attr "length" "13")])
14219 (define_expand "tls_local_dynamic_base_32"
14220   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14221                    (unspec:SI [(match_dup 1) (match_dup 2)]
14222                               UNSPEC_TLS_LD_BASE))
14223               (clobber (match_scratch:SI 3 ""))
14224               (clobber (match_scratch:SI 4 ""))
14225               (clobber (reg:CC FLAGS_REG))])]
14226   ""
14228   if (flag_pic)
14229     operands[1] = pic_offset_table_rtx;
14230   else
14231     {
14232       operands[1] = gen_reg_rtx (Pmode);
14233       emit_insn (gen_set_got (operands[1]));
14234     }
14235   operands[2] = ix86_tls_get_addr ();
14238 (define_insn "*tls_local_dynamic_base_64"
14239   [(set (match_operand:DI 0 "register_operand" "=a")
14240         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14241                       (match_operand:DI 2 "" "")))
14242    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14243   "TARGET_64BIT"
14244   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14245   [(set_attr "type" "multi")
14246    (set_attr "length" "12")])
14248 (define_expand "tls_local_dynamic_base_64"
14249   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14250                    (call (mem:QI (match_dup 1)) (const_int 0)))
14251               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14252   ""
14254   operands[1] = ix86_tls_get_addr ();
14257 ;; Local dynamic of a single variable is a lose.  Show combine how
14258 ;; to convert that back to global dynamic.
14260 (define_insn_and_split "*tls_local_dynamic_32_once"
14261   [(set (match_operand:SI 0 "register_operand" "=a")
14262         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14263                              (match_operand:SI 2 "call_insn_operand" "")]
14264                             UNSPEC_TLS_LD_BASE)
14265                  (const:SI (unspec:SI
14266                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14267                             UNSPEC_DTPOFF))))
14268    (clobber (match_scratch:SI 4 "=d"))
14269    (clobber (match_scratch:SI 5 "=c"))
14270    (clobber (reg:CC FLAGS_REG))]
14271   ""
14272   "#"
14273   ""
14274   [(parallel [(set (match_dup 0)
14275                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14276                               UNSPEC_TLS_GD))
14277               (clobber (match_dup 4))
14278               (clobber (match_dup 5))
14279               (clobber (reg:CC FLAGS_REG))])]
14280   "")
14282 ;; Load and add the thread base pointer from %gs:0.
14284 (define_insn "*load_tp_si"
14285   [(set (match_operand:SI 0 "register_operand" "=r")
14286         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14287   "!TARGET_64BIT"
14288   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14289   [(set_attr "type" "imov")
14290    (set_attr "modrm" "0")
14291    (set_attr "length" "7")
14292    (set_attr "memory" "load")
14293    (set_attr "imm_disp" "false")])
14295 (define_insn "*add_tp_si"
14296   [(set (match_operand:SI 0 "register_operand" "=r")
14297         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14298                  (match_operand:SI 1 "register_operand" "0")))
14299    (clobber (reg:CC FLAGS_REG))]
14300   "!TARGET_64BIT"
14301   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14302   [(set_attr "type" "alu")
14303    (set_attr "modrm" "0")
14304    (set_attr "length" "7")
14305    (set_attr "memory" "load")
14306    (set_attr "imm_disp" "false")])
14308 (define_insn "*load_tp_di"
14309   [(set (match_operand:DI 0 "register_operand" "=r")
14310         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14311   "TARGET_64BIT"
14312   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14313   [(set_attr "type" "imov")
14314    (set_attr "modrm" "0")
14315    (set_attr "length" "7")
14316    (set_attr "memory" "load")
14317    (set_attr "imm_disp" "false")])
14319 (define_insn "*add_tp_di"
14320   [(set (match_operand:DI 0 "register_operand" "=r")
14321         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14322                  (match_operand:DI 1 "register_operand" "0")))
14323    (clobber (reg:CC FLAGS_REG))]
14324   "TARGET_64BIT"
14325   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14326   [(set_attr "type" "alu")
14327    (set_attr "modrm" "0")
14328    (set_attr "length" "7")
14329    (set_attr "memory" "load")
14330    (set_attr "imm_disp" "false")])
14332 ;; These patterns match the binary 387 instructions for addM3, subM3,
14333 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14334 ;; SFmode.  The first is the normal insn, the second the same insn but
14335 ;; with one operand a conversion, and the third the same insn but with
14336 ;; the other operand a conversion.  The conversion may be SFmode or
14337 ;; SImode if the target mode DFmode, but only SImode if the target mode
14338 ;; is SFmode.
14340 ;; Gcc is slightly more smart about handling normal two address instructions
14341 ;; so use special patterns for add and mull.
14342 (define_insn "*fop_sf_comm_nosse"
14343   [(set (match_operand:SF 0 "register_operand" "=f")
14344         (match_operator:SF 3 "binary_fp_operator"
14345                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14346                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14347   "TARGET_80387 && !TARGET_SSE_MATH
14348    && COMMUTATIVE_ARITH_P (operands[3])
14349    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14350   "* return output_387_binary_op (insn, operands);"
14351   [(set (attr "type") 
14352         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14353            (const_string "fmul")
14354            (const_string "fop")))
14355    (set_attr "mode" "SF")])
14357 (define_insn "*fop_sf_comm"
14358   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14359         (match_operator:SF 3 "binary_fp_operator"
14360                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14361                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14362   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14363    && COMMUTATIVE_ARITH_P (operands[3])
14364    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14365   "* return output_387_binary_op (insn, operands);"
14366   [(set (attr "type") 
14367         (if_then_else (eq_attr "alternative" "1")
14368            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14369               (const_string "ssemul")
14370               (const_string "sseadd"))
14371            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14372               (const_string "fmul")
14373               (const_string "fop"))))
14374    (set_attr "mode" "SF")])
14376 (define_insn "*fop_sf_comm_sse"
14377   [(set (match_operand:SF 0 "register_operand" "=x")
14378         (match_operator:SF 3 "binary_fp_operator"
14379                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14380                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14381   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14382    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14383   "* return output_387_binary_op (insn, operands);"
14384   [(set (attr "type") 
14385         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14386            (const_string "ssemul")
14387            (const_string "sseadd")))
14388    (set_attr "mode" "SF")])
14390 (define_insn "*fop_df_comm_nosse"
14391   [(set (match_operand:DF 0 "register_operand" "=f")
14392         (match_operator:DF 3 "binary_fp_operator"
14393                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14394                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14395   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14396    && COMMUTATIVE_ARITH_P (operands[3])
14397    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14398   "* return output_387_binary_op (insn, operands);"
14399   [(set (attr "type") 
14400         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14401            (const_string "fmul")
14402            (const_string "fop")))
14403    (set_attr "mode" "DF")])
14405 (define_insn "*fop_df_comm"
14406   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14407         (match_operator:DF 3 "binary_fp_operator"
14408                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14409                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14410   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14411    && COMMUTATIVE_ARITH_P (operands[3])
14412    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14413   "* return output_387_binary_op (insn, operands);"
14414   [(set (attr "type") 
14415         (if_then_else (eq_attr "alternative" "1")
14416            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14417               (const_string "ssemul")
14418               (const_string "sseadd"))
14419            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14420               (const_string "fmul")
14421               (const_string "fop"))))
14422    (set_attr "mode" "DF")])
14424 (define_insn "*fop_df_comm_sse"
14425   [(set (match_operand:DF 0 "register_operand" "=Y")
14426         (match_operator:DF 3 "binary_fp_operator"
14427                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14428                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14429   "TARGET_SSE2 && TARGET_SSE_MATH
14430    && COMMUTATIVE_ARITH_P (operands[3])
14431    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14432   "* return output_387_binary_op (insn, operands);"
14433   [(set (attr "type") 
14434         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14435            (const_string "ssemul")
14436            (const_string "sseadd")))
14437    (set_attr "mode" "DF")])
14439 (define_insn "*fop_xf_comm"
14440   [(set (match_operand:XF 0 "register_operand" "=f")
14441         (match_operator:XF 3 "binary_fp_operator"
14442                         [(match_operand:XF 1 "register_operand" "%0")
14443                          (match_operand:XF 2 "register_operand" "f")]))]
14444   "TARGET_80387
14445    && COMMUTATIVE_ARITH_P (operands[3])"
14446   "* return output_387_binary_op (insn, operands);"
14447   [(set (attr "type") 
14448         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14449            (const_string "fmul")
14450            (const_string "fop")))
14451    (set_attr "mode" "XF")])
14453 (define_insn "*fop_sf_1_nosse"
14454   [(set (match_operand:SF 0 "register_operand" "=f,f")
14455         (match_operator:SF 3 "binary_fp_operator"
14456                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14457                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14458   "TARGET_80387 && !TARGET_SSE_MATH
14459    && !COMMUTATIVE_ARITH_P (operands[3])
14460    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14461   "* return output_387_binary_op (insn, operands);"
14462   [(set (attr "type") 
14463         (cond [(match_operand:SF 3 "mult_operator" "") 
14464                  (const_string "fmul")
14465                (match_operand:SF 3 "div_operator" "") 
14466                  (const_string "fdiv")
14467               ]
14468               (const_string "fop")))
14469    (set_attr "mode" "SF")])
14471 (define_insn "*fop_sf_1"
14472   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14473         (match_operator:SF 3 "binary_fp_operator"
14474                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14475                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14476   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14477    && !COMMUTATIVE_ARITH_P (operands[3])
14478    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14479   "* return output_387_binary_op (insn, operands);"
14480   [(set (attr "type") 
14481         (cond [(and (eq_attr "alternative" "2")
14482                     (match_operand:SF 3 "mult_operator" ""))
14483                  (const_string "ssemul")
14484                (and (eq_attr "alternative" "2")
14485                     (match_operand:SF 3 "div_operator" ""))
14486                  (const_string "ssediv")
14487                (eq_attr "alternative" "2")
14488                  (const_string "sseadd")
14489                (match_operand:SF 3 "mult_operator" "") 
14490                  (const_string "fmul")
14491                (match_operand:SF 3 "div_operator" "") 
14492                  (const_string "fdiv")
14493               ]
14494               (const_string "fop")))
14495    (set_attr "mode" "SF")])
14497 (define_insn "*fop_sf_1_sse"
14498   [(set (match_operand:SF 0 "register_operand" "=x")
14499         (match_operator:SF 3 "binary_fp_operator"
14500                         [(match_operand:SF 1 "register_operand" "0")
14501                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14502   "TARGET_SSE_MATH
14503    && !COMMUTATIVE_ARITH_P (operands[3])"
14504   "* return output_387_binary_op (insn, operands);"
14505   [(set (attr "type") 
14506         (cond [(match_operand:SF 3 "mult_operator" "")
14507                  (const_string "ssemul")
14508                (match_operand:SF 3 "div_operator" "")
14509                  (const_string "ssediv")
14510               ]
14511               (const_string "sseadd")))
14512    (set_attr "mode" "SF")])
14514 ;; ??? Add SSE splitters for these!
14515 (define_insn "*fop_sf_2"
14516   [(set (match_operand:SF 0 "register_operand" "=f,f")
14517         (match_operator:SF 3 "binary_fp_operator"
14518           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14519            (match_operand:SF 2 "register_operand" "0,0")]))]
14520   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14521   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14522   [(set (attr "type") 
14523         (cond [(match_operand:SF 3 "mult_operator" "") 
14524                  (const_string "fmul")
14525                (match_operand:SF 3 "div_operator" "") 
14526                  (const_string "fdiv")
14527               ]
14528               (const_string "fop")))
14529    (set_attr "fp_int_src" "true")
14530    (set_attr "mode" "SI")])
14532 (define_insn "*fop_sf_3"
14533   [(set (match_operand:SF 0 "register_operand" "=f,f")
14534         (match_operator:SF 3 "binary_fp_operator"
14535           [(match_operand:SF 1 "register_operand" "0,0")
14536            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14537   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14538   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14539   [(set (attr "type") 
14540         (cond [(match_operand:SF 3 "mult_operator" "") 
14541                  (const_string "fmul")
14542                (match_operand:SF 3 "div_operator" "") 
14543                  (const_string "fdiv")
14544               ]
14545               (const_string "fop")))
14546    (set_attr "fp_int_src" "true")
14547    (set_attr "mode" "SI")])
14549 (define_insn "*fop_df_1_nosse"
14550   [(set (match_operand:DF 0 "register_operand" "=f,f")
14551         (match_operator:DF 3 "binary_fp_operator"
14552                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14553                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14554   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14555    && !COMMUTATIVE_ARITH_P (operands[3])
14556    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14557   "* return output_387_binary_op (insn, operands);"
14558   [(set (attr "type") 
14559         (cond [(match_operand:DF 3 "mult_operator" "") 
14560                  (const_string "fmul")
14561                (match_operand:DF 3 "div_operator" "")
14562                  (const_string "fdiv")
14563               ]
14564               (const_string "fop")))
14565    (set_attr "mode" "DF")])
14568 (define_insn "*fop_df_1"
14569   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14570         (match_operator:DF 3 "binary_fp_operator"
14571                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14572                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14573   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14574    && !COMMUTATIVE_ARITH_P (operands[3])
14575    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14576   "* return output_387_binary_op (insn, operands);"
14577   [(set (attr "type") 
14578         (cond [(and (eq_attr "alternative" "2")
14579                     (match_operand:SF 3 "mult_operator" ""))
14580                  (const_string "ssemul")
14581                (and (eq_attr "alternative" "2")
14582                     (match_operand:SF 3 "div_operator" ""))
14583                  (const_string "ssediv")
14584                (eq_attr "alternative" "2")
14585                  (const_string "sseadd")
14586                (match_operand:DF 3 "mult_operator" "") 
14587                  (const_string "fmul")
14588                (match_operand:DF 3 "div_operator" "") 
14589                  (const_string "fdiv")
14590               ]
14591               (const_string "fop")))
14592    (set_attr "mode" "DF")])
14594 (define_insn "*fop_df_1_sse"
14595   [(set (match_operand:DF 0 "register_operand" "=Y")
14596         (match_operator:DF 3 "binary_fp_operator"
14597                         [(match_operand:DF 1 "register_operand" "0")
14598                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14599   "TARGET_SSE2 && TARGET_SSE_MATH
14600    && !COMMUTATIVE_ARITH_P (operands[3])"
14601   "* return output_387_binary_op (insn, operands);"
14602   [(set_attr "mode" "DF")
14603    (set (attr "type") 
14604         (cond [(match_operand:SF 3 "mult_operator" "")
14605                  (const_string "ssemul")
14606                (match_operand:SF 3 "div_operator" "")
14607                  (const_string "ssediv")
14608               ]
14609               (const_string "sseadd")))])
14611 ;; ??? Add SSE splitters for these!
14612 (define_insn "*fop_df_2"
14613   [(set (match_operand:DF 0 "register_operand" "=f,f")
14614         (match_operator:DF 3 "binary_fp_operator"
14615            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14616             (match_operand:DF 2 "register_operand" "0,0")]))]
14617   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14618   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14619   [(set (attr "type") 
14620         (cond [(match_operand:DF 3 "mult_operator" "") 
14621                  (const_string "fmul")
14622                (match_operand:DF 3 "div_operator" "") 
14623                  (const_string "fdiv")
14624               ]
14625               (const_string "fop")))
14626    (set_attr "fp_int_src" "true")
14627    (set_attr "mode" "SI")])
14629 (define_insn "*fop_df_3"
14630   [(set (match_operand:DF 0 "register_operand" "=f,f")
14631         (match_operator:DF 3 "binary_fp_operator"
14632            [(match_operand:DF 1 "register_operand" "0,0")
14633             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14634   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14635   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14636   [(set (attr "type") 
14637         (cond [(match_operand:DF 3 "mult_operator" "") 
14638                  (const_string "fmul")
14639                (match_operand:DF 3 "div_operator" "") 
14640                  (const_string "fdiv")
14641               ]
14642               (const_string "fop")))
14643    (set_attr "fp_int_src" "true")
14644    (set_attr "mode" "SI")])
14646 (define_insn "*fop_df_4"
14647   [(set (match_operand:DF 0 "register_operand" "=f,f")
14648         (match_operator:DF 3 "binary_fp_operator"
14649            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14650             (match_operand:DF 2 "register_operand" "0,f")]))]
14651   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14652    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14653   "* return output_387_binary_op (insn, operands);"
14654   [(set (attr "type") 
14655         (cond [(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" "SF")])
14663 (define_insn "*fop_df_5"
14664   [(set (match_operand:DF 0 "register_operand" "=f,f")
14665         (match_operator:DF 3 "binary_fp_operator"
14666           [(match_operand:DF 1 "register_operand" "0,f")
14667            (float_extend:DF
14668             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14669   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14670   "* return output_387_binary_op (insn, operands);"
14671   [(set (attr "type") 
14672         (cond [(match_operand:DF 3 "mult_operator" "") 
14673                  (const_string "fmul")
14674                (match_operand:DF 3 "div_operator" "") 
14675                  (const_string "fdiv")
14676               ]
14677               (const_string "fop")))
14678    (set_attr "mode" "SF")])
14680 (define_insn "*fop_df_6"
14681   [(set (match_operand:DF 0 "register_operand" "=f,f")
14682         (match_operator:DF 3 "binary_fp_operator"
14683           [(float_extend:DF
14684             (match_operand:SF 1 "register_operand" "0,f"))
14685            (float_extend:DF
14686             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14687   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14688   "* return output_387_binary_op (insn, operands);"
14689   [(set (attr "type") 
14690         (cond [(match_operand:DF 3 "mult_operator" "") 
14691                  (const_string "fmul")
14692                (match_operand:DF 3 "div_operator" "") 
14693                  (const_string "fdiv")
14694               ]
14695               (const_string "fop")))
14696    (set_attr "mode" "SF")])
14698 (define_insn "*fop_xf_1"
14699   [(set (match_operand:XF 0 "register_operand" "=f,f")
14700         (match_operator:XF 3 "binary_fp_operator"
14701                         [(match_operand:XF 1 "register_operand" "0,f")
14702                          (match_operand:XF 2 "register_operand" "f,0")]))]
14703   "TARGET_80387
14704    && !COMMUTATIVE_ARITH_P (operands[3])"
14705   "* return output_387_binary_op (insn, operands);"
14706   [(set (attr "type") 
14707         (cond [(match_operand:XF 3 "mult_operator" "") 
14708                  (const_string "fmul")
14709                (match_operand:XF 3 "div_operator" "") 
14710                  (const_string "fdiv")
14711               ]
14712               (const_string "fop")))
14713    (set_attr "mode" "XF")])
14715 (define_insn "*fop_xf_2"
14716   [(set (match_operand:XF 0 "register_operand" "=f,f")
14717         (match_operator:XF 3 "binary_fp_operator"
14718            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14719             (match_operand:XF 2 "register_operand" "0,0")]))]
14720   "TARGET_80387 && TARGET_USE_FIOP"
14721   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14722   [(set (attr "type") 
14723         (cond [(match_operand:XF 3 "mult_operator" "") 
14724                  (const_string "fmul")
14725                (match_operand:XF 3 "div_operator" "") 
14726                  (const_string "fdiv")
14727               ]
14728               (const_string "fop")))
14729    (set_attr "fp_int_src" "true")
14730    (set_attr "mode" "SI")])
14732 (define_insn "*fop_xf_3"
14733   [(set (match_operand:XF 0 "register_operand" "=f,f")
14734         (match_operator:XF 3 "binary_fp_operator"
14735           [(match_operand:XF 1 "register_operand" "0,0")
14736            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14737   "TARGET_80387 && TARGET_USE_FIOP"
14738   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14739   [(set (attr "type") 
14740         (cond [(match_operand:XF 3 "mult_operator" "") 
14741                  (const_string "fmul")
14742                (match_operand:XF 3 "div_operator" "") 
14743                  (const_string "fdiv")
14744               ]
14745               (const_string "fop")))
14746    (set_attr "fp_int_src" "true")
14747    (set_attr "mode" "SI")])
14749 (define_insn "*fop_xf_4"
14750   [(set (match_operand:XF 0 "register_operand" "=f,f")
14751         (match_operator:XF 3 "binary_fp_operator"
14752            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14753             (match_operand:XF 2 "register_operand" "0,f")]))]
14754   "TARGET_80387"
14755   "* return output_387_binary_op (insn, operands);"
14756   [(set (attr "type") 
14757         (cond [(match_operand:XF 3 "mult_operator" "") 
14758                  (const_string "fmul")
14759                (match_operand:XF 3 "div_operator" "") 
14760                  (const_string "fdiv")
14761               ]
14762               (const_string "fop")))
14763    (set_attr "mode" "SF")])
14765 (define_insn "*fop_xf_5"
14766   [(set (match_operand:XF 0 "register_operand" "=f,f")
14767         (match_operator:XF 3 "binary_fp_operator"
14768           [(match_operand:XF 1 "register_operand" "0,f")
14769            (float_extend:XF
14770             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14771   "TARGET_80387"
14772   "* return output_387_binary_op (insn, operands);"
14773   [(set (attr "type") 
14774         (cond [(match_operand:XF 3 "mult_operator" "") 
14775                  (const_string "fmul")
14776                (match_operand:XF 3 "div_operator" "") 
14777                  (const_string "fdiv")
14778               ]
14779               (const_string "fop")))
14780    (set_attr "mode" "SF")])
14782 (define_insn "*fop_xf_6"
14783   [(set (match_operand:XF 0 "register_operand" "=f,f")
14784         (match_operator:XF 3 "binary_fp_operator"
14785           [(float_extend:XF
14786             (match_operand 1 "register_operand" "0,f"))
14787            (float_extend:XF
14788             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14789   "TARGET_80387"
14790   "* return 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 "mode" "SF")])
14800 (define_split
14801   [(set (match_operand 0 "register_operand" "")
14802         (match_operator 3 "binary_fp_operator"
14803            [(float (match_operand:SI 1 "register_operand" ""))
14804             (match_operand 2 "register_operand" "")]))]
14805   "TARGET_80387 && reload_completed
14806    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14807   [(const_int 0)]
14809   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14810   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14811   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14812                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14813                                           GET_MODE (operands[3]),
14814                                           operands[4],
14815                                           operands[2])));
14816   ix86_free_from_memory (GET_MODE (operands[1]));
14817   DONE;
14820 (define_split
14821   [(set (match_operand 0 "register_operand" "")
14822         (match_operator 3 "binary_fp_operator"
14823            [(match_operand 1 "register_operand" "")
14824             (float (match_operand:SI 2 "register_operand" ""))]))]
14825   "TARGET_80387 && reload_completed
14826    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14827   [(const_int 0)]
14829   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14830   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14831   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14832                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14833                                           GET_MODE (operands[3]),
14834                                           operands[1],
14835                                           operands[4])));
14836   ix86_free_from_memory (GET_MODE (operands[2]));
14837   DONE;
14840 ;; FPU special functions.
14842 (define_expand "sqrtsf2"
14843   [(set (match_operand:SF 0 "register_operand" "")
14844         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14845   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14847   if (!TARGET_SSE_MATH)
14848     operands[1] = force_reg (SFmode, operands[1]);
14851 (define_insn "sqrtsf2_1"
14852   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14853         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14854   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14855    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14856   "@
14857    fsqrt
14858    sqrtss\t{%1, %0|%0, %1}"
14859   [(set_attr "type" "fpspc,sse")
14860    (set_attr "mode" "SF,SF")
14861    (set_attr "athlon_decode" "direct,*")])
14863 (define_insn "sqrtsf2_1_sse_only"
14864   [(set (match_operand:SF 0 "register_operand" "=x")
14865         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14866   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14867   "sqrtss\t{%1, %0|%0, %1}"
14868   [(set_attr "type" "sse")
14869    (set_attr "mode" "SF")
14870    (set_attr "athlon_decode" "*")])
14872 (define_insn "sqrtsf2_i387"
14873   [(set (match_operand:SF 0 "register_operand" "=f")
14874         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14875   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14876    && !TARGET_SSE_MATH"
14877   "fsqrt"
14878   [(set_attr "type" "fpspc")
14879    (set_attr "mode" "SF")
14880    (set_attr "athlon_decode" "direct")])
14882 (define_expand "sqrtdf2"
14883   [(set (match_operand:DF 0 "register_operand" "")
14884         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14885   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14886    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14888   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14889     operands[1] = force_reg (DFmode, operands[1]);
14892 (define_insn "sqrtdf2_1"
14893   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14894         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14895   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14896    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14897   "@
14898    fsqrt
14899    sqrtsd\t{%1, %0|%0, %1}"
14900   [(set_attr "type" "fpspc,sse")
14901    (set_attr "mode" "DF,DF")
14902    (set_attr "athlon_decode" "direct,*")])
14904 (define_insn "sqrtdf2_1_sse_only"
14905   [(set (match_operand:DF 0 "register_operand" "=Y")
14906         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14907   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14908   "sqrtsd\t{%1, %0|%0, %1}"
14909   [(set_attr "type" "sse")
14910    (set_attr "mode" "DF")
14911    (set_attr "athlon_decode" "*")])
14913 (define_insn "sqrtdf2_i387"
14914   [(set (match_operand:DF 0 "register_operand" "=f")
14915         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14916   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14917    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14918   "fsqrt"
14919   [(set_attr "type" "fpspc")
14920    (set_attr "mode" "DF")
14921    (set_attr "athlon_decode" "direct")])
14923 (define_insn "*sqrtextendsfdf2"
14924   [(set (match_operand:DF 0 "register_operand" "=f")
14925         (sqrt:DF (float_extend:DF
14926                   (match_operand:SF 1 "register_operand" "0"))))]
14927   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14928    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14929   "fsqrt"
14930   [(set_attr "type" "fpspc")
14931    (set_attr "mode" "DF")
14932    (set_attr "athlon_decode" "direct")])
14934 (define_insn "sqrtxf2"
14935   [(set (match_operand:XF 0 "register_operand" "=f")
14936         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14937   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14938    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14939   "fsqrt"
14940   [(set_attr "type" "fpspc")
14941    (set_attr "mode" "XF")
14942    (set_attr "athlon_decode" "direct")])
14944 (define_insn "*sqrtextenddfxf2"
14945   [(set (match_operand:XF 0 "register_operand" "=f")
14946         (sqrt:XF (float_extend:XF
14947                   (match_operand:DF 1 "register_operand" "0"))))]
14948   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14949   "fsqrt"
14950   [(set_attr "type" "fpspc")
14951    (set_attr "mode" "XF")
14952    (set_attr "athlon_decode" "direct")])
14954 (define_insn "*sqrtextendsfxf2"
14955   [(set (match_operand:XF 0 "register_operand" "=f")
14956         (sqrt:XF (float_extend:XF
14957                   (match_operand:SF 1 "register_operand" "0"))))]
14958   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14959   "fsqrt"
14960   [(set_attr "type" "fpspc")
14961    (set_attr "mode" "XF")
14962    (set_attr "athlon_decode" "direct")])
14964 (define_insn "fpremxf4"
14965   [(set (match_operand:XF 0 "register_operand" "=f")
14966         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14967                     (match_operand:XF 3 "register_operand" "1")]
14968                    UNSPEC_FPREM_F))
14969    (set (match_operand:XF 1 "register_operand" "=u")
14970         (unspec:XF [(match_dup 2) (match_dup 3)]
14971                    UNSPEC_FPREM_U))
14972    (set (reg:CCFP FPSR_REG)
14973         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14974   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14975    && flag_unsafe_math_optimizations"
14976   "fprem"
14977   [(set_attr "type" "fpspc")
14978    (set_attr "mode" "XF")])
14980 (define_expand "fmodsf3"
14981   [(use (match_operand:SF 0 "register_operand" ""))
14982    (use (match_operand:SF 1 "register_operand" ""))
14983    (use (match_operand:SF 2 "register_operand" ""))]
14984   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14985    && flag_unsafe_math_optimizations"
14987   rtx label = gen_label_rtx ();
14989   rtx op1 = gen_reg_rtx (XFmode);
14990   rtx op2 = gen_reg_rtx (XFmode);
14992   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14993   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14995   emit_label (label);
14997   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14998   ix86_emit_fp_unordered_jump (label);
15000   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15001   DONE;
15004 (define_expand "fmoddf3"
15005   [(use (match_operand:DF 0 "register_operand" ""))
15006    (use (match_operand:DF 1 "register_operand" ""))
15007    (use (match_operand:DF 2 "register_operand" ""))]
15008   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15009    && flag_unsafe_math_optimizations"
15011   rtx label = gen_label_rtx ();
15013   rtx op1 = gen_reg_rtx (XFmode);
15014   rtx op2 = gen_reg_rtx (XFmode);
15016   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15017   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15019   emit_label (label);
15021   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15022   ix86_emit_fp_unordered_jump (label);
15024   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15025   DONE;
15028 (define_expand "fmodxf3"
15029   [(use (match_operand:XF 0 "register_operand" ""))
15030    (use (match_operand:XF 1 "register_operand" ""))
15031    (use (match_operand:XF 2 "register_operand" ""))]
15032   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15033    && flag_unsafe_math_optimizations"
15035   rtx label = gen_label_rtx ();
15037   emit_label (label);
15039   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15040                            operands[1], operands[2]));
15041   ix86_emit_fp_unordered_jump (label);
15043   emit_move_insn (operands[0], operands[1]);
15044   DONE;
15047 (define_insn "fprem1xf4"
15048   [(set (match_operand:XF 0 "register_operand" "=f")
15049         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15050                     (match_operand:XF 3 "register_operand" "1")]
15051                    UNSPEC_FPREM1_F))
15052    (set (match_operand:XF 1 "register_operand" "=u")
15053         (unspec:XF [(match_dup 2) (match_dup 3)]
15054                    UNSPEC_FPREM1_U))
15055    (set (reg:CCFP FPSR_REG)
15056         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15057   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15058    && flag_unsafe_math_optimizations"
15059   "fprem1"
15060   [(set_attr "type" "fpspc")
15061    (set_attr "mode" "XF")])
15063 (define_expand "dremsf3"
15064   [(use (match_operand:SF 0 "register_operand" ""))
15065    (use (match_operand:SF 1 "register_operand" ""))
15066    (use (match_operand:SF 2 "register_operand" ""))]
15067   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15068    && flag_unsafe_math_optimizations"
15070   rtx label = gen_label_rtx ();
15072   rtx op1 = gen_reg_rtx (XFmode);
15073   rtx op2 = gen_reg_rtx (XFmode);
15075   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15076   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15078   emit_label (label);
15080   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15081   ix86_emit_fp_unordered_jump (label);
15083   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15084   DONE;
15087 (define_expand "dremdf3"
15088   [(use (match_operand:DF 0 "register_operand" ""))
15089    (use (match_operand:DF 1 "register_operand" ""))
15090    (use (match_operand:DF 2 "register_operand" ""))]
15091   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15092    && flag_unsafe_math_optimizations"
15094   rtx label = gen_label_rtx ();
15096   rtx op1 = gen_reg_rtx (XFmode);
15097   rtx op2 = gen_reg_rtx (XFmode);
15099   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15100   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15102   emit_label (label);
15104   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15105   ix86_emit_fp_unordered_jump (label);
15107   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15108   DONE;
15111 (define_expand "dremxf3"
15112   [(use (match_operand:XF 0 "register_operand" ""))
15113    (use (match_operand:XF 1 "register_operand" ""))
15114    (use (match_operand:XF 2 "register_operand" ""))]
15115   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15116    && flag_unsafe_math_optimizations"
15118   rtx label = gen_label_rtx ();
15120   emit_label (label);
15122   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15123                             operands[1], operands[2]));
15124   ix86_emit_fp_unordered_jump (label);
15126   emit_move_insn (operands[0], operands[1]);
15127   DONE;
15130 (define_insn "*sindf2"
15131   [(set (match_operand:DF 0 "register_operand" "=f")
15132         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15133   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15134    && flag_unsafe_math_optimizations"
15135   "fsin"
15136   [(set_attr "type" "fpspc")
15137    (set_attr "mode" "DF")])
15139 (define_insn "*sinsf2"
15140   [(set (match_operand:SF 0 "register_operand" "=f")
15141         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15142   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15143    && flag_unsafe_math_optimizations"
15144   "fsin"
15145   [(set_attr "type" "fpspc")
15146    (set_attr "mode" "SF")])
15148 (define_insn "*sinextendsfdf2"
15149   [(set (match_operand:DF 0 "register_operand" "=f")
15150         (unspec:DF [(float_extend:DF
15151                      (match_operand:SF 1 "register_operand" "0"))]
15152                    UNSPEC_SIN))]
15153   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15154    && flag_unsafe_math_optimizations"
15155   "fsin"
15156   [(set_attr "type" "fpspc")
15157    (set_attr "mode" "DF")])
15159 (define_insn "*sinxf2"
15160   [(set (match_operand:XF 0 "register_operand" "=f")
15161         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15162   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15163    && flag_unsafe_math_optimizations"
15164   "fsin"
15165   [(set_attr "type" "fpspc")
15166    (set_attr "mode" "XF")])
15168 (define_insn "*cosdf2"
15169   [(set (match_operand:DF 0 "register_operand" "=f")
15170         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15171   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15172    && flag_unsafe_math_optimizations"
15173   "fcos"
15174   [(set_attr "type" "fpspc")
15175    (set_attr "mode" "DF")])
15177 (define_insn "*cossf2"
15178   [(set (match_operand:SF 0 "register_operand" "=f")
15179         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15180   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15181    && flag_unsafe_math_optimizations"
15182   "fcos"
15183   [(set_attr "type" "fpspc")
15184    (set_attr "mode" "SF")])
15186 (define_insn "*cosextendsfdf2"
15187   [(set (match_operand:DF 0 "register_operand" "=f")
15188         (unspec:DF [(float_extend:DF
15189                      (match_operand:SF 1 "register_operand" "0"))]
15190                    UNSPEC_COS))]
15191   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15192    && flag_unsafe_math_optimizations"
15193   "fcos"
15194   [(set_attr "type" "fpspc")
15195    (set_attr "mode" "DF")])
15197 (define_insn "*cosxf2"
15198   [(set (match_operand:XF 0 "register_operand" "=f")
15199         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15200   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15201    && flag_unsafe_math_optimizations"
15202   "fcos"
15203   [(set_attr "type" "fpspc")
15204    (set_attr "mode" "XF")])
15206 ;; With sincos pattern defined, sin and cos builtin function will be
15207 ;; expanded to sincos pattern with one of its outputs left unused. 
15208 ;; Cse pass  will detected, if two sincos patterns can be combined,
15209 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15210 ;; depending on the unused output.
15212 (define_insn "sincosdf3"
15213   [(set (match_operand:DF 0 "register_operand" "=f")
15214         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15215                    UNSPEC_SINCOS_COS))
15216    (set (match_operand:DF 1 "register_operand" "=u")
15217         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15218   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15219    && flag_unsafe_math_optimizations"
15220   "fsincos"
15221   [(set_attr "type" "fpspc")
15222    (set_attr "mode" "DF")])
15224 (define_split
15225   [(set (match_operand:DF 0 "register_operand" "")
15226         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15227                    UNSPEC_SINCOS_COS))
15228    (set (match_operand:DF 1 "register_operand" "")
15229         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15230   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15231    && !reload_completed && !reload_in_progress"
15232   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15233   "")
15235 (define_split
15236   [(set (match_operand:DF 0 "register_operand" "")
15237         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15238                    UNSPEC_SINCOS_COS))
15239    (set (match_operand:DF 1 "register_operand" "")
15240         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15241   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15242    && !reload_completed && !reload_in_progress"
15243   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15244   "")
15246 (define_insn "sincossf3"
15247   [(set (match_operand:SF 0 "register_operand" "=f")
15248         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15249                    UNSPEC_SINCOS_COS))
15250    (set (match_operand:SF 1 "register_operand" "=u")
15251         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15252   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15253    && flag_unsafe_math_optimizations"
15254   "fsincos"
15255   [(set_attr "type" "fpspc")
15256    (set_attr "mode" "SF")])
15258 (define_split
15259   [(set (match_operand:SF 0 "register_operand" "")
15260         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15261                    UNSPEC_SINCOS_COS))
15262    (set (match_operand:SF 1 "register_operand" "")
15263         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15264   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15265    && !reload_completed && !reload_in_progress"
15266   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15267   "")
15269 (define_split
15270   [(set (match_operand:SF 0 "register_operand" "")
15271         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15272                    UNSPEC_SINCOS_COS))
15273    (set (match_operand:SF 1 "register_operand" "")
15274         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15275   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15276    && !reload_completed && !reload_in_progress"
15277   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15278   "")
15280 (define_insn "*sincosextendsfdf3"
15281   [(set (match_operand:DF 0 "register_operand" "=f")
15282         (unspec:DF [(float_extend:DF
15283                      (match_operand:SF 2 "register_operand" "0"))]
15284                    UNSPEC_SINCOS_COS))
15285    (set (match_operand:DF 1 "register_operand" "=u")
15286         (unspec:DF [(float_extend:DF
15287                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15288   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15289    && flag_unsafe_math_optimizations"
15290   "fsincos"
15291   [(set_attr "type" "fpspc")
15292    (set_attr "mode" "DF")])
15294 (define_split
15295   [(set (match_operand:DF 0 "register_operand" "")
15296         (unspec:DF [(float_extend:DF
15297                      (match_operand:SF 2 "register_operand" ""))]
15298                    UNSPEC_SINCOS_COS))
15299    (set (match_operand:DF 1 "register_operand" "")
15300         (unspec:DF [(float_extend:DF
15301                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15302   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15303    && !reload_completed && !reload_in_progress"
15304   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15305                                    (match_dup 2))] UNSPEC_SIN))]
15306   "")
15308 (define_split
15309   [(set (match_operand:DF 0 "register_operand" "")
15310         (unspec:DF [(float_extend:DF
15311                      (match_operand:SF 2 "register_operand" ""))]
15312                    UNSPEC_SINCOS_COS))
15313    (set (match_operand:DF 1 "register_operand" "")
15314         (unspec:DF [(float_extend:DF
15315                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15316   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15317    && !reload_completed && !reload_in_progress"
15318   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15319                                    (match_dup 2))] UNSPEC_COS))]
15320   "")
15322 (define_insn "sincosxf3"
15323   [(set (match_operand:XF 0 "register_operand" "=f")
15324         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15325                    UNSPEC_SINCOS_COS))
15326    (set (match_operand:XF 1 "register_operand" "=u")
15327         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15328   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15329    && flag_unsafe_math_optimizations"
15330   "fsincos"
15331   [(set_attr "type" "fpspc")
15332    (set_attr "mode" "XF")])
15334 (define_split
15335   [(set (match_operand:XF 0 "register_operand" "")
15336         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15337                    UNSPEC_SINCOS_COS))
15338    (set (match_operand:XF 1 "register_operand" "")
15339         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15340   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15341    && !reload_completed && !reload_in_progress"
15342   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15343   "")
15345 (define_split
15346   [(set (match_operand:XF 0 "register_operand" "")
15347         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15348                    UNSPEC_SINCOS_COS))
15349    (set (match_operand:XF 1 "register_operand" "")
15350         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15351   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15352    && !reload_completed && !reload_in_progress"
15353   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15354   "")
15356 (define_insn "*tandf3_1"
15357   [(set (match_operand:DF 0 "register_operand" "=f")
15358         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15359                    UNSPEC_TAN_ONE))
15360    (set (match_operand:DF 1 "register_operand" "=u")
15361         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15362   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15363    && flag_unsafe_math_optimizations"
15364   "fptan"
15365   [(set_attr "type" "fpspc")
15366    (set_attr "mode" "DF")])
15368 ;; optimize sequence: fptan
15369 ;;                    fstp    %st(0)
15370 ;;                    fld1
15371 ;; into fptan insn.
15373 (define_peephole2
15374   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15375                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15376                              UNSPEC_TAN_ONE))
15377              (set (match_operand:DF 1 "register_operand" "")
15378                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15379    (set (match_dup 0)
15380         (match_operand:DF 3 "immediate_operand" ""))]
15381   "standard_80387_constant_p (operands[3]) == 2"
15382   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15383              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15384   "")
15386 (define_expand "tandf2"
15387   [(parallel [(set (match_dup 2)
15388                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15389                               UNSPEC_TAN_ONE))
15390               (set (match_operand:DF 0 "register_operand" "")
15391                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15392   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15393    && flag_unsafe_math_optimizations"
15395   operands[2] = gen_reg_rtx (DFmode);
15398 (define_insn "*tansf3_1"
15399   [(set (match_operand:SF 0 "register_operand" "=f")
15400         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15401                    UNSPEC_TAN_ONE))
15402    (set (match_operand:SF 1 "register_operand" "=u")
15403         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15404   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15405    && flag_unsafe_math_optimizations"
15406   "fptan"
15407   [(set_attr "type" "fpspc")
15408    (set_attr "mode" "SF")])
15410 ;; optimize sequence: fptan
15411 ;;                    fstp    %st(0)
15412 ;;                    fld1
15413 ;; into fptan insn.
15415 (define_peephole2
15416   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15417                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15418                              UNSPEC_TAN_ONE))
15419              (set (match_operand:SF 1 "register_operand" "")
15420                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15421    (set (match_dup 0)
15422         (match_operand:SF 3 "immediate_operand" ""))]
15423   "standard_80387_constant_p (operands[3]) == 2"
15424   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15425              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15426   "")
15428 (define_expand "tansf2"
15429   [(parallel [(set (match_dup 2)
15430                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15431                               UNSPEC_TAN_ONE))
15432               (set (match_operand:SF 0 "register_operand" "")
15433                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15434   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15435    && flag_unsafe_math_optimizations"
15437   operands[2] = gen_reg_rtx (SFmode);
15440 (define_insn "*tanxf3_1"
15441   [(set (match_operand:XF 0 "register_operand" "=f")
15442         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15443                    UNSPEC_TAN_ONE))
15444    (set (match_operand:XF 1 "register_operand" "=u")
15445         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15446   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15447    && flag_unsafe_math_optimizations"
15448   "fptan"
15449   [(set_attr "type" "fpspc")
15450    (set_attr "mode" "XF")])
15452 ;; optimize sequence: fptan
15453 ;;                    fstp    %st(0)
15454 ;;                    fld1
15455 ;; into fptan insn.
15457 (define_peephole2
15458   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15459                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15460                              UNSPEC_TAN_ONE))
15461              (set (match_operand:XF 1 "register_operand" "")
15462                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15463    (set (match_dup 0)
15464         (match_operand:XF 3 "immediate_operand" ""))]
15465   "standard_80387_constant_p (operands[3]) == 2"
15466   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15467              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15468   "")
15470 (define_expand "tanxf2"
15471   [(parallel [(set (match_dup 2)
15472                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15473                               UNSPEC_TAN_ONE))
15474               (set (match_operand:XF 0 "register_operand" "")
15475                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15476   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15477    && flag_unsafe_math_optimizations"
15479   operands[2] = gen_reg_rtx (XFmode);
15482 (define_insn "atan2df3_1"
15483   [(set (match_operand:DF 0 "register_operand" "=f")
15484         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15485                     (match_operand:DF 1 "register_operand" "u")]
15486                    UNSPEC_FPATAN))
15487    (clobber (match_scratch:DF 3 "=1"))]
15488   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15489    && flag_unsafe_math_optimizations"
15490   "fpatan"
15491   [(set_attr "type" "fpspc")
15492    (set_attr "mode" "DF")])
15494 (define_expand "atan2df3"
15495   [(use (match_operand:DF 0 "register_operand" "=f"))
15496    (use (match_operand:DF 2 "register_operand" "0"))
15497    (use (match_operand:DF 1 "register_operand" "u"))]
15498   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15499    && flag_unsafe_math_optimizations"
15501   rtx copy = gen_reg_rtx (DFmode);
15502   emit_move_insn (copy, operands[1]);
15503   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15504   DONE;
15507 (define_expand "atandf2"
15508   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15509                    (unspec:DF [(match_dup 2)
15510                                (match_operand:DF 1 "register_operand" "")]
15511                     UNSPEC_FPATAN))
15512               (clobber (match_scratch:DF 3 ""))])]
15513   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15514    && flag_unsafe_math_optimizations"
15516   operands[2] = gen_reg_rtx (DFmode);
15517   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15520 (define_insn "atan2sf3_1"
15521   [(set (match_operand:SF 0 "register_operand" "=f")
15522         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15523                     (match_operand:SF 1 "register_operand" "u")]
15524                    UNSPEC_FPATAN))
15525    (clobber (match_scratch:SF 3 "=1"))]
15526   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15527    && flag_unsafe_math_optimizations"
15528   "fpatan"
15529   [(set_attr "type" "fpspc")
15530    (set_attr "mode" "SF")])
15532 (define_expand "atan2sf3"
15533   [(use (match_operand:SF 0 "register_operand" "=f"))
15534    (use (match_operand:SF 2 "register_operand" "0"))
15535    (use (match_operand:SF 1 "register_operand" "u"))]
15536   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15537    && flag_unsafe_math_optimizations"
15539   rtx copy = gen_reg_rtx (SFmode);
15540   emit_move_insn (copy, operands[1]);
15541   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15542   DONE;
15545 (define_expand "atansf2"
15546   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15547                    (unspec:SF [(match_dup 2)
15548                                (match_operand:SF 1 "register_operand" "")]
15549                     UNSPEC_FPATAN))
15550               (clobber (match_scratch:SF 3 ""))])]
15551   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15552    && flag_unsafe_math_optimizations"
15554   operands[2] = gen_reg_rtx (SFmode);
15555   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15558 (define_insn "atan2xf3_1"
15559   [(set (match_operand:XF 0 "register_operand" "=f")
15560         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15561                     (match_operand:XF 1 "register_operand" "u")]
15562                    UNSPEC_FPATAN))
15563    (clobber (match_scratch:XF 3 "=1"))]
15564   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15565    && flag_unsafe_math_optimizations"
15566   "fpatan"
15567   [(set_attr "type" "fpspc")
15568    (set_attr "mode" "XF")])
15570 (define_expand "atan2xf3"
15571   [(use (match_operand:XF 0 "register_operand" "=f"))
15572    (use (match_operand:XF 2 "register_operand" "0"))
15573    (use (match_operand:XF 1 "register_operand" "u"))]
15574   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15575    && flag_unsafe_math_optimizations"
15577   rtx copy = gen_reg_rtx (XFmode);
15578   emit_move_insn (copy, operands[1]);
15579   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15580   DONE;
15583 (define_expand "atanxf2"
15584   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15585                    (unspec:XF [(match_dup 2)
15586                                (match_operand:XF 1 "register_operand" "")]
15587                     UNSPEC_FPATAN))
15588               (clobber (match_scratch:XF 3 ""))])]
15589   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15590    && flag_unsafe_math_optimizations"
15592   operands[2] = gen_reg_rtx (XFmode);
15593   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15596 (define_expand "asindf2"
15597   [(set (match_dup 2)
15598         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15599    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15600    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15601    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15602    (parallel [(set (match_dup 7)
15603                    (unspec:XF [(match_dup 6) (match_dup 2)]
15604                               UNSPEC_FPATAN))
15605               (clobber (match_scratch:XF 8 ""))])
15606    (set (match_operand:DF 0 "register_operand" "")
15607         (float_truncate:DF (match_dup 7)))]
15608   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15609    && flag_unsafe_math_optimizations"
15611   int i;
15613   for (i=2; i<8; i++)
15614     operands[i] = gen_reg_rtx (XFmode);
15616   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15619 (define_expand "asinsf2"
15620   [(set (match_dup 2)
15621         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15622    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15623    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15624    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15625    (parallel [(set (match_dup 7)
15626                    (unspec:XF [(match_dup 6) (match_dup 2)]
15627                               UNSPEC_FPATAN))
15628               (clobber (match_scratch:XF 8 ""))])
15629    (set (match_operand:SF 0 "register_operand" "")
15630         (float_truncate:SF (match_dup 7)))]
15631   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15632    && flag_unsafe_math_optimizations"
15634   int i;
15636   for (i=2; i<8; i++)
15637     operands[i] = gen_reg_rtx (XFmode);
15639   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15642 (define_expand "asinxf2"
15643   [(set (match_dup 2)
15644         (mult:XF (match_operand:XF 1 "register_operand" "")
15645                  (match_dup 1)))
15646    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15647    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15648    (parallel [(set (match_operand:XF 0 "register_operand" "")
15649                    (unspec:XF [(match_dup 5) (match_dup 1)]
15650                               UNSPEC_FPATAN))
15651               (clobber (match_scratch:XF 6 ""))])]
15652   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15653    && flag_unsafe_math_optimizations"
15655   int i;
15657   for (i=2; i<6; i++)
15658     operands[i] = gen_reg_rtx (XFmode);
15660   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15663 (define_expand "acosdf2"
15664   [(set (match_dup 2)
15665         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15666    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15667    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15668    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15669    (parallel [(set (match_dup 7)
15670                    (unspec:XF [(match_dup 2) (match_dup 6)]
15671                               UNSPEC_FPATAN))
15672               (clobber (match_scratch:XF 8 ""))])
15673    (set (match_operand:DF 0 "register_operand" "")
15674         (float_truncate:DF (match_dup 7)))]
15675   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15676    && flag_unsafe_math_optimizations"
15678   int i;
15680   for (i=2; i<8; i++)
15681     operands[i] = gen_reg_rtx (XFmode);
15683   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15686 (define_expand "acossf2"
15687   [(set (match_dup 2)
15688         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15689    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15690    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15691    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15692    (parallel [(set (match_dup 7)
15693                    (unspec:XF [(match_dup 2) (match_dup 6)]
15694                               UNSPEC_FPATAN))
15695               (clobber (match_scratch:XF 8 ""))])
15696    (set (match_operand:SF 0 "register_operand" "")
15697         (float_truncate:SF (match_dup 7)))]
15698   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15699    && flag_unsafe_math_optimizations"
15701   int i;
15703   for (i=2; i<8; i++)
15704     operands[i] = gen_reg_rtx (XFmode);
15706   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15709 (define_expand "acosxf2"
15710   [(set (match_dup 2)
15711         (mult:XF (match_operand:XF 1 "register_operand" "")
15712                  (match_dup 1)))
15713    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15714    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15715    (parallel [(set (match_operand:XF 0 "register_operand" "")
15716                    (unspec:XF [(match_dup 1) (match_dup 5)]
15717                               UNSPEC_FPATAN))
15718               (clobber (match_scratch:XF 6 ""))])]
15719   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15720    && flag_unsafe_math_optimizations"
15722   int i;
15724   for (i=2; i<6; i++)
15725     operands[i] = gen_reg_rtx (XFmode);
15727   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15730 (define_insn "fyl2x_xf3"
15731   [(set (match_operand:XF 0 "register_operand" "=f")
15732         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15733                     (match_operand:XF 1 "register_operand" "u")]
15734                    UNSPEC_FYL2X))
15735    (clobber (match_scratch:XF 3 "=1"))]
15736   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15737    && flag_unsafe_math_optimizations"
15738   "fyl2x"
15739   [(set_attr "type" "fpspc")
15740    (set_attr "mode" "XF")])
15742 (define_expand "logsf2"
15743   [(set (match_dup 2)
15744         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15745    (parallel [(set (match_dup 4)
15746                    (unspec:XF [(match_dup 2)
15747                                (match_dup 3)] UNSPEC_FYL2X))
15748               (clobber (match_scratch:XF 5 ""))])
15749    (set (match_operand:SF 0 "register_operand" "")
15750         (float_truncate:SF (match_dup 4)))]
15751   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15752    && flag_unsafe_math_optimizations"
15754   rtx temp;
15756   operands[2] = gen_reg_rtx (XFmode);
15757   operands[3] = gen_reg_rtx (XFmode);
15758   operands[4] = gen_reg_rtx (XFmode);
15760   temp = standard_80387_constant_rtx (4); /* fldln2 */
15761   emit_move_insn (operands[3], temp);
15764 (define_expand "logdf2"
15765   [(set (match_dup 2)
15766         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15767    (parallel [(set (match_dup 4)
15768                    (unspec:XF [(match_dup 2)
15769                                (match_dup 3)] UNSPEC_FYL2X))
15770               (clobber (match_scratch:XF 5 ""))])
15771    (set (match_operand:DF 0 "register_operand" "")
15772         (float_truncate:DF (match_dup 4)))]
15773   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15774    && flag_unsafe_math_optimizations"
15776   rtx temp;
15778   operands[2] = gen_reg_rtx (XFmode);
15779   operands[3] = gen_reg_rtx (XFmode);
15780   operands[4] = gen_reg_rtx (XFmode);
15782   temp = standard_80387_constant_rtx (4); /* fldln2 */
15783   emit_move_insn (operands[3], temp);
15786 (define_expand "logxf2"
15787   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15788                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15789                                (match_dup 2)] UNSPEC_FYL2X))
15790               (clobber (match_scratch:XF 3 ""))])]
15791   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15792    && flag_unsafe_math_optimizations"
15794   rtx temp;
15796   operands[2] = gen_reg_rtx (XFmode);
15797   temp = standard_80387_constant_rtx (4); /* fldln2 */
15798   emit_move_insn (operands[2], temp);
15801 (define_expand "log10sf2"
15802   [(set (match_dup 2)
15803         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15804    (parallel [(set (match_dup 4)
15805                    (unspec:XF [(match_dup 2)
15806                                (match_dup 3)] UNSPEC_FYL2X))
15807               (clobber (match_scratch:XF 5 ""))])
15808    (set (match_operand:SF 0 "register_operand" "")
15809         (float_truncate:SF (match_dup 4)))]
15810   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15811    && flag_unsafe_math_optimizations"
15813   rtx temp;
15815   operands[2] = gen_reg_rtx (XFmode);
15816   operands[3] = gen_reg_rtx (XFmode);
15817   operands[4] = gen_reg_rtx (XFmode);
15819   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15820   emit_move_insn (operands[3], temp);
15823 (define_expand "log10df2"
15824   [(set (match_dup 2)
15825         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15826    (parallel [(set (match_dup 4)
15827                    (unspec:XF [(match_dup 2)
15828                                (match_dup 3)] UNSPEC_FYL2X))
15829               (clobber (match_scratch:XF 5 ""))])
15830    (set (match_operand:DF 0 "register_operand" "")
15831         (float_truncate:DF (match_dup 4)))]
15832   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15833    && flag_unsafe_math_optimizations"
15835   rtx temp;
15837   operands[2] = gen_reg_rtx (XFmode);
15838   operands[3] = gen_reg_rtx (XFmode);
15839   operands[4] = gen_reg_rtx (XFmode);
15841   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15842   emit_move_insn (operands[3], temp);
15845 (define_expand "log10xf2"
15846   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15847                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15848                                (match_dup 2)] UNSPEC_FYL2X))
15849               (clobber (match_scratch:XF 3 ""))])]
15850   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15851    && flag_unsafe_math_optimizations"
15853   rtx temp;
15855   operands[2] = gen_reg_rtx (XFmode);
15856   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15857   emit_move_insn (operands[2], temp);
15860 (define_expand "log2sf2"
15861   [(set (match_dup 2)
15862         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15863    (parallel [(set (match_dup 4)
15864                    (unspec:XF [(match_dup 2)
15865                                (match_dup 3)] UNSPEC_FYL2X))
15866               (clobber (match_scratch:XF 5 ""))])
15867    (set (match_operand:SF 0 "register_operand" "")
15868         (float_truncate:SF (match_dup 4)))]
15869   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15870    && flag_unsafe_math_optimizations"
15872   operands[2] = gen_reg_rtx (XFmode);
15873   operands[3] = gen_reg_rtx (XFmode);
15874   operands[4] = gen_reg_rtx (XFmode);
15876   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15879 (define_expand "log2df2"
15880   [(set (match_dup 2)
15881         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15882    (parallel [(set (match_dup 4)
15883                    (unspec:XF [(match_dup 2)
15884                                (match_dup 3)] UNSPEC_FYL2X))
15885               (clobber (match_scratch:XF 5 ""))])
15886    (set (match_operand:DF 0 "register_operand" "")
15887         (float_truncate:DF (match_dup 4)))]
15888   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15889    && flag_unsafe_math_optimizations"
15891   operands[2] = gen_reg_rtx (XFmode);
15892   operands[3] = gen_reg_rtx (XFmode);
15893   operands[4] = gen_reg_rtx (XFmode);
15895   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15898 (define_expand "log2xf2"
15899   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15900                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15901                                (match_dup 2)] UNSPEC_FYL2X))
15902               (clobber (match_scratch:XF 3 ""))])]
15903   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15904    && flag_unsafe_math_optimizations"
15906   operands[2] = gen_reg_rtx (XFmode);
15907   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15910 (define_insn "fyl2xp1_xf3"
15911   [(set (match_operand:XF 0 "register_operand" "=f")
15912         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15913                     (match_operand:XF 1 "register_operand" "u")]
15914                    UNSPEC_FYL2XP1))
15915    (clobber (match_scratch:XF 3 "=1"))]
15916   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15917    && flag_unsafe_math_optimizations"
15918   "fyl2xp1"
15919   [(set_attr "type" "fpspc")
15920    (set_attr "mode" "XF")])
15922 (define_expand "log1psf2"
15923   [(use (match_operand:XF 0 "register_operand" ""))
15924    (use (match_operand:XF 1 "register_operand" ""))]
15925   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15926    && flag_unsafe_math_optimizations"
15928   rtx op0 = gen_reg_rtx (XFmode);
15929   rtx op1 = gen_reg_rtx (XFmode);
15931   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15932   ix86_emit_i387_log1p (op0, op1);
15933   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15934   DONE;
15937 (define_expand "log1pdf2"
15938   [(use (match_operand:XF 0 "register_operand" ""))
15939    (use (match_operand:XF 1 "register_operand" ""))]
15940   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15941    && flag_unsafe_math_optimizations"
15943   rtx op0 = gen_reg_rtx (XFmode);
15944   rtx op1 = gen_reg_rtx (XFmode);
15946   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15947   ix86_emit_i387_log1p (op0, op1);
15948   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15949   DONE;
15952 (define_expand "log1pxf2"
15953   [(use (match_operand:XF 0 "register_operand" ""))
15954    (use (match_operand:XF 1 "register_operand" ""))]
15955   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15956    && flag_unsafe_math_optimizations"
15958   ix86_emit_i387_log1p (operands[0], operands[1]);
15959   DONE;
15962 (define_insn "*fxtractxf3"
15963   [(set (match_operand:XF 0 "register_operand" "=f")
15964         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15965                    UNSPEC_XTRACT_FRACT))
15966    (set (match_operand:XF 1 "register_operand" "=u")
15967         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15968   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15969    && flag_unsafe_math_optimizations"
15970   "fxtract"
15971   [(set_attr "type" "fpspc")
15972    (set_attr "mode" "XF")])
15974 (define_expand "logbsf2"
15975   [(set (match_dup 2)
15976         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15977    (parallel [(set (match_dup 3)
15978                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15979               (set (match_dup 4)
15980                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15981    (set (match_operand:SF 0 "register_operand" "")
15982         (float_truncate:SF (match_dup 4)))]
15983   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15984    && flag_unsafe_math_optimizations"
15986   operands[2] = gen_reg_rtx (XFmode);
15987   operands[3] = gen_reg_rtx (XFmode);
15988   operands[4] = gen_reg_rtx (XFmode);
15991 (define_expand "logbdf2"
15992   [(set (match_dup 2)
15993         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15994    (parallel [(set (match_dup 3)
15995                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15996               (set (match_dup 4)
15997                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15998    (set (match_operand:DF 0 "register_operand" "")
15999         (float_truncate:DF (match_dup 4)))]
16000   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16001    && flag_unsafe_math_optimizations"
16003   operands[2] = gen_reg_rtx (XFmode);
16004   operands[3] = gen_reg_rtx (XFmode);
16005   operands[4] = gen_reg_rtx (XFmode);
16008 (define_expand "logbxf2"
16009   [(parallel [(set (match_dup 2)
16010                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16011                               UNSPEC_XTRACT_FRACT))
16012               (set (match_operand:XF 0 "register_operand" "")
16013                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16014   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16015    && flag_unsafe_math_optimizations"
16017   operands[2] = gen_reg_rtx (XFmode);
16020 (define_expand "ilogbsi2"
16021   [(parallel [(set (match_dup 2)
16022                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16023                               UNSPEC_XTRACT_FRACT))
16024               (set (match_operand:XF 3 "register_operand" "")
16025                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16026    (parallel [(set (match_operand:SI 0 "register_operand" "")
16027                    (fix:SI (match_dup 3)))
16028               (clobber (reg:CC FLAGS_REG))])]
16029   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16030    && flag_unsafe_math_optimizations"
16032   operands[2] = gen_reg_rtx (XFmode);
16033   operands[3] = gen_reg_rtx (XFmode);
16036 (define_insn "*f2xm1xf2"
16037   [(set (match_operand:XF 0 "register_operand" "=f")
16038         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16039          UNSPEC_F2XM1))]
16040   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16041    && flag_unsafe_math_optimizations"
16042   "f2xm1"
16043   [(set_attr "type" "fpspc")
16044    (set_attr "mode" "XF")])
16046 (define_insn "*fscalexf4"
16047   [(set (match_operand:XF 0 "register_operand" "=f")
16048         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16049                     (match_operand:XF 3 "register_operand" "1")]
16050                    UNSPEC_FSCALE_FRACT))
16051    (set (match_operand:XF 1 "register_operand" "=u")
16052         (unspec:XF [(match_dup 2) (match_dup 3)]
16053                    UNSPEC_FSCALE_EXP))]
16054   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16055    && flag_unsafe_math_optimizations"
16056   "fscale"
16057   [(set_attr "type" "fpspc")
16058    (set_attr "mode" "XF")])
16060 (define_expand "expsf2"
16061   [(set (match_dup 2)
16062         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16063    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16064    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16065    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16066    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16067    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16068    (parallel [(set (match_dup 10)
16069                    (unspec:XF [(match_dup 9) (match_dup 5)]
16070                               UNSPEC_FSCALE_FRACT))
16071               (set (match_dup 11)
16072                    (unspec:XF [(match_dup 9) (match_dup 5)]
16073                               UNSPEC_FSCALE_EXP))])
16074    (set (match_operand:SF 0 "register_operand" "")
16075         (float_truncate:SF (match_dup 10)))]
16076   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16077    && flag_unsafe_math_optimizations"
16079   rtx temp;
16080   int i;
16082   for (i=2; i<12; i++)
16083     operands[i] = gen_reg_rtx (XFmode);
16084   temp = standard_80387_constant_rtx (5); /* fldl2e */
16085   emit_move_insn (operands[3], temp);
16086   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16089 (define_expand "expdf2"
16090   [(set (match_dup 2)
16091         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16092    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16093    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16094    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16095    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16096    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16097    (parallel [(set (match_dup 10)
16098                    (unspec:XF [(match_dup 9) (match_dup 5)]
16099                               UNSPEC_FSCALE_FRACT))
16100               (set (match_dup 11)
16101                    (unspec:XF [(match_dup 9) (match_dup 5)]
16102                               UNSPEC_FSCALE_EXP))])
16103    (set (match_operand:DF 0 "register_operand" "")
16104         (float_truncate:DF (match_dup 10)))]
16105   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16106    && flag_unsafe_math_optimizations"
16108   rtx temp;
16109   int i;
16111   for (i=2; i<12; i++)
16112     operands[i] = gen_reg_rtx (XFmode);
16113   temp = standard_80387_constant_rtx (5); /* fldl2e */
16114   emit_move_insn (operands[3], temp);
16115   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16118 (define_expand "expxf2"
16119   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16120                                (match_dup 2)))
16121    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16122    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16123    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16124    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16125    (parallel [(set (match_operand:XF 0 "register_operand" "")
16126                    (unspec:XF [(match_dup 8) (match_dup 4)]
16127                               UNSPEC_FSCALE_FRACT))
16128               (set (match_dup 9)
16129                    (unspec:XF [(match_dup 8) (match_dup 4)]
16130                               UNSPEC_FSCALE_EXP))])]
16131   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16132    && flag_unsafe_math_optimizations"
16134   rtx temp;
16135   int i;
16137   for (i=2; i<10; i++)
16138     operands[i] = gen_reg_rtx (XFmode);
16139   temp = standard_80387_constant_rtx (5); /* fldl2e */
16140   emit_move_insn (operands[2], temp);
16141   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16144 (define_expand "exp10sf2"
16145   [(set (match_dup 2)
16146         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16147    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16148    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16149    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16150    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16151    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16152    (parallel [(set (match_dup 10)
16153                    (unspec:XF [(match_dup 9) (match_dup 5)]
16154                               UNSPEC_FSCALE_FRACT))
16155               (set (match_dup 11)
16156                    (unspec:XF [(match_dup 9) (match_dup 5)]
16157                               UNSPEC_FSCALE_EXP))])
16158    (set (match_operand:SF 0 "register_operand" "")
16159         (float_truncate:SF (match_dup 10)))]
16160   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16161    && flag_unsafe_math_optimizations"
16163   rtx temp;
16164   int i;
16166   for (i=2; i<12; i++)
16167     operands[i] = gen_reg_rtx (XFmode);
16168   temp = standard_80387_constant_rtx (6); /* fldl2t */
16169   emit_move_insn (operands[3], temp);
16170   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16173 (define_expand "exp10df2"
16174   [(set (match_dup 2)
16175         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16176    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16177    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16178    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16179    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16180    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16181    (parallel [(set (match_dup 10)
16182                    (unspec:XF [(match_dup 9) (match_dup 5)]
16183                               UNSPEC_FSCALE_FRACT))
16184               (set (match_dup 11)
16185                    (unspec:XF [(match_dup 9) (match_dup 5)]
16186                               UNSPEC_FSCALE_EXP))])
16187    (set (match_operand:DF 0 "register_operand" "")
16188         (float_truncate:DF (match_dup 10)))]
16189   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16190    && flag_unsafe_math_optimizations"
16192   rtx temp;
16193   int i;
16195   for (i=2; i<12; i++)
16196     operands[i] = gen_reg_rtx (XFmode);
16197   temp = standard_80387_constant_rtx (6); /* fldl2t */
16198   emit_move_insn (operands[3], temp);
16199   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16202 (define_expand "exp10xf2"
16203   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16204                                (match_dup 2)))
16205    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16206    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16207    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16208    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16209    (parallel [(set (match_operand:XF 0 "register_operand" "")
16210                    (unspec:XF [(match_dup 8) (match_dup 4)]
16211                               UNSPEC_FSCALE_FRACT))
16212               (set (match_dup 9)
16213                    (unspec:XF [(match_dup 8) (match_dup 4)]
16214                               UNSPEC_FSCALE_EXP))])]
16215   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16216    && flag_unsafe_math_optimizations"
16218   rtx temp;
16219   int i;
16221   for (i=2; i<10; i++)
16222     operands[i] = gen_reg_rtx (XFmode);
16223   temp = standard_80387_constant_rtx (6); /* fldl2t */
16224   emit_move_insn (operands[2], temp);
16225   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16228 (define_expand "exp2sf2"
16229   [(set (match_dup 2)
16230         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16231    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16232    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16233    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16234    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16235    (parallel [(set (match_dup 8)
16236                    (unspec:XF [(match_dup 7) (match_dup 3)]
16237                               UNSPEC_FSCALE_FRACT))
16238               (set (match_dup 9)
16239                    (unspec:XF [(match_dup 7) (match_dup 3)]
16240                               UNSPEC_FSCALE_EXP))])
16241    (set (match_operand:SF 0 "register_operand" "")
16242         (float_truncate:SF (match_dup 8)))]
16243   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16244    && flag_unsafe_math_optimizations"
16246   int i;
16248   for (i=2; i<10; i++)
16249     operands[i] = gen_reg_rtx (XFmode);
16250   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16253 (define_expand "exp2df2"
16254   [(set (match_dup 2)
16255         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16256    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16257    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16258    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16259    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16260    (parallel [(set (match_dup 8)
16261                    (unspec:XF [(match_dup 7) (match_dup 3)]
16262                               UNSPEC_FSCALE_FRACT))
16263               (set (match_dup 9)
16264                    (unspec:XF [(match_dup 7) (match_dup 3)]
16265                               UNSPEC_FSCALE_EXP))])
16266    (set (match_operand:DF 0 "register_operand" "")
16267         (float_truncate:DF (match_dup 8)))]
16268   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16269    && flag_unsafe_math_optimizations"
16271   int i;
16273   for (i=2; i<10; i++)
16274     operands[i] = gen_reg_rtx (XFmode);
16275   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16278 (define_expand "exp2xf2"
16279   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16280    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16281    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16282    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16283    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16284    (parallel [(set (match_operand:XF 0 "register_operand" "")
16285                    (unspec:XF [(match_dup 7) (match_dup 3)]
16286                               UNSPEC_FSCALE_FRACT))
16287               (set (match_dup 8)
16288                    (unspec:XF [(match_dup 7) (match_dup 3)]
16289                               UNSPEC_FSCALE_EXP))])]
16290   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16291    && flag_unsafe_math_optimizations"
16293   int i;
16295   for (i=2; i<9; i++)
16296     operands[i] = gen_reg_rtx (XFmode);
16297   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16300 (define_expand "expm1df2"
16301   [(set (match_dup 2)
16302         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16303    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16304    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16305    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16306    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16307    (parallel [(set (match_dup 8)
16308                    (unspec:XF [(match_dup 7) (match_dup 5)]
16309                               UNSPEC_FSCALE_FRACT))
16310                    (set (match_dup 9)
16311                    (unspec:XF [(match_dup 7) (match_dup 5)]
16312                               UNSPEC_FSCALE_EXP))])
16313    (parallel [(set (match_dup 11)
16314                    (unspec:XF [(match_dup 10) (match_dup 9)]
16315                               UNSPEC_FSCALE_FRACT))
16316               (set (match_dup 12)
16317                    (unspec:XF [(match_dup 10) (match_dup 9)]
16318                               UNSPEC_FSCALE_EXP))])
16319    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16320    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16321    (set (match_operand:DF 0 "register_operand" "")
16322         (float_truncate:DF (match_dup 14)))]
16323   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16324    && flag_unsafe_math_optimizations"
16326   rtx temp;
16327   int i;
16329   for (i=2; i<15; i++)
16330     operands[i] = gen_reg_rtx (XFmode);
16331   temp = standard_80387_constant_rtx (5); /* fldl2e */
16332   emit_move_insn (operands[3], temp);
16333   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16336 (define_expand "expm1sf2"
16337   [(set (match_dup 2)
16338         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16339    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16340    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16341    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16342    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16343    (parallel [(set (match_dup 8)
16344                    (unspec:XF [(match_dup 7) (match_dup 5)]
16345                               UNSPEC_FSCALE_FRACT))
16346                    (set (match_dup 9)
16347                    (unspec:XF [(match_dup 7) (match_dup 5)]
16348                               UNSPEC_FSCALE_EXP))])
16349    (parallel [(set (match_dup 11)
16350                    (unspec:XF [(match_dup 10) (match_dup 9)]
16351                               UNSPEC_FSCALE_FRACT))
16352               (set (match_dup 12)
16353                    (unspec:XF [(match_dup 10) (match_dup 9)]
16354                               UNSPEC_FSCALE_EXP))])
16355    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16356    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16357    (set (match_operand:SF 0 "register_operand" "")
16358         (float_truncate:SF (match_dup 14)))]
16359   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16360    && flag_unsafe_math_optimizations"
16362   rtx temp;
16363   int i;
16365   for (i=2; i<15; i++)
16366     operands[i] = gen_reg_rtx (XFmode);
16367   temp = standard_80387_constant_rtx (5); /* fldl2e */
16368   emit_move_insn (operands[3], temp);
16369   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16372 (define_expand "expm1xf2"
16373   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16374                                (match_dup 2)))
16375    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16376    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16377    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16378    (parallel [(set (match_dup 7)
16379                    (unspec:XF [(match_dup 6) (match_dup 4)]
16380                               UNSPEC_FSCALE_FRACT))
16381                    (set (match_dup 8)
16382                    (unspec:XF [(match_dup 6) (match_dup 4)]
16383                               UNSPEC_FSCALE_EXP))])
16384    (parallel [(set (match_dup 10)
16385                    (unspec:XF [(match_dup 9) (match_dup 8)]
16386                               UNSPEC_FSCALE_FRACT))
16387               (set (match_dup 11)
16388                    (unspec:XF [(match_dup 9) (match_dup 8)]
16389                               UNSPEC_FSCALE_EXP))])
16390    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16391    (set (match_operand:XF 0 "register_operand" "")
16392         (plus:XF (match_dup 12) (match_dup 7)))]
16393   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16394    && flag_unsafe_math_optimizations"
16396   rtx temp;
16397   int i;
16399   for (i=2; i<13; i++)
16400     operands[i] = gen_reg_rtx (XFmode);
16401   temp = standard_80387_constant_rtx (5); /* fldl2e */
16402   emit_move_insn (operands[2], temp);
16403   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16407 (define_insn "frndintxf2"
16408   [(set (match_operand:XF 0 "register_operand" "=f")
16409         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16410          UNSPEC_FRNDINT))]
16411   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16412    && flag_unsafe_math_optimizations"
16413   "frndint"
16414   [(set_attr "type" "fpspc")
16415    (set_attr "mode" "XF")])
16417 (define_expand "rintdf2"
16418   [(use (match_operand:DF 0 "register_operand" ""))
16419    (use (match_operand:DF 1 "register_operand" ""))]
16420   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16421    && flag_unsafe_math_optimizations"
16423   rtx op0 = gen_reg_rtx (XFmode);
16424   rtx op1 = gen_reg_rtx (XFmode);
16426   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16427   emit_insn (gen_frndintxf2 (op0, op1));
16429   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16430   DONE;
16433 (define_expand "rintsf2"
16434   [(use (match_operand:SF 0 "register_operand" ""))
16435    (use (match_operand:SF 1 "register_operand" ""))]
16436   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16437    && flag_unsafe_math_optimizations"
16439   rtx op0 = gen_reg_rtx (XFmode);
16440   rtx op1 = gen_reg_rtx (XFmode);
16442   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16443   emit_insn (gen_frndintxf2 (op0, op1));
16445   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16446   DONE;
16449 (define_expand "rintxf2"
16450   [(use (match_operand:XF 0 "register_operand" ""))
16451    (use (match_operand:XF 1 "register_operand" ""))]
16452   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16453    && flag_unsafe_math_optimizations"
16455   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16456   DONE;
16459 (define_insn "frndintxf2_floor"
16460   [(set (match_operand:XF 0 "register_operand" "=f")
16461         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16462          UNSPEC_FRNDINT_FLOOR))
16463    (use (match_operand:HI 2 "memory_operand" "m"))
16464    (use (match_operand:HI 3 "memory_operand" "m"))]
16465   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16466    && flag_unsafe_math_optimizations"
16467   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16468   [(set_attr "type" "frndint")
16469    (set_attr "i387_cw" "floor")
16470    (set_attr "mode" "XF")])
16472 (define_expand "floordf2"
16473   [(use (match_operand:DF 0 "register_operand" ""))
16474    (use (match_operand:DF 1 "register_operand" ""))]
16475   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16476    && flag_unsafe_math_optimizations"
16478   rtx op0 = gen_reg_rtx (XFmode);
16479   rtx op1 = gen_reg_rtx (XFmode);
16480   rtx op2 = assign_386_stack_local (HImode, 1);
16481   rtx op3 = assign_386_stack_local (HImode, 2);
16482         
16483   ix86_optimize_mode_switching = 1;
16485   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16486   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16488   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16489   DONE;
16492 (define_expand "floorsf2"
16493   [(use (match_operand:SF 0 "register_operand" ""))
16494    (use (match_operand:SF 1 "register_operand" ""))]
16495   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16496    && flag_unsafe_math_optimizations"
16498   rtx op0 = gen_reg_rtx (XFmode);
16499   rtx op1 = gen_reg_rtx (XFmode);
16500   rtx op2 = assign_386_stack_local (HImode, 1);
16501   rtx op3 = assign_386_stack_local (HImode, 2);
16502         
16503   ix86_optimize_mode_switching = 1;
16505   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16506   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16508   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16509   DONE;
16512 (define_expand "floorxf2"
16513   [(use (match_operand:XF 0 "register_operand" ""))
16514    (use (match_operand:XF 1 "register_operand" ""))]
16515   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16516    && flag_unsafe_math_optimizations"
16518   rtx op2 = assign_386_stack_local (HImode, 1);
16519   rtx op3 = assign_386_stack_local (HImode, 2);
16520         
16521   ix86_optimize_mode_switching = 1;
16523   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16524   DONE;
16527 (define_insn "frndintxf2_ceil"
16528   [(set (match_operand:XF 0 "register_operand" "=f")
16529         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16530          UNSPEC_FRNDINT_CEIL))
16531    (use (match_operand:HI 2 "memory_operand" "m"))
16532    (use (match_operand:HI 3 "memory_operand" "m"))]
16533   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16534    && flag_unsafe_math_optimizations"
16535   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16536   [(set_attr "type" "frndint")
16537    (set_attr "i387_cw" "ceil")
16538    (set_attr "mode" "XF")])
16540 (define_expand "ceildf2"
16541   [(use (match_operand:DF 0 "register_operand" ""))
16542    (use (match_operand:DF 1 "register_operand" ""))]
16543   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16544    && flag_unsafe_math_optimizations"
16546   rtx op0 = gen_reg_rtx (XFmode);
16547   rtx op1 = gen_reg_rtx (XFmode);
16548   rtx op2 = assign_386_stack_local (HImode, 1);
16549   rtx op3 = assign_386_stack_local (HImode, 2);
16550         
16551   ix86_optimize_mode_switching = 1;
16553   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16554   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16556   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16557   DONE;
16560 (define_expand "ceilsf2"
16561   [(use (match_operand:SF 0 "register_operand" ""))
16562    (use (match_operand:SF 1 "register_operand" ""))]
16563   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16564    && flag_unsafe_math_optimizations"
16566   rtx op0 = gen_reg_rtx (XFmode);
16567   rtx op1 = gen_reg_rtx (XFmode);
16568   rtx op2 = assign_386_stack_local (HImode, 1);
16569   rtx op3 = assign_386_stack_local (HImode, 2);
16570         
16571   ix86_optimize_mode_switching = 1;
16573   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16574   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16576   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16577   DONE;
16580 (define_expand "ceilxf2"
16581   [(use (match_operand:XF 0 "register_operand" ""))
16582    (use (match_operand:XF 1 "register_operand" ""))]
16583   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16584    && flag_unsafe_math_optimizations"
16586   rtx op2 = assign_386_stack_local (HImode, 1);
16587   rtx op3 = assign_386_stack_local (HImode, 2);
16588         
16589   ix86_optimize_mode_switching = 1;
16591   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16592   DONE;
16595 (define_insn "frndintxf2_trunc"
16596   [(set (match_operand:XF 0 "register_operand" "=f")
16597         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16598          UNSPEC_FRNDINT_TRUNC))
16599    (use (match_operand:HI 2 "memory_operand" "m"))
16600    (use (match_operand:HI 3 "memory_operand" "m"))]
16601   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16602    && flag_unsafe_math_optimizations"
16603   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16604   [(set_attr "type" "frndint")
16605    (set_attr "i387_cw" "trunc")
16606    (set_attr "mode" "XF")])
16608 (define_expand "btruncdf2"
16609   [(use (match_operand:DF 0 "register_operand" ""))
16610    (use (match_operand:DF 1 "register_operand" ""))]
16611   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16612    && flag_unsafe_math_optimizations"
16614   rtx op0 = gen_reg_rtx (XFmode);
16615   rtx op1 = gen_reg_rtx (XFmode);
16616   rtx op2 = assign_386_stack_local (HImode, 1);
16617   rtx op3 = assign_386_stack_local (HImode, 2);
16618         
16619   ix86_optimize_mode_switching = 1;
16621   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16622   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16624   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16625   DONE;
16628 (define_expand "btruncsf2"
16629   [(use (match_operand:SF 0 "register_operand" ""))
16630    (use (match_operand:SF 1 "register_operand" ""))]
16631   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16632    && flag_unsafe_math_optimizations"
16634   rtx op0 = gen_reg_rtx (XFmode);
16635   rtx op1 = gen_reg_rtx (XFmode);
16636   rtx op2 = assign_386_stack_local (HImode, 1);
16637   rtx op3 = assign_386_stack_local (HImode, 2);
16638         
16639   ix86_optimize_mode_switching = 1;
16641   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16642   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16644   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16645   DONE;
16648 (define_expand "btruncxf2"
16649   [(use (match_operand:XF 0 "register_operand" ""))
16650    (use (match_operand:XF 1 "register_operand" ""))]
16651   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16652    && flag_unsafe_math_optimizations"
16654   rtx op2 = assign_386_stack_local (HImode, 1);
16655   rtx op3 = assign_386_stack_local (HImode, 2);
16656         
16657   ix86_optimize_mode_switching = 1;
16659   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16660   DONE;
16663 (define_insn "frndintxf2_mask_pm"
16664   [(set (match_operand:XF 0 "register_operand" "=f")
16665         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16666          UNSPEC_FRNDINT_MASK_PM))
16667    (use (match_operand:HI 2 "memory_operand" "m"))
16668    (use (match_operand:HI 3 "memory_operand" "m"))]
16669   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16670    && flag_unsafe_math_optimizations"
16671   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16672   [(set_attr "type" "frndint")
16673    (set_attr "i387_cw" "mask_pm")
16674    (set_attr "mode" "XF")])
16676 (define_expand "nearbyintdf2"
16677   [(use (match_operand:DF 0 "register_operand" ""))
16678    (use (match_operand:DF 1 "register_operand" ""))]
16679   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16680    && flag_unsafe_math_optimizations"
16682   rtx op0 = gen_reg_rtx (XFmode);
16683   rtx op1 = gen_reg_rtx (XFmode);
16684   rtx op2 = assign_386_stack_local (HImode, 1);
16685   rtx op3 = assign_386_stack_local (HImode, 2);
16686         
16687   ix86_optimize_mode_switching = 1;
16689   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16690   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16692   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16693   DONE;
16696 (define_expand "nearbyintsf2"
16697   [(use (match_operand:SF 0 "register_operand" ""))
16698    (use (match_operand:SF 1 "register_operand" ""))]
16699   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16700    && flag_unsafe_math_optimizations"
16702   rtx op0 = gen_reg_rtx (XFmode);
16703   rtx op1 = gen_reg_rtx (XFmode);
16704   rtx op2 = assign_386_stack_local (HImode, 1);
16705   rtx op3 = assign_386_stack_local (HImode, 2);
16706         
16707   ix86_optimize_mode_switching = 1;
16709   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16710   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16712   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16713   DONE;
16716 (define_expand "nearbyintxf2"
16717   [(use (match_operand:XF 0 "register_operand" ""))
16718    (use (match_operand:XF 1 "register_operand" ""))]
16719   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16720    && flag_unsafe_math_optimizations"
16722   rtx op2 = assign_386_stack_local (HImode, 1);
16723   rtx op3 = assign_386_stack_local (HImode, 2);
16724         
16725   ix86_optimize_mode_switching = 1;
16727   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16728                                      op2, op3));
16729   DONE;
16733 ;; Block operation instructions
16735 (define_insn "cld"
16736  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16737  ""
16738  "cld"
16739   [(set_attr "type" "cld")])
16741 (define_expand "movmemsi"
16742   [(use (match_operand:BLK 0 "memory_operand" ""))
16743    (use (match_operand:BLK 1 "memory_operand" ""))
16744    (use (match_operand:SI 2 "nonmemory_operand" ""))
16745    (use (match_operand:SI 3 "const_int_operand" ""))]
16746   "! optimize_size"
16748  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16749    DONE;
16750  else
16751    FAIL;
16754 (define_expand "movmemdi"
16755   [(use (match_operand:BLK 0 "memory_operand" ""))
16756    (use (match_operand:BLK 1 "memory_operand" ""))
16757    (use (match_operand:DI 2 "nonmemory_operand" ""))
16758    (use (match_operand:DI 3 "const_int_operand" ""))]
16759   "TARGET_64BIT"
16761  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16762    DONE;
16763  else
16764    FAIL;
16767 ;; Most CPUs don't like single string operations
16768 ;; Handle this case here to simplify previous expander.
16770 (define_expand "strmov"
16771   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16772    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16773    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16774               (clobber (reg:CC FLAGS_REG))])
16775    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16776               (clobber (reg:CC FLAGS_REG))])]
16777   ""
16779   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16781   /* If .md ever supports :P for Pmode, these can be directly
16782      in the pattern above.  */
16783   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16784   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16786   if (TARGET_SINGLE_STRINGOP || optimize_size)
16787     {
16788       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16789                                       operands[2], operands[3],
16790                                       operands[5], operands[6]));
16791       DONE;
16792     }
16794   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16797 (define_expand "strmov_singleop"
16798   [(parallel [(set (match_operand 1 "memory_operand" "")
16799                    (match_operand 3 "memory_operand" ""))
16800               (set (match_operand 0 "register_operand" "")
16801                    (match_operand 4 "" ""))
16802               (set (match_operand 2 "register_operand" "")
16803                    (match_operand 5 "" ""))
16804               (use (reg:SI DIRFLAG_REG))])]
16805   "TARGET_SINGLE_STRINGOP || optimize_size"
16806   "")
16808 (define_insn "*strmovdi_rex_1"
16809   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16810         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16811    (set (match_operand:DI 0 "register_operand" "=D")
16812         (plus:DI (match_dup 2)
16813                  (const_int 8)))
16814    (set (match_operand:DI 1 "register_operand" "=S")
16815         (plus:DI (match_dup 3)
16816                  (const_int 8)))
16817    (use (reg:SI DIRFLAG_REG))]
16818   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16819   "movsq"
16820   [(set_attr "type" "str")
16821    (set_attr "mode" "DI")
16822    (set_attr "memory" "both")])
16824 (define_insn "*strmovsi_1"
16825   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16826         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16827    (set (match_operand:SI 0 "register_operand" "=D")
16828         (plus:SI (match_dup 2)
16829                  (const_int 4)))
16830    (set (match_operand:SI 1 "register_operand" "=S")
16831         (plus:SI (match_dup 3)
16832                  (const_int 4)))
16833    (use (reg:SI DIRFLAG_REG))]
16834   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16835   "{movsl|movsd}"
16836   [(set_attr "type" "str")
16837    (set_attr "mode" "SI")
16838    (set_attr "memory" "both")])
16840 (define_insn "*strmovsi_rex_1"
16841   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16842         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16843    (set (match_operand:DI 0 "register_operand" "=D")
16844         (plus:DI (match_dup 2)
16845                  (const_int 4)))
16846    (set (match_operand:DI 1 "register_operand" "=S")
16847         (plus:DI (match_dup 3)
16848                  (const_int 4)))
16849    (use (reg:SI DIRFLAG_REG))]
16850   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16851   "{movsl|movsd}"
16852   [(set_attr "type" "str")
16853    (set_attr "mode" "SI")
16854    (set_attr "memory" "both")])
16856 (define_insn "*strmovhi_1"
16857   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16858         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16859    (set (match_operand:SI 0 "register_operand" "=D")
16860         (plus:SI (match_dup 2)
16861                  (const_int 2)))
16862    (set (match_operand:SI 1 "register_operand" "=S")
16863         (plus:SI (match_dup 3)
16864                  (const_int 2)))
16865    (use (reg:SI DIRFLAG_REG))]
16866   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16867   "movsw"
16868   [(set_attr "type" "str")
16869    (set_attr "memory" "both")
16870    (set_attr "mode" "HI")])
16872 (define_insn "*strmovhi_rex_1"
16873   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16874         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16875    (set (match_operand:DI 0 "register_operand" "=D")
16876         (plus:DI (match_dup 2)
16877                  (const_int 2)))
16878    (set (match_operand:DI 1 "register_operand" "=S")
16879         (plus:DI (match_dup 3)
16880                  (const_int 2)))
16881    (use (reg:SI DIRFLAG_REG))]
16882   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16883   "movsw"
16884   [(set_attr "type" "str")
16885    (set_attr "memory" "both")
16886    (set_attr "mode" "HI")])
16888 (define_insn "*strmovqi_1"
16889   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16890         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16891    (set (match_operand:SI 0 "register_operand" "=D")
16892         (plus:SI (match_dup 2)
16893                  (const_int 1)))
16894    (set (match_operand:SI 1 "register_operand" "=S")
16895         (plus:SI (match_dup 3)
16896                  (const_int 1)))
16897    (use (reg:SI DIRFLAG_REG))]
16898   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16899   "movsb"
16900   [(set_attr "type" "str")
16901    (set_attr "memory" "both")
16902    (set_attr "mode" "QI")])
16904 (define_insn "*strmovqi_rex_1"
16905   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16906         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16907    (set (match_operand:DI 0 "register_operand" "=D")
16908         (plus:DI (match_dup 2)
16909                  (const_int 1)))
16910    (set (match_operand:DI 1 "register_operand" "=S")
16911         (plus:DI (match_dup 3)
16912                  (const_int 1)))
16913    (use (reg:SI DIRFLAG_REG))]
16914   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16915   "movsb"
16916   [(set_attr "type" "str")
16917    (set_attr "memory" "both")
16918    (set_attr "mode" "QI")])
16920 (define_expand "rep_mov"
16921   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16922               (set (match_operand 0 "register_operand" "")
16923                    (match_operand 5 "" ""))
16924               (set (match_operand 2 "register_operand" "")
16925                    (match_operand 6 "" ""))
16926               (set (match_operand 1 "memory_operand" "")
16927                    (match_operand 3 "memory_operand" ""))
16928               (use (match_dup 4))
16929               (use (reg:SI DIRFLAG_REG))])]
16930   ""
16931   "")
16933 (define_insn "*rep_movdi_rex64"
16934   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16935    (set (match_operand:DI 0 "register_operand" "=D") 
16936         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16937                             (const_int 3))
16938                  (match_operand:DI 3 "register_operand" "0")))
16939    (set (match_operand:DI 1 "register_operand" "=S") 
16940         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16941                  (match_operand:DI 4 "register_operand" "1")))
16942    (set (mem:BLK (match_dup 3))
16943         (mem:BLK (match_dup 4)))
16944    (use (match_dup 5))
16945    (use (reg:SI DIRFLAG_REG))]
16946   "TARGET_64BIT"
16947   "{rep\;movsq|rep movsq}"
16948   [(set_attr "type" "str")
16949    (set_attr "prefix_rep" "1")
16950    (set_attr "memory" "both")
16951    (set_attr "mode" "DI")])
16953 (define_insn "*rep_movsi"
16954   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16955    (set (match_operand:SI 0 "register_operand" "=D") 
16956         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16957                             (const_int 2))
16958                  (match_operand:SI 3 "register_operand" "0")))
16959    (set (match_operand:SI 1 "register_operand" "=S") 
16960         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16961                  (match_operand:SI 4 "register_operand" "1")))
16962    (set (mem:BLK (match_dup 3))
16963         (mem:BLK (match_dup 4)))
16964    (use (match_dup 5))
16965    (use (reg:SI DIRFLAG_REG))]
16966   "!TARGET_64BIT"
16967   "{rep\;movsl|rep movsd}"
16968   [(set_attr "type" "str")
16969    (set_attr "prefix_rep" "1")
16970    (set_attr "memory" "both")
16971    (set_attr "mode" "SI")])
16973 (define_insn "*rep_movsi_rex64"
16974   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16975    (set (match_operand:DI 0 "register_operand" "=D") 
16976         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16977                             (const_int 2))
16978                  (match_operand:DI 3 "register_operand" "0")))
16979    (set (match_operand:DI 1 "register_operand" "=S") 
16980         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16981                  (match_operand:DI 4 "register_operand" "1")))
16982    (set (mem:BLK (match_dup 3))
16983         (mem:BLK (match_dup 4)))
16984    (use (match_dup 5))
16985    (use (reg:SI DIRFLAG_REG))]
16986   "TARGET_64BIT"
16987   "{rep\;movsl|rep movsd}"
16988   [(set_attr "type" "str")
16989    (set_attr "prefix_rep" "1")
16990    (set_attr "memory" "both")
16991    (set_attr "mode" "SI")])
16993 (define_insn "*rep_movqi"
16994   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16995    (set (match_operand:SI 0 "register_operand" "=D") 
16996         (plus:SI (match_operand:SI 3 "register_operand" "0")
16997                  (match_operand:SI 5 "register_operand" "2")))
16998    (set (match_operand:SI 1 "register_operand" "=S") 
16999         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17000    (set (mem:BLK (match_dup 3))
17001         (mem:BLK (match_dup 4)))
17002    (use (match_dup 5))
17003    (use (reg:SI DIRFLAG_REG))]
17004   "!TARGET_64BIT"
17005   "{rep\;movsb|rep movsb}"
17006   [(set_attr "type" "str")
17007    (set_attr "prefix_rep" "1")
17008    (set_attr "memory" "both")
17009    (set_attr "mode" "SI")])
17011 (define_insn "*rep_movqi_rex64"
17012   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17013    (set (match_operand:DI 0 "register_operand" "=D") 
17014         (plus:DI (match_operand:DI 3 "register_operand" "0")
17015                  (match_operand:DI 5 "register_operand" "2")))
17016    (set (match_operand:DI 1 "register_operand" "=S") 
17017         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17018    (set (mem:BLK (match_dup 3))
17019         (mem:BLK (match_dup 4)))
17020    (use (match_dup 5))
17021    (use (reg:SI DIRFLAG_REG))]
17022   "TARGET_64BIT"
17023   "{rep\;movsb|rep movsb}"
17024   [(set_attr "type" "str")
17025    (set_attr "prefix_rep" "1")
17026    (set_attr "memory" "both")
17027    (set_attr "mode" "SI")])
17029 (define_expand "clrmemsi"
17030    [(use (match_operand:BLK 0 "memory_operand" ""))
17031     (use (match_operand:SI 1 "nonmemory_operand" ""))
17032     (use (match_operand 2 "const_int_operand" ""))]
17033   ""
17035  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17036    DONE;
17037  else
17038    FAIL;
17041 (define_expand "clrmemdi"
17042    [(use (match_operand:BLK 0 "memory_operand" ""))
17043     (use (match_operand:DI 1 "nonmemory_operand" ""))
17044     (use (match_operand 2 "const_int_operand" ""))]
17045   "TARGET_64BIT"
17047  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17048    DONE;
17049  else
17050    FAIL;
17053 ;; Most CPUs don't like single string operations
17054 ;; Handle this case here to simplify previous expander.
17056 (define_expand "strset"
17057   [(set (match_operand 1 "memory_operand" "")
17058         (match_operand 2 "register_operand" ""))
17059    (parallel [(set (match_operand 0 "register_operand" "")
17060                    (match_dup 3))
17061               (clobber (reg:CC FLAGS_REG))])]
17062   ""
17064   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17065     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17067   /* If .md ever supports :P for Pmode, this can be directly
17068      in the pattern above.  */
17069   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17070                               GEN_INT (GET_MODE_SIZE (GET_MODE
17071                                                       (operands[2]))));
17072   if (TARGET_SINGLE_STRINGOP || optimize_size)
17073     {
17074       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17075                                       operands[3]));
17076       DONE;
17077     }
17080 (define_expand "strset_singleop"
17081   [(parallel [(set (match_operand 1 "memory_operand" "")
17082                    (match_operand 2 "register_operand" ""))
17083               (set (match_operand 0 "register_operand" "")
17084                    (match_operand 3 "" ""))
17085               (use (reg:SI DIRFLAG_REG))])]
17086   "TARGET_SINGLE_STRINGOP || optimize_size"
17087   "")
17089 (define_insn "*strsetdi_rex_1"
17090   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17091         (match_operand:DI 2 "register_operand" "a"))
17092    (set (match_operand:DI 0 "register_operand" "=D")
17093         (plus:DI (match_dup 1)
17094                  (const_int 8)))
17095    (use (reg:SI DIRFLAG_REG))]
17096   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17097   "stosq"
17098   [(set_attr "type" "str")
17099    (set_attr "memory" "store")
17100    (set_attr "mode" "DI")])
17102 (define_insn "*strsetsi_1"
17103   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17104         (match_operand:SI 2 "register_operand" "a"))
17105    (set (match_operand:SI 0 "register_operand" "=D")
17106         (plus:SI (match_dup 1)
17107                  (const_int 4)))
17108    (use (reg:SI DIRFLAG_REG))]
17109   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17110   "{stosl|stosd}"
17111   [(set_attr "type" "str")
17112    (set_attr "memory" "store")
17113    (set_attr "mode" "SI")])
17115 (define_insn "*strsetsi_rex_1"
17116   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17117         (match_operand:SI 2 "register_operand" "a"))
17118    (set (match_operand:DI 0 "register_operand" "=D")
17119         (plus:DI (match_dup 1)
17120                  (const_int 4)))
17121    (use (reg:SI DIRFLAG_REG))]
17122   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17123   "{stosl|stosd}"
17124   [(set_attr "type" "str")
17125    (set_attr "memory" "store")
17126    (set_attr "mode" "SI")])
17128 (define_insn "*strsethi_1"
17129   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17130         (match_operand:HI 2 "register_operand" "a"))
17131    (set (match_operand:SI 0 "register_operand" "=D")
17132         (plus:SI (match_dup 1)
17133                  (const_int 2)))
17134    (use (reg:SI DIRFLAG_REG))]
17135   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17136   "stosw"
17137   [(set_attr "type" "str")
17138    (set_attr "memory" "store")
17139    (set_attr "mode" "HI")])
17141 (define_insn "*strsethi_rex_1"
17142   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17143         (match_operand:HI 2 "register_operand" "a"))
17144    (set (match_operand:DI 0 "register_operand" "=D")
17145         (plus:DI (match_dup 1)
17146                  (const_int 2)))
17147    (use (reg:SI DIRFLAG_REG))]
17148   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17149   "stosw"
17150   [(set_attr "type" "str")
17151    (set_attr "memory" "store")
17152    (set_attr "mode" "HI")])
17154 (define_insn "*strsetqi_1"
17155   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17156         (match_operand:QI 2 "register_operand" "a"))
17157    (set (match_operand:SI 0 "register_operand" "=D")
17158         (plus:SI (match_dup 1)
17159                  (const_int 1)))
17160    (use (reg:SI DIRFLAG_REG))]
17161   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17162   "stosb"
17163   [(set_attr "type" "str")
17164    (set_attr "memory" "store")
17165    (set_attr "mode" "QI")])
17167 (define_insn "*strsetqi_rex_1"
17168   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17169         (match_operand:QI 2 "register_operand" "a"))
17170    (set (match_operand:DI 0 "register_operand" "=D")
17171         (plus:DI (match_dup 1)
17172                  (const_int 1)))
17173    (use (reg:SI DIRFLAG_REG))]
17174   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17175   "stosb"
17176   [(set_attr "type" "str")
17177    (set_attr "memory" "store")
17178    (set_attr "mode" "QI")])
17180 (define_expand "rep_stos"
17181   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17182               (set (match_operand 0 "register_operand" "")
17183                    (match_operand 4 "" ""))
17184               (set (match_operand 2 "memory_operand" "") (const_int 0))
17185               (use (match_operand 3 "register_operand" ""))
17186               (use (match_dup 1))
17187               (use (reg:SI DIRFLAG_REG))])]
17188   ""
17189   "")
17191 (define_insn "*rep_stosdi_rex64"
17192   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17193    (set (match_operand:DI 0 "register_operand" "=D") 
17194         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17195                             (const_int 3))
17196                  (match_operand:DI 3 "register_operand" "0")))
17197    (set (mem:BLK (match_dup 3))
17198         (const_int 0))
17199    (use (match_operand:DI 2 "register_operand" "a"))
17200    (use (match_dup 4))
17201    (use (reg:SI DIRFLAG_REG))]
17202   "TARGET_64BIT"
17203   "{rep\;stosq|rep stosq}"
17204   [(set_attr "type" "str")
17205    (set_attr "prefix_rep" "1")
17206    (set_attr "memory" "store")
17207    (set_attr "mode" "DI")])
17209 (define_insn "*rep_stossi"
17210   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17211    (set (match_operand:SI 0 "register_operand" "=D") 
17212         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17213                             (const_int 2))
17214                  (match_operand:SI 3 "register_operand" "0")))
17215    (set (mem:BLK (match_dup 3))
17216         (const_int 0))
17217    (use (match_operand:SI 2 "register_operand" "a"))
17218    (use (match_dup 4))
17219    (use (reg:SI DIRFLAG_REG))]
17220   "!TARGET_64BIT"
17221   "{rep\;stosl|rep stosd}"
17222   [(set_attr "type" "str")
17223    (set_attr "prefix_rep" "1")
17224    (set_attr "memory" "store")
17225    (set_attr "mode" "SI")])
17227 (define_insn "*rep_stossi_rex64"
17228   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17229    (set (match_operand:DI 0 "register_operand" "=D") 
17230         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17231                             (const_int 2))
17232                  (match_operand:DI 3 "register_operand" "0")))
17233    (set (mem:BLK (match_dup 3))
17234         (const_int 0))
17235    (use (match_operand:SI 2 "register_operand" "a"))
17236    (use (match_dup 4))
17237    (use (reg:SI DIRFLAG_REG))]
17238   "TARGET_64BIT"
17239   "{rep\;stosl|rep stosd}"
17240   [(set_attr "type" "str")
17241    (set_attr "prefix_rep" "1")
17242    (set_attr "memory" "store")
17243    (set_attr "mode" "SI")])
17245 (define_insn "*rep_stosqi"
17246   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17247    (set (match_operand:SI 0 "register_operand" "=D") 
17248         (plus:SI (match_operand:SI 3 "register_operand" "0")
17249                  (match_operand:SI 4 "register_operand" "1")))
17250    (set (mem:BLK (match_dup 3))
17251         (const_int 0))
17252    (use (match_operand:QI 2 "register_operand" "a"))
17253    (use (match_dup 4))
17254    (use (reg:SI DIRFLAG_REG))]
17255   "!TARGET_64BIT"
17256   "{rep\;stosb|rep stosb}"
17257   [(set_attr "type" "str")
17258    (set_attr "prefix_rep" "1")
17259    (set_attr "memory" "store")
17260    (set_attr "mode" "QI")])
17262 (define_insn "*rep_stosqi_rex64"
17263   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17264    (set (match_operand:DI 0 "register_operand" "=D") 
17265         (plus:DI (match_operand:DI 3 "register_operand" "0")
17266                  (match_operand:DI 4 "register_operand" "1")))
17267    (set (mem:BLK (match_dup 3))
17268         (const_int 0))
17269    (use (match_operand:QI 2 "register_operand" "a"))
17270    (use (match_dup 4))
17271    (use (reg:SI DIRFLAG_REG))]
17272   "TARGET_64BIT"
17273   "{rep\;stosb|rep stosb}"
17274   [(set_attr "type" "str")
17275    (set_attr "prefix_rep" "1")
17276    (set_attr "memory" "store")
17277    (set_attr "mode" "QI")])
17279 (define_expand "cmpstrsi"
17280   [(set (match_operand:SI 0 "register_operand" "")
17281         (compare:SI (match_operand:BLK 1 "general_operand" "")
17282                     (match_operand:BLK 2 "general_operand" "")))
17283    (use (match_operand 3 "general_operand" ""))
17284    (use (match_operand 4 "immediate_operand" ""))]
17285   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17287   rtx addr1, addr2, out, outlow, count, countreg, align;
17289   /* Can't use this if the user has appropriated esi or edi.  */
17290   if (global_regs[4] || global_regs[5])
17291     FAIL;
17293   out = operands[0];
17294   if (GET_CODE (out) != REG)
17295     out = gen_reg_rtx (SImode);
17297   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17298   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17299   if (addr1 != XEXP (operands[1], 0))
17300     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17301   if (addr2 != XEXP (operands[2], 0))
17302     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17304   count = operands[3];
17305   countreg = ix86_zero_extend_to_Pmode (count);
17307   /* %%% Iff we are testing strict equality, we can use known alignment
17308      to good advantage.  This may be possible with combine, particularly
17309      once cc0 is dead.  */
17310   align = operands[4];
17312   emit_insn (gen_cld ());
17313   if (GET_CODE (count) == CONST_INT)
17314     {
17315       if (INTVAL (count) == 0)
17316         {
17317           emit_move_insn (operands[0], const0_rtx);
17318           DONE;
17319         }
17320       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17321                                     operands[1], operands[2]));
17322     }
17323   else
17324     {
17325       if (TARGET_64BIT)
17326         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17327       else
17328         emit_insn (gen_cmpsi_1 (countreg, countreg));
17329       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17330                                  operands[1], operands[2]));
17331     }
17333   outlow = gen_lowpart (QImode, out);
17334   emit_insn (gen_cmpintqi (outlow));
17335   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17337   if (operands[0] != out)
17338     emit_move_insn (operands[0], out);
17340   DONE;
17343 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17345 (define_expand "cmpintqi"
17346   [(set (match_dup 1)
17347         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17348    (set (match_dup 2)
17349         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17350    (parallel [(set (match_operand:QI 0 "register_operand" "")
17351                    (minus:QI (match_dup 1)
17352                              (match_dup 2)))
17353               (clobber (reg:CC FLAGS_REG))])]
17354   ""
17355   "operands[1] = gen_reg_rtx (QImode);
17356    operands[2] = gen_reg_rtx (QImode);")
17358 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17359 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17361 (define_expand "cmpstrqi_nz_1"
17362   [(parallel [(set (reg:CC FLAGS_REG)
17363                    (compare:CC (match_operand 4 "memory_operand" "")
17364                                (match_operand 5 "memory_operand" "")))
17365               (use (match_operand 2 "register_operand" ""))
17366               (use (match_operand:SI 3 "immediate_operand" ""))
17367               (use (reg:SI DIRFLAG_REG))
17368               (clobber (match_operand 0 "register_operand" ""))
17369               (clobber (match_operand 1 "register_operand" ""))
17370               (clobber (match_dup 2))])]
17371   ""
17372   "")
17374 (define_insn "*cmpstrqi_nz_1"
17375   [(set (reg:CC FLAGS_REG)
17376         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17377                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17378    (use (match_operand:SI 6 "register_operand" "2"))
17379    (use (match_operand:SI 3 "immediate_operand" "i"))
17380    (use (reg:SI DIRFLAG_REG))
17381    (clobber (match_operand:SI 0 "register_operand" "=S"))
17382    (clobber (match_operand:SI 1 "register_operand" "=D"))
17383    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17384   "!TARGET_64BIT"
17385   "repz{\;| }cmpsb"
17386   [(set_attr "type" "str")
17387    (set_attr "mode" "QI")
17388    (set_attr "prefix_rep" "1")])
17390 (define_insn "*cmpstrqi_nz_rex_1"
17391   [(set (reg:CC FLAGS_REG)
17392         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17393                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17394    (use (match_operand:DI 6 "register_operand" "2"))
17395    (use (match_operand:SI 3 "immediate_operand" "i"))
17396    (use (reg:SI DIRFLAG_REG))
17397    (clobber (match_operand:DI 0 "register_operand" "=S"))
17398    (clobber (match_operand:DI 1 "register_operand" "=D"))
17399    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17400   "TARGET_64BIT"
17401   "repz{\;| }cmpsb"
17402   [(set_attr "type" "str")
17403    (set_attr "mode" "QI")
17404    (set_attr "prefix_rep" "1")])
17406 ;; The same, but the count is not known to not be zero.
17408 (define_expand "cmpstrqi_1"
17409   [(parallel [(set (reg:CC FLAGS_REG)
17410                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17411                                      (const_int 0))
17412                   (compare:CC (match_operand 4 "memory_operand" "")
17413                               (match_operand 5 "memory_operand" ""))
17414                   (const_int 0)))
17415               (use (match_operand:SI 3 "immediate_operand" ""))
17416               (use (reg:CC FLAGS_REG))
17417               (use (reg:SI DIRFLAG_REG))
17418               (clobber (match_operand 0 "register_operand" ""))
17419               (clobber (match_operand 1 "register_operand" ""))
17420               (clobber (match_dup 2))])]
17421   ""
17422   "")
17424 (define_insn "*cmpstrqi_1"
17425   [(set (reg:CC FLAGS_REG)
17426         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17427                              (const_int 0))
17428           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17429                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17430           (const_int 0)))
17431    (use (match_operand:SI 3 "immediate_operand" "i"))
17432    (use (reg:CC FLAGS_REG))
17433    (use (reg:SI DIRFLAG_REG))
17434    (clobber (match_operand:SI 0 "register_operand" "=S"))
17435    (clobber (match_operand:SI 1 "register_operand" "=D"))
17436    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17437   "!TARGET_64BIT"
17438   "repz{\;| }cmpsb"
17439   [(set_attr "type" "str")
17440    (set_attr "mode" "QI")
17441    (set_attr "prefix_rep" "1")])
17443 (define_insn "*cmpstrqi_rex_1"
17444   [(set (reg:CC FLAGS_REG)
17445         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17446                              (const_int 0))
17447           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17448                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17449           (const_int 0)))
17450    (use (match_operand:SI 3 "immediate_operand" "i"))
17451    (use (reg:CC FLAGS_REG))
17452    (use (reg:SI DIRFLAG_REG))
17453    (clobber (match_operand:DI 0 "register_operand" "=S"))
17454    (clobber (match_operand:DI 1 "register_operand" "=D"))
17455    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17456   "TARGET_64BIT"
17457   "repz{\;| }cmpsb"
17458   [(set_attr "type" "str")
17459    (set_attr "mode" "QI")
17460    (set_attr "prefix_rep" "1")])
17462 (define_expand "strlensi"
17463   [(set (match_operand:SI 0 "register_operand" "")
17464         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17465                     (match_operand:QI 2 "immediate_operand" "")
17466                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17467   ""
17469  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17470    DONE;
17471  else
17472    FAIL;
17475 (define_expand "strlendi"
17476   [(set (match_operand:DI 0 "register_operand" "")
17477         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17478                     (match_operand:QI 2 "immediate_operand" "")
17479                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17480   ""
17482  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17483    DONE;
17484  else
17485    FAIL;
17488 (define_expand "strlenqi_1"
17489   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17490               (use (reg:SI DIRFLAG_REG))
17491               (clobber (match_operand 1 "register_operand" ""))
17492               (clobber (reg:CC FLAGS_REG))])]
17493   ""
17494   "")
17496 (define_insn "*strlenqi_1"
17497   [(set (match_operand:SI 0 "register_operand" "=&c")
17498         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17499                     (match_operand:QI 2 "register_operand" "a")
17500                     (match_operand:SI 3 "immediate_operand" "i")
17501                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17502    (use (reg:SI DIRFLAG_REG))
17503    (clobber (match_operand:SI 1 "register_operand" "=D"))
17504    (clobber (reg:CC FLAGS_REG))]
17505   "!TARGET_64BIT"
17506   "repnz{\;| }scasb"
17507   [(set_attr "type" "str")
17508    (set_attr "mode" "QI")
17509    (set_attr "prefix_rep" "1")])
17511 (define_insn "*strlenqi_rex_1"
17512   [(set (match_operand:DI 0 "register_operand" "=&c")
17513         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17514                     (match_operand:QI 2 "register_operand" "a")
17515                     (match_operand:DI 3 "immediate_operand" "i")
17516                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17517    (use (reg:SI DIRFLAG_REG))
17518    (clobber (match_operand:DI 1 "register_operand" "=D"))
17519    (clobber (reg:CC FLAGS_REG))]
17520   "TARGET_64BIT"
17521   "repnz{\;| }scasb"
17522   [(set_attr "type" "str")
17523    (set_attr "mode" "QI")
17524    (set_attr "prefix_rep" "1")])
17526 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17527 ;; handled in combine, but it is not currently up to the task.
17528 ;; When used for their truth value, the cmpstr* expanders generate
17529 ;; code like this:
17531 ;;   repz cmpsb
17532 ;;   seta       %al
17533 ;;   setb       %dl
17534 ;;   cmpb       %al, %dl
17535 ;;   jcc        label
17537 ;; The intermediate three instructions are unnecessary.
17539 ;; This one handles cmpstr*_nz_1...
17540 (define_peephole2
17541   [(parallel[
17542      (set (reg:CC FLAGS_REG)
17543           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17544                       (mem:BLK (match_operand 5 "register_operand" ""))))
17545      (use (match_operand 6 "register_operand" ""))
17546      (use (match_operand:SI 3 "immediate_operand" ""))
17547      (use (reg:SI DIRFLAG_REG))
17548      (clobber (match_operand 0 "register_operand" ""))
17549      (clobber (match_operand 1 "register_operand" ""))
17550      (clobber (match_operand 2 "register_operand" ""))])
17551    (set (match_operand:QI 7 "register_operand" "")
17552         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17553    (set (match_operand:QI 8 "register_operand" "")
17554         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17555    (set (reg 17)
17556         (compare (match_dup 7) (match_dup 8)))
17557   ]
17558   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17559   [(parallel[
17560      (set (reg:CC FLAGS_REG)
17561           (compare:CC (mem:BLK (match_dup 4))
17562                       (mem:BLK (match_dup 5))))
17563      (use (match_dup 6))
17564      (use (match_dup 3))
17565      (use (reg:SI DIRFLAG_REG))
17566      (clobber (match_dup 0))
17567      (clobber (match_dup 1))
17568      (clobber (match_dup 2))])]
17569   "")
17571 ;; ...and this one handles cmpstr*_1.
17572 (define_peephole2
17573   [(parallel[
17574      (set (reg:CC FLAGS_REG)
17575           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17576                                (const_int 0))
17577             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17578                         (mem:BLK (match_operand 5 "register_operand" "")))
17579             (const_int 0)))
17580      (use (match_operand:SI 3 "immediate_operand" ""))
17581      (use (reg:CC FLAGS_REG))
17582      (use (reg:SI DIRFLAG_REG))
17583      (clobber (match_operand 0 "register_operand" ""))
17584      (clobber (match_operand 1 "register_operand" ""))
17585      (clobber (match_operand 2 "register_operand" ""))])
17586    (set (match_operand:QI 7 "register_operand" "")
17587         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17588    (set (match_operand:QI 8 "register_operand" "")
17589         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17590    (set (reg 17)
17591         (compare (match_dup 7) (match_dup 8)))
17592   ]
17593   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17594   [(parallel[
17595      (set (reg:CC FLAGS_REG)
17596           (if_then_else:CC (ne (match_dup 6)
17597                                (const_int 0))
17598             (compare:CC (mem:BLK (match_dup 4))
17599                         (mem:BLK (match_dup 5)))
17600             (const_int 0)))
17601      (use (match_dup 3))
17602      (use (reg:CC FLAGS_REG))
17603      (use (reg:SI DIRFLAG_REG))
17604      (clobber (match_dup 0))
17605      (clobber (match_dup 1))
17606      (clobber (match_dup 2))])]
17607   "")
17611 ;; Conditional move instructions.
17613 (define_expand "movdicc"
17614   [(set (match_operand:DI 0 "register_operand" "")
17615         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17616                          (match_operand:DI 2 "general_operand" "")
17617                          (match_operand:DI 3 "general_operand" "")))]
17618   "TARGET_64BIT"
17619   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17621 (define_insn "x86_movdicc_0_m1_rex64"
17622   [(set (match_operand:DI 0 "register_operand" "=r")
17623         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17624           (const_int -1)
17625           (const_int 0)))
17626    (clobber (reg:CC FLAGS_REG))]
17627   "TARGET_64BIT"
17628   "sbb{q}\t%0, %0"
17629   ; Since we don't have the proper number of operands for an alu insn,
17630   ; fill in all the blanks.
17631   [(set_attr "type" "alu")
17632    (set_attr "pent_pair" "pu")
17633    (set_attr "memory" "none")
17634    (set_attr "imm_disp" "false")
17635    (set_attr "mode" "DI")
17636    (set_attr "length_immediate" "0")])
17638 (define_insn "movdicc_c_rex64"
17639   [(set (match_operand:DI 0 "register_operand" "=r,r")
17640         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17641                                 [(reg 17) (const_int 0)])
17642                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17643                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17644   "TARGET_64BIT && TARGET_CMOVE
17645    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17646   "@
17647    cmov%O2%C1\t{%2, %0|%0, %2}
17648    cmov%O2%c1\t{%3, %0|%0, %3}"
17649   [(set_attr "type" "icmov")
17650    (set_attr "mode" "DI")])
17652 (define_expand "movsicc"
17653   [(set (match_operand:SI 0 "register_operand" "")
17654         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17655                          (match_operand:SI 2 "general_operand" "")
17656                          (match_operand:SI 3 "general_operand" "")))]
17657   ""
17658   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17660 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17661 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17662 ;; So just document what we're doing explicitly.
17664 (define_insn "x86_movsicc_0_m1"
17665   [(set (match_operand:SI 0 "register_operand" "=r")
17666         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17667           (const_int -1)
17668           (const_int 0)))
17669    (clobber (reg:CC FLAGS_REG))]
17670   ""
17671   "sbb{l}\t%0, %0"
17672   ; Since we don't have the proper number of operands for an alu insn,
17673   ; fill in all the blanks.
17674   [(set_attr "type" "alu")
17675    (set_attr "pent_pair" "pu")
17676    (set_attr "memory" "none")
17677    (set_attr "imm_disp" "false")
17678    (set_attr "mode" "SI")
17679    (set_attr "length_immediate" "0")])
17681 (define_insn "*movsicc_noc"
17682   [(set (match_operand:SI 0 "register_operand" "=r,r")
17683         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17684                                 [(reg 17) (const_int 0)])
17685                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17686                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17687   "TARGET_CMOVE
17688    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17689   "@
17690    cmov%O2%C1\t{%2, %0|%0, %2}
17691    cmov%O2%c1\t{%3, %0|%0, %3}"
17692   [(set_attr "type" "icmov")
17693    (set_attr "mode" "SI")])
17695 (define_expand "movhicc"
17696   [(set (match_operand:HI 0 "register_operand" "")
17697         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17698                          (match_operand:HI 2 "general_operand" "")
17699                          (match_operand:HI 3 "general_operand" "")))]
17700   "TARGET_HIMODE_MATH"
17701   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17703 (define_insn "*movhicc_noc"
17704   [(set (match_operand:HI 0 "register_operand" "=r,r")
17705         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17706                                 [(reg 17) (const_int 0)])
17707                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17708                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17709   "TARGET_CMOVE
17710    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17711   "@
17712    cmov%O2%C1\t{%2, %0|%0, %2}
17713    cmov%O2%c1\t{%3, %0|%0, %3}"
17714   [(set_attr "type" "icmov")
17715    (set_attr "mode" "HI")])
17717 (define_expand "movqicc"
17718   [(set (match_operand:QI 0 "register_operand" "")
17719         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17720                          (match_operand:QI 2 "general_operand" "")
17721                          (match_operand:QI 3 "general_operand" "")))]
17722   "TARGET_QIMODE_MATH"
17723   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17725 (define_insn_and_split "*movqicc_noc"
17726   [(set (match_operand:QI 0 "register_operand" "=r,r")
17727         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17728                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17729                       (match_operand:QI 2 "register_operand" "r,0")
17730                       (match_operand:QI 3 "register_operand" "0,r")))]
17731   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17732   "#"
17733   "&& reload_completed"
17734   [(set (match_dup 0)
17735         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17736                       (match_dup 2)
17737                       (match_dup 3)))]
17738   "operands[0] = gen_lowpart (SImode, operands[0]);
17739    operands[2] = gen_lowpart (SImode, operands[2]);
17740    operands[3] = gen_lowpart (SImode, operands[3]);"
17741   [(set_attr "type" "icmov")
17742    (set_attr "mode" "SI")])
17744 (define_expand "movsfcc"
17745   [(set (match_operand:SF 0 "register_operand" "")
17746         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17747                          (match_operand:SF 2 "register_operand" "")
17748                          (match_operand:SF 3 "register_operand" "")))]
17749   "TARGET_CMOVE"
17750   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17752 (define_insn "*movsfcc_1"
17753   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17754         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17755                                 [(reg 17) (const_int 0)])
17756                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17757                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17758   "TARGET_CMOVE
17759    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17760   "@
17761    fcmov%F1\t{%2, %0|%0, %2}
17762    fcmov%f1\t{%3, %0|%0, %3}
17763    cmov%O2%C1\t{%2, %0|%0, %2}
17764    cmov%O2%c1\t{%3, %0|%0, %3}"
17765   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17766    (set_attr "mode" "SF,SF,SI,SI")])
17768 (define_expand "movdfcc"
17769   [(set (match_operand:DF 0 "register_operand" "")
17770         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17771                          (match_operand:DF 2 "register_operand" "")
17772                          (match_operand:DF 3 "register_operand" "")))]
17773   "TARGET_CMOVE"
17774   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17776 (define_insn "*movdfcc_1"
17777   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17778         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17779                                 [(reg 17) (const_int 0)])
17780                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17781                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17782   "!TARGET_64BIT && TARGET_CMOVE
17783    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17784   "@
17785    fcmov%F1\t{%2, %0|%0, %2}
17786    fcmov%f1\t{%3, %0|%0, %3}
17787    #
17788    #"
17789   [(set_attr "type" "fcmov,fcmov,multi,multi")
17790    (set_attr "mode" "DF")])
17792 (define_insn "*movdfcc_1_rex64"
17793   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17794         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17795                                 [(reg 17) (const_int 0)])
17796                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17797                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17798   "TARGET_64BIT && TARGET_CMOVE
17799    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17800   "@
17801    fcmov%F1\t{%2, %0|%0, %2}
17802    fcmov%f1\t{%3, %0|%0, %3}
17803    cmov%O2%C1\t{%2, %0|%0, %2}
17804    cmov%O2%c1\t{%3, %0|%0, %3}"
17805   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17806    (set_attr "mode" "DF")])
17808 (define_split
17809   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17810         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17811                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17812                       (match_operand:DF 2 "nonimmediate_operand" "")
17813                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17814   "!TARGET_64BIT && reload_completed"
17815   [(set (match_dup 2)
17816         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17817                       (match_dup 5)
17818                       (match_dup 7)))
17819    (set (match_dup 3)
17820         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17821                       (match_dup 6)
17822                       (match_dup 8)))]
17823   "split_di (operands+2, 1, operands+5, operands+6);
17824    split_di (operands+3, 1, operands+7, operands+8);
17825    split_di (operands, 1, operands+2, operands+3);")
17827 (define_expand "movxfcc"
17828   [(set (match_operand:XF 0 "register_operand" "")
17829         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17830                          (match_operand:XF 2 "register_operand" "")
17831                          (match_operand:XF 3 "register_operand" "")))]
17832   "TARGET_CMOVE"
17833   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17835 (define_insn "*movxfcc_1"
17836   [(set (match_operand:XF 0 "register_operand" "=f,f")
17837         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17838                                 [(reg 17) (const_int 0)])
17839                       (match_operand:XF 2 "register_operand" "f,0")
17840                       (match_operand:XF 3 "register_operand" "0,f")))]
17841   "TARGET_CMOVE"
17842   "@
17843    fcmov%F1\t{%2, %0|%0, %2}
17844    fcmov%f1\t{%3, %0|%0, %3}"
17845   [(set_attr "type" "fcmov")
17846    (set_attr "mode" "XF")])
17848 (define_expand "minsf3"
17849   [(parallel [
17850      (set (match_operand:SF 0 "register_operand" "")
17851           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17852                                (match_operand:SF 2 "nonimmediate_operand" ""))
17853                            (match_dup 1)
17854                            (match_dup 2)))
17855      (clobber (reg:CC FLAGS_REG))])]
17856   "TARGET_SSE"
17857   "")
17859 (define_insn "*minsf"
17860   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17861         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17862                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17863                          (match_dup 1)
17864                          (match_dup 2)))
17865    (clobber (reg:CC FLAGS_REG))]
17866   "TARGET_SSE && TARGET_IEEE_FP"
17867   "#")
17869 (define_insn "*minsf_nonieee"
17870   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17871         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17872                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17873                          (match_dup 1)
17874                          (match_dup 2)))
17875    (clobber (reg:CC FLAGS_REG))]
17876   "TARGET_SSE && !TARGET_IEEE_FP
17877    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17878   "#")
17880 (define_split
17881   [(set (match_operand:SF 0 "register_operand" "")
17882         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17883                              (match_operand:SF 2 "nonimmediate_operand" ""))
17884                          (match_operand:SF 3 "register_operand" "")
17885                          (match_operand:SF 4 "nonimmediate_operand" "")))
17886    (clobber (reg:CC FLAGS_REG))]
17887   "SSE_REG_P (operands[0]) && reload_completed
17888    && ((operands_match_p (operands[1], operands[3])
17889         && operands_match_p (operands[2], operands[4]))
17890        || (operands_match_p (operands[1], operands[4])
17891            && operands_match_p (operands[2], operands[3])))"
17892   [(set (match_dup 0)
17893         (if_then_else:SF (lt (match_dup 1)
17894                              (match_dup 2))
17895                          (match_dup 1)
17896                          (match_dup 2)))])
17898 ;; Conditional addition patterns
17899 (define_expand "addqicc"
17900   [(match_operand:QI 0 "register_operand" "")
17901    (match_operand 1 "comparison_operator" "")
17902    (match_operand:QI 2 "register_operand" "")
17903    (match_operand:QI 3 "const_int_operand" "")]
17904   ""
17905   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17907 (define_expand "addhicc"
17908   [(match_operand:HI 0 "register_operand" "")
17909    (match_operand 1 "comparison_operator" "")
17910    (match_operand:HI 2 "register_operand" "")
17911    (match_operand:HI 3 "const_int_operand" "")]
17912   ""
17913   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17915 (define_expand "addsicc"
17916   [(match_operand:SI 0 "register_operand" "")
17917    (match_operand 1 "comparison_operator" "")
17918    (match_operand:SI 2 "register_operand" "")
17919    (match_operand:SI 3 "const_int_operand" "")]
17920   ""
17921   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17923 (define_expand "adddicc"
17924   [(match_operand:DI 0 "register_operand" "")
17925    (match_operand 1 "comparison_operator" "")
17926    (match_operand:DI 2 "register_operand" "")
17927    (match_operand:DI 3 "const_int_operand" "")]
17928   "TARGET_64BIT"
17929   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17931 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17933 (define_split
17934   [(set (match_operand:SF 0 "fp_register_operand" "")
17935         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17936                              (match_operand:SF 2 "register_operand" ""))
17937                          (match_operand:SF 3 "register_operand" "")
17938                          (match_operand:SF 4 "register_operand" "")))
17939    (clobber (reg:CC FLAGS_REG))]
17940   "reload_completed
17941    && ((operands_match_p (operands[1], operands[3])
17942         && operands_match_p (operands[2], operands[4]))
17943        || (operands_match_p (operands[1], operands[4])
17944            && operands_match_p (operands[2], operands[3])))"
17945   [(set (reg:CCFP FLAGS_REG)
17946         (compare:CCFP (match_dup 2)
17947                       (match_dup 1)))
17948    (set (match_dup 0)
17949         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17950                          (match_dup 1)
17951                          (match_dup 2)))])
17953 (define_insn "*minsf_sse"
17954   [(set (match_operand:SF 0 "register_operand" "=x")
17955         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17956                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17957                          (match_dup 1)
17958                          (match_dup 2)))]
17959   "TARGET_SSE && reload_completed"
17960   "minss\t{%2, %0|%0, %2}"
17961   [(set_attr "type" "sse")
17962    (set_attr "mode" "SF")])
17964 (define_expand "mindf3"
17965   [(parallel [
17966      (set (match_operand:DF 0 "register_operand" "")
17967           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17968                                (match_operand:DF 2 "nonimmediate_operand" ""))
17969                            (match_dup 1)
17970                            (match_dup 2)))
17971      (clobber (reg:CC FLAGS_REG))])]
17972   "TARGET_SSE2 && TARGET_SSE_MATH"
17973   "#")
17975 (define_insn "*mindf"
17976   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17977         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17978                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17979                          (match_dup 1)
17980                          (match_dup 2)))
17981    (clobber (reg:CC FLAGS_REG))]
17982   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17983   "#")
17985 (define_insn "*mindf_nonieee"
17986   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17987         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17988                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17989                          (match_dup 1)
17990                          (match_dup 2)))
17991    (clobber (reg:CC FLAGS_REG))]
17992   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17993    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17994   "#")
17996 (define_split
17997   [(set (match_operand:DF 0 "register_operand" "")
17998         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17999                              (match_operand:DF 2 "nonimmediate_operand" ""))
18000                          (match_operand:DF 3 "register_operand" "")
18001                          (match_operand:DF 4 "nonimmediate_operand" "")))
18002    (clobber (reg:CC FLAGS_REG))]
18003   "SSE_REG_P (operands[0]) && reload_completed
18004    && ((operands_match_p (operands[1], operands[3])
18005         && operands_match_p (operands[2], operands[4]))
18006        || (operands_match_p (operands[1], operands[4])
18007            && operands_match_p (operands[2], operands[3])))"
18008   [(set (match_dup 0)
18009         (if_then_else:DF (lt (match_dup 1)
18010                              (match_dup 2))
18011                          (match_dup 1)
18012                          (match_dup 2)))])
18014 ;; We can't represent the LT test directly.  Do this by swapping the operands.
18015 (define_split
18016   [(set (match_operand:DF 0 "fp_register_operand" "")
18017         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18018                              (match_operand:DF 2 "register_operand" ""))
18019                          (match_operand:DF 3 "register_operand" "")
18020                          (match_operand:DF 4 "register_operand" "")))
18021    (clobber (reg:CC FLAGS_REG))]
18022   "reload_completed
18023    && ((operands_match_p (operands[1], operands[3])
18024         && operands_match_p (operands[2], operands[4]))
18025        || (operands_match_p (operands[1], operands[4])
18026            && operands_match_p (operands[2], operands[3])))"
18027   [(set (reg:CCFP FLAGS_REG)
18028         (compare:CCFP (match_dup 2)
18029                       (match_dup 1)))
18030    (set (match_dup 0)
18031         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18032                          (match_dup 1)
18033                          (match_dup 2)))])
18035 (define_insn "*mindf_sse"
18036   [(set (match_operand:DF 0 "register_operand" "=Y")
18037         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
18038                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18039                          (match_dup 1)
18040                          (match_dup 2)))]
18041   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18042   "minsd\t{%2, %0|%0, %2}"
18043   [(set_attr "type" "sse")
18044    (set_attr "mode" "DF")])
18046 (define_expand "maxsf3"
18047   [(parallel [
18048      (set (match_operand:SF 0 "register_operand" "")
18049           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18050                                (match_operand:SF 2 "nonimmediate_operand" ""))
18051                            (match_dup 1)
18052                            (match_dup 2)))
18053      (clobber (reg:CC FLAGS_REG))])]
18054   "TARGET_SSE"
18055   "#")
18057 (define_insn "*maxsf"
18058   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
18059         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
18060                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
18061                          (match_dup 1)
18062                          (match_dup 2)))
18063    (clobber (reg:CC FLAGS_REG))]
18064   "TARGET_SSE && TARGET_IEEE_FP"
18065   "#")
18067 (define_insn "*maxsf_nonieee"
18068   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
18069         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
18070                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
18071                          (match_dup 1)
18072                          (match_dup 2)))
18073    (clobber (reg:CC FLAGS_REG))]
18074   "TARGET_SSE && !TARGET_IEEE_FP
18075    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18076   "#")
18078 (define_split
18079   [(set (match_operand:SF 0 "register_operand" "")
18080         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18081                              (match_operand:SF 2 "nonimmediate_operand" ""))
18082                          (match_operand:SF 3 "register_operand" "")
18083                          (match_operand:SF 4 "nonimmediate_operand" "")))
18084    (clobber (reg:CC FLAGS_REG))]
18085   "SSE_REG_P (operands[0]) && reload_completed
18086    && ((operands_match_p (operands[1], operands[3])
18087         && operands_match_p (operands[2], operands[4]))
18088        || (operands_match_p (operands[1], operands[4])
18089            && operands_match_p (operands[2], operands[3])))"
18090   [(set (match_dup 0)
18091         (if_then_else:SF (gt (match_dup 1)
18092                              (match_dup 2))
18093                          (match_dup 1)
18094                          (match_dup 2)))])
18096 (define_split
18097   [(set (match_operand:SF 0 "fp_register_operand" "")
18098         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18099                              (match_operand:SF 2 "register_operand" ""))
18100                          (match_operand:SF 3 "register_operand" "")
18101                          (match_operand:SF 4 "register_operand" "")))
18102    (clobber (reg:CC FLAGS_REG))]
18103   "reload_completed
18104    && ((operands_match_p (operands[1], operands[3])
18105         && operands_match_p (operands[2], operands[4]))
18106        || (operands_match_p (operands[1], operands[4])
18107            && operands_match_p (operands[2], operands[3])))"
18108   [(set (reg:CCFP FLAGS_REG)
18109         (compare:CCFP (match_dup 1)
18110                       (match_dup 2)))
18111    (set (match_dup 0)
18112         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18113                          (match_dup 1)
18114                          (match_dup 2)))])
18116 (define_insn "*maxsf_sse"
18117   [(set (match_operand:SF 0 "register_operand" "=x")
18118         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
18119                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18120                          (match_dup 1)
18121                          (match_dup 2)))]
18122   "TARGET_SSE && reload_completed"
18123   "maxss\t{%2, %0|%0, %2}"
18124   [(set_attr "type" "sse")
18125    (set_attr "mode" "SF")])
18127 (define_expand "maxdf3"
18128   [(parallel [
18129      (set (match_operand:DF 0 "register_operand" "")
18130           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18131                                (match_operand:DF 2 "nonimmediate_operand" ""))
18132                            (match_dup 1)
18133                            (match_dup 2)))
18134      (clobber (reg:CC FLAGS_REG))])]
18135   "TARGET_SSE2 && TARGET_SSE_MATH"
18136   "#")
18138 (define_insn "*maxdf"
18139   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18140         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18141                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18142                          (match_dup 1)
18143                          (match_dup 2)))
18144    (clobber (reg:CC FLAGS_REG))]
18145   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
18146   "#")
18148 (define_insn "*maxdf_nonieee"
18149   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18150         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18151                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18152                          (match_dup 1)
18153                          (match_dup 2)))
18154    (clobber (reg:CC FLAGS_REG))]
18155   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18157   "#")
18159 (define_split
18160   [(set (match_operand:DF 0 "register_operand" "")
18161         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18162                              (match_operand:DF 2 "nonimmediate_operand" ""))
18163                          (match_operand:DF 3 "register_operand" "")
18164                          (match_operand:DF 4 "nonimmediate_operand" "")))
18165    (clobber (reg:CC FLAGS_REG))]
18166   "SSE_REG_P (operands[0]) && reload_completed
18167    && ((operands_match_p (operands[1], operands[3])
18168         && operands_match_p (operands[2], operands[4]))
18169        || (operands_match_p (operands[1], operands[4])
18170            && operands_match_p (operands[2], operands[3])))"
18171   [(set (match_dup 0)
18172         (if_then_else:DF (gt (match_dup 1)
18173                              (match_dup 2))
18174                          (match_dup 1)
18175                          (match_dup 2)))])
18177 (define_split
18178   [(set (match_operand:DF 0 "fp_register_operand" "")
18179         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18180                              (match_operand:DF 2 "register_operand" ""))
18181                          (match_operand:DF 3 "register_operand" "")
18182                          (match_operand:DF 4 "register_operand" "")))
18183    (clobber (reg:CC FLAGS_REG))]
18184   "reload_completed
18185    && ((operands_match_p (operands[1], operands[3])
18186         && operands_match_p (operands[2], operands[4]))
18187        || (operands_match_p (operands[1], operands[4])
18188            && operands_match_p (operands[2], operands[3])))"
18189   [(set (reg:CCFP FLAGS_REG)
18190         (compare:CCFP (match_dup 1)
18191                       (match_dup 2)))
18192    (set (match_dup 0)
18193         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18194                          (match_dup 1)
18195                          (match_dup 2)))])
18197 (define_insn "*maxdf_sse"
18198   [(set (match_operand:DF 0 "register_operand" "=Y")
18199         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
18200                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18201                          (match_dup 1)
18202                          (match_dup 2)))]
18203   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18204   "maxsd\t{%2, %0|%0, %2}"
18205   [(set_attr "type" "sse")
18206    (set_attr "mode" "DF")])
18208 ;; Misc patterns (?)
18210 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18211 ;; Otherwise there will be nothing to keep
18212 ;; 
18213 ;; [(set (reg ebp) (reg esp))]
18214 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18215 ;;  (clobber (eflags)]
18216 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18218 ;; in proper program order.
18219 (define_insn "pro_epilogue_adjust_stack_1"
18220   [(set (match_operand:SI 0 "register_operand" "=r,r")
18221         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18222                  (match_operand:SI 2 "immediate_operand" "i,i")))
18223    (clobber (reg:CC FLAGS_REG))
18224    (clobber (mem:BLK (scratch)))]
18225   "!TARGET_64BIT"
18227   switch (get_attr_type (insn))
18228     {
18229     case TYPE_IMOV:
18230       return "mov{l}\t{%1, %0|%0, %1}";
18232     case TYPE_ALU:
18233       if (GET_CODE (operands[2]) == CONST_INT
18234           && (INTVAL (operands[2]) == 128
18235               || (INTVAL (operands[2]) < 0
18236                   && INTVAL (operands[2]) != -128)))
18237         {
18238           operands[2] = GEN_INT (-INTVAL (operands[2]));
18239           return "sub{l}\t{%2, %0|%0, %2}";
18240         }
18241       return "add{l}\t{%2, %0|%0, %2}";
18243     case TYPE_LEA:
18244       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18245       return "lea{l}\t{%a2, %0|%0, %a2}";
18247     default:
18248       abort ();
18249     }
18251   [(set (attr "type")
18252         (cond [(eq_attr "alternative" "0")
18253                  (const_string "alu")
18254                (match_operand:SI 2 "const0_operand" "")
18255                  (const_string "imov")
18256               ]
18257               (const_string "lea")))
18258    (set_attr "mode" "SI")])
18260 (define_insn "pro_epilogue_adjust_stack_rex64"
18261   [(set (match_operand:DI 0 "register_operand" "=r,r")
18262         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18263                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18264    (clobber (reg:CC FLAGS_REG))
18265    (clobber (mem:BLK (scratch)))]
18266   "TARGET_64BIT"
18268   switch (get_attr_type (insn))
18269     {
18270     case TYPE_IMOV:
18271       return "mov{q}\t{%1, %0|%0, %1}";
18273     case TYPE_ALU:
18274       if (GET_CODE (operands[2]) == CONST_INT
18275           /* Avoid overflows.  */
18276           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18277           && (INTVAL (operands[2]) == 128
18278               || (INTVAL (operands[2]) < 0
18279                   && INTVAL (operands[2]) != -128)))
18280         {
18281           operands[2] = GEN_INT (-INTVAL (operands[2]));
18282           return "sub{q}\t{%2, %0|%0, %2}";
18283         }
18284       return "add{q}\t{%2, %0|%0, %2}";
18286     case TYPE_LEA:
18287       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18288       return "lea{q}\t{%a2, %0|%0, %a2}";
18290     default:
18291       abort ();
18292     }
18294   [(set (attr "type")
18295         (cond [(eq_attr "alternative" "0")
18296                  (const_string "alu")
18297                (match_operand:DI 2 "const0_operand" "")
18298                  (const_string "imov")
18299               ]
18300               (const_string "lea")))
18301    (set_attr "mode" "DI")])
18303 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18304   [(set (match_operand:DI 0 "register_operand" "=r,r")
18305         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18306                  (match_operand:DI 3 "immediate_operand" "i,i")))
18307    (use (match_operand:DI 2 "register_operand" "r,r"))
18308    (clobber (reg:CC FLAGS_REG))
18309    (clobber (mem:BLK (scratch)))]
18310   "TARGET_64BIT"
18312   switch (get_attr_type (insn))
18313     {
18314     case TYPE_ALU:
18315       return "add{q}\t{%2, %0|%0, %2}";
18317     case TYPE_LEA:
18318       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18319       return "lea{q}\t{%a2, %0|%0, %a2}";
18321     default:
18322       abort ();
18323     }
18325   [(set_attr "type" "alu,lea")
18326    (set_attr "mode" "DI")])
18328 ;; Placeholder for the conditional moves.  This one is split either to SSE
18329 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18330 ;; fact is that compares supported by the cmp??ss instructions are exactly
18331 ;; swapped of those supported by cmove sequence.
18332 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18333 ;; supported by i387 comparisons and we do need to emit two conditional moves
18334 ;; in tandem.
18336 (define_insn "sse_movsfcc"
18337   [(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")
18338         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18339                         [(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")
18340                          (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")])
18341                       (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")
18342                       (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")))
18343    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18344    (clobber (reg:CC FLAGS_REG))]
18345   "TARGET_SSE
18346    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18347    /* Avoid combine from being smart and converting min/max
18348       instruction patterns into conditional moves.  */
18349    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18350         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18351        || !rtx_equal_p (operands[4], operands[2])
18352        || !rtx_equal_p (operands[5], operands[3]))
18353    && (!TARGET_IEEE_FP
18354        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18355   "#")
18357 (define_insn "sse_movsfcc_eq"
18358   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18359         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18360                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18361                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18362                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18363    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18364    (clobber (reg:CC FLAGS_REG))]
18365   "TARGET_SSE
18366    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18367   "#")
18369 (define_insn "sse_movdfcc"
18370   [(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")
18371         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18372                         [(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")
18373                          (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")])
18374                       (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")
18375                       (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")))
18376    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18377    (clobber (reg:CC FLAGS_REG))]
18378   "TARGET_SSE2
18379    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18380    /* Avoid combine from being smart and converting min/max
18381       instruction patterns into conditional moves.  */
18382    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18383         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18384        || !rtx_equal_p (operands[4], operands[2])
18385        || !rtx_equal_p (operands[5], operands[3]))
18386    && (!TARGET_IEEE_FP
18387        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18388   "#")
18390 (define_insn "sse_movdfcc_eq"
18391   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18392         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18393                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18394                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18395                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18396    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18397    (clobber (reg:CC FLAGS_REG))]
18398   "TARGET_SSE
18399    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18400   "#")
18402 ;; For non-sse moves just expand the usual cmove sequence.
18403 (define_split
18404   [(set (match_operand 0 "register_operand" "")
18405         (if_then_else (match_operator 1 "comparison_operator"
18406                         [(match_operand 4 "nonimmediate_operand" "")
18407                          (match_operand 5 "register_operand" "")])
18408                       (match_operand 2 "nonimmediate_operand" "")
18409                       (match_operand 3 "nonimmediate_operand" "")))
18410    (clobber (match_operand 6 "" ""))
18411    (clobber (reg:CC FLAGS_REG))]
18412   "!SSE_REG_P (operands[0]) && reload_completed
18413    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18414   [(const_int 0)]
18416    ix86_compare_op0 = operands[5];
18417    ix86_compare_op1 = operands[4];
18418    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18419                                  VOIDmode, operands[5], operands[4]);
18420    ix86_expand_fp_movcc (operands);
18421    DONE;
18424 ;; Split SSE based conditional move into sequence:
18425 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18426 ;; and   op2, op0   -  zero op2 if comparison was false
18427 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18428 ;; or    op2, op0   -  get the nonzero one into the result.
18429 (define_split
18430   [(set (match_operand:SF 0 "register_operand" "")
18431         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18432                         [(match_operand:SF 4 "register_operand" "")
18433                          (match_operand:SF 5 "nonimmediate_operand" "")])
18434                       (match_operand:SF 2 "register_operand" "")
18435                       (match_operand:SF 3 "register_operand" "")))
18436    (clobber (match_operand 6 "" ""))
18437    (clobber (reg:CC FLAGS_REG))]
18438   "SSE_REG_P (operands[0]) && reload_completed"
18439   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18440    (set (match_dup 2) (and:V4SF (match_dup 2)
18441                                 (match_dup 8)))
18442    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18443                                           (match_dup 3)))
18444    (set (match_dup 0) (ior:V4SF (match_dup 6)
18445                                 (match_dup 7)))]
18447   /* If op2 == op3, op3 would be clobbered before it is used.  */
18448   if (operands_match_p (operands[2], operands[3]))
18449     {
18450       emit_move_insn (operands[0], operands[2]);
18451       DONE;
18452     }
18454   PUT_MODE (operands[1], GET_MODE (operands[0]));
18455   if (operands_match_p (operands[0], operands[4]))
18456     operands[6] = operands[4], operands[7] = operands[2];
18457   else
18458     operands[6] = operands[2], operands[7] = operands[4];
18459   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18460   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18461   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18462   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18463   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18464   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18467 (define_split
18468   [(set (match_operand:DF 0 "register_operand" "")
18469         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18470                         [(match_operand:DF 4 "register_operand" "")
18471                          (match_operand:DF 5 "nonimmediate_operand" "")])
18472                       (match_operand:DF 2 "register_operand" "")
18473                       (match_operand:DF 3 "register_operand" "")))
18474    (clobber (match_operand 6 "" ""))
18475    (clobber (reg:CC FLAGS_REG))]
18476   "SSE_REG_P (operands[0]) && reload_completed"
18477   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18478    (set (match_dup 2) (and:V2DF (match_dup 2)
18479                                 (match_dup 8)))
18480    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18481                                           (match_dup 3)))
18482    (set (match_dup 0) (ior:V2DF (match_dup 6)
18483                                 (match_dup 7)))]
18485   if (GET_MODE (operands[2]) == DFmode
18486       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18487     {
18488       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18489       emit_insn (gen_sse2_unpcklpd (op, op, op));
18490       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18491       emit_insn (gen_sse2_unpcklpd (op, op, op));
18492     }
18494   /* If op2 == op3, op3 would be clobbered before it is used.  */
18495   if (operands_match_p (operands[2], operands[3]))
18496     {
18497       emit_move_insn (operands[0], operands[2]);
18498       DONE;
18499     }
18501   PUT_MODE (operands[1], GET_MODE (operands[0]));
18502   if (operands_match_p (operands[0], operands[4]))
18503     operands[6] = operands[4], operands[7] = operands[2];
18504   else
18505     operands[6] = operands[2], operands[7] = operands[4];
18506   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18507   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18508   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18509   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18510   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18511   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18514 ;; Special case of conditional move we can handle effectively.
18515 ;; Do not brother with the integer/floating point case, since these are
18516 ;; bot considerably slower, unlike in the generic case.
18517 (define_insn "*sse_movsfcc_const0_1"
18518   [(set (match_operand:SF 0 "register_operand" "=&x")
18519         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18520                         [(match_operand:SF 4 "register_operand" "0")
18521                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18522                       (match_operand:SF 2 "register_operand" "x")
18523                       (match_operand:SF 3 "const0_operand" "X")))]
18524   "TARGET_SSE"
18525   "#")
18527 (define_insn "*sse_movsfcc_const0_2"
18528   [(set (match_operand:SF 0 "register_operand" "=&x")
18529         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18530                         [(match_operand:SF 4 "register_operand" "0")
18531                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18532                       (match_operand:SF 2 "const0_operand" "X")
18533                       (match_operand:SF 3 "register_operand" "x")))]
18534   "TARGET_SSE"
18535   "#")
18537 (define_insn "*sse_movsfcc_const0_3"
18538   [(set (match_operand:SF 0 "register_operand" "=&x")
18539         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18540                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18541                          (match_operand:SF 5 "register_operand" "0")])
18542                       (match_operand:SF 2 "register_operand" "x")
18543                       (match_operand:SF 3 "const0_operand" "X")))]
18544   "TARGET_SSE"
18545   "#")
18547 (define_insn "*sse_movsfcc_const0_4"
18548   [(set (match_operand:SF 0 "register_operand" "=&x")
18549         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18550                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18551                          (match_operand:SF 5 "register_operand" "0")])
18552                       (match_operand:SF 2 "const0_operand" "X")
18553                       (match_operand:SF 3 "register_operand" "x")))]
18554   "TARGET_SSE"
18555   "#")
18557 (define_insn "*sse_movdfcc_const0_1"
18558   [(set (match_operand:DF 0 "register_operand" "=&Y")
18559         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18560                         [(match_operand:DF 4 "register_operand" "0")
18561                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18562                       (match_operand:DF 2 "register_operand" "Y")
18563                       (match_operand:DF 3 "const0_operand" "X")))]
18564   "TARGET_SSE2"
18565   "#")
18567 (define_insn "*sse_movdfcc_const0_2"
18568   [(set (match_operand:DF 0 "register_operand" "=&Y")
18569         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18570                         [(match_operand:DF 4 "register_operand" "0")
18571                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18572                       (match_operand:DF 2 "const0_operand" "X")
18573                       (match_operand:DF 3 "register_operand" "Y")))]
18574   "TARGET_SSE2"
18575   "#")
18577 (define_insn "*sse_movdfcc_const0_3"
18578   [(set (match_operand:DF 0 "register_operand" "=&Y")
18579         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18580                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18581                          (match_operand:DF 5 "register_operand" "0")])
18582                       (match_operand:DF 2 "register_operand" "Y")
18583                       (match_operand:DF 3 "const0_operand" "X")))]
18584   "TARGET_SSE2"
18585   "#")
18587 (define_insn "*sse_movdfcc_const0_4"
18588   [(set (match_operand:DF 0 "register_operand" "=&Y")
18589         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18590                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18591                          (match_operand:DF 5 "register_operand" "0")])
18592                       (match_operand:DF 2 "const0_operand" "X")
18593                       (match_operand:DF 3 "register_operand" "Y")))]
18594   "TARGET_SSE2"
18595   "#")
18597 (define_split
18598   [(set (match_operand:SF 0 "register_operand" "")
18599         (if_then_else (match_operator 1 "comparison_operator"
18600                         [(match_operand:SF 4 "nonimmediate_operand" "")
18601                          (match_operand:SF 5 "nonimmediate_operand" "")])
18602                       (match_operand:SF 2 "nonmemory_operand" "")
18603                       (match_operand:SF 3 "nonmemory_operand" "")))]
18604   "SSE_REG_P (operands[0]) && reload_completed
18605    && (const0_operand (operands[2], GET_MODE (operands[0]))
18606        || const0_operand (operands[3], GET_MODE (operands[0])))"
18607   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18608    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18610   PUT_MODE (operands[1], GET_MODE (operands[0]));
18611   if (!sse_comparison_operator (operands[1], VOIDmode)
18612       || !rtx_equal_p (operands[0], operands[4]))
18613     {
18614       rtx tmp = operands[5];
18615       operands[5] = operands[4];
18616       operands[4] = tmp;
18617       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18618     }
18619   if (!rtx_equal_p (operands[0], operands[4]))
18620     abort ();
18621   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18622   if (const0_operand (operands[2], GET_MODE (operands[2])))
18623     {
18624       operands[7] = operands[3];
18625       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18626     }
18627   else
18628     {
18629       operands[7] = operands[2];
18630       operands[6] = operands[8];
18631     }
18632   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18635 (define_split
18636   [(set (match_operand:DF 0 "register_operand" "")
18637         (if_then_else (match_operator 1 "comparison_operator"
18638                         [(match_operand:DF 4 "nonimmediate_operand" "")
18639                          (match_operand:DF 5 "nonimmediate_operand" "")])
18640                       (match_operand:DF 2 "nonmemory_operand" "")
18641                       (match_operand:DF 3 "nonmemory_operand" "")))]
18642   "SSE_REG_P (operands[0]) && reload_completed
18643    && (const0_operand (operands[2], GET_MODE (operands[0]))
18644        || const0_operand (operands[3], GET_MODE (operands[0])))"
18645   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18646    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18648   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18649       && GET_MODE (operands[2]) == DFmode)
18650     {
18651       if (REG_P (operands[2]))
18652         {
18653           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18654           emit_insn (gen_sse2_unpcklpd (op, op, op));
18655         }
18656       if (REG_P (operands[3]))
18657         {
18658           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18659           emit_insn (gen_sse2_unpcklpd (op, op, op));
18660         }
18661     }
18662   PUT_MODE (operands[1], GET_MODE (operands[0]));
18663   if (!sse_comparison_operator (operands[1], VOIDmode)
18664       || !rtx_equal_p (operands[0], operands[4]))
18665     {
18666       rtx tmp = operands[5];
18667       operands[5] = operands[4];
18668       operands[4] = tmp;
18669       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18670     }
18671   if (!rtx_equal_p (operands[0], operands[4]))
18672     abort ();
18673   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18674   if (const0_operand (operands[2], GET_MODE (operands[2])))
18675     {
18676       operands[7] = operands[3];
18677       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18678     }
18679   else
18680     {
18681       operands[7] = operands[2];
18682       operands[6] = operands[8];
18683     }
18684   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18687 (define_expand "allocate_stack_worker"
18688   [(match_operand:SI 0 "register_operand" "")]
18689   "TARGET_STACK_PROBE"
18691   if (reload_completed)
18692     {
18693       if (TARGET_64BIT)
18694         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18695       else
18696         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18697     }
18698   else
18699     {
18700       if (TARGET_64BIT)
18701         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18702       else
18703         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18704     }
18705   DONE;
18708 (define_insn "allocate_stack_worker_1"
18709   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18710     UNSPECV_STACK_PROBE)
18711    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18712    (clobber (match_scratch:SI 1 "=0"))
18713    (clobber (reg:CC FLAGS_REG))]
18714   "!TARGET_64BIT && TARGET_STACK_PROBE"
18715   "call\t__alloca"
18716   [(set_attr "type" "multi")
18717    (set_attr "length" "5")])
18719 (define_expand "allocate_stack_worker_postreload"
18720   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18721                                     UNSPECV_STACK_PROBE)
18722               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18723               (clobber (match_dup 0))
18724               (clobber (reg:CC FLAGS_REG))])]
18725   ""
18726   "")
18728 (define_insn "allocate_stack_worker_rex64"
18729   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18730     UNSPECV_STACK_PROBE)
18731    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18732    (clobber (match_scratch:DI 1 "=0"))
18733    (clobber (reg:CC FLAGS_REG))]
18734   "TARGET_64BIT && TARGET_STACK_PROBE"
18735   "call\t__alloca"
18736   [(set_attr "type" "multi")
18737    (set_attr "length" "5")])
18739 (define_expand "allocate_stack_worker_rex64_postreload"
18740   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18741                                     UNSPECV_STACK_PROBE)
18742               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18743               (clobber (match_dup 0))
18744               (clobber (reg:CC FLAGS_REG))])]
18745   ""
18746   "")
18748 (define_expand "allocate_stack"
18749   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18750                    (minus:SI (reg:SI SP_REG)
18751                              (match_operand:SI 1 "general_operand" "")))
18752               (clobber (reg:CC FLAGS_REG))])
18753    (parallel [(set (reg:SI SP_REG)
18754                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18755               (clobber (reg:CC FLAGS_REG))])]
18756   "TARGET_STACK_PROBE"
18758 #ifdef CHECK_STACK_LIMIT
18759   if (GET_CODE (operands[1]) == CONST_INT
18760       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18761     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18762                            operands[1]));
18763   else 
18764 #endif
18765     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18766                                                             operands[1])));
18768   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18769   DONE;
18772 (define_expand "builtin_setjmp_receiver"
18773   [(label_ref (match_operand 0 "" ""))]
18774   "!TARGET_64BIT && flag_pic"
18776   emit_insn (gen_set_got (pic_offset_table_rtx));
18777   DONE;
18780 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18782 (define_split
18783   [(set (match_operand 0 "register_operand" "")
18784         (match_operator 3 "promotable_binary_operator"
18785            [(match_operand 1 "register_operand" "")
18786             (match_operand 2 "aligned_operand" "")]))
18787    (clobber (reg:CC FLAGS_REG))]
18788   "! TARGET_PARTIAL_REG_STALL && reload_completed
18789    && ((GET_MODE (operands[0]) == HImode 
18790         && ((!optimize_size && !TARGET_FAST_PREFIX)
18791             || GET_CODE (operands[2]) != CONST_INT
18792             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18793        || (GET_MODE (operands[0]) == QImode 
18794            && (TARGET_PROMOTE_QImode || optimize_size)))"
18795   [(parallel [(set (match_dup 0)
18796                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18797               (clobber (reg:CC FLAGS_REG))])]
18798   "operands[0] = gen_lowpart (SImode, operands[0]);
18799    operands[1] = gen_lowpart (SImode, operands[1]);
18800    if (GET_CODE (operands[3]) != ASHIFT)
18801      operands[2] = gen_lowpart (SImode, operands[2]);
18802    PUT_MODE (operands[3], SImode);")
18804 ; Promote the QImode tests, as i386 has encoding of the AND
18805 ; instruction with 32-bit sign-extended immediate and thus the
18806 ; instruction size is unchanged, except in the %eax case for
18807 ; which it is increased by one byte, hence the ! optimize_size.
18808 (define_split
18809   [(set (reg 17)
18810         (compare (and (match_operand 1 "aligned_operand" "")
18811                       (match_operand 2 "const_int_operand" ""))
18812                  (const_int 0)))
18813    (set (match_operand 0 "register_operand" "")
18814         (and (match_dup 1) (match_dup 2)))]
18815   "! TARGET_PARTIAL_REG_STALL && reload_completed
18816    /* Ensure that the operand will remain sign-extended immediate.  */
18817    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18818    && ! optimize_size
18819    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18820        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18821   [(parallel [(set (reg:CCNO FLAGS_REG)
18822                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18823                                  (const_int 0)))
18824               (set (match_dup 0)
18825                    (and:SI (match_dup 1) (match_dup 2)))])]
18826   "operands[2]
18827      = gen_int_mode (INTVAL (operands[2])
18828                      & GET_MODE_MASK (GET_MODE (operands[0])),
18829                      SImode);
18830    operands[0] = gen_lowpart (SImode, operands[0]);
18831    operands[1] = gen_lowpart (SImode, operands[1]);")
18833 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18834 ; the TEST instruction with 32-bit sign-extended immediate and thus
18835 ; the instruction size would at least double, which is not what we
18836 ; want even with ! optimize_size.
18837 (define_split
18838   [(set (reg 17)
18839         (compare (and (match_operand:HI 0 "aligned_operand" "")
18840                       (match_operand:HI 1 "const_int_operand" ""))
18841                  (const_int 0)))]
18842   "! TARGET_PARTIAL_REG_STALL && reload_completed
18843    /* Ensure that the operand will remain sign-extended immediate.  */
18844    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18845    && ! TARGET_FAST_PREFIX
18846    && ! optimize_size"
18847   [(set (reg:CCNO FLAGS_REG)
18848         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18849                       (const_int 0)))]
18850   "operands[1]
18851      = gen_int_mode (INTVAL (operands[1])
18852                      & GET_MODE_MASK (GET_MODE (operands[0])),
18853                      SImode);
18854    operands[0] = gen_lowpart (SImode, operands[0]);")
18856 (define_split
18857   [(set (match_operand 0 "register_operand" "")
18858         (neg (match_operand 1 "register_operand" "")))
18859    (clobber (reg:CC FLAGS_REG))]
18860   "! TARGET_PARTIAL_REG_STALL && reload_completed
18861    && (GET_MODE (operands[0]) == HImode
18862        || (GET_MODE (operands[0]) == QImode 
18863            && (TARGET_PROMOTE_QImode || optimize_size)))"
18864   [(parallel [(set (match_dup 0)
18865                    (neg:SI (match_dup 1)))
18866               (clobber (reg:CC FLAGS_REG))])]
18867   "operands[0] = gen_lowpart (SImode, operands[0]);
18868    operands[1] = gen_lowpart (SImode, operands[1]);")
18870 (define_split
18871   [(set (match_operand 0 "register_operand" "")
18872         (not (match_operand 1 "register_operand" "")))]
18873   "! TARGET_PARTIAL_REG_STALL && reload_completed
18874    && (GET_MODE (operands[0]) == HImode
18875        || (GET_MODE (operands[0]) == QImode 
18876            && (TARGET_PROMOTE_QImode || optimize_size)))"
18877   [(set (match_dup 0)
18878         (not:SI (match_dup 1)))]
18879   "operands[0] = gen_lowpart (SImode, operands[0]);
18880    operands[1] = gen_lowpart (SImode, operands[1]);")
18882 (define_split 
18883   [(set (match_operand 0 "register_operand" "")
18884         (if_then_else (match_operator 1 "comparison_operator" 
18885                                 [(reg 17) (const_int 0)])
18886                       (match_operand 2 "register_operand" "")
18887                       (match_operand 3 "register_operand" "")))]
18888   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18889    && (GET_MODE (operands[0]) == HImode
18890        || (GET_MODE (operands[0]) == QImode 
18891            && (TARGET_PROMOTE_QImode || optimize_size)))"
18892   [(set (match_dup 0)
18893         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18894   "operands[0] = gen_lowpart (SImode, operands[0]);
18895    operands[2] = gen_lowpart (SImode, operands[2]);
18896    operands[3] = gen_lowpart (SImode, operands[3]);")
18897                         
18899 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18900 ;; transform a complex memory operation into two memory to register operations.
18902 ;; Don't push memory operands
18903 (define_peephole2
18904   [(set (match_operand:SI 0 "push_operand" "")
18905         (match_operand:SI 1 "memory_operand" ""))
18906    (match_scratch:SI 2 "r")]
18907   "! optimize_size && ! TARGET_PUSH_MEMORY"
18908   [(set (match_dup 2) (match_dup 1))
18909    (set (match_dup 0) (match_dup 2))]
18910   "")
18912 (define_peephole2
18913   [(set (match_operand:DI 0 "push_operand" "")
18914         (match_operand:DI 1 "memory_operand" ""))
18915    (match_scratch:DI 2 "r")]
18916   "! optimize_size && ! TARGET_PUSH_MEMORY"
18917   [(set (match_dup 2) (match_dup 1))
18918    (set (match_dup 0) (match_dup 2))]
18919   "")
18921 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18922 ;; SImode pushes.
18923 (define_peephole2
18924   [(set (match_operand:SF 0 "push_operand" "")
18925         (match_operand:SF 1 "memory_operand" ""))
18926    (match_scratch:SF 2 "r")]
18927   "! optimize_size && ! TARGET_PUSH_MEMORY"
18928   [(set (match_dup 2) (match_dup 1))
18929    (set (match_dup 0) (match_dup 2))]
18930   "")
18932 (define_peephole2
18933   [(set (match_operand:HI 0 "push_operand" "")
18934         (match_operand:HI 1 "memory_operand" ""))
18935    (match_scratch:HI 2 "r")]
18936   "! optimize_size && ! TARGET_PUSH_MEMORY"
18937   [(set (match_dup 2) (match_dup 1))
18938    (set (match_dup 0) (match_dup 2))]
18939   "")
18941 (define_peephole2
18942   [(set (match_operand:QI 0 "push_operand" "")
18943         (match_operand:QI 1 "memory_operand" ""))
18944    (match_scratch:QI 2 "q")]
18945   "! optimize_size && ! TARGET_PUSH_MEMORY"
18946   [(set (match_dup 2) (match_dup 1))
18947    (set (match_dup 0) (match_dup 2))]
18948   "")
18950 ;; Don't move an immediate directly to memory when the instruction
18951 ;; gets too big.
18952 (define_peephole2
18953   [(match_scratch:SI 1 "r")
18954    (set (match_operand:SI 0 "memory_operand" "")
18955         (const_int 0))]
18956   "! optimize_size
18957    && ! TARGET_USE_MOV0
18958    && TARGET_SPLIT_LONG_MOVES
18959    && get_attr_length (insn) >= ix86_cost->large_insn
18960    && peep2_regno_dead_p (0, FLAGS_REG)"
18961   [(parallel [(set (match_dup 1) (const_int 0))
18962               (clobber (reg:CC FLAGS_REG))])
18963    (set (match_dup 0) (match_dup 1))]
18964   "")
18966 (define_peephole2
18967   [(match_scratch:HI 1 "r")
18968    (set (match_operand:HI 0 "memory_operand" "")
18969         (const_int 0))]
18970   "! optimize_size
18971    && ! TARGET_USE_MOV0
18972    && TARGET_SPLIT_LONG_MOVES
18973    && get_attr_length (insn) >= ix86_cost->large_insn
18974    && peep2_regno_dead_p (0, FLAGS_REG)"
18975   [(parallel [(set (match_dup 2) (const_int 0))
18976               (clobber (reg:CC FLAGS_REG))])
18977    (set (match_dup 0) (match_dup 1))]
18978   "operands[2] = gen_lowpart (SImode, operands[1]);")
18980 (define_peephole2
18981   [(match_scratch:QI 1 "q")
18982    (set (match_operand:QI 0 "memory_operand" "")
18983         (const_int 0))]
18984   "! optimize_size
18985    && ! TARGET_USE_MOV0
18986    && TARGET_SPLIT_LONG_MOVES
18987    && get_attr_length (insn) >= ix86_cost->large_insn
18988    && peep2_regno_dead_p (0, FLAGS_REG)"
18989   [(parallel [(set (match_dup 2) (const_int 0))
18990               (clobber (reg:CC FLAGS_REG))])
18991    (set (match_dup 0) (match_dup 1))]
18992   "operands[2] = gen_lowpart (SImode, operands[1]);")
18994 (define_peephole2
18995   [(match_scratch:SI 2 "r")
18996    (set (match_operand:SI 0 "memory_operand" "")
18997         (match_operand:SI 1 "immediate_operand" ""))]
18998   "! optimize_size
18999    && get_attr_length (insn) >= ix86_cost->large_insn
19000    && TARGET_SPLIT_LONG_MOVES"
19001   [(set (match_dup 2) (match_dup 1))
19002    (set (match_dup 0) (match_dup 2))]
19003   "")
19005 (define_peephole2
19006   [(match_scratch:HI 2 "r")
19007    (set (match_operand:HI 0 "memory_operand" "")
19008         (match_operand:HI 1 "immediate_operand" ""))]
19009   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19010   && TARGET_SPLIT_LONG_MOVES"
19011   [(set (match_dup 2) (match_dup 1))
19012    (set (match_dup 0) (match_dup 2))]
19013   "")
19015 (define_peephole2
19016   [(match_scratch:QI 2 "q")
19017    (set (match_operand:QI 0 "memory_operand" "")
19018         (match_operand:QI 1 "immediate_operand" ""))]
19019   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19020   && TARGET_SPLIT_LONG_MOVES"
19021   [(set (match_dup 2) (match_dup 1))
19022    (set (match_dup 0) (match_dup 2))]
19023   "")
19025 ;; Don't compare memory with zero, load and use a test instead.
19026 (define_peephole2
19027   [(set (reg 17)
19028         (compare (match_operand:SI 0 "memory_operand" "")
19029                  (const_int 0)))
19030    (match_scratch:SI 3 "r")]
19031   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19032   [(set (match_dup 3) (match_dup 0))
19033    (set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
19034   "")
19036 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19037 ;; Don't split NOTs with a displacement operand, because resulting XOR
19038 ;; will not be pairable anyway.
19040 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19041 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19042 ;; so this split helps here as well.
19044 ;; Note: Can't do this as a regular split because we can't get proper
19045 ;; lifetime information then.
19047 (define_peephole2
19048   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19049         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19050   "!optimize_size
19051    && peep2_regno_dead_p (0, FLAGS_REG)
19052    && ((TARGET_PENTIUM 
19053         && (GET_CODE (operands[0]) != MEM
19054             || !memory_displacement_operand (operands[0], SImode)))
19055        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19056   [(parallel [(set (match_dup 0)
19057                    (xor:SI (match_dup 1) (const_int -1)))
19058               (clobber (reg:CC FLAGS_REG))])]
19059   "")
19061 (define_peephole2
19062   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19063         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19064   "!optimize_size
19065    && peep2_regno_dead_p (0, FLAGS_REG)
19066    && ((TARGET_PENTIUM 
19067         && (GET_CODE (operands[0]) != MEM
19068             || !memory_displacement_operand (operands[0], HImode)))
19069        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19070   [(parallel [(set (match_dup 0)
19071                    (xor:HI (match_dup 1) (const_int -1)))
19072               (clobber (reg:CC FLAGS_REG))])]
19073   "")
19075 (define_peephole2
19076   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19077         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19078   "!optimize_size
19079    && peep2_regno_dead_p (0, FLAGS_REG)
19080    && ((TARGET_PENTIUM 
19081         && (GET_CODE (operands[0]) != MEM
19082             || !memory_displacement_operand (operands[0], QImode)))
19083        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19084   [(parallel [(set (match_dup 0)
19085                    (xor:QI (match_dup 1) (const_int -1)))
19086               (clobber (reg:CC FLAGS_REG))])]
19087   "")
19089 ;; Non pairable "test imm, reg" instructions can be translated to
19090 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19091 ;; byte opcode instead of two, have a short form for byte operands),
19092 ;; so do it for other CPUs as well.  Given that the value was dead,
19093 ;; this should not create any new dependencies.  Pass on the sub-word
19094 ;; versions if we're concerned about partial register stalls.
19096 (define_peephole2
19097   [(set (reg 17)
19098         (compare (and:SI (match_operand:SI 0 "register_operand" "")
19099                          (match_operand:SI 1 "immediate_operand" ""))
19100                  (const_int 0)))]
19101   "ix86_match_ccmode (insn, CCNOmode)
19102    && (true_regnum (operands[0]) != 0
19103        || (GET_CODE (operands[1]) == CONST_INT
19104            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
19105    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19106   [(parallel
19107      [(set (reg:CCNO FLAGS_REG)
19108            (compare:CCNO (and:SI (match_dup 0)
19109                                  (match_dup 1))
19110                          (const_int 0)))
19111       (set (match_dup 0)
19112            (and:SI (match_dup 0) (match_dup 1)))])]
19113   "")
19115 ;; We don't need to handle HImode case, because it will be promoted to SImode
19116 ;; on ! TARGET_PARTIAL_REG_STALL
19118 (define_peephole2
19119   [(set (reg 17)
19120         (compare (and:QI (match_operand:QI 0 "register_operand" "")
19121                          (match_operand:QI 1 "immediate_operand" ""))
19122                  (const_int 0)))]
19123   "! TARGET_PARTIAL_REG_STALL
19124    && ix86_match_ccmode (insn, CCNOmode)
19125    && true_regnum (operands[0]) != 0
19126    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19127   [(parallel
19128      [(set (reg:CCNO FLAGS_REG)
19129            (compare:CCNO (and:QI (match_dup 0)
19130                                  (match_dup 1))
19131                          (const_int 0)))
19132       (set (match_dup 0)
19133            (and:QI (match_dup 0) (match_dup 1)))])]
19134   "")
19136 (define_peephole2
19137   [(set (reg 17)
19138         (compare
19139           (and:SI
19140             (zero_extract:SI
19141               (match_operand 0 "ext_register_operand" "")
19142               (const_int 8)
19143               (const_int 8))
19144             (match_operand 1 "const_int_operand" ""))
19145           (const_int 0)))]
19146   "! TARGET_PARTIAL_REG_STALL
19147    && ix86_match_ccmode (insn, CCNOmode)
19148    && true_regnum (operands[0]) != 0
19149    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19150   [(parallel [(set (reg:CCNO FLAGS_REG)
19151                    (compare:CCNO
19152                        (and:SI
19153                          (zero_extract:SI
19154                          (match_dup 0)
19155                          (const_int 8)
19156                          (const_int 8))
19157                         (match_dup 1))
19158                    (const_int 0)))
19159               (set (zero_extract:SI (match_dup 0)
19160                                     (const_int 8)
19161                                     (const_int 8))
19162                    (and:SI 
19163                      (zero_extract:SI
19164                        (match_dup 0)
19165                        (const_int 8)
19166                        (const_int 8))
19167                      (match_dup 1)))])]
19168   "")
19170 ;; Don't do logical operations with memory inputs.
19171 (define_peephole2
19172   [(match_scratch:SI 2 "r")
19173    (parallel [(set (match_operand:SI 0 "register_operand" "")
19174                    (match_operator:SI 3 "arith_or_logical_operator"
19175                      [(match_dup 0)
19176                       (match_operand:SI 1 "memory_operand" "")]))
19177               (clobber (reg:CC FLAGS_REG))])]
19178   "! optimize_size && ! TARGET_READ_MODIFY"
19179   [(set (match_dup 2) (match_dup 1))
19180    (parallel [(set (match_dup 0)
19181                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19182               (clobber (reg:CC FLAGS_REG))])]
19183   "")
19185 (define_peephole2
19186   [(match_scratch:SI 2 "r")
19187    (parallel [(set (match_operand:SI 0 "register_operand" "")
19188                    (match_operator:SI 3 "arith_or_logical_operator"
19189                      [(match_operand:SI 1 "memory_operand" "")
19190                       (match_dup 0)]))
19191               (clobber (reg:CC FLAGS_REG))])]
19192   "! optimize_size && ! TARGET_READ_MODIFY"
19193   [(set (match_dup 2) (match_dup 1))
19194    (parallel [(set (match_dup 0)
19195                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19196               (clobber (reg:CC FLAGS_REG))])]
19197   "")
19199 ; Don't do logical operations with memory outputs
19201 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19202 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19203 ; the same decoder scheduling characteristics as the original.
19205 (define_peephole2
19206   [(match_scratch:SI 2 "r")
19207    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19208                    (match_operator:SI 3 "arith_or_logical_operator"
19209                      [(match_dup 0)
19210                       (match_operand:SI 1 "nonmemory_operand" "")]))
19211               (clobber (reg:CC FLAGS_REG))])]
19212   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19213   [(set (match_dup 2) (match_dup 0))
19214    (parallel [(set (match_dup 2)
19215                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19216               (clobber (reg:CC FLAGS_REG))])
19217    (set (match_dup 0) (match_dup 2))]
19218   "")
19220 (define_peephole2
19221   [(match_scratch:SI 2 "r")
19222    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19223                    (match_operator:SI 3 "arith_or_logical_operator"
19224                      [(match_operand:SI 1 "nonmemory_operand" "")
19225                       (match_dup 0)]))
19226               (clobber (reg:CC FLAGS_REG))])]
19227   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19228   [(set (match_dup 2) (match_dup 0))
19229    (parallel [(set (match_dup 2)
19230                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19231               (clobber (reg:CC FLAGS_REG))])
19232    (set (match_dup 0) (match_dup 2))]
19233   "")
19235 ;; Attempt to always use XOR for zeroing registers.
19236 (define_peephole2
19237   [(set (match_operand 0 "register_operand" "")
19238         (const_int 0))]
19239   "(GET_MODE (operands[0]) == QImode
19240     || GET_MODE (operands[0]) == HImode
19241     || GET_MODE (operands[0]) == SImode
19242     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19243    && (! TARGET_USE_MOV0 || optimize_size)
19244    && peep2_regno_dead_p (0, FLAGS_REG)"
19245   [(parallel [(set (match_dup 0) (const_int 0))
19246               (clobber (reg:CC FLAGS_REG))])]
19247   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19248                               operands[0]);")
19250 (define_peephole2
19251   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19252         (const_int 0))]
19253   "(GET_MODE (operands[0]) == QImode
19254     || GET_MODE (operands[0]) == HImode)
19255    && (! TARGET_USE_MOV0 || optimize_size)
19256    && peep2_regno_dead_p (0, FLAGS_REG)"
19257   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19258               (clobber (reg:CC FLAGS_REG))])])
19260 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19261 (define_peephole2
19262   [(set (match_operand 0 "register_operand" "")
19263         (const_int -1))]
19264   "(GET_MODE (operands[0]) == HImode
19265     || GET_MODE (operands[0]) == SImode 
19266     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19267    && (optimize_size || TARGET_PENTIUM)
19268    && peep2_regno_dead_p (0, FLAGS_REG)"
19269   [(parallel [(set (match_dup 0) (const_int -1))
19270               (clobber (reg:CC FLAGS_REG))])]
19271   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19272                               operands[0]);")
19274 ;; Attempt to convert simple leas to adds. These can be created by
19275 ;; move expanders.
19276 (define_peephole2
19277   [(set (match_operand:SI 0 "register_operand" "")
19278         (plus:SI (match_dup 0)
19279                  (match_operand:SI 1 "nonmemory_operand" "")))]
19280   "peep2_regno_dead_p (0, FLAGS_REG)"
19281   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19282               (clobber (reg:CC FLAGS_REG))])]
19283   "")
19285 (define_peephole2
19286   [(set (match_operand:SI 0 "register_operand" "")
19287         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19288                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19289   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19290   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19291               (clobber (reg:CC FLAGS_REG))])]
19292   "operands[2] = gen_lowpart (SImode, operands[2]);")
19294 (define_peephole2
19295   [(set (match_operand:DI 0 "register_operand" "")
19296         (plus:DI (match_dup 0)
19297                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19298   "peep2_regno_dead_p (0, FLAGS_REG)"
19299   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19300               (clobber (reg:CC FLAGS_REG))])]
19301   "")
19303 (define_peephole2
19304   [(set (match_operand:SI 0 "register_operand" "")
19305         (mult:SI (match_dup 0)
19306                  (match_operand:SI 1 "const_int_operand" "")))]
19307   "exact_log2 (INTVAL (operands[1])) >= 0
19308    && peep2_regno_dead_p (0, FLAGS_REG)"
19309   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19310               (clobber (reg:CC FLAGS_REG))])]
19311   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19313 (define_peephole2
19314   [(set (match_operand:DI 0 "register_operand" "")
19315         (mult:DI (match_dup 0)
19316                  (match_operand:DI 1 "const_int_operand" "")))]
19317   "exact_log2 (INTVAL (operands[1])) >= 0
19318    && peep2_regno_dead_p (0, FLAGS_REG)"
19319   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19320               (clobber (reg:CC FLAGS_REG))])]
19321   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19323 (define_peephole2
19324   [(set (match_operand:SI 0 "register_operand" "")
19325         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19326                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19327   "exact_log2 (INTVAL (operands[2])) >= 0
19328    && REGNO (operands[0]) == REGNO (operands[1])
19329    && peep2_regno_dead_p (0, FLAGS_REG)"
19330   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19331               (clobber (reg:CC FLAGS_REG))])]
19332   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19334 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19335 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19336 ;; many CPUs it is also faster, since special hardware to avoid esp
19337 ;; dependencies is present.
19339 ;; While some of these conversions may be done using splitters, we use peepholes
19340 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19342 ;; Convert prologue esp subtractions to push.
19343 ;; We need register to push.  In order to keep verify_flow_info happy we have
19344 ;; two choices
19345 ;; - use scratch and clobber it in order to avoid dependencies
19346 ;; - use already live register
19347 ;; We can't use the second way right now, since there is no reliable way how to
19348 ;; verify that given register is live.  First choice will also most likely in
19349 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19350 ;; call clobbered registers are dead.  We may want to use base pointer as an
19351 ;; alternative when no register is available later.
19353 (define_peephole2
19354   [(match_scratch:SI 0 "r")
19355    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19356               (clobber (reg:CC FLAGS_REG))
19357               (clobber (mem:BLK (scratch)))])]
19358   "optimize_size || !TARGET_SUB_ESP_4"
19359   [(clobber (match_dup 0))
19360    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19361               (clobber (mem:BLK (scratch)))])])
19363 (define_peephole2
19364   [(match_scratch:SI 0 "r")
19365    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19366               (clobber (reg:CC FLAGS_REG))
19367               (clobber (mem:BLK (scratch)))])]
19368   "optimize_size || !TARGET_SUB_ESP_8"
19369   [(clobber (match_dup 0))
19370    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19371    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19372               (clobber (mem:BLK (scratch)))])])
19374 ;; Convert esp subtractions to push.
19375 (define_peephole2
19376   [(match_scratch:SI 0 "r")
19377    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19378               (clobber (reg:CC FLAGS_REG))])]
19379   "optimize_size || !TARGET_SUB_ESP_4"
19380   [(clobber (match_dup 0))
19381    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19383 (define_peephole2
19384   [(match_scratch:SI 0 "r")
19385    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19386               (clobber (reg:CC FLAGS_REG))])]
19387   "optimize_size || !TARGET_SUB_ESP_8"
19388   [(clobber (match_dup 0))
19389    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19390    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19392 ;; Convert epilogue deallocator to pop.
19393 (define_peephole2
19394   [(match_scratch:SI 0 "r")
19395    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19396               (clobber (reg:CC FLAGS_REG))
19397               (clobber (mem:BLK (scratch)))])]
19398   "optimize_size || !TARGET_ADD_ESP_4"
19399   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19400               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19401               (clobber (mem:BLK (scratch)))])]
19402   "")
19404 ;; Two pops case is tricky, since pop causes dependency on destination register.
19405 ;; We use two registers if available.
19406 (define_peephole2
19407   [(match_scratch:SI 0 "r")
19408    (match_scratch:SI 1 "r")
19409    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19410               (clobber (reg:CC FLAGS_REG))
19411               (clobber (mem:BLK (scratch)))])]
19412   "optimize_size || !TARGET_ADD_ESP_8"
19413   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19414               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19415               (clobber (mem:BLK (scratch)))])
19416    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19417               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19418   "")
19420 (define_peephole2
19421   [(match_scratch:SI 0 "r")
19422    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19423               (clobber (reg:CC FLAGS_REG))
19424               (clobber (mem:BLK (scratch)))])]
19425   "optimize_size"
19426   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19427               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19428               (clobber (mem:BLK (scratch)))])
19429    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19430               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19431   "")
19433 ;; Convert esp additions to pop.
19434 (define_peephole2
19435   [(match_scratch:SI 0 "r")
19436    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19437               (clobber (reg:CC FLAGS_REG))])]
19438   ""
19439   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19440               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19441   "")
19443 ;; Two pops case is tricky, since pop causes dependency on destination register.
19444 ;; We use two registers if available.
19445 (define_peephole2
19446   [(match_scratch:SI 0 "r")
19447    (match_scratch:SI 1 "r")
19448    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19449               (clobber (reg:CC FLAGS_REG))])]
19450   ""
19451   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19452               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19453    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19454               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19455   "")
19457 (define_peephole2
19458   [(match_scratch:SI 0 "r")
19459    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19460               (clobber (reg:CC FLAGS_REG))])]
19461   "optimize_size"
19462   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19463               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19464    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19465               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19466   "")
19468 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19469 ;; required and register dies.
19470 (define_peephole2
19471   [(set (reg 17)
19472         (compare (match_operand:SI 0 "register_operand" "")
19473                  (match_operand:SI 1 "incdec_operand" "")))]
19474   "ix86_match_ccmode (insn, CCGCmode)
19475    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19476   [(parallel [(set (reg:CCGC FLAGS_REG)
19477                    (compare:CCGC (match_dup 0)
19478                                  (match_dup 1)))
19479               (clobber (match_dup 0))])]
19480   "")
19482 (define_peephole2
19483   [(set (reg 17)
19484         (compare (match_operand:HI 0 "register_operand" "")
19485                  (match_operand:HI 1 "incdec_operand" "")))]
19486   "ix86_match_ccmode (insn, CCGCmode)
19487    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19488   [(parallel [(set (reg:CCGC FLAGS_REG)
19489                    (compare:CCGC (match_dup 0)
19490                                  (match_dup 1)))
19491               (clobber (match_dup 0))])]
19492   "")
19494 (define_peephole2
19495   [(set (reg 17)
19496         (compare (match_operand:QI 0 "register_operand" "")
19497                  (match_operand:QI 1 "incdec_operand" "")))]
19498   "ix86_match_ccmode (insn, CCGCmode)
19499    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19500   [(parallel [(set (reg:CCGC FLAGS_REG)
19501                    (compare:CCGC (match_dup 0)
19502                                  (match_dup 1)))
19503               (clobber (match_dup 0))])]
19504   "")
19506 ;; Convert compares with 128 to shorter add -128
19507 (define_peephole2
19508   [(set (reg 17)
19509         (compare (match_operand:SI 0 "register_operand" "")
19510                  (const_int 128)))]
19511   "ix86_match_ccmode (insn, CCGCmode)
19512    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19513   [(parallel [(set (reg:CCGC FLAGS_REG)
19514                    (compare:CCGC (match_dup 0)
19515                                  (const_int 128)))
19516               (clobber (match_dup 0))])]
19517   "")
19519 (define_peephole2
19520   [(set (reg 17)
19521         (compare (match_operand:HI 0 "register_operand" "")
19522                  (const_int 128)))]
19523   "ix86_match_ccmode (insn, CCGCmode)
19524    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19525   [(parallel [(set (reg:CCGC FLAGS_REG)
19526                    (compare:CCGC (match_dup 0)
19527                                  (const_int 128)))
19528               (clobber (match_dup 0))])]
19529   "")
19531 (define_peephole2
19532   [(match_scratch:DI 0 "r")
19533    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19534               (clobber (reg:CC FLAGS_REG))
19535               (clobber (mem:BLK (scratch)))])]
19536   "optimize_size || !TARGET_SUB_ESP_4"
19537   [(clobber (match_dup 0))
19538    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19539               (clobber (mem:BLK (scratch)))])])
19541 (define_peephole2
19542   [(match_scratch:DI 0 "r")
19543    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19544               (clobber (reg:CC FLAGS_REG))
19545               (clobber (mem:BLK (scratch)))])]
19546   "optimize_size || !TARGET_SUB_ESP_8"
19547   [(clobber (match_dup 0))
19548    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19549    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19550               (clobber (mem:BLK (scratch)))])])
19552 ;; Convert esp subtractions to push.
19553 (define_peephole2
19554   [(match_scratch:DI 0 "r")
19555    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19556               (clobber (reg:CC FLAGS_REG))])]
19557   "optimize_size || !TARGET_SUB_ESP_4"
19558   [(clobber (match_dup 0))
19559    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19561 (define_peephole2
19562   [(match_scratch:DI 0 "r")
19563    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19564               (clobber (reg:CC FLAGS_REG))])]
19565   "optimize_size || !TARGET_SUB_ESP_8"
19566   [(clobber (match_dup 0))
19567    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19568    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19570 ;; Convert epilogue deallocator to pop.
19571 (define_peephole2
19572   [(match_scratch:DI 0 "r")
19573    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19574               (clobber (reg:CC FLAGS_REG))
19575               (clobber (mem:BLK (scratch)))])]
19576   "optimize_size || !TARGET_ADD_ESP_4"
19577   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19578               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19579               (clobber (mem:BLK (scratch)))])]
19580   "")
19582 ;; Two pops case is tricky, since pop causes dependency on destination register.
19583 ;; We use two registers if available.
19584 (define_peephole2
19585   [(match_scratch:DI 0 "r")
19586    (match_scratch:DI 1 "r")
19587    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19588               (clobber (reg:CC FLAGS_REG))
19589               (clobber (mem:BLK (scratch)))])]
19590   "optimize_size || !TARGET_ADD_ESP_8"
19591   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19592               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19593               (clobber (mem:BLK (scratch)))])
19594    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19595               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19596   "")
19598 (define_peephole2
19599   [(match_scratch:DI 0 "r")
19600    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19601               (clobber (reg:CC FLAGS_REG))
19602               (clobber (mem:BLK (scratch)))])]
19603   "optimize_size"
19604   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19605               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19606               (clobber (mem:BLK (scratch)))])
19607    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19608               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19609   "")
19611 ;; Convert esp additions to pop.
19612 (define_peephole2
19613   [(match_scratch:DI 0 "r")
19614    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19615               (clobber (reg:CC FLAGS_REG))])]
19616   ""
19617   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19618               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19619   "")
19621 ;; Two pops case is tricky, since pop causes dependency on destination register.
19622 ;; We use two registers if available.
19623 (define_peephole2
19624   [(match_scratch:DI 0 "r")
19625    (match_scratch:DI 1 "r")
19626    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19627               (clobber (reg:CC FLAGS_REG))])]
19628   ""
19629   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19630               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19631    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19632               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19633   "")
19635 (define_peephole2
19636   [(match_scratch:DI 0 "r")
19637    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19638               (clobber (reg:CC FLAGS_REG))])]
19639   "optimize_size"
19640   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19641               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19642    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19643               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19644   "")
19646 ;; Convert imul by three, five and nine into lea
19647 (define_peephole2
19648   [(parallel
19649     [(set (match_operand:SI 0 "register_operand" "")
19650           (mult:SI (match_operand:SI 1 "register_operand" "")
19651                    (match_operand:SI 2 "const_int_operand" "")))
19652      (clobber (reg:CC FLAGS_REG))])]
19653   "INTVAL (operands[2]) == 3
19654    || INTVAL (operands[2]) == 5
19655    || INTVAL (operands[2]) == 9"
19656   [(set (match_dup 0)
19657         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19658                  (match_dup 1)))]
19659   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19661 (define_peephole2
19662   [(parallel
19663     [(set (match_operand:SI 0 "register_operand" "")
19664           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19665                    (match_operand:SI 2 "const_int_operand" "")))
19666      (clobber (reg:CC FLAGS_REG))])]
19667   "!optimize_size 
19668    && (INTVAL (operands[2]) == 3
19669        || INTVAL (operands[2]) == 5
19670        || INTVAL (operands[2]) == 9)"
19671   [(set (match_dup 0) (match_dup 1))
19672    (set (match_dup 0)
19673         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19674                  (match_dup 0)))]
19675   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19677 (define_peephole2
19678   [(parallel
19679     [(set (match_operand:DI 0 "register_operand" "")
19680           (mult:DI (match_operand:DI 1 "register_operand" "")
19681                    (match_operand:DI 2 "const_int_operand" "")))
19682      (clobber (reg:CC FLAGS_REG))])]
19683   "TARGET_64BIT
19684    && (INTVAL (operands[2]) == 3
19685        || INTVAL (operands[2]) == 5
19686        || INTVAL (operands[2]) == 9)"
19687   [(set (match_dup 0)
19688         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19689                  (match_dup 1)))]
19690   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19692 (define_peephole2
19693   [(parallel
19694     [(set (match_operand:DI 0 "register_operand" "")
19695           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19696                    (match_operand:DI 2 "const_int_operand" "")))
19697      (clobber (reg:CC FLAGS_REG))])]
19698   "TARGET_64BIT
19699    && !optimize_size 
19700    && (INTVAL (operands[2]) == 3
19701        || INTVAL (operands[2]) == 5
19702        || INTVAL (operands[2]) == 9)"
19703   [(set (match_dup 0) (match_dup 1))
19704    (set (match_dup 0)
19705         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19706                  (match_dup 0)))]
19707   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19709 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19710 ;; imul $32bit_imm, reg, reg is direct decoded.
19711 (define_peephole2
19712   [(match_scratch:DI 3 "r")
19713    (parallel [(set (match_operand:DI 0 "register_operand" "")
19714                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19715                             (match_operand:DI 2 "immediate_operand" "")))
19716               (clobber (reg:CC FLAGS_REG))])]
19717   "TARGET_K8 && !optimize_size
19718    && (GET_CODE (operands[2]) != CONST_INT
19719        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19720   [(set (match_dup 3) (match_dup 1))
19721    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19722               (clobber (reg:CC FLAGS_REG))])]
19725 (define_peephole2
19726   [(match_scratch:SI 3 "r")
19727    (parallel [(set (match_operand:SI 0 "register_operand" "")
19728                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19729                             (match_operand:SI 2 "immediate_operand" "")))
19730               (clobber (reg:CC FLAGS_REG))])]
19731   "TARGET_K8 && !optimize_size
19732    && (GET_CODE (operands[2]) != CONST_INT
19733        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19734   [(set (match_dup 3) (match_dup 1))
19735    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19736               (clobber (reg:CC FLAGS_REG))])]
19739 (define_peephole2
19740   [(match_scratch:SI 3 "r")
19741    (parallel [(set (match_operand:DI 0 "register_operand" "")
19742                    (zero_extend:DI
19743                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19744                               (match_operand:SI 2 "immediate_operand" ""))))
19745               (clobber (reg:CC FLAGS_REG))])]
19746   "TARGET_K8 && !optimize_size
19747    && (GET_CODE (operands[2]) != CONST_INT
19748        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19749   [(set (match_dup 3) (match_dup 1))
19750    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19751               (clobber (reg:CC FLAGS_REG))])]
19754 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19755 ;; Convert it into imul reg, reg
19756 ;; It would be better to force assembler to encode instruction using long
19757 ;; immediate, but there is apparently no way to do so.
19758 (define_peephole2
19759   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19760                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19761                             (match_operand:DI 2 "const_int_operand" "")))
19762               (clobber (reg:CC FLAGS_REG))])
19763    (match_scratch:DI 3 "r")]
19764   "TARGET_K8 && !optimize_size
19765    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19766   [(set (match_dup 3) (match_dup 2))
19767    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19768               (clobber (reg:CC FLAGS_REG))])]
19770   if (!rtx_equal_p (operands[0], operands[1]))
19771     emit_move_insn (operands[0], operands[1]);
19774 (define_peephole2
19775   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19776                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19777                             (match_operand:SI 2 "const_int_operand" "")))
19778               (clobber (reg:CC FLAGS_REG))])
19779    (match_scratch:SI 3 "r")]
19780   "TARGET_K8 && !optimize_size
19781    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19782   [(set (match_dup 3) (match_dup 2))
19783    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19784               (clobber (reg:CC FLAGS_REG))])]
19786   if (!rtx_equal_p (operands[0], operands[1]))
19787     emit_move_insn (operands[0], operands[1]);
19790 (define_peephole2
19791   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19792                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19793                             (match_operand:HI 2 "immediate_operand" "")))
19794               (clobber (reg:CC FLAGS_REG))])
19795    (match_scratch:HI 3 "r")]
19796   "TARGET_K8 && !optimize_size"
19797   [(set (match_dup 3) (match_dup 2))
19798    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19799               (clobber (reg:CC FLAGS_REG))])]
19801   if (!rtx_equal_p (operands[0], operands[1]))
19802     emit_move_insn (operands[0], operands[1]);
19805 ;; Call-value patterns last so that the wildcard operand does not
19806 ;; disrupt insn-recog's switch tables.
19808 (define_insn "*call_value_pop_0"
19809   [(set (match_operand 0 "" "")
19810         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19811               (match_operand:SI 2 "" "")))
19812    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19813                             (match_operand:SI 3 "immediate_operand" "")))]
19814   "!TARGET_64BIT"
19816   if (SIBLING_CALL_P (insn))
19817     return "jmp\t%P1";
19818   else
19819     return "call\t%P1";
19821   [(set_attr "type" "callv")])
19823 (define_insn "*call_value_pop_1"
19824   [(set (match_operand 0 "" "")
19825         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19826               (match_operand:SI 2 "" "")))
19827    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19828                             (match_operand:SI 3 "immediate_operand" "i")))]
19829   "!TARGET_64BIT"
19831   if (constant_call_address_operand (operands[1], Pmode))
19832     {
19833       if (SIBLING_CALL_P (insn))
19834         return "jmp\t%P1";
19835       else
19836         return "call\t%P1";
19837     }
19838   if (SIBLING_CALL_P (insn))
19839     return "jmp\t%A1";
19840   else
19841     return "call\t%A1";
19843   [(set_attr "type" "callv")])
19845 (define_insn "*call_value_0"
19846   [(set (match_operand 0 "" "")
19847         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19848               (match_operand:SI 2 "" "")))]
19849   "!TARGET_64BIT"
19851   if (SIBLING_CALL_P (insn))
19852     return "jmp\t%P1";
19853   else
19854     return "call\t%P1";
19856   [(set_attr "type" "callv")])
19858 (define_insn "*call_value_0_rex64"
19859   [(set (match_operand 0 "" "")
19860         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19861               (match_operand:DI 2 "const_int_operand" "")))]
19862   "TARGET_64BIT"
19864   if (SIBLING_CALL_P (insn))
19865     return "jmp\t%P1";
19866   else
19867     return "call\t%P1";
19869   [(set_attr "type" "callv")])
19871 (define_insn "*call_value_1"
19872   [(set (match_operand 0 "" "")
19873         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19874               (match_operand:SI 2 "" "")))]
19875   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19877   if (constant_call_address_operand (operands[1], Pmode))
19878     return "call\t%P1";
19879   return "call\t%*%1";
19881   [(set_attr "type" "callv")])
19883 (define_insn "*sibcall_value_1"
19884   [(set (match_operand 0 "" "")
19885         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19886               (match_operand:SI 2 "" "")))]
19887   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19889   if (constant_call_address_operand (operands[1], Pmode))
19890     return "jmp\t%P1";
19891   return "jmp\t%*%1";
19893   [(set_attr "type" "callv")])
19895 (define_insn "*call_value_1_rex64"
19896   [(set (match_operand 0 "" "")
19897         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19898               (match_operand:DI 2 "" "")))]
19899   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19901   if (constant_call_address_operand (operands[1], Pmode))
19902     return "call\t%P1";
19903   return "call\t%A1";
19905   [(set_attr "type" "callv")])
19907 (define_insn "*sibcall_value_1_rex64"
19908   [(set (match_operand 0 "" "")
19909         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19910               (match_operand:DI 2 "" "")))]
19911   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19912   "jmp\t%P1"
19913   [(set_attr "type" "callv")])
19915 (define_insn "*sibcall_value_1_rex64_v"
19916   [(set (match_operand 0 "" "")
19917         (call (mem:QI (reg:DI 40))
19918               (match_operand:DI 1 "" "")))]
19919   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19920   "jmp\t*%%r11"
19921   [(set_attr "type" "callv")])
19923 (define_insn "trap"
19924   [(trap_if (const_int 1) (const_int 5))]
19925   ""
19926   "int\t$5")
19928 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19929 ;;; for the sake of bounds checking.  By emitting bounds checks as
19930 ;;; conditional traps rather than as conditional jumps around
19931 ;;; unconditional traps we avoid introducing spurious basic-block
19932 ;;; boundaries and facilitate elimination of redundant checks.  In
19933 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19934 ;;; interrupt 5.
19935 ;;; 
19936 ;;; FIXME: Static branch prediction rules for ix86 are such that
19937 ;;; forward conditional branches predict as untaken.  As implemented
19938 ;;; below, pseudo conditional traps violate that rule.  We should use
19939 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19940 ;;; section loaded at the end of the text segment and branch forward
19941 ;;; there on bounds-failure, and then jump back immediately (in case
19942 ;;; the system chooses to ignore bounds violations, or to report
19943 ;;; violations and continue execution).
19945 (define_expand "conditional_trap"
19946   [(trap_if (match_operator 0 "comparison_operator"
19947              [(match_dup 2) (const_int 0)])
19948             (match_operand 1 "const_int_operand" ""))]
19949   ""
19951   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19952                               ix86_expand_compare (GET_CODE (operands[0]),
19953                                                    NULL, NULL),
19954                               operands[1]));
19955   DONE;
19958 (define_insn "*conditional_trap_1"
19959   [(trap_if (match_operator 0 "comparison_operator"
19960              [(reg 17) (const_int 0)])
19961             (match_operand 1 "const_int_operand" ""))]
19962   ""
19964   operands[2] = gen_label_rtx ();
19965   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19966   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19967                              CODE_LABEL_NUMBER (operands[2]));
19968   RET;
19971         ;; Pentium III SIMD instructions.
19973 ;; Moves for SSE/MMX regs.
19975 (define_insn "movv4sf_internal"
19976   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19977         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19978   "TARGET_SSE"
19979   "@
19980     xorps\t%0, %0
19981     movaps\t{%1, %0|%0, %1}
19982     movaps\t{%1, %0|%0, %1}"
19983   [(set_attr "type" "ssemov")
19984    (set_attr "mode" "V4SF")])
19986 (define_split
19987   [(set (match_operand:V4SF 0 "register_operand" "")
19988         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19989   "TARGET_SSE"
19990   [(set (match_dup 0)
19991         (vec_merge:V4SF
19992          (vec_duplicate:V4SF (match_dup 1))
19993          (match_dup 2)
19994          (const_int 1)))]
19996   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19997   operands[2] = CONST0_RTX (V4SFmode);
20000 (define_insn "movv4si_internal"
20001   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
20002         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
20003   "TARGET_SSE"
20005   switch (which_alternative)
20006     {
20007     case 0:
20008       if (get_attr_mode (insn) == MODE_V4SF)
20009         return "xorps\t%0, %0";
20010       else
20011         return "pxor\t%0, %0";
20012     case 1:
20013     case 2:
20014       if (get_attr_mode (insn) == MODE_V4SF)
20015         return "movaps\t{%1, %0|%0, %1}";
20016       else
20017         return "movdqa\t{%1, %0|%0, %1}";
20018     default:
20019       abort ();
20020     }
20022   [(set_attr "type" "ssemov")
20023    (set (attr "mode")
20024         (cond [(eq_attr "alternative" "0,1")
20025                  (if_then_else
20026                    (ne (symbol_ref "optimize_size")
20027                        (const_int 0))
20028                    (const_string "V4SF")
20029                    (const_string "TI"))
20030                (eq_attr "alternative" "2")
20031                  (if_then_else
20032                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20033                             (const_int 0))
20034                         (ne (symbol_ref "optimize_size")
20035                             (const_int 0)))
20036                    (const_string "V4SF")
20037                    (const_string "TI"))]
20038                (const_string "TI")))])
20040 (define_insn "movv2di_internal"
20041   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
20042         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
20043   "TARGET_SSE"
20045   switch (which_alternative)
20046     {
20047     case 0:
20048       if (get_attr_mode (insn) == MODE_V4SF)
20049         return "xorps\t%0, %0";
20050       else
20051         return "pxor\t%0, %0";
20052     case 1:
20053     case 2:
20054       if (get_attr_mode (insn) == MODE_V4SF)
20055         return "movaps\t{%1, %0|%0, %1}";
20056       else
20057         return "movdqa\t{%1, %0|%0, %1}";
20058     default:
20059       abort ();
20060     }
20062   [(set_attr "type" "ssemov")
20063    (set (attr "mode")
20064         (cond [(eq_attr "alternative" "0,1")
20065                  (if_then_else
20066                    (ne (symbol_ref "optimize_size")
20067                        (const_int 0))
20068                    (const_string "V4SF")
20069                    (const_string "TI"))
20070                (eq_attr "alternative" "2")
20071                  (if_then_else
20072                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20073                             (const_int 0))
20074                         (ne (symbol_ref "optimize_size")
20075                             (const_int 0)))
20076                    (const_string "V4SF")
20077                    (const_string "TI"))]
20078                (const_string "TI")))])
20080 (define_split
20081   [(set (match_operand:V2DF 0 "register_operand" "")
20082         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
20083   "TARGET_SSE2"
20084   [(set (match_dup 0)
20085         (vec_merge:V2DF
20086          (vec_duplicate:V2DF (match_dup 1))
20087          (match_dup 2)
20088          (const_int 1)))]
20090   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
20091   operands[2] = CONST0_RTX (V2DFmode);
20094 (define_insn "movv8qi_internal"
20095   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20096         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20097   "TARGET_MMX
20098    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20099   "@
20100     pxor\t%0, %0
20101     movq\t{%1, %0|%0, %1}
20102     movq\t{%1, %0|%0, %1}
20103     movdq2q\t{%1, %0|%0, %1}
20104     movq2dq\t{%1, %0|%0, %1}
20105     movq\t{%1, %0|%0, %1}
20106     movq\t{%1, %0|%0, %1}"
20107   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20108    (set_attr "mode" "DI")])
20110 (define_insn "movv4hi_internal"
20111   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20112         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20113   "TARGET_MMX
20114    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20115   "@
20116     pxor\t%0, %0
20117     movq\t{%1, %0|%0, %1}
20118     movq\t{%1, %0|%0, %1}
20119     movdq2q\t{%1, %0|%0, %1}
20120     movq2dq\t{%1, %0|%0, %1}
20121     movq\t{%1, %0|%0, %1}
20122     movq\t{%1, %0|%0, %1}"
20123   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20124    (set_attr "mode" "DI")])
20126 (define_insn "*movv2si_internal"
20127   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20128         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20129   "TARGET_MMX
20130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20131   "@
20132     pxor\t%0, %0
20133     movq\t{%1, %0|%0, %1}
20134     movq\t{%1, %0|%0, %1}
20135     movdq2q\t{%1, %0|%0, %1}
20136     movq2dq\t{%1, %0|%0, %1}
20137     movq\t{%1, %0|%0, %1}
20138     movq\t{%1, %0|%0, %1}"
20139   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20140    (set_attr "mode" "DI")])
20142 (define_insn "movv2sf_internal"
20143   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
20144         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
20145   "TARGET_3DNOW
20146    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20147   "@
20148     pxor\t%0, %0
20149     movq\t{%1, %0|%0, %1}
20150     movq\t{%1, %0|%0, %1}
20151     movdq2q\t{%1, %0|%0, %1}
20152     movq2dq\t{%1, %0|%0, %1}
20153     movlps\t{%1, %0|%0, %1}
20154     movlps\t{%1, %0|%0, %1}"
20155   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20156    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
20158 (define_expand "movti"
20159   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20160         (match_operand:TI 1 "nonimmediate_operand" ""))]
20161   "TARGET_SSE || TARGET_64BIT"
20163   if (TARGET_64BIT)
20164     ix86_expand_move (TImode, operands);
20165   else
20166     ix86_expand_vector_move (TImode, operands);
20167   DONE;
20170 (define_expand "movtf"
20171   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20172         (match_operand:TF 1 "nonimmediate_operand" ""))]
20173   "TARGET_64BIT"
20175   if (TARGET_64BIT)
20176     ix86_expand_move (TFmode, operands);
20177   else
20178     ix86_expand_vector_move (TFmode, operands);
20179   DONE;
20182 (define_insn "movv2df_internal"
20183   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
20184         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
20185   "TARGET_SSE2
20186    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20188   switch (which_alternative)
20189     {
20190     case 0:
20191       if (get_attr_mode (insn) == MODE_V4SF)
20192         return "xorps\t%0, %0";
20193       else
20194         return "xorpd\t%0, %0";
20195     case 1:
20196     case 2:
20197       if (get_attr_mode (insn) == MODE_V4SF)
20198         return "movaps\t{%1, %0|%0, %1}";
20199       else
20200         return "movapd\t{%1, %0|%0, %1}";
20201     default:
20202       abort ();
20203     }
20205   [(set_attr "type" "ssemov")
20206    (set (attr "mode")
20207         (cond [(eq_attr "alternative" "0,1")
20208                  (if_then_else
20209                    (ne (symbol_ref "optimize_size")
20210                        (const_int 0))
20211                    (const_string "V4SF")
20212                    (const_string "V2DF"))
20213                (eq_attr "alternative" "2")
20214                  (if_then_else
20215                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20216                             (const_int 0))
20217                         (ne (symbol_ref "optimize_size")
20218                             (const_int 0)))
20219                    (const_string "V4SF")
20220                    (const_string "V2DF"))]
20221                (const_string "V2DF")))])
20223 (define_insn "movv8hi_internal"
20224   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
20225         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
20226   "TARGET_SSE2
20227    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20229   switch (which_alternative)
20230     {
20231     case 0:
20232       if (get_attr_mode (insn) == MODE_V4SF)
20233         return "xorps\t%0, %0";
20234       else
20235         return "pxor\t%0, %0";
20236     case 1:
20237     case 2:
20238       if (get_attr_mode (insn) == MODE_V4SF)
20239         return "movaps\t{%1, %0|%0, %1}";
20240       else
20241         return "movdqa\t{%1, %0|%0, %1}";
20242     default:
20243       abort ();
20244     }
20246   [(set_attr "type" "ssemov")
20247    (set (attr "mode")
20248         (cond [(eq_attr "alternative" "0,1")
20249                  (if_then_else
20250                    (ne (symbol_ref "optimize_size")
20251                        (const_int 0))
20252                    (const_string "V4SF")
20253                    (const_string "TI"))
20254                (eq_attr "alternative" "2")
20255                  (if_then_else
20256                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20257                             (const_int 0))
20258                         (ne (symbol_ref "optimize_size")
20259                             (const_int 0)))
20260                    (const_string "V4SF")
20261                    (const_string "TI"))]
20262                (const_string "TI")))])
20264 (define_insn "movv16qi_internal"
20265   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20266         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20267   "TARGET_SSE2
20268    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20270   switch (which_alternative)
20271     {
20272     case 0:
20273       if (get_attr_mode (insn) == MODE_V4SF)
20274         return "xorps\t%0, %0";
20275       else
20276         return "pxor\t%0, %0";
20277     case 1:
20278     case 2:
20279       if (get_attr_mode (insn) == MODE_V4SF)
20280         return "movaps\t{%1, %0|%0, %1}";
20281       else
20282         return "movdqa\t{%1, %0|%0, %1}";
20283     default:
20284       abort ();
20285     }
20287   [(set_attr "type" "ssemov")
20288    (set (attr "mode")
20289         (cond [(eq_attr "alternative" "0,1")
20290                  (if_then_else
20291                    (ne (symbol_ref "optimize_size")
20292                        (const_int 0))
20293                    (const_string "V4SF")
20294                    (const_string "TI"))
20295                (eq_attr "alternative" "2")
20296                  (if_then_else
20297                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20298                             (const_int 0))
20299                         (ne (symbol_ref "optimize_size")
20300                             (const_int 0)))
20301                    (const_string "V4SF")
20302                    (const_string "TI"))]
20303                (const_string "TI")))])
20305 (define_expand "movv2df"
20306   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20307         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20308   "TARGET_SSE2"
20310   ix86_expand_vector_move (V2DFmode, operands);
20311   DONE;
20314 (define_expand "movv8hi"
20315   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20316         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20317   "TARGET_SSE2"
20319   ix86_expand_vector_move (V8HImode, operands);
20320   DONE;
20323 (define_expand "movv16qi"
20324   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20325         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20326   "TARGET_SSE2"
20328   ix86_expand_vector_move (V16QImode, operands);
20329   DONE;
20332 (define_expand "movv4sf"
20333   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20334         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20335   "TARGET_SSE"
20337   ix86_expand_vector_move (V4SFmode, operands);
20338   DONE;
20341 (define_expand "movv4si"
20342   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20343         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20344   "TARGET_SSE"
20346   ix86_expand_vector_move (V4SImode, operands);
20347   DONE;
20350 (define_expand "movv2di"
20351   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20352         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20353   "TARGET_SSE"
20355   ix86_expand_vector_move (V2DImode, operands);
20356   DONE;
20359 (define_expand "movv2si"
20360   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20361         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20362   "TARGET_MMX"
20364   ix86_expand_vector_move (V2SImode, operands);
20365   DONE;
20368 (define_expand "movv4hi"
20369   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20370         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20371   "TARGET_MMX"
20373   ix86_expand_vector_move (V4HImode, operands);
20374   DONE;
20377 (define_expand "movv8qi"
20378   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20379         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20380   "TARGET_MMX"
20382   ix86_expand_vector_move (V8QImode, operands);
20383   DONE;
20386 (define_expand "movv2sf"
20387   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20388         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20389    "TARGET_3DNOW"
20391   ix86_expand_vector_move (V2SFmode, operands);
20392   DONE;
20395 (define_insn "*pushti"
20396   [(set (match_operand:TI 0 "push_operand" "=<")
20397         (match_operand:TI 1 "register_operand" "x"))]
20398   "TARGET_SSE"
20399   "#")
20401 (define_insn "*pushv2df"
20402   [(set (match_operand:V2DF 0 "push_operand" "=<")
20403         (match_operand:V2DF 1 "register_operand" "x"))]
20404   "TARGET_SSE"
20405   "#")
20407 (define_insn "*pushv2di"
20408   [(set (match_operand:V2DI 0 "push_operand" "=<")
20409         (match_operand:V2DI 1 "register_operand" "x"))]
20410   "TARGET_SSE2"
20411   "#")
20413 (define_insn "*pushv8hi"
20414   [(set (match_operand:V8HI 0 "push_operand" "=<")
20415         (match_operand:V8HI 1 "register_operand" "x"))]
20416   "TARGET_SSE2"
20417   "#")
20419 (define_insn "*pushv16qi"
20420   [(set (match_operand:V16QI 0 "push_operand" "=<")
20421         (match_operand:V16QI 1 "register_operand" "x"))]
20422   "TARGET_SSE2"
20423   "#")
20425 (define_insn "*pushv4sf"
20426   [(set (match_operand:V4SF 0 "push_operand" "=<")
20427         (match_operand:V4SF 1 "register_operand" "x"))]
20428   "TARGET_SSE"
20429   "#")
20431 (define_insn "*pushv4si"
20432   [(set (match_operand:V4SI 0 "push_operand" "=<")
20433         (match_operand:V4SI 1 "register_operand" "x"))]
20434   "TARGET_SSE2"
20435   "#")
20437 (define_insn "*pushv2si"
20438   [(set (match_operand:V2SI 0 "push_operand" "=<")
20439         (match_operand:V2SI 1 "register_operand" "y"))]
20440   "TARGET_MMX"
20441   "#")
20443 (define_insn "*pushv4hi"
20444   [(set (match_operand:V4HI 0 "push_operand" "=<")
20445         (match_operand:V4HI 1 "register_operand" "y"))]
20446   "TARGET_MMX"
20447   "#")
20449 (define_insn "*pushv8qi"
20450   [(set (match_operand:V8QI 0 "push_operand" "=<")
20451         (match_operand:V8QI 1 "register_operand" "y"))]
20452   "TARGET_MMX"
20453   "#")
20455 (define_insn "*pushv2sf"
20456   [(set (match_operand:V2SF 0 "push_operand" "=<")
20457         (match_operand:V2SF 1 "register_operand" "y"))]
20458   "TARGET_3DNOW"
20459   "#")
20461 (define_split
20462   [(set (match_operand 0 "push_operand" "")
20463         (match_operand 1 "register_operand" ""))]
20464   "!TARGET_64BIT && reload_completed
20465    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20466   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20467    (set (match_dup 2) (match_dup 1))]
20468   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20469                                  stack_pointer_rtx);
20470    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20472 (define_split
20473   [(set (match_operand 0 "push_operand" "")
20474         (match_operand 1 "register_operand" ""))]
20475   "TARGET_64BIT && reload_completed
20476    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20477   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20478    (set (match_dup 2) (match_dup 1))]
20479   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20480                                  stack_pointer_rtx);
20481    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20484 (define_insn "movti_internal"
20485   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20486         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20487   "TARGET_SSE && !TARGET_64BIT
20488    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20490   switch (which_alternative)
20491     {
20492     case 0:
20493       if (get_attr_mode (insn) == MODE_V4SF)
20494         return "xorps\t%0, %0";
20495       else
20496         return "pxor\t%0, %0";
20497     case 1:
20498     case 2:
20499       if (get_attr_mode (insn) == MODE_V4SF)
20500         return "movaps\t{%1, %0|%0, %1}";
20501       else
20502         return "movdqa\t{%1, %0|%0, %1}";
20503     default:
20504       abort ();
20505     }
20507   [(set_attr "type" "ssemov,ssemov,ssemov")
20508    (set (attr "mode")
20509         (cond [(eq_attr "alternative" "0,1")
20510                  (if_then_else
20511                    (ne (symbol_ref "optimize_size")
20512                        (const_int 0))
20513                    (const_string "V4SF")
20514                    (const_string "TI"))
20515                (eq_attr "alternative" "2")
20516                  (if_then_else
20517                    (ne (symbol_ref "optimize_size")
20518                        (const_int 0))
20519                    (const_string "V4SF")
20520                    (const_string "TI"))]
20521                (const_string "TI")))])
20523 (define_insn "*movti_rex64"
20524   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20525         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20526   "TARGET_64BIT
20527    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20529   switch (which_alternative)
20530     {
20531     case 0:
20532     case 1:
20533       return "#";
20534     case 2:
20535       if (get_attr_mode (insn) == MODE_V4SF)
20536         return "xorps\t%0, %0";
20537       else
20538         return "pxor\t%0, %0";
20539     case 3:
20540     case 4:
20541       if (get_attr_mode (insn) == MODE_V4SF)
20542         return "movaps\t{%1, %0|%0, %1}";
20543       else
20544         return "movdqa\t{%1, %0|%0, %1}";
20545     default:
20546       abort ();
20547     }
20549   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20550    (set (attr "mode")
20551         (cond [(eq_attr "alternative" "2,3")
20552                  (if_then_else
20553                    (ne (symbol_ref "optimize_size")
20554                        (const_int 0))
20555                    (const_string "V4SF")
20556                    (const_string "TI"))
20557                (eq_attr "alternative" "4")
20558                  (if_then_else
20559                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20560                             (const_int 0))
20561                         (ne (symbol_ref "optimize_size")
20562                             (const_int 0)))
20563                    (const_string "V4SF")
20564                    (const_string "TI"))]
20565                (const_string "DI")))])
20567 (define_insn "*movtf_rex64"
20568   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20569         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20570   "TARGET_64BIT
20571    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20573   switch (which_alternative)
20574     {
20575     case 0:
20576     case 1:
20577       return "#";
20578     case 2:
20579       if (get_attr_mode (insn) == MODE_V4SF)
20580         return "xorps\t%0, %0";
20581       else
20582         return "pxor\t%0, %0";
20583     case 3:
20584     case 4:
20585       if (get_attr_mode (insn) == MODE_V4SF)
20586         return "movaps\t{%1, %0|%0, %1}";
20587       else
20588         return "movdqa\t{%1, %0|%0, %1}";
20589     default:
20590       abort ();
20591     }
20593   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20594    (set (attr "mode")
20595         (cond [(eq_attr "alternative" "2,3")
20596                  (if_then_else
20597                    (ne (symbol_ref "optimize_size")
20598                        (const_int 0))
20599                    (const_string "V4SF")
20600                    (const_string "TI"))
20601                (eq_attr "alternative" "4")
20602                  (if_then_else
20603                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20604                             (const_int 0))
20605                         (ne (symbol_ref "optimize_size")
20606                             (const_int 0)))
20607                    (const_string "V4SF")
20608                    (const_string "TI"))]
20609                (const_string "DI")))])
20611 (define_split
20612   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20613         (match_operand:TI 1 "general_operand" ""))]
20614   "reload_completed && !SSE_REG_P (operands[0])
20615    && !SSE_REG_P (operands[1])"
20616   [(const_int 0)]
20617   "ix86_split_long_move (operands); DONE;")
20619 (define_split
20620   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20621         (match_operand:TF 1 "general_operand" ""))]
20622   "reload_completed && !SSE_REG_P (operands[0])
20623    && !SSE_REG_P (operands[1])"
20624   [(const_int 0)]
20625   "ix86_split_long_move (operands); DONE;")
20627 ;; These two patterns are useful for specifying exactly whether to use
20628 ;; movaps or movups
20629 (define_expand "sse_movaps"
20630   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20631         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20632                      UNSPEC_MOVA))]
20633   "TARGET_SSE"
20635   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20636     {
20637       rtx tmp = gen_reg_rtx (V4SFmode);
20638       emit_insn (gen_sse_movaps (tmp, operands[1]));
20639       emit_move_insn (operands[0], tmp);
20640       DONE;
20641     }
20644 (define_insn "*sse_movaps_1"
20645   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20646         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20647                      UNSPEC_MOVA))]
20648   "TARGET_SSE
20649    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20650   "movaps\t{%1, %0|%0, %1}"
20651   [(set_attr "type" "ssemov,ssemov")
20652    (set_attr "mode" "V4SF")])
20654 (define_expand "sse_movups"
20655   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20656         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20657                      UNSPEC_MOVU))]
20658   "TARGET_SSE"
20660   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20661     {
20662       rtx tmp = gen_reg_rtx (V4SFmode);
20663       emit_insn (gen_sse_movups (tmp, operands[1]));
20664       emit_move_insn (operands[0], tmp);
20665       DONE;
20666     }
20669 (define_insn "*sse_movups_1"
20670   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20671         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20672                      UNSPEC_MOVU))]
20673   "TARGET_SSE
20674    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20675   "movups\t{%1, %0|%0, %1}"
20676   [(set_attr "type" "ssecvt,ssecvt")
20677    (set_attr "mode" "V4SF")])
20679 ;; SSE Strange Moves.
20681 (define_insn "sse_movmskps"
20682   [(set (match_operand:SI 0 "register_operand" "=r")
20683         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20684                    UNSPEC_MOVMSK))]
20685   "TARGET_SSE"
20686   "movmskps\t{%1, %0|%0, %1}"
20687   [(set_attr "type" "ssecvt")
20688    (set_attr "mode" "V4SF")])
20690 (define_insn "mmx_pmovmskb"
20691   [(set (match_operand:SI 0 "register_operand" "=r")
20692         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20693                    UNSPEC_MOVMSK))]
20694   "TARGET_SSE || TARGET_3DNOW_A"
20695   "pmovmskb\t{%1, %0|%0, %1}"
20696   [(set_attr "type" "ssecvt")
20697    (set_attr "mode" "V4SF")])
20700 (define_insn "mmx_maskmovq"
20701   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20702         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20703                       (match_operand:V8QI 2 "register_operand" "y")]
20704                      UNSPEC_MASKMOV))]
20705   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20706   ;; @@@ check ordering of operands in intel/nonintel syntax
20707   "maskmovq\t{%2, %1|%1, %2}"
20708   [(set_attr "type" "mmxcvt")
20709    (set_attr "mode" "DI")])
20711 (define_insn "mmx_maskmovq_rex"
20712   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20713         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20714                       (match_operand:V8QI 2 "register_operand" "y")]
20715                      UNSPEC_MASKMOV))]
20716   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20717   ;; @@@ check ordering of operands in intel/nonintel syntax
20718   "maskmovq\t{%2, %1|%1, %2}"
20719   [(set_attr "type" "mmxcvt")
20720    (set_attr "mode" "DI")])
20722 (define_insn "sse_movntv4sf"
20723   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20724         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20725                      UNSPEC_MOVNT))]
20726   "TARGET_SSE"
20727   "movntps\t{%1, %0|%0, %1}"
20728   [(set_attr "type" "ssemov")
20729    (set_attr "mode" "V4SF")])
20731 (define_insn "sse_movntdi"
20732   [(set (match_operand:DI 0 "memory_operand" "=m")
20733         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20734                    UNSPEC_MOVNT))]
20735   "TARGET_SSE || TARGET_3DNOW_A"
20736   "movntq\t{%1, %0|%0, %1}"
20737   [(set_attr "type" "mmxmov")
20738    (set_attr "mode" "DI")])
20740 (define_insn "sse_movhlps"
20741   [(set (match_operand:V4SF 0 "register_operand" "=x")
20742         (vec_merge:V4SF
20743          (match_operand:V4SF 1 "register_operand" "0")
20744          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20745                           (parallel [(const_int 2)
20746                                      (const_int 3)
20747                                      (const_int 0)
20748                                      (const_int 1)]))
20749          (const_int 3)))]
20750   "TARGET_SSE"
20751   "movhlps\t{%2, %0|%0, %2}"
20752   [(set_attr "type" "ssecvt")
20753    (set_attr "mode" "V4SF")])
20755 (define_insn "sse_movlhps"
20756   [(set (match_operand:V4SF 0 "register_operand" "=x")
20757         (vec_merge:V4SF
20758          (match_operand:V4SF 1 "register_operand" "0")
20759          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20760                           (parallel [(const_int 2)
20761                                      (const_int 3)
20762                                      (const_int 0)
20763                                      (const_int 1)]))
20764          (const_int 12)))]
20765   "TARGET_SSE"
20766   "movlhps\t{%2, %0|%0, %2}"
20767   [(set_attr "type" "ssecvt")
20768    (set_attr "mode" "V4SF")])
20770 (define_insn "sse_movhps"
20771   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20772         (vec_merge:V4SF
20773          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20774          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20775          (const_int 12)))]
20776   "TARGET_SSE
20777    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20778   "movhps\t{%2, %0|%0, %2}"
20779   [(set_attr "type" "ssecvt")
20780    (set_attr "mode" "V4SF")])
20782 (define_insn "sse_movlps"
20783   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20784         (vec_merge:V4SF
20785          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20786          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20787          (const_int 3)))]
20788   "TARGET_SSE
20789    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20790   "movlps\t{%2, %0|%0, %2}"
20791   [(set_attr "type" "ssecvt")
20792    (set_attr "mode" "V4SF")])
20794 (define_expand "sse_loadss"
20795   [(match_operand:V4SF 0 "register_operand" "")
20796    (match_operand:SF 1 "memory_operand" "")]
20797   "TARGET_SSE"
20799   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20800                                CONST0_RTX (V4SFmode)));
20801   DONE;
20804 (define_insn "sse_loadss_1"
20805   [(set (match_operand:V4SF 0 "register_operand" "=x")
20806         (vec_merge:V4SF
20807          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20808          (match_operand:V4SF 2 "const0_operand" "X")
20809          (const_int 1)))]
20810   "TARGET_SSE"
20811   "movss\t{%1, %0|%0, %1}"
20812   [(set_attr "type" "ssemov")
20813    (set_attr "mode" "SF")])
20815 (define_insn "sse_movss"
20816   [(set (match_operand:V4SF 0 "register_operand" "=x")
20817         (vec_merge:V4SF
20818          (match_operand:V4SF 1 "register_operand" "0")
20819          (match_operand:V4SF 2 "register_operand" "x")
20820          (const_int 1)))]
20821   "TARGET_SSE"
20822   "movss\t{%2, %0|%0, %2}"
20823   [(set_attr "type" "ssemov")
20824    (set_attr "mode" "SF")])
20826 (define_insn "sse_storess"
20827   [(set (match_operand:SF 0 "memory_operand" "=m")
20828         (vec_select:SF
20829          (match_operand:V4SF 1 "register_operand" "x")
20830          (parallel [(const_int 0)])))]
20831   "TARGET_SSE"
20832   "movss\t{%1, %0|%0, %1}"
20833   [(set_attr "type" "ssemov")
20834    (set_attr "mode" "SF")])
20836 (define_insn "sse_shufps"
20837   [(set (match_operand:V4SF 0 "register_operand" "=x")
20838         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20839                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20840                       (match_operand:SI 3 "immediate_operand" "i")]
20841                      UNSPEC_SHUFFLE))]
20842   "TARGET_SSE"
20843   ;; @@@ check operand order for intel/nonintel syntax
20844   "shufps\t{%3, %2, %0|%0, %2, %3}"
20845   [(set_attr "type" "ssecvt")
20846    (set_attr "mode" "V4SF")])
20849 ;; SSE arithmetic
20851 (define_insn "addv4sf3"
20852   [(set (match_operand:V4SF 0 "register_operand" "=x")
20853         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20854                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20855   "TARGET_SSE"
20856   "addps\t{%2, %0|%0, %2}"
20857   [(set_attr "type" "sseadd")
20858    (set_attr "mode" "V4SF")])
20860 (define_insn "vmaddv4sf3"
20861   [(set (match_operand:V4SF 0 "register_operand" "=x")
20862         (vec_merge:V4SF
20863          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20864                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20865          (match_dup 1)
20866          (const_int 1)))]
20867   "TARGET_SSE"
20868   "addss\t{%2, %0|%0, %2}"
20869   [(set_attr "type" "sseadd")
20870    (set_attr "mode" "SF")])
20872 (define_insn "subv4sf3"
20873   [(set (match_operand:V4SF 0 "register_operand" "=x")
20874         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20875                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20876   "TARGET_SSE"
20877   "subps\t{%2, %0|%0, %2}"
20878   [(set_attr "type" "sseadd")
20879    (set_attr "mode" "V4SF")])
20881 (define_insn "vmsubv4sf3"
20882   [(set (match_operand:V4SF 0 "register_operand" "=x")
20883         (vec_merge:V4SF
20884          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20885                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20886          (match_dup 1)
20887          (const_int 1)))]
20888   "TARGET_SSE"
20889   "subss\t{%2, %0|%0, %2}"
20890   [(set_attr "type" "sseadd")
20891    (set_attr "mode" "SF")])
20893 ;; ??? Should probably be done by generic code instead.
20894 (define_expand "negv4sf2"
20895   [(set (match_operand:V4SF 0 "register_operand" "")
20896         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20897                   (match_dup 2)))]
20898   "TARGET_SSE"
20900   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20901   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20902   operands[2] = force_reg (V4SFmode, vm0);
20905 (define_insn "mulv4sf3"
20906   [(set (match_operand:V4SF 0 "register_operand" "=x")
20907         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20908                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20909   "TARGET_SSE"
20910   "mulps\t{%2, %0|%0, %2}"
20911   [(set_attr "type" "ssemul")
20912    (set_attr "mode" "V4SF")])
20914 (define_insn "vmmulv4sf3"
20915   [(set (match_operand:V4SF 0 "register_operand" "=x")
20916         (vec_merge:V4SF
20917          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20918                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20919          (match_dup 1)
20920          (const_int 1)))]
20921   "TARGET_SSE"
20922   "mulss\t{%2, %0|%0, %2}"
20923   [(set_attr "type" "ssemul")
20924    (set_attr "mode" "SF")])
20926 (define_insn "divv4sf3"
20927   [(set (match_operand:V4SF 0 "register_operand" "=x")
20928         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20929                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20930   "TARGET_SSE"
20931   "divps\t{%2, %0|%0, %2}"
20932   [(set_attr "type" "ssediv")
20933    (set_attr "mode" "V4SF")])
20935 (define_insn "vmdivv4sf3"
20936   [(set (match_operand:V4SF 0 "register_operand" "=x")
20937         (vec_merge:V4SF
20938          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20939                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20940          (match_dup 1)
20941          (const_int 1)))]
20942   "TARGET_SSE"
20943   "divss\t{%2, %0|%0, %2}"
20944   [(set_attr "type" "ssediv")
20945    (set_attr "mode" "SF")])
20948 ;; SSE square root/reciprocal
20950 (define_insn "rcpv4sf2"
20951   [(set (match_operand:V4SF 0 "register_operand" "=x")
20952         (unspec:V4SF
20953          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20954   "TARGET_SSE"
20955   "rcpps\t{%1, %0|%0, %1}"
20956   [(set_attr "type" "sse")
20957    (set_attr "mode" "V4SF")])
20959 (define_insn "vmrcpv4sf2"
20960   [(set (match_operand:V4SF 0 "register_operand" "=x")
20961         (vec_merge:V4SF
20962          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20963                       UNSPEC_RCP)
20964          (match_operand:V4SF 2 "register_operand" "0")
20965          (const_int 1)))]
20966   "TARGET_SSE"
20967   "rcpss\t{%1, %0|%0, %1}"
20968   [(set_attr "type" "sse")
20969    (set_attr "mode" "SF")])
20971 (define_insn "rsqrtv4sf2"
20972   [(set (match_operand:V4SF 0 "register_operand" "=x")
20973         (unspec:V4SF
20974          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20975   "TARGET_SSE"
20976   "rsqrtps\t{%1, %0|%0, %1}"
20977   [(set_attr "type" "sse")
20978    (set_attr "mode" "V4SF")])
20980 (define_insn "vmrsqrtv4sf2"
20981   [(set (match_operand:V4SF 0 "register_operand" "=x")
20982         (vec_merge:V4SF
20983          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20984                       UNSPEC_RSQRT)
20985          (match_operand:V4SF 2 "register_operand" "0")
20986          (const_int 1)))]
20987   "TARGET_SSE"
20988   "rsqrtss\t{%1, %0|%0, %1}"
20989   [(set_attr "type" "sse")
20990    (set_attr "mode" "SF")])
20992 (define_insn "sqrtv4sf2"
20993   [(set (match_operand:V4SF 0 "register_operand" "=x")
20994         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20995   "TARGET_SSE"
20996   "sqrtps\t{%1, %0|%0, %1}"
20997   [(set_attr "type" "sse")
20998    (set_attr "mode" "V4SF")])
21000 (define_insn "vmsqrtv4sf2"
21001   [(set (match_operand:V4SF 0 "register_operand" "=x")
21002         (vec_merge:V4SF
21003          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21004          (match_operand:V4SF 2 "register_operand" "0")
21005          (const_int 1)))]
21006   "TARGET_SSE"
21007   "sqrtss\t{%1, %0|%0, %1}"
21008   [(set_attr "type" "sse")
21009    (set_attr "mode" "SF")])
21011 ;; SSE logical operations.
21013 ;; SSE defines logical operations on floating point values.  This brings
21014 ;; interesting challenge to RTL representation where logicals are only valid
21015 ;; on integral types.  We deal with this by representing the floating point
21016 ;; logical as logical on arguments casted to TImode as this is what hardware
21017 ;; really does.  Unfortunately hardware requires the type information to be
21018 ;; present and thus we must avoid subregs from being simplified and eliminated
21019 ;; in later compilation phases.
21021 ;; We have following variants from each instruction:
21022 ;; sse_andsf3 - the operation taking V4SF vector operands
21023 ;;              and doing TImode cast on them
21024 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
21025 ;;                      TImode, since backend insist on eliminating casts
21026 ;;                      on memory operands
21027 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
21028 ;;                   We cannot accept memory operand here as instruction reads
21029 ;;                   whole scalar.  This is generated only post reload by GCC
21030 ;;                   scalar float operations that expands to logicals (fabs)
21031 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
21032 ;;                   memory operand.  Eventually combine can be able
21033 ;;                   to synthesize these using splitter.
21034 ;; sse2_anddf3, *sse2_anddf3_memory
21035 ;;              
21036 ;; 
21037 ;; These are not called andti3 etc. because we really really don't want
21038 ;; the compiler to widen DImode ands to TImode ands and then try to move
21039 ;; into DImode subregs of SSE registers, and them together, and move out
21040 ;; of DImode subregs again!
21041 ;; SSE1 single precision floating point logical operation
21042 (define_expand "sse_andv4sf3"
21043   [(set (match_operand:V4SF 0 "register_operand" "")
21044         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
21045                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21046   "TARGET_SSE"
21047   "")
21049 (define_insn "*sse_andv4sf3"
21050   [(set (match_operand:V4SF 0 "register_operand" "=x")
21051         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21052                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21053   "TARGET_SSE
21054    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21055   "andps\t{%2, %0|%0, %2}"
21056   [(set_attr "type" "sselog")
21057    (set_attr "mode" "V4SF")])
21059 (define_expand "sse_nandv4sf3"
21060   [(set (match_operand:V4SF 0 "register_operand" "")
21061         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
21062                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21063   "TARGET_SSE"
21064   "")
21066 (define_insn "*sse_nandv4sf3"
21067   [(set (match_operand:V4SF 0 "register_operand" "=x")
21068         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
21069                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21070   "TARGET_SSE"
21071   "andnps\t{%2, %0|%0, %2}"
21072   [(set_attr "type" "sselog")
21073    (set_attr "mode" "V4SF")])
21075 (define_expand "sse_iorv4sf3"
21076   [(set (match_operand:V4SF 0 "register_operand" "")
21077         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
21078                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21079   "TARGET_SSE"
21080   "")
21082 (define_insn "*sse_iorv4sf3"
21083   [(set (match_operand:V4SF 0 "register_operand" "=x")
21084         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21085                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21086   "TARGET_SSE
21087    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21088   "orps\t{%2, %0|%0, %2}"
21089   [(set_attr "type" "sselog")
21090    (set_attr "mode" "V4SF")])
21092 (define_expand "sse_xorv4sf3"
21093   [(set (match_operand:V4SF 0 "register_operand" "")
21094         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
21095                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21096   "TARGET_SSE"
21097   "")
21099 (define_insn "*sse_xorv4sf3"
21100   [(set (match_operand:V4SF 0 "register_operand" "=x")
21101         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21102                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21103   "TARGET_SSE
21104    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21105   "xorps\t{%2, %0|%0, %2}"
21106   [(set_attr "type" "sselog")
21107    (set_attr "mode" "V4SF")])
21109 ;; SSE2 double precision floating point logical operation
21111 (define_expand "sse2_andv2df3"
21112   [(set (match_operand:V2DF 0 "register_operand" "")
21113         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
21114                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21115   "TARGET_SSE2"
21116   "")
21118 (define_insn "*sse2_andv2df3"
21119   [(set (match_operand:V2DF 0 "register_operand" "=x")
21120         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21121                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21122   "TARGET_SSE2
21123    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21124   "andpd\t{%2, %0|%0, %2}"
21125   [(set_attr "type" "sselog")
21126    (set_attr "mode" "V2DF")])
21128 (define_expand "sse2_nandv2df3"
21129   [(set (match_operand:V2DF 0 "register_operand" "")
21130         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
21131                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21132   "TARGET_SSE2"
21133   "")
21135 (define_insn "*sse2_nandv2df3"
21136   [(set (match_operand:V2DF 0 "register_operand" "=x")
21137         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
21138                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21139   "TARGET_SSE2"
21140   "andnpd\t{%2, %0|%0, %2}"
21141   [(set_attr "type" "sselog")
21142    (set_attr "mode" "V2DF")])
21144 (define_expand "sse2_iorv2df3"
21145   [(set (match_operand:V2DF 0 "register_operand" "")
21146         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
21147                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21148   "TARGET_SSE2"
21149   "")
21151 (define_insn "*sse2_iorv2df3"
21152   [(set (match_operand:V2DF 0 "register_operand" "=x")
21153         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21154                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21155   "TARGET_SSE2
21156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21157   "orpd\t{%2, %0|%0, %2}"
21158   [(set_attr "type" "sselog")
21159    (set_attr "mode" "V2DF")])
21161 (define_expand "sse2_xorv2df3"
21162   [(set (match_operand:V2DF 0 "register_operand" "")
21163         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
21164                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21165   "TARGET_SSE2"
21166   "")
21168 (define_insn "*sse2_xorv2df3"
21169   [(set (match_operand:V2DF 0 "register_operand" "=x")
21170         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21171                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21172   "TARGET_SSE2
21173    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21174   "xorpd\t{%2, %0|%0, %2}"
21175   [(set_attr "type" "sselog")
21176    (set_attr "mode" "V2DF")])
21178 ;; SSE2 integral logicals.  These patterns must always come after floating
21179 ;; point ones since we don't want compiler to use integer opcodes on floating
21180 ;; point SSE values to avoid matching of subregs in the match_operand.
21181 (define_insn "*sse2_andti3"
21182   [(set (match_operand:TI 0 "register_operand" "=x")
21183         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21184                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21185   "TARGET_SSE2
21186    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21187   "pand\t{%2, %0|%0, %2}"
21188   [(set_attr "type" "sselog")
21189    (set_attr "mode" "TI")])
21191 (define_insn "sse2_andv2di3"
21192   [(set (match_operand:V2DI 0 "register_operand" "=x")
21193         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21194                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21195   "TARGET_SSE2
21196    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21197   "pand\t{%2, %0|%0, %2}"
21198   [(set_attr "type" "sselog")
21199    (set_attr "mode" "TI")])
21201 (define_insn "*sse2_nandti3"
21202   [(set (match_operand:TI 0 "register_operand" "=x")
21203         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
21204                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21205   "TARGET_SSE2"
21206   "pandn\t{%2, %0|%0, %2}"
21207   [(set_attr "type" "sselog")
21208    (set_attr "mode" "TI")])
21210 (define_insn "sse2_nandv2di3"
21211   [(set (match_operand:V2DI 0 "register_operand" "=x")
21212         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
21213                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21214   "TARGET_SSE2
21215    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21216   "pandn\t{%2, %0|%0, %2}"
21217   [(set_attr "type" "sselog")
21218    (set_attr "mode" "TI")])
21220 (define_insn "*sse2_iorti3"
21221   [(set (match_operand:TI 0 "register_operand" "=x")
21222         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21223                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21224   "TARGET_SSE2
21225    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21226   "por\t{%2, %0|%0, %2}"
21227   [(set_attr "type" "sselog")
21228    (set_attr "mode" "TI")])
21230 (define_insn "sse2_iorv2di3"
21231   [(set (match_operand:V2DI 0 "register_operand" "=x")
21232         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21233                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21234   "TARGET_SSE2
21235    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21236   "por\t{%2, %0|%0, %2}"
21237   [(set_attr "type" "sselog")
21238    (set_attr "mode" "TI")])
21240 (define_insn "*sse2_xorti3"
21241   [(set (match_operand:TI 0 "register_operand" "=x")
21242         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21243                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21244   "TARGET_SSE2
21245    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21246   "pxor\t{%2, %0|%0, %2}"
21247   [(set_attr "type" "sselog")
21248    (set_attr "mode" "TI")])
21250 (define_insn "sse2_xorv2di3"
21251   [(set (match_operand:V2DI 0 "register_operand" "=x")
21252         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21253                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21254   "TARGET_SSE2
21255    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21256   "pxor\t{%2, %0|%0, %2}"
21257   [(set_attr "type" "sselog")
21258    (set_attr "mode" "TI")])
21260 ;; Use xor, but don't show input operands so they aren't live before
21261 ;; this insn.
21262 (define_insn "sse_clrv4sf"
21263   [(set (match_operand:V4SF 0 "register_operand" "=x")
21264         (match_operand:V4SF 1 "const0_operand" "X"))]
21265   "TARGET_SSE"
21267   if (get_attr_mode (insn) == MODE_TI)
21268     return "pxor\t{%0, %0|%0, %0}";
21269   else
21270     return "xorps\t{%0, %0|%0, %0}";
21272   [(set_attr "type" "sselog")
21273    (set_attr "memory" "none")
21274    (set (attr "mode")
21275         (if_then_else
21276            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21277                          (const_int 0))
21278                      (ne (symbol_ref "TARGET_SSE2")
21279                          (const_int 0)))
21280                 (eq (symbol_ref "optimize_size")
21281                     (const_int 0)))
21282          (const_string "TI")
21283          (const_string "V4SF")))])
21285 ;; Use xor, but don't show input operands so they aren't live before
21286 ;; this insn.
21287 (define_insn "sse_clrv2df"
21288   [(set (match_operand:V2DF 0 "register_operand" "=x")
21289         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21290   "TARGET_SSE2"
21291   "xorpd\t{%0, %0|%0, %0}"
21292   [(set_attr "type" "sselog")
21293    (set_attr "memory" "none")
21294    (set_attr "mode" "V4SF")])
21296 ;; SSE mask-generating compares
21298 (define_insn "maskcmpv4sf3"
21299   [(set (match_operand:V4SI 0 "register_operand" "=x")
21300         (match_operator:V4SI 3 "sse_comparison_operator"
21301                 [(match_operand:V4SF 1 "register_operand" "0")
21302                  (match_operand:V4SF 2 "register_operand" "x")]))]
21303   "TARGET_SSE"
21304   "cmp%D3ps\t{%2, %0|%0, %2}"
21305   [(set_attr "type" "ssecmp")
21306    (set_attr "mode" "V4SF")])
21308 (define_insn "maskncmpv4sf3"
21309   [(set (match_operand:V4SI 0 "register_operand" "=x")
21310         (not:V4SI
21311          (match_operator:V4SI 3 "sse_comparison_operator"
21312                 [(match_operand:V4SF 1 "register_operand" "0")
21313                  (match_operand:V4SF 2 "register_operand" "x")])))]
21314   "TARGET_SSE"
21316   if (GET_CODE (operands[3]) == UNORDERED)
21317     return "cmpordps\t{%2, %0|%0, %2}";
21318   else
21319     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21321   [(set_attr "type" "ssecmp")
21322    (set_attr "mode" "V4SF")])
21324 (define_insn "vmmaskcmpv4sf3"
21325   [(set (match_operand:V4SI 0 "register_operand" "=x")
21326         (vec_merge:V4SI
21327          (match_operator:V4SI 3 "sse_comparison_operator"
21328                 [(match_operand:V4SF 1 "register_operand" "0")
21329                  (match_operand:V4SF 2 "register_operand" "x")])
21330          (subreg:V4SI (match_dup 1) 0)
21331          (const_int 1)))]
21332   "TARGET_SSE"
21333   "cmp%D3ss\t{%2, %0|%0, %2}"
21334   [(set_attr "type" "ssecmp")
21335    (set_attr "mode" "SF")])
21337 (define_insn "vmmaskncmpv4sf3"
21338   [(set (match_operand:V4SI 0 "register_operand" "=x")
21339         (vec_merge:V4SI
21340          (not:V4SI
21341           (match_operator:V4SI 3 "sse_comparison_operator"
21342                 [(match_operand:V4SF 1 "register_operand" "0")
21343                  (match_operand:V4SF 2 "register_operand" "x")]))
21344          (subreg:V4SI (match_dup 1) 0)
21345          (const_int 1)))]
21346   "TARGET_SSE"
21348   if (GET_CODE (operands[3]) == UNORDERED)
21349     return "cmpordss\t{%2, %0|%0, %2}";
21350   else
21351     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21353   [(set_attr "type" "ssecmp")
21354    (set_attr "mode" "SF")])
21356 (define_insn "sse_comi"
21357   [(set (reg:CCFP FLAGS_REG)
21358         (compare:CCFP (vec_select:SF
21359                        (match_operand:V4SF 0 "register_operand" "x")
21360                        (parallel [(const_int 0)]))
21361                       (vec_select:SF
21362                        (match_operand:V4SF 1 "register_operand" "x")
21363                        (parallel [(const_int 0)]))))]
21364   "TARGET_SSE"
21365   "comiss\t{%1, %0|%0, %1}"
21366   [(set_attr "type" "ssecomi")
21367    (set_attr "mode" "SF")])
21369 (define_insn "sse_ucomi"
21370   [(set (reg:CCFPU FLAGS_REG)
21371         (compare:CCFPU (vec_select:SF
21372                         (match_operand:V4SF 0 "register_operand" "x")
21373                         (parallel [(const_int 0)]))
21374                        (vec_select:SF
21375                         (match_operand:V4SF 1 "register_operand" "x")
21376                         (parallel [(const_int 0)]))))]
21377   "TARGET_SSE"
21378   "ucomiss\t{%1, %0|%0, %1}"
21379   [(set_attr "type" "ssecomi")
21380    (set_attr "mode" "SF")])
21383 ;; SSE unpack
21385 (define_insn "sse_unpckhps"
21386   [(set (match_operand:V4SF 0 "register_operand" "=x")
21387         (vec_merge:V4SF
21388          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21389                           (parallel [(const_int 2)
21390                                      (const_int 0)
21391                                      (const_int 3)
21392                                      (const_int 1)]))
21393          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21394                           (parallel [(const_int 0)
21395                                      (const_int 2)
21396                                      (const_int 1)
21397                                      (const_int 3)]))
21398          (const_int 5)))]
21399   "TARGET_SSE"
21400   "unpckhps\t{%2, %0|%0, %2}"
21401   [(set_attr "type" "ssecvt")
21402    (set_attr "mode" "V4SF")])
21404 (define_insn "sse_unpcklps"
21405   [(set (match_operand:V4SF 0 "register_operand" "=x")
21406         (vec_merge:V4SF
21407          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21408                           (parallel [(const_int 0)
21409                                      (const_int 2)
21410                                      (const_int 1)
21411                                      (const_int 3)]))
21412          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21413                           (parallel [(const_int 2)
21414                                      (const_int 0)
21415                                      (const_int 3)
21416                                      (const_int 1)]))
21417          (const_int 5)))]
21418   "TARGET_SSE"
21419   "unpcklps\t{%2, %0|%0, %2}"
21420   [(set_attr "type" "ssecvt")
21421    (set_attr "mode" "V4SF")])
21424 ;; SSE min/max
21426 (define_insn "smaxv4sf3"
21427   [(set (match_operand:V4SF 0 "register_operand" "=x")
21428         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21429                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21430   "TARGET_SSE"
21431   "maxps\t{%2, %0|%0, %2}"
21432   [(set_attr "type" "sse")
21433    (set_attr "mode" "V4SF")])
21435 (define_insn "vmsmaxv4sf3"
21436   [(set (match_operand:V4SF 0 "register_operand" "=x")
21437         (vec_merge:V4SF
21438          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21439                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21440          (match_dup 1)
21441          (const_int 1)))]
21442   "TARGET_SSE"
21443   "maxss\t{%2, %0|%0, %2}"
21444   [(set_attr "type" "sse")
21445    (set_attr "mode" "SF")])
21447 (define_insn "sminv4sf3"
21448   [(set (match_operand:V4SF 0 "register_operand" "=x")
21449         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21450                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21451   "TARGET_SSE"
21452   "minps\t{%2, %0|%0, %2}"
21453   [(set_attr "type" "sse")
21454    (set_attr "mode" "V4SF")])
21456 (define_insn "vmsminv4sf3"
21457   [(set (match_operand:V4SF 0 "register_operand" "=x")
21458         (vec_merge:V4SF
21459          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21460                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21461          (match_dup 1)
21462          (const_int 1)))]
21463   "TARGET_SSE"
21464   "minss\t{%2, %0|%0, %2}"
21465   [(set_attr "type" "sse")
21466    (set_attr "mode" "SF")])
21468 ;; SSE <-> integer/MMX conversions
21470 (define_insn "cvtpi2ps"
21471   [(set (match_operand:V4SF 0 "register_operand" "=x")
21472         (vec_merge:V4SF
21473          (match_operand:V4SF 1 "register_operand" "0")
21474          (vec_duplicate:V4SF
21475           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21476          (const_int 12)))]
21477   "TARGET_SSE"
21478   "cvtpi2ps\t{%2, %0|%0, %2}"
21479   [(set_attr "type" "ssecvt")
21480    (set_attr "mode" "V4SF")])
21482 (define_insn "cvtps2pi"
21483   [(set (match_operand:V2SI 0 "register_operand" "=y")
21484         (vec_select:V2SI
21485          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21486          (parallel [(const_int 0) (const_int 1)])))]
21487   "TARGET_SSE"
21488   "cvtps2pi\t{%1, %0|%0, %1}"
21489   [(set_attr "type" "ssecvt")
21490    (set_attr "mode" "V4SF")])
21492 (define_insn "cvttps2pi"
21493   [(set (match_operand:V2SI 0 "register_operand" "=y")
21494         (vec_select:V2SI
21495          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21496                       UNSPEC_FIX)
21497          (parallel [(const_int 0) (const_int 1)])))]
21498   "TARGET_SSE"
21499   "cvttps2pi\t{%1, %0|%0, %1}"
21500   [(set_attr "type" "ssecvt")
21501    (set_attr "mode" "SF")])
21503 (define_insn "cvtsi2ss"
21504   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21505         (vec_merge:V4SF
21506          (match_operand:V4SF 1 "register_operand" "0,0")
21507          (vec_duplicate:V4SF
21508           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21509          (const_int 14)))]
21510   "TARGET_SSE"
21511   "cvtsi2ss\t{%2, %0|%0, %2}"
21512   [(set_attr "type" "sseicvt")
21513    (set_attr "athlon_decode" "vector,double")
21514    (set_attr "mode" "SF")])
21516 (define_insn "cvtsi2ssq"
21517   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21518         (vec_merge:V4SF
21519          (match_operand:V4SF 1 "register_operand" "0,0")
21520          (vec_duplicate:V4SF
21521           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21522          (const_int 14)))]
21523   "TARGET_SSE && TARGET_64BIT"
21524   "cvtsi2ssq\t{%2, %0|%0, %2}"
21525   [(set_attr "type" "sseicvt")
21526    (set_attr "athlon_decode" "vector,double")
21527    (set_attr "mode" "SF")])
21529 (define_insn "cvtss2si"
21530   [(set (match_operand:SI 0 "register_operand" "=r,r")
21531         (vec_select:SI
21532          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21533          (parallel [(const_int 0)])))]
21534   "TARGET_SSE"
21535   "cvtss2si\t{%1, %0|%0, %1}"
21536   [(set_attr "type" "sseicvt")
21537    (set_attr "athlon_decode" "double,vector")
21538    (set_attr "mode" "SI")])
21540 (define_insn "cvtss2siq"
21541   [(set (match_operand:DI 0 "register_operand" "=r,r")
21542         (vec_select:DI
21543          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21544          (parallel [(const_int 0)])))]
21545   "TARGET_SSE"
21546   "cvtss2siq\t{%1, %0|%0, %1}"
21547   [(set_attr "type" "sseicvt")
21548    (set_attr "athlon_decode" "double,vector")
21549    (set_attr "mode" "DI")])
21551 (define_insn "cvttss2si"
21552   [(set (match_operand:SI 0 "register_operand" "=r,r")
21553         (vec_select:SI
21554          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21555                       UNSPEC_FIX)
21556          (parallel [(const_int 0)])))]
21557   "TARGET_SSE"
21558   "cvttss2si\t{%1, %0|%0, %1}"
21559   [(set_attr "type" "sseicvt")
21560    (set_attr "mode" "SF")
21561    (set_attr "athlon_decode" "double,vector")])
21563 (define_insn "cvttss2siq"
21564   [(set (match_operand:DI 0 "register_operand" "=r,r")
21565         (vec_select:DI
21566          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21567                       UNSPEC_FIX)
21568          (parallel [(const_int 0)])))]
21569   "TARGET_SSE && TARGET_64BIT"
21570   "cvttss2siq\t{%1, %0|%0, %1}"
21571   [(set_attr "type" "sseicvt")
21572    (set_attr "mode" "SF")
21573    (set_attr "athlon_decode" "double,vector")])
21576 ;; MMX insns
21578 ;; MMX arithmetic
21580 (define_insn "addv8qi3"
21581   [(set (match_operand:V8QI 0 "register_operand" "=y")
21582         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21583                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21584   "TARGET_MMX"
21585   "paddb\t{%2, %0|%0, %2}"
21586   [(set_attr "type" "mmxadd")
21587    (set_attr "mode" "DI")])
21589 (define_insn "addv4hi3"
21590   [(set (match_operand:V4HI 0 "register_operand" "=y")
21591         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21592                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21593   "TARGET_MMX"
21594   "paddw\t{%2, %0|%0, %2}"
21595   [(set_attr "type" "mmxadd")
21596    (set_attr "mode" "DI")])
21598 (define_insn "addv2si3"
21599   [(set (match_operand:V2SI 0 "register_operand" "=y")
21600         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21601                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21602   "TARGET_MMX"
21603   "paddd\t{%2, %0|%0, %2}"
21604   [(set_attr "type" "mmxadd")
21605    (set_attr "mode" "DI")])
21607 (define_insn "mmx_adddi3"
21608   [(set (match_operand:DI 0 "register_operand" "=y")
21609         (unspec:DI
21610          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21611                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21612          UNSPEC_NOP))]
21613   "TARGET_MMX"
21614   "paddq\t{%2, %0|%0, %2}"
21615   [(set_attr "type" "mmxadd")
21616    (set_attr "mode" "DI")])
21618 (define_insn "ssaddv8qi3"
21619   [(set (match_operand:V8QI 0 "register_operand" "=y")
21620         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21621                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21622   "TARGET_MMX"
21623   "paddsb\t{%2, %0|%0, %2}"
21624   [(set_attr "type" "mmxadd")
21625    (set_attr "mode" "DI")])
21627 (define_insn "ssaddv4hi3"
21628   [(set (match_operand:V4HI 0 "register_operand" "=y")
21629         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21630                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21631   "TARGET_MMX"
21632   "paddsw\t{%2, %0|%0, %2}"
21633   [(set_attr "type" "mmxadd")
21634    (set_attr "mode" "DI")])
21636 (define_insn "usaddv8qi3"
21637   [(set (match_operand:V8QI 0 "register_operand" "=y")
21638         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21639                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21640   "TARGET_MMX"
21641   "paddusb\t{%2, %0|%0, %2}"
21642   [(set_attr "type" "mmxadd")
21643    (set_attr "mode" "DI")])
21645 (define_insn "usaddv4hi3"
21646   [(set (match_operand:V4HI 0 "register_operand" "=y")
21647         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21648                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21649   "TARGET_MMX"
21650   "paddusw\t{%2, %0|%0, %2}"
21651   [(set_attr "type" "mmxadd")
21652    (set_attr "mode" "DI")])
21654 (define_insn "subv8qi3"
21655   [(set (match_operand:V8QI 0 "register_operand" "=y")
21656         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21657                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21658   "TARGET_MMX"
21659   "psubb\t{%2, %0|%0, %2}"
21660   [(set_attr "type" "mmxadd")
21661    (set_attr "mode" "DI")])
21663 (define_insn "subv4hi3"
21664   [(set (match_operand:V4HI 0 "register_operand" "=y")
21665         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21666                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21667   "TARGET_MMX"
21668   "psubw\t{%2, %0|%0, %2}"
21669   [(set_attr "type" "mmxadd")
21670    (set_attr "mode" "DI")])
21672 (define_insn "subv2si3"
21673   [(set (match_operand:V2SI 0 "register_operand" "=y")
21674         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21675                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21676   "TARGET_MMX"
21677   "psubd\t{%2, %0|%0, %2}"
21678   [(set_attr "type" "mmxadd")
21679    (set_attr "mode" "DI")])
21681 (define_insn "mmx_subdi3"
21682   [(set (match_operand:DI 0 "register_operand" "=y")
21683         (unspec:DI
21684          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21685                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21686          UNSPEC_NOP))]
21687   "TARGET_MMX"
21688   "psubq\t{%2, %0|%0, %2}"
21689   [(set_attr "type" "mmxadd")
21690    (set_attr "mode" "DI")])
21692 (define_insn "sssubv8qi3"
21693   [(set (match_operand:V8QI 0 "register_operand" "=y")
21694         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21695                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21696   "TARGET_MMX"
21697   "psubsb\t{%2, %0|%0, %2}"
21698   [(set_attr "type" "mmxadd")
21699    (set_attr "mode" "DI")])
21701 (define_insn "sssubv4hi3"
21702   [(set (match_operand:V4HI 0 "register_operand" "=y")
21703         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21704                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21705   "TARGET_MMX"
21706   "psubsw\t{%2, %0|%0, %2}"
21707   [(set_attr "type" "mmxadd")
21708    (set_attr "mode" "DI")])
21710 (define_insn "ussubv8qi3"
21711   [(set (match_operand:V8QI 0 "register_operand" "=y")
21712         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21713                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21714   "TARGET_MMX"
21715   "psubusb\t{%2, %0|%0, %2}"
21716   [(set_attr "type" "mmxadd")
21717    (set_attr "mode" "DI")])
21719 (define_insn "ussubv4hi3"
21720   [(set (match_operand:V4HI 0 "register_operand" "=y")
21721         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21722                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21723   "TARGET_MMX"
21724   "psubusw\t{%2, %0|%0, %2}"
21725   [(set_attr "type" "mmxadd")
21726    (set_attr "mode" "DI")])
21728 (define_insn "mulv4hi3"
21729   [(set (match_operand:V4HI 0 "register_operand" "=y")
21730         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21731                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21732   "TARGET_MMX"
21733   "pmullw\t{%2, %0|%0, %2}"
21734   [(set_attr "type" "mmxmul")
21735    (set_attr "mode" "DI")])
21737 (define_insn "smulv4hi3_highpart"
21738   [(set (match_operand:V4HI 0 "register_operand" "=y")
21739         (truncate:V4HI
21740          (lshiftrt:V4SI
21741           (mult:V4SI (sign_extend:V4SI
21742                       (match_operand:V4HI 1 "register_operand" "0"))
21743                      (sign_extend:V4SI
21744                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21745           (const_int 16))))]
21746   "TARGET_MMX"
21747   "pmulhw\t{%2, %0|%0, %2}"
21748   [(set_attr "type" "mmxmul")
21749    (set_attr "mode" "DI")])
21751 (define_insn "umulv4hi3_highpart"
21752   [(set (match_operand:V4HI 0 "register_operand" "=y")
21753         (truncate:V4HI
21754          (lshiftrt:V4SI
21755           (mult:V4SI (zero_extend:V4SI
21756                       (match_operand:V4HI 1 "register_operand" "0"))
21757                      (zero_extend:V4SI
21758                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21759           (const_int 16))))]
21760   "TARGET_SSE || TARGET_3DNOW_A"
21761   "pmulhuw\t{%2, %0|%0, %2}"
21762   [(set_attr "type" "mmxmul")
21763    (set_attr "mode" "DI")])
21765 (define_insn "mmx_pmaddwd"
21766   [(set (match_operand:V2SI 0 "register_operand" "=y")
21767         (plus:V2SI
21768          (mult:V2SI
21769           (sign_extend:V2SI
21770            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21771                             (parallel [(const_int 0) (const_int 2)])))
21772           (sign_extend:V2SI
21773            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21774                             (parallel [(const_int 0) (const_int 2)]))))
21775          (mult:V2SI
21776           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21777                                              (parallel [(const_int 1)
21778                                                         (const_int 3)])))
21779           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21780                                              (parallel [(const_int 1)
21781                                                         (const_int 3)]))))))]
21782   "TARGET_MMX"
21783   "pmaddwd\t{%2, %0|%0, %2}"
21784   [(set_attr "type" "mmxmul")
21785    (set_attr "mode" "DI")])
21788 ;; MMX logical operations
21789 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21790 ;; normal code that also wants to use the FPU from getting broken.
21791 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21792 (define_insn "mmx_iordi3"
21793   [(set (match_operand:DI 0 "register_operand" "=y")
21794         (unspec:DI
21795          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21796                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21797          UNSPEC_NOP))]
21798   "TARGET_MMX"
21799   "por\t{%2, %0|%0, %2}"
21800   [(set_attr "type" "mmxadd")
21801    (set_attr "mode" "DI")])
21803 (define_insn "mmx_xordi3"
21804   [(set (match_operand:DI 0 "register_operand" "=y")
21805         (unspec:DI
21806          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21807                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21808          UNSPEC_NOP))]
21809   "TARGET_MMX"
21810   "pxor\t{%2, %0|%0, %2}"
21811   [(set_attr "type" "mmxadd")
21812    (set_attr "mode" "DI")
21813    (set_attr "memory" "none")])
21815 ;; Same as pxor, but don't show input operands so that we don't think
21816 ;; they are live.
21817 (define_insn "mmx_clrdi"
21818   [(set (match_operand:DI 0 "register_operand" "=y")
21819         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21820   "TARGET_MMX"
21821   "pxor\t{%0, %0|%0, %0}"
21822   [(set_attr "type" "mmxadd")
21823    (set_attr "mode" "DI")
21824    (set_attr "memory" "none")])
21826 (define_insn "mmx_anddi3"
21827   [(set (match_operand:DI 0 "register_operand" "=y")
21828         (unspec:DI
21829          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21830                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21831          UNSPEC_NOP))]
21832   "TARGET_MMX"
21833   "pand\t{%2, %0|%0, %2}"
21834   [(set_attr "type" "mmxadd")
21835    (set_attr "mode" "DI")])
21837 (define_insn "mmx_nanddi3"
21838   [(set (match_operand:DI 0 "register_operand" "=y")
21839         (unspec:DI
21840          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21841                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21842          UNSPEC_NOP))]
21843   "TARGET_MMX"
21844   "pandn\t{%2, %0|%0, %2}"
21845   [(set_attr "type" "mmxadd")
21846    (set_attr "mode" "DI")])
21849 ;; MMX unsigned averages/sum of absolute differences
21851 (define_insn "mmx_uavgv8qi3"
21852   [(set (match_operand:V8QI 0 "register_operand" "=y")
21853         (ashiftrt:V8QI
21854          (plus:V8QI (plus:V8QI
21855                      (match_operand:V8QI 1 "register_operand" "0")
21856                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21857                     (const_vector:V8QI [(const_int 1)
21858                                         (const_int 1)
21859                                         (const_int 1)
21860                                         (const_int 1)
21861                                         (const_int 1)
21862                                         (const_int 1)
21863                                         (const_int 1)
21864                                         (const_int 1)]))
21865          (const_int 1)))]
21866   "TARGET_SSE || TARGET_3DNOW_A"
21867   "pavgb\t{%2, %0|%0, %2}"
21868   [(set_attr "type" "mmxshft")
21869    (set_attr "mode" "DI")])
21871 (define_insn "mmx_uavgv4hi3"
21872   [(set (match_operand:V4HI 0 "register_operand" "=y")
21873         (ashiftrt:V4HI
21874          (plus:V4HI (plus:V4HI
21875                      (match_operand:V4HI 1 "register_operand" "0")
21876                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21877                     (const_vector:V4HI [(const_int 1)
21878                                         (const_int 1)
21879                                         (const_int 1)
21880                                         (const_int 1)]))
21881          (const_int 1)))]
21882   "TARGET_SSE || TARGET_3DNOW_A"
21883   "pavgw\t{%2, %0|%0, %2}"
21884   [(set_attr "type" "mmxshft")
21885    (set_attr "mode" "DI")])
21887 (define_insn "mmx_psadbw"
21888   [(set (match_operand:DI 0 "register_operand" "=y")
21889         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21890                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21891                    UNSPEC_PSADBW))]
21892   "TARGET_SSE || TARGET_3DNOW_A"
21893   "psadbw\t{%2, %0|%0, %2}"
21894   [(set_attr "type" "mmxshft")
21895    (set_attr "mode" "DI")])
21898 ;; MMX insert/extract/shuffle
21900 (define_insn "mmx_pinsrw"
21901   [(set (match_operand:V4HI 0 "register_operand" "=y")
21902         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21903                         (vec_duplicate:V4HI
21904                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21905                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21906   "TARGET_SSE || TARGET_3DNOW_A"
21907   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21908   [(set_attr "type" "mmxcvt")
21909    (set_attr "mode" "DI")])
21911 (define_insn "mmx_pextrw"
21912   [(set (match_operand:SI 0 "register_operand" "=r")
21913         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21914                                        (parallel
21915                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21916   "TARGET_SSE || TARGET_3DNOW_A"
21917   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21918   [(set_attr "type" "mmxcvt")
21919    (set_attr "mode" "DI")])
21921 (define_insn "mmx_pshufw"
21922   [(set (match_operand:V4HI 0 "register_operand" "=y")
21923         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21924                       (match_operand:SI 2 "immediate_operand" "i")]
21925                      UNSPEC_SHUFFLE))]
21926   "TARGET_SSE || TARGET_3DNOW_A"
21927   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21928   [(set_attr "type" "mmxcvt")
21929    (set_attr "mode" "DI")])
21932 ;; MMX mask-generating comparisons
21934 (define_insn "eqv8qi3"
21935   [(set (match_operand:V8QI 0 "register_operand" "=y")
21936         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21937                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21938   "TARGET_MMX"
21939   "pcmpeqb\t{%2, %0|%0, %2}"
21940   [(set_attr "type" "mmxcmp")
21941    (set_attr "mode" "DI")])
21943 (define_insn "eqv4hi3"
21944   [(set (match_operand:V4HI 0 "register_operand" "=y")
21945         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21946                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21947   "TARGET_MMX"
21948   "pcmpeqw\t{%2, %0|%0, %2}"
21949   [(set_attr "type" "mmxcmp")
21950    (set_attr "mode" "DI")])
21952 (define_insn "eqv2si3"
21953   [(set (match_operand:V2SI 0 "register_operand" "=y")
21954         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21955                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21956   "TARGET_MMX"
21957   "pcmpeqd\t{%2, %0|%0, %2}"
21958   [(set_attr "type" "mmxcmp")
21959    (set_attr "mode" "DI")])
21961 (define_insn "gtv8qi3"
21962   [(set (match_operand:V8QI 0 "register_operand" "=y")
21963         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21964                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21965   "TARGET_MMX"
21966   "pcmpgtb\t{%2, %0|%0, %2}"
21967   [(set_attr "type" "mmxcmp")
21968    (set_attr "mode" "DI")])
21970 (define_insn "gtv4hi3"
21971   [(set (match_operand:V4HI 0 "register_operand" "=y")
21972         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21973                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21974   "TARGET_MMX"
21975   "pcmpgtw\t{%2, %0|%0, %2}"
21976   [(set_attr "type" "mmxcmp")
21977    (set_attr "mode" "DI")])
21979 (define_insn "gtv2si3"
21980   [(set (match_operand:V2SI 0 "register_operand" "=y")
21981         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21982                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21983   "TARGET_MMX"
21984   "pcmpgtd\t{%2, %0|%0, %2}"
21985   [(set_attr "type" "mmxcmp")
21986    (set_attr "mode" "DI")])
21989 ;; MMX max/min insns
21991 (define_insn "umaxv8qi3"
21992   [(set (match_operand:V8QI 0 "register_operand" "=y")
21993         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21994                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21995   "TARGET_SSE || TARGET_3DNOW_A"
21996   "pmaxub\t{%2, %0|%0, %2}"
21997   [(set_attr "type" "mmxadd")
21998    (set_attr "mode" "DI")])
22000 (define_insn "smaxv4hi3"
22001   [(set (match_operand:V4HI 0 "register_operand" "=y")
22002         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
22003                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22004   "TARGET_SSE || TARGET_3DNOW_A"
22005   "pmaxsw\t{%2, %0|%0, %2}"
22006   [(set_attr "type" "mmxadd")
22007    (set_attr "mode" "DI")])
22009 (define_insn "uminv8qi3"
22010   [(set (match_operand:V8QI 0 "register_operand" "=y")
22011         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
22012                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22013   "TARGET_SSE || TARGET_3DNOW_A"
22014   "pminub\t{%2, %0|%0, %2}"
22015   [(set_attr "type" "mmxadd")
22016    (set_attr "mode" "DI")])
22018 (define_insn "sminv4hi3"
22019   [(set (match_operand:V4HI 0 "register_operand" "=y")
22020         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
22021                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22022   "TARGET_SSE || TARGET_3DNOW_A"
22023   "pminsw\t{%2, %0|%0, %2}"
22024   [(set_attr "type" "mmxadd")
22025    (set_attr "mode" "DI")])
22028 ;; MMX shifts
22030 (define_insn "ashrv4hi3"
22031   [(set (match_operand:V4HI 0 "register_operand" "=y")
22032         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22033                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22034   "TARGET_MMX"
22035   "psraw\t{%2, %0|%0, %2}"
22036   [(set_attr "type" "mmxshft")
22037    (set_attr "mode" "DI")])
22039 (define_insn "ashrv2si3"
22040   [(set (match_operand:V2SI 0 "register_operand" "=y")
22041         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22042                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22043   "TARGET_MMX"
22044   "psrad\t{%2, %0|%0, %2}"
22045   [(set_attr "type" "mmxshft")
22046    (set_attr "mode" "DI")])
22048 (define_insn "lshrv4hi3"
22049   [(set (match_operand:V4HI 0 "register_operand" "=y")
22050         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22051                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22052   "TARGET_MMX"
22053   "psrlw\t{%2, %0|%0, %2}"
22054   [(set_attr "type" "mmxshft")
22055    (set_attr "mode" "DI")])
22057 (define_insn "lshrv2si3"
22058   [(set (match_operand:V2SI 0 "register_operand" "=y")
22059         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22060                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22061   "TARGET_MMX"
22062   "psrld\t{%2, %0|%0, %2}"
22063   [(set_attr "type" "mmxshft")
22064    (set_attr "mode" "DI")])
22066 ;; See logical MMX insns.
22067 (define_insn "mmx_lshrdi3"
22068   [(set (match_operand:DI 0 "register_operand" "=y")
22069         (unspec:DI
22070           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
22071                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
22072           UNSPEC_NOP))]
22073   "TARGET_MMX"
22074   "psrlq\t{%2, %0|%0, %2}"
22075   [(set_attr "type" "mmxshft")
22076    (set_attr "mode" "DI")])
22078 (define_insn "ashlv4hi3"
22079   [(set (match_operand:V4HI 0 "register_operand" "=y")
22080         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
22081                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22082   "TARGET_MMX"
22083   "psllw\t{%2, %0|%0, %2}"
22084   [(set_attr "type" "mmxshft")
22085    (set_attr "mode" "DI")])
22087 (define_insn "ashlv2si3"
22088   [(set (match_operand:V2SI 0 "register_operand" "=y")
22089         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
22090                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22091   "TARGET_MMX"
22092   "pslld\t{%2, %0|%0, %2}"
22093   [(set_attr "type" "mmxshft")
22094    (set_attr "mode" "DI")])
22096 ;; See logical MMX insns.
22097 (define_insn "mmx_ashldi3"
22098   [(set (match_operand:DI 0 "register_operand" "=y")
22099         (unspec:DI
22100          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
22101                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
22102          UNSPEC_NOP))]
22103   "TARGET_MMX"
22104   "psllq\t{%2, %0|%0, %2}"
22105   [(set_attr "type" "mmxshft")
22106    (set_attr "mode" "DI")])
22109 ;; MMX pack/unpack insns.
22111 (define_insn "mmx_packsswb"
22112   [(set (match_operand:V8QI 0 "register_operand" "=y")
22113         (vec_concat:V8QI
22114          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22115          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22116   "TARGET_MMX"
22117   "packsswb\t{%2, %0|%0, %2}"
22118   [(set_attr "type" "mmxshft")
22119    (set_attr "mode" "DI")])
22121 (define_insn "mmx_packssdw"
22122   [(set (match_operand:V4HI 0 "register_operand" "=y")
22123         (vec_concat:V4HI
22124          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
22125          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
22126   "TARGET_MMX"
22127   "packssdw\t{%2, %0|%0, %2}"
22128   [(set_attr "type" "mmxshft")
22129    (set_attr "mode" "DI")])
22131 (define_insn "mmx_packuswb"
22132   [(set (match_operand:V8QI 0 "register_operand" "=y")
22133         (vec_concat:V8QI
22134          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22135          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22136   "TARGET_MMX"
22137   "packuswb\t{%2, %0|%0, %2}"
22138   [(set_attr "type" "mmxshft")
22139    (set_attr "mode" "DI")])
22141 (define_insn "mmx_punpckhbw"
22142   [(set (match_operand:V8QI 0 "register_operand" "=y")
22143         (vec_merge:V8QI
22144          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22145                           (parallel [(const_int 4)
22146                                      (const_int 0)
22147                                      (const_int 5)
22148                                      (const_int 1)
22149                                      (const_int 6)
22150                                      (const_int 2)
22151                                      (const_int 7)
22152                                      (const_int 3)]))
22153          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22154                           (parallel [(const_int 0)
22155                                      (const_int 4)
22156                                      (const_int 1)
22157                                      (const_int 5)
22158                                      (const_int 2)
22159                                      (const_int 6)
22160                                      (const_int 3)
22161                                      (const_int 7)]))
22162          (const_int 85)))]
22163   "TARGET_MMX"
22164   "punpckhbw\t{%2, %0|%0, %2}"
22165   [(set_attr "type" "mmxcvt")
22166    (set_attr "mode" "DI")])
22168 (define_insn "mmx_punpckhwd"
22169   [(set (match_operand:V4HI 0 "register_operand" "=y")
22170         (vec_merge:V4HI
22171          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22172                           (parallel [(const_int 0)
22173                                      (const_int 2)
22174                                      (const_int 1)
22175                                      (const_int 3)]))
22176          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22177                           (parallel [(const_int 2)
22178                                      (const_int 0)
22179                                      (const_int 3)
22180                                      (const_int 1)]))
22181          (const_int 5)))]
22182   "TARGET_MMX"
22183   "punpckhwd\t{%2, %0|%0, %2}"
22184   [(set_attr "type" "mmxcvt")
22185    (set_attr "mode" "DI")])
22187 (define_insn "mmx_punpckhdq"
22188   [(set (match_operand:V2SI 0 "register_operand" "=y")
22189         (vec_merge:V2SI
22190          (match_operand:V2SI 1 "register_operand" "0")
22191          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
22192                           (parallel [(const_int 1)
22193                                      (const_int 0)]))
22194          (const_int 1)))]
22195   "TARGET_MMX"
22196   "punpckhdq\t{%2, %0|%0, %2}"
22197   [(set_attr "type" "mmxcvt")
22198    (set_attr "mode" "DI")])
22200 (define_insn "mmx_punpcklbw"
22201   [(set (match_operand:V8QI 0 "register_operand" "=y")
22202         (vec_merge:V8QI
22203          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22204                           (parallel [(const_int 0)
22205                                      (const_int 4)
22206                                      (const_int 1)
22207                                      (const_int 5)
22208                                      (const_int 2)
22209                                      (const_int 6)
22210                                      (const_int 3)
22211                                      (const_int 7)]))
22212          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22213                           (parallel [(const_int 4)
22214                                      (const_int 0)
22215                                      (const_int 5)
22216                                      (const_int 1)
22217                                      (const_int 6)
22218                                      (const_int 2)
22219                                      (const_int 7)
22220                                      (const_int 3)]))
22221          (const_int 85)))]
22222   "TARGET_MMX"
22223   "punpcklbw\t{%2, %0|%0, %2}"
22224   [(set_attr "type" "mmxcvt")
22225    (set_attr "mode" "DI")])
22227 (define_insn "mmx_punpcklwd"
22228   [(set (match_operand:V4HI 0 "register_operand" "=y")
22229         (vec_merge:V4HI
22230          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22231                           (parallel [(const_int 2)
22232                                      (const_int 0)
22233                                      (const_int 3)
22234                                      (const_int 1)]))
22235          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22236                           (parallel [(const_int 0)
22237                                      (const_int 2)
22238                                      (const_int 1)
22239                                      (const_int 3)]))
22240          (const_int 5)))]
22241   "TARGET_MMX"
22242   "punpcklwd\t{%2, %0|%0, %2}"
22243   [(set_attr "type" "mmxcvt")
22244    (set_attr "mode" "DI")])
22246 (define_insn "mmx_punpckldq"
22247   [(set (match_operand:V2SI 0 "register_operand" "=y")
22248         (vec_merge:V2SI
22249          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22250                            (parallel [(const_int 1)
22251                                       (const_int 0)]))
22252          (match_operand:V2SI 2 "register_operand" "y")
22253          (const_int 1)))]
22254   "TARGET_MMX"
22255   "punpckldq\t{%2, %0|%0, %2}"
22256   [(set_attr "type" "mmxcvt")
22257    (set_attr "mode" "DI")])
22260 ;; Miscellaneous stuff
22262 (define_insn "emms"
22263   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22264    (clobber (reg:XF 8))
22265    (clobber (reg:XF 9))
22266    (clobber (reg:XF 10))
22267    (clobber (reg:XF 11))
22268    (clobber (reg:XF 12))
22269    (clobber (reg:XF 13))
22270    (clobber (reg:XF 14))
22271    (clobber (reg:XF 15))
22272    (clobber (reg:DI 29))
22273    (clobber (reg:DI 30))
22274    (clobber (reg:DI 31))
22275    (clobber (reg:DI 32))
22276    (clobber (reg:DI 33))
22277    (clobber (reg:DI 34))
22278    (clobber (reg:DI 35))
22279    (clobber (reg:DI 36))]
22280   "TARGET_MMX"
22281   "emms"
22282   [(set_attr "type" "mmx")
22283    (set_attr "memory" "unknown")])
22285 (define_insn "ldmxcsr"
22286   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22287                     UNSPECV_LDMXCSR)]
22288   "TARGET_SSE"
22289   "ldmxcsr\t%0"
22290   [(set_attr "type" "sse")
22291    (set_attr "memory" "load")])
22293 (define_insn "stmxcsr"
22294   [(set (match_operand:SI 0 "memory_operand" "=m")
22295         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22296   "TARGET_SSE"
22297   "stmxcsr\t%0"
22298   [(set_attr "type" "sse")
22299    (set_attr "memory" "store")])
22301 (define_expand "sfence"
22302   [(set (match_dup 0)
22303         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22304   "TARGET_SSE || TARGET_3DNOW_A"
22306   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22307   MEM_VOLATILE_P (operands[0]) = 1;
22310 (define_insn "*sfence_insn"
22311   [(set (match_operand:BLK 0 "" "")
22312         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22313   "TARGET_SSE || TARGET_3DNOW_A"
22314   "sfence"
22315   [(set_attr "type" "sse")
22316    (set_attr "memory" "unknown")])
22318 (define_expand "sse_prologue_save"
22319   [(parallel [(set (match_operand:BLK 0 "" "")
22320                    (unspec:BLK [(reg:DI 21)
22321                                 (reg:DI 22)
22322                                 (reg:DI 23)
22323                                 (reg:DI 24)
22324                                 (reg:DI 25)
22325                                 (reg:DI 26)
22326                                 (reg:DI 27)
22327                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22328               (use (match_operand:DI 1 "register_operand" ""))
22329               (use (match_operand:DI 2 "immediate_operand" ""))
22330               (use (label_ref:DI (match_operand 3 "" "")))])]
22331   "TARGET_64BIT"
22332   "")
22334 (define_insn "*sse_prologue_save_insn"
22335   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22336                           (match_operand:DI 4 "const_int_operand" "n")))
22337         (unspec:BLK [(reg:DI 21)
22338                      (reg:DI 22)
22339                      (reg:DI 23)
22340                      (reg:DI 24)
22341                      (reg:DI 25)
22342                      (reg:DI 26)
22343                      (reg:DI 27)
22344                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22345    (use (match_operand:DI 1 "register_operand" "r"))
22346    (use (match_operand:DI 2 "const_int_operand" "i"))
22347    (use (label_ref:DI (match_operand 3 "" "X")))]
22348   "TARGET_64BIT
22349    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22350    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22351   "*
22353   int i;
22354   operands[0] = gen_rtx_MEM (Pmode,
22355                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22356   output_asm_insn (\"jmp\\t%A1\", operands);
22357   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22358     {
22359       operands[4] = adjust_address (operands[0], DImode, i*16);
22360       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22361       PUT_MODE (operands[4], TImode);
22362       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22363         output_asm_insn (\"rex\", operands);
22364       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22365     }
22366   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22367                              CODE_LABEL_NUMBER (operands[3]));
22368   RET;
22370   "
22371   [(set_attr "type" "other")
22372    (set_attr "length_immediate" "0")
22373    (set_attr "length_address" "0")
22374    (set_attr "length" "135")
22375    (set_attr "memory" "store")
22376    (set_attr "modrm" "0")
22377    (set_attr "mode" "DI")])
22379 ;; 3Dnow! instructions
22381 (define_insn "addv2sf3"
22382   [(set (match_operand:V2SF 0 "register_operand" "=y")
22383         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22384                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22385   "TARGET_3DNOW"
22386   "pfadd\\t{%2, %0|%0, %2}"
22387   [(set_attr "type" "mmxadd")
22388    (set_attr "mode" "V2SF")])
22390 (define_insn "subv2sf3"
22391   [(set (match_operand:V2SF 0 "register_operand" "=y")
22392         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22393                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22394   "TARGET_3DNOW"
22395   "pfsub\\t{%2, %0|%0, %2}"
22396   [(set_attr "type" "mmxadd")
22397    (set_attr "mode" "V2SF")])
22399 (define_insn "subrv2sf3"
22400   [(set (match_operand:V2SF 0 "register_operand" "=y")
22401         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22402                     (match_operand:V2SF 1 "register_operand" "0")))]
22403   "TARGET_3DNOW"
22404   "pfsubr\\t{%2, %0|%0, %2}"
22405   [(set_attr "type" "mmxadd")
22406    (set_attr "mode" "V2SF")])
22408 (define_insn "gtv2sf3"
22409   [(set (match_operand:V2SI 0 "register_operand" "=y")
22410         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22411                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22412  "TARGET_3DNOW"
22413   "pfcmpgt\\t{%2, %0|%0, %2}"
22414   [(set_attr "type" "mmxcmp")
22415    (set_attr "mode" "V2SF")])
22417 (define_insn "gev2sf3"
22418   [(set (match_operand:V2SI 0 "register_operand" "=y")
22419         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22420                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22421   "TARGET_3DNOW"
22422   "pfcmpge\\t{%2, %0|%0, %2}"
22423   [(set_attr "type" "mmxcmp")
22424    (set_attr "mode" "V2SF")])
22426 (define_insn "eqv2sf3"
22427   [(set (match_operand:V2SI 0 "register_operand" "=y")
22428         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22429                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22430   "TARGET_3DNOW"
22431   "pfcmpeq\\t{%2, %0|%0, %2}"
22432   [(set_attr "type" "mmxcmp")
22433    (set_attr "mode" "V2SF")])
22435 (define_insn "pfmaxv2sf3"
22436   [(set (match_operand:V2SF 0 "register_operand" "=y")
22437         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22438                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22439   "TARGET_3DNOW"
22440   "pfmax\\t{%2, %0|%0, %2}"
22441   [(set_attr "type" "mmxadd")
22442    (set_attr "mode" "V2SF")])
22444 (define_insn "pfminv2sf3"
22445   [(set (match_operand:V2SF 0 "register_operand" "=y")
22446         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22447                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22448   "TARGET_3DNOW"
22449   "pfmin\\t{%2, %0|%0, %2}"
22450   [(set_attr "type" "mmxadd")
22451    (set_attr "mode" "V2SF")])
22453 (define_insn "mulv2sf3"
22454   [(set (match_operand:V2SF 0 "register_operand" "=y")
22455         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22456                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22457   "TARGET_3DNOW"
22458   "pfmul\\t{%2, %0|%0, %2}"
22459   [(set_attr "type" "mmxmul")
22460    (set_attr "mode" "V2SF")])
22462 (define_insn "femms"
22463   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22464    (clobber (reg:XF 8))
22465    (clobber (reg:XF 9))
22466    (clobber (reg:XF 10))
22467    (clobber (reg:XF 11))
22468    (clobber (reg:XF 12))
22469    (clobber (reg:XF 13))
22470    (clobber (reg:XF 14))
22471    (clobber (reg:XF 15))
22472    (clobber (reg:DI 29))
22473    (clobber (reg:DI 30))
22474    (clobber (reg:DI 31))
22475    (clobber (reg:DI 32))
22476    (clobber (reg:DI 33))
22477    (clobber (reg:DI 34))
22478    (clobber (reg:DI 35))
22479    (clobber (reg:DI 36))]
22480   "TARGET_3DNOW"
22481   "femms"
22482   [(set_attr "type" "mmx")
22483    (set_attr "memory" "none")]) 
22485 (define_insn "pf2id"
22486   [(set (match_operand:V2SI 0 "register_operand" "=y")
22487         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22488   "TARGET_3DNOW"
22489   "pf2id\\t{%1, %0|%0, %1}"
22490   [(set_attr "type" "mmxcvt")
22491    (set_attr "mode" "V2SF")])
22493 (define_insn "pf2iw"
22494   [(set (match_operand:V2SI 0 "register_operand" "=y")
22495         (sign_extend:V2SI
22496            (ss_truncate:V2HI
22497               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22498   "TARGET_3DNOW_A"
22499   "pf2iw\\t{%1, %0|%0, %1}"
22500   [(set_attr "type" "mmxcvt")
22501    (set_attr "mode" "V2SF")])
22503 (define_insn "pfacc"
22504   [(set (match_operand:V2SF 0 "register_operand" "=y")
22505         (vec_concat:V2SF
22506            (plus:SF
22507               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22508                              (parallel [(const_int  0)]))
22509               (vec_select:SF (match_dup 1)
22510                              (parallel [(const_int 1)])))
22511            (plus:SF
22512               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22513                              (parallel [(const_int  0)]))
22514               (vec_select:SF (match_dup 2)
22515                              (parallel [(const_int 1)])))))]
22516   "TARGET_3DNOW"
22517   "pfacc\\t{%2, %0|%0, %2}"
22518   [(set_attr "type" "mmxadd")
22519    (set_attr "mode" "V2SF")])
22521 (define_insn "pfnacc"
22522   [(set (match_operand:V2SF 0 "register_operand" "=y")
22523         (vec_concat:V2SF
22524            (minus:SF
22525               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22526                              (parallel [(const_int 0)]))
22527               (vec_select:SF (match_dup 1)
22528                              (parallel [(const_int 1)])))
22529            (minus:SF
22530               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22531                              (parallel [(const_int  0)]))
22532               (vec_select:SF (match_dup 2)
22533                              (parallel [(const_int 1)])))))]
22534   "TARGET_3DNOW_A"
22535   "pfnacc\\t{%2, %0|%0, %2}"
22536   [(set_attr "type" "mmxadd")
22537    (set_attr "mode" "V2SF")])
22539 (define_insn "pfpnacc"
22540   [(set (match_operand:V2SF 0 "register_operand" "=y")
22541         (vec_concat:V2SF
22542            (minus:SF
22543               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22544                              (parallel [(const_int 0)]))
22545               (vec_select:SF (match_dup 1)
22546                              (parallel [(const_int 1)])))
22547            (plus:SF
22548               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22549                              (parallel [(const_int 0)]))
22550               (vec_select:SF (match_dup 2)
22551                              (parallel [(const_int 1)])))))]
22552   "TARGET_3DNOW_A"
22553   "pfpnacc\\t{%2, %0|%0, %2}"
22554   [(set_attr "type" "mmxadd")
22555    (set_attr "mode" "V2SF")])
22557 (define_insn "pi2fw"
22558   [(set (match_operand:V2SF 0 "register_operand" "=y")
22559         (float:V2SF
22560            (vec_concat:V2SI
22561               (sign_extend:SI
22562                  (truncate:HI
22563                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22564                                    (parallel [(const_int 0)]))))
22565               (sign_extend:SI
22566                  (truncate:HI
22567                     (vec_select:SI (match_dup 1)
22568                                    (parallel [(const_int  1)])))))))]
22569   "TARGET_3DNOW_A"
22570   "pi2fw\\t{%1, %0|%0, %1}"
22571   [(set_attr "type" "mmxcvt")
22572    (set_attr "mode" "V2SF")])
22574 (define_insn "floatv2si2"
22575   [(set (match_operand:V2SF 0 "register_operand" "=y")
22576         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22577   "TARGET_3DNOW"
22578   "pi2fd\\t{%1, %0|%0, %1}"
22579   [(set_attr "type" "mmxcvt")
22580    (set_attr "mode" "V2SF")])
22582 ;; This insn is identical to pavgb in operation, but the opcode is
22583 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22585 (define_insn "pavgusb"
22586  [(set (match_operand:V8QI 0 "register_operand" "=y")
22587        (unspec:V8QI
22588           [(match_operand:V8QI 1 "register_operand" "0")
22589            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22590           UNSPEC_PAVGUSB))]
22591   "TARGET_3DNOW"
22592   "pavgusb\\t{%2, %0|%0, %2}"
22593   [(set_attr "type" "mmxshft")
22594    (set_attr "mode" "TI")])
22596 ;; 3DNow reciprocal and sqrt
22598 (define_insn "pfrcpv2sf2"
22599   [(set (match_operand:V2SF 0 "register_operand" "=y")
22600         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22601         UNSPEC_PFRCP))]
22602   "TARGET_3DNOW"
22603   "pfrcp\\t{%1, %0|%0, %1}"
22604   [(set_attr "type" "mmx")
22605    (set_attr "mode" "TI")])
22607 (define_insn "pfrcpit1v2sf3"
22608   [(set (match_operand:V2SF 0 "register_operand" "=y")
22609         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22610                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22611                      UNSPEC_PFRCPIT1))]
22612   "TARGET_3DNOW"
22613   "pfrcpit1\\t{%2, %0|%0, %2}"
22614   [(set_attr "type" "mmx")
22615    (set_attr "mode" "TI")])
22617 (define_insn "pfrcpit2v2sf3"
22618   [(set (match_operand:V2SF 0 "register_operand" "=y")
22619         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22620                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22621                      UNSPEC_PFRCPIT2))]
22622   "TARGET_3DNOW"
22623   "pfrcpit2\\t{%2, %0|%0, %2}"
22624   [(set_attr "type" "mmx")
22625    (set_attr "mode" "TI")])
22627 (define_insn "pfrsqrtv2sf2"
22628   [(set (match_operand:V2SF 0 "register_operand" "=y")
22629         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22630                      UNSPEC_PFRSQRT))]
22631   "TARGET_3DNOW"
22632   "pfrsqrt\\t{%1, %0|%0, %1}"
22633   [(set_attr "type" "mmx")
22634    (set_attr "mode" "TI")])
22635                 
22636 (define_insn "pfrsqit1v2sf3"
22637   [(set (match_operand:V2SF 0 "register_operand" "=y")
22638         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22639                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22640                      UNSPEC_PFRSQIT1))]
22641   "TARGET_3DNOW"
22642   "pfrsqit1\\t{%2, %0|%0, %2}"
22643   [(set_attr "type" "mmx")
22644    (set_attr "mode" "TI")])
22646 (define_insn "pmulhrwv4hi3"
22647   [(set (match_operand:V4HI 0 "register_operand" "=y")
22648         (truncate:V4HI
22649            (lshiftrt:V4SI
22650               (plus:V4SI
22651                  (mult:V4SI
22652                     (sign_extend:V4SI
22653                        (match_operand:V4HI 1 "register_operand" "0"))
22654                     (sign_extend:V4SI
22655                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22656                  (const_vector:V4SI [(const_int 32768)
22657                                      (const_int 32768)
22658                                      (const_int 32768)
22659                                      (const_int 32768)]))
22660               (const_int 16))))]
22661   "TARGET_3DNOW"
22662   "pmulhrw\\t{%2, %0|%0, %2}"
22663   [(set_attr "type" "mmxmul")
22664    (set_attr "mode" "TI")])
22666 (define_insn "pswapdv2si2"
22667   [(set (match_operand:V2SI 0 "register_operand" "=y")
22668         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22669                          (parallel [(const_int 1) (const_int 0)])))]
22670   "TARGET_3DNOW_A"
22671   "pswapd\\t{%1, %0|%0, %1}"
22672   [(set_attr "type" "mmxcvt")
22673    (set_attr "mode" "TI")])
22675 (define_insn "pswapdv2sf2"
22676   [(set (match_operand:V2SF 0 "register_operand" "=y")
22677         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22678                          (parallel [(const_int 1) (const_int 0)])))]
22679   "TARGET_3DNOW_A"
22680   "pswapd\\t{%1, %0|%0, %1}"
22681   [(set_attr "type" "mmxcvt")
22682    (set_attr "mode" "TI")])
22684 (define_expand "prefetch"
22685   [(prefetch (match_operand 0 "address_operand" "")
22686              (match_operand:SI 1 "const_int_operand" "")
22687              (match_operand:SI 2 "const_int_operand" ""))]
22688   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22690   int rw = INTVAL (operands[1]);
22691   int locality = INTVAL (operands[2]);
22693   if (rw != 0 && rw != 1)
22694     abort ();
22695   if (locality < 0 || locality > 3)
22696     abort ();
22697   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22698     abort ();
22700   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22701      suported by SSE counterpart or the SSE prefetch is not available
22702      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22703      of locality.  */
22704   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22705     operands[2] = GEN_INT (3);
22706   else
22707     operands[1] = const0_rtx;
22710 (define_insn "*prefetch_sse"
22711   [(prefetch (match_operand:SI 0 "address_operand" "p")
22712              (const_int 0)
22713              (match_operand:SI 1 "const_int_operand" ""))]
22714   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22716   static const char * const patterns[4] = {
22717    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22718   };
22720   int locality = INTVAL (operands[1]);
22721   if (locality < 0 || locality > 3)
22722     abort ();
22724   return patterns[locality];  
22726   [(set_attr "type" "sse")
22727    (set_attr "memory" "none")])
22729 (define_insn "*prefetch_sse_rex"
22730   [(prefetch (match_operand:DI 0 "address_operand" "p")
22731              (const_int 0)
22732              (match_operand:SI 1 "const_int_operand" ""))]
22733   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22735   static const char * const patterns[4] = {
22736    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22737   };
22739   int locality = INTVAL (operands[1]);
22740   if (locality < 0 || locality > 3)
22741     abort ();
22743   return patterns[locality];  
22745   [(set_attr "type" "sse")
22746    (set_attr "memory" "none")])
22748 (define_insn "*prefetch_3dnow"
22749   [(prefetch (match_operand:SI 0 "address_operand" "p")
22750              (match_operand:SI 1 "const_int_operand" "n")
22751              (const_int 3))]
22752   "TARGET_3DNOW && !TARGET_64BIT"
22754   if (INTVAL (operands[1]) == 0)
22755     return "prefetch\t%a0";
22756   else
22757     return "prefetchw\t%a0";
22759   [(set_attr "type" "mmx")
22760    (set_attr "memory" "none")])
22762 (define_insn "*prefetch_3dnow_rex"
22763   [(prefetch (match_operand:DI 0 "address_operand" "p")
22764              (match_operand:SI 1 "const_int_operand" "n")
22765              (const_int 3))]
22766   "TARGET_3DNOW && TARGET_64BIT"
22768   if (INTVAL (operands[1]) == 0)
22769     return "prefetch\t%a0";
22770   else
22771     return "prefetchw\t%a0";
22773   [(set_attr "type" "mmx")
22774    (set_attr "memory" "none")])
22776 ;; SSE2 support
22778 (define_insn "addv2df3"
22779   [(set (match_operand:V2DF 0 "register_operand" "=x")
22780         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22781                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22782   "TARGET_SSE2"
22783   "addpd\t{%2, %0|%0, %2}"
22784   [(set_attr "type" "sseadd")
22785    (set_attr "mode" "V2DF")])
22787 (define_insn "vmaddv2df3"
22788   [(set (match_operand:V2DF 0 "register_operand" "=x")
22789         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22790                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22791                         (match_dup 1)
22792                         (const_int 1)))]
22793   "TARGET_SSE2"
22794   "addsd\t{%2, %0|%0, %2}"
22795   [(set_attr "type" "sseadd")
22796    (set_attr "mode" "DF")])
22798 (define_insn "subv2df3"
22799   [(set (match_operand:V2DF 0 "register_operand" "=x")
22800         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22801                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22802   "TARGET_SSE2"
22803   "subpd\t{%2, %0|%0, %2}"
22804   [(set_attr "type" "sseadd")
22805    (set_attr "mode" "V2DF")])
22807 (define_insn "vmsubv2df3"
22808   [(set (match_operand:V2DF 0 "register_operand" "=x")
22809         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22810                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22811                         (match_dup 1)
22812                         (const_int 1)))]
22813   "TARGET_SSE2"
22814   "subsd\t{%2, %0|%0, %2}"
22815   [(set_attr "type" "sseadd")
22816    (set_attr "mode" "DF")])
22818 (define_insn "mulv2df3"
22819   [(set (match_operand:V2DF 0 "register_operand" "=x")
22820         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22821                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22822   "TARGET_SSE2"
22823   "mulpd\t{%2, %0|%0, %2}"
22824   [(set_attr "type" "ssemul")
22825    (set_attr "mode" "V2DF")])
22827 (define_insn "vmmulv2df3"
22828   [(set (match_operand:V2DF 0 "register_operand" "=x")
22829         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22830                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22831                         (match_dup 1)
22832                         (const_int 1)))]
22833   "TARGET_SSE2"
22834   "mulsd\t{%2, %0|%0, %2}"
22835   [(set_attr "type" "ssemul")
22836    (set_attr "mode" "DF")])
22838 (define_insn "divv2df3"
22839   [(set (match_operand:V2DF 0 "register_operand" "=x")
22840         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22841                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22842   "TARGET_SSE2"
22843   "divpd\t{%2, %0|%0, %2}"
22844   [(set_attr "type" "ssediv")
22845    (set_attr "mode" "V2DF")])
22847 (define_insn "vmdivv2df3"
22848   [(set (match_operand:V2DF 0 "register_operand" "=x")
22849         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22850                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22851                         (match_dup 1)
22852                         (const_int 1)))]
22853   "TARGET_SSE2"
22854   "divsd\t{%2, %0|%0, %2}"
22855   [(set_attr "type" "ssediv")
22856    (set_attr "mode" "DF")])
22858 ;; SSE min/max
22860 (define_insn "smaxv2df3"
22861   [(set (match_operand:V2DF 0 "register_operand" "=x")
22862         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22863                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22864   "TARGET_SSE2"
22865   "maxpd\t{%2, %0|%0, %2}"
22866   [(set_attr "type" "sseadd")
22867    (set_attr "mode" "V2DF")])
22869 (define_insn "vmsmaxv2df3"
22870   [(set (match_operand:V2DF 0 "register_operand" "=x")
22871         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22872                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22873                         (match_dup 1)
22874                         (const_int 1)))]
22875   "TARGET_SSE2"
22876   "maxsd\t{%2, %0|%0, %2}"
22877   [(set_attr "type" "sseadd")
22878    (set_attr "mode" "DF")])
22880 (define_insn "sminv2df3"
22881   [(set (match_operand:V2DF 0 "register_operand" "=x")
22882         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22883                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22884   "TARGET_SSE2"
22885   "minpd\t{%2, %0|%0, %2}"
22886   [(set_attr "type" "sseadd")
22887    (set_attr "mode" "V2DF")])
22889 (define_insn "vmsminv2df3"
22890   [(set (match_operand:V2DF 0 "register_operand" "=x")
22891         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22892                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22893                         (match_dup 1)
22894                         (const_int 1)))]
22895   "TARGET_SSE2"
22896   "minsd\t{%2, %0|%0, %2}"
22897   [(set_attr "type" "sseadd")
22898    (set_attr "mode" "DF")])
22899 ;; SSE2 square root.  There doesn't appear to be an extension for the
22900 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22902 (define_insn "sqrtv2df2"
22903   [(set (match_operand:V2DF 0 "register_operand" "=x")
22904         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22905   "TARGET_SSE2"
22906   "sqrtpd\t{%1, %0|%0, %1}"
22907   [(set_attr "type" "sse")
22908    (set_attr "mode" "V2DF")])
22910 (define_insn "vmsqrtv2df2"
22911   [(set (match_operand:V2DF 0 "register_operand" "=x")
22912         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22913                         (match_operand:V2DF 2 "register_operand" "0")
22914                         (const_int 1)))]
22915   "TARGET_SSE2"
22916   "sqrtsd\t{%1, %0|%0, %1}"
22917   [(set_attr "type" "sse")
22918    (set_attr "mode" "SF")])
22920 ;; SSE mask-generating compares
22922 (define_insn "maskcmpv2df3"
22923   [(set (match_operand:V2DI 0 "register_operand" "=x")
22924         (match_operator:V2DI 3 "sse_comparison_operator"
22925                              [(match_operand:V2DF 1 "register_operand" "0")
22926                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22927   "TARGET_SSE2"
22928   "cmp%D3pd\t{%2, %0|%0, %2}"
22929   [(set_attr "type" "ssecmp")
22930    (set_attr "mode" "V2DF")])
22932 (define_insn "maskncmpv2df3"
22933   [(set (match_operand:V2DI 0 "register_operand" "=x")
22934         (not:V2DI
22935          (match_operator:V2DI 3 "sse_comparison_operator"
22936                               [(match_operand:V2DF 1 "register_operand" "0")
22937                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22938   "TARGET_SSE2"
22940   if (GET_CODE (operands[3]) == UNORDERED)
22941     return "cmpordps\t{%2, %0|%0, %2}";
22942   else
22943     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22945   [(set_attr "type" "ssecmp")
22946    (set_attr "mode" "V2DF")])
22948 (define_insn "vmmaskcmpv2df3"
22949   [(set (match_operand:V2DI 0 "register_operand" "=x")
22950         (vec_merge:V2DI
22951          (match_operator:V2DI 3 "sse_comparison_operator"
22952                               [(match_operand:V2DF 1 "register_operand" "0")
22953                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22954          (subreg:V2DI (match_dup 1) 0)
22955          (const_int 1)))]
22956   "TARGET_SSE2"
22957   "cmp%D3sd\t{%2, %0|%0, %2}"
22958   [(set_attr "type" "ssecmp")
22959    (set_attr "mode" "DF")])
22961 (define_insn "vmmaskncmpv2df3"
22962   [(set (match_operand:V2DI 0 "register_operand" "=x")
22963         (vec_merge:V2DI
22964          (not:V2DI
22965           (match_operator:V2DI 3 "sse_comparison_operator"
22966                                [(match_operand:V2DF 1 "register_operand" "0")
22967                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22968          (subreg:V2DI (match_dup 1) 0)
22969          (const_int 1)))]
22970   "TARGET_SSE2"
22972   if (GET_CODE (operands[3]) == UNORDERED)
22973     return "cmpordsd\t{%2, %0|%0, %2}";
22974   else
22975     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22977   [(set_attr "type" "ssecmp")
22978    (set_attr "mode" "DF")])
22980 (define_insn "sse2_comi"
22981   [(set (reg:CCFP FLAGS_REG)
22982         (compare:CCFP (vec_select:DF
22983                        (match_operand:V2DF 0 "register_operand" "x")
22984                        (parallel [(const_int 0)]))
22985                       (vec_select:DF
22986                        (match_operand:V2DF 1 "register_operand" "x")
22987                        (parallel [(const_int 0)]))))]
22988   "TARGET_SSE2"
22989   "comisd\t{%1, %0|%0, %1}"
22990   [(set_attr "type" "ssecomi")
22991    (set_attr "mode" "DF")])
22993 (define_insn "sse2_ucomi"
22994   [(set (reg:CCFPU FLAGS_REG)
22995         (compare:CCFPU (vec_select:DF
22996                          (match_operand:V2DF 0 "register_operand" "x")
22997                          (parallel [(const_int 0)]))
22998                         (vec_select:DF
22999                          (match_operand:V2DF 1 "register_operand" "x")
23000                          (parallel [(const_int 0)]))))]
23001   "TARGET_SSE2"
23002   "ucomisd\t{%1, %0|%0, %1}"
23003   [(set_attr "type" "ssecomi")
23004    (set_attr "mode" "DF")])
23006 ;; SSE Strange Moves.
23008 (define_insn "sse2_movmskpd"
23009   [(set (match_operand:SI 0 "register_operand" "=r")
23010         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
23011                    UNSPEC_MOVMSK))]
23012   "TARGET_SSE2"
23013   "movmskpd\t{%1, %0|%0, %1}"
23014   [(set_attr "type" "ssecvt")
23015    (set_attr "mode" "V2DF")])
23017 (define_insn "sse2_pmovmskb"
23018   [(set (match_operand:SI 0 "register_operand" "=r")
23019         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
23020                    UNSPEC_MOVMSK))]
23021   "TARGET_SSE2"
23022   "pmovmskb\t{%1, %0|%0, %1}"
23023   [(set_attr "type" "ssecvt")
23024    (set_attr "mode" "V2DF")])
23026 (define_insn "sse2_maskmovdqu"
23027   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
23028         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23029                        (match_operand:V16QI 2 "register_operand" "x")]
23030                       UNSPEC_MASKMOV))]
23031   "TARGET_SSE2"
23032   ;; @@@ check ordering of operands in intel/nonintel syntax
23033   "maskmovdqu\t{%2, %1|%1, %2}"
23034   [(set_attr "type" "ssecvt")
23035    (set_attr "mode" "TI")])
23037 (define_insn "sse2_maskmovdqu_rex64"
23038   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
23039         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23040                        (match_operand:V16QI 2 "register_operand" "x")]
23041                       UNSPEC_MASKMOV))]
23042   "TARGET_SSE2"
23043   ;; @@@ check ordering of operands in intel/nonintel syntax
23044   "maskmovdqu\t{%2, %1|%1, %2}"
23045   [(set_attr "type" "ssecvt")
23046    (set_attr "mode" "TI")])
23048 (define_insn "sse2_movntv2df"
23049   [(set (match_operand:V2DF 0 "memory_operand" "=m")
23050         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
23051                      UNSPEC_MOVNT))]
23052   "TARGET_SSE2"
23053   "movntpd\t{%1, %0|%0, %1}"
23054   [(set_attr "type" "ssecvt")
23055    (set_attr "mode" "V2DF")])
23057 (define_insn "sse2_movntv2di"
23058   [(set (match_operand:V2DI 0 "memory_operand" "=m")
23059         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
23060                      UNSPEC_MOVNT))]
23061   "TARGET_SSE2"
23062   "movntdq\t{%1, %0|%0, %1}"
23063   [(set_attr "type" "ssecvt")
23064    (set_attr "mode" "TI")])
23066 (define_insn "sse2_movntsi"
23067   [(set (match_operand:SI 0 "memory_operand" "=m")
23068         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
23069                    UNSPEC_MOVNT))]
23070   "TARGET_SSE2"
23071   "movnti\t{%1, %0|%0, %1}"
23072   [(set_attr "type" "ssecvt")
23073    (set_attr "mode" "V2DF")])
23075 ;; SSE <-> integer/MMX conversions
23077 ;; Conversions between SI and SF
23079 (define_insn "cvtdq2ps"
23080   [(set (match_operand:V4SF 0 "register_operand" "=x")
23081         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
23082   "TARGET_SSE2"
23083   "cvtdq2ps\t{%1, %0|%0, %1}"
23084   [(set_attr "type" "ssecvt")
23085    (set_attr "mode" "V2DF")])
23087 (define_insn "cvtps2dq"
23088   [(set (match_operand:V4SI 0 "register_operand" "=x")
23089         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
23090   "TARGET_SSE2"
23091   "cvtps2dq\t{%1, %0|%0, %1}"
23092   [(set_attr "type" "ssecvt")
23093    (set_attr "mode" "TI")])
23095 (define_insn "cvttps2dq"
23096   [(set (match_operand:V4SI 0 "register_operand" "=x")
23097         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
23098                      UNSPEC_FIX))]
23099   "TARGET_SSE2"
23100   "cvttps2dq\t{%1, %0|%0, %1}"
23101   [(set_attr "type" "ssecvt")
23102    (set_attr "mode" "TI")])
23104 ;; Conversions between SI and DF
23106 (define_insn "cvtdq2pd"
23107   [(set (match_operand:V2DF 0 "register_operand" "=x")
23108         (float:V2DF (vec_select:V2SI
23109                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
23110                      (parallel
23111                       [(const_int 0)
23112                        (const_int 1)]))))]
23113   "TARGET_SSE2"
23114   "cvtdq2pd\t{%1, %0|%0, %1}"
23115   [(set_attr "type" "ssecvt")
23116    (set_attr "mode" "V2DF")])
23118 (define_insn "cvtpd2dq"
23119   [(set (match_operand:V4SI 0 "register_operand" "=x")
23120         (vec_concat:V4SI
23121          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
23122          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23123   "TARGET_SSE2"
23124   "cvtpd2dq\t{%1, %0|%0, %1}"
23125   [(set_attr "type" "ssecvt")
23126    (set_attr "mode" "TI")])
23128 (define_insn "cvttpd2dq"
23129   [(set (match_operand:V4SI 0 "register_operand" "=x")
23130         (vec_concat:V4SI
23131          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23132                       UNSPEC_FIX)
23133          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23134   "TARGET_SSE2"
23135   "cvttpd2dq\t{%1, %0|%0, %1}"
23136   [(set_attr "type" "ssecvt")
23137    (set_attr "mode" "TI")])
23139 (define_insn "cvtpd2pi"
23140   [(set (match_operand:V2SI 0 "register_operand" "=y")
23141         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
23142   "TARGET_SSE2"
23143   "cvtpd2pi\t{%1, %0|%0, %1}"
23144   [(set_attr "type" "ssecvt")
23145    (set_attr "mode" "TI")])
23147 (define_insn "cvttpd2pi"
23148   [(set (match_operand:V2SI 0 "register_operand" "=y")
23149         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23150                      UNSPEC_FIX))]
23151   "TARGET_SSE2"
23152   "cvttpd2pi\t{%1, %0|%0, %1}"
23153   [(set_attr "type" "ssecvt")
23154    (set_attr "mode" "TI")])
23156 (define_insn "cvtpi2pd"
23157   [(set (match_operand:V2DF 0 "register_operand" "=x")
23158         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
23159   "TARGET_SSE2"
23160   "cvtpi2pd\t{%1, %0|%0, %1}"
23161   [(set_attr "type" "ssecvt")
23162    (set_attr "mode" "TI")])
23164 ;; Conversions between SI and DF
23166 (define_insn "cvtsd2si"
23167   [(set (match_operand:SI 0 "register_operand" "=r,r")
23168         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23169                                (parallel [(const_int 0)]))))]
23170   "TARGET_SSE2"
23171   "cvtsd2si\t{%1, %0|%0, %1}"
23172   [(set_attr "type" "sseicvt")
23173    (set_attr "athlon_decode" "double,vector")
23174    (set_attr "mode" "SI")])
23176 (define_insn "cvtsd2siq"
23177   [(set (match_operand:DI 0 "register_operand" "=r,r")
23178         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23179                                (parallel [(const_int 0)]))))]
23180   "TARGET_SSE2 && TARGET_64BIT"
23181   "cvtsd2siq\t{%1, %0|%0, %1}"
23182   [(set_attr "type" "sseicvt")
23183    (set_attr "athlon_decode" "double,vector")
23184    (set_attr "mode" "DI")])
23186 (define_insn "cvttsd2si"
23187   [(set (match_operand:SI 0 "register_operand" "=r,r")
23188         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23189                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23190   "TARGET_SSE2"
23191   "cvttsd2si\t{%1, %0|%0, %1}"
23192   [(set_attr "type" "sseicvt")
23193    (set_attr "mode" "SI")
23194    (set_attr "athlon_decode" "double,vector")])
23196 (define_insn "cvttsd2siq"
23197   [(set (match_operand:DI 0 "register_operand" "=r,r")
23198         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23199                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23200   "TARGET_SSE2 && TARGET_64BIT"
23201   "cvttsd2siq\t{%1, %0|%0, %1}"
23202   [(set_attr "type" "sseicvt")
23203    (set_attr "mode" "DI")
23204    (set_attr "athlon_decode" "double,vector")])
23206 (define_insn "cvtsi2sd"
23207   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23208         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23209                         (vec_duplicate:V2DF
23210                           (float:DF
23211                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
23212                         (const_int 2)))]
23213   "TARGET_SSE2"
23214   "cvtsi2sd\t{%2, %0|%0, %2}"
23215   [(set_attr "type" "sseicvt")
23216    (set_attr "mode" "DF")
23217    (set_attr "athlon_decode" "double,direct")])
23219 (define_insn "cvtsi2sdq"
23220   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23221         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23222                         (vec_duplicate:V2DF
23223                           (float:DF
23224                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
23225                         (const_int 2)))]
23226   "TARGET_SSE2 && TARGET_64BIT"
23227   "cvtsi2sdq\t{%2, %0|%0, %2}"
23228   [(set_attr "type" "sseicvt")
23229    (set_attr "mode" "DF")
23230    (set_attr "athlon_decode" "double,direct")])
23232 ;; Conversions between SF and DF
23234 (define_insn "cvtsd2ss"
23235   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
23236         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
23237                         (vec_duplicate:V4SF
23238                           (float_truncate:V2SF
23239                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
23240                         (const_int 14)))]
23241   "TARGET_SSE2"
23242   "cvtsd2ss\t{%2, %0|%0, %2}"
23243   [(set_attr "type" "ssecvt")
23244    (set_attr "athlon_decode" "vector,double")
23245    (set_attr "mode" "SF")])
23247 (define_insn "cvtss2sd"
23248   [(set (match_operand:V2DF 0 "register_operand" "=x")
23249         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23250                         (float_extend:V2DF
23251                           (vec_select:V2SF
23252                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23253                             (parallel [(const_int 0)
23254                                        (const_int 1)])))
23255                         (const_int 2)))]
23256   "TARGET_SSE2"
23257   "cvtss2sd\t{%2, %0|%0, %2}"
23258   [(set_attr "type" "ssecvt")
23259    (set_attr "mode" "DF")])
23261 (define_insn "cvtpd2ps"
23262   [(set (match_operand:V4SF 0 "register_operand" "=x")
23263         (subreg:V4SF
23264           (vec_concat:V4SI
23265             (subreg:V2SI (float_truncate:V2SF
23266                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23267             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23268   "TARGET_SSE2"
23269   "cvtpd2ps\t{%1, %0|%0, %1}"
23270   [(set_attr "type" "ssecvt")
23271    (set_attr "mode" "V4SF")])
23273 (define_insn "cvtps2pd"
23274   [(set (match_operand:V2DF 0 "register_operand" "=x")
23275         (float_extend:V2DF
23276           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23277                            (parallel [(const_int 0)
23278                                       (const_int 1)]))))]
23279   "TARGET_SSE2"
23280   "cvtps2pd\t{%1, %0|%0, %1}"
23281   [(set_attr "type" "ssecvt")
23282    (set_attr "mode" "V2DF")])
23284 ;; SSE2 variants of MMX insns
23286 ;; MMX arithmetic
23288 (define_insn "addv16qi3"
23289   [(set (match_operand:V16QI 0 "register_operand" "=x")
23290         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23291                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23292   "TARGET_SSE2"
23293   "paddb\t{%2, %0|%0, %2}"
23294   [(set_attr "type" "sseiadd")
23295    (set_attr "mode" "TI")])
23297 (define_insn "addv8hi3"
23298   [(set (match_operand:V8HI 0 "register_operand" "=x")
23299         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23300                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23301   "TARGET_SSE2"
23302   "paddw\t{%2, %0|%0, %2}"
23303   [(set_attr "type" "sseiadd")
23304    (set_attr "mode" "TI")])
23306 (define_insn "addv4si3"
23307   [(set (match_operand:V4SI 0 "register_operand" "=x")
23308         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23309                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23310   "TARGET_SSE2"
23311   "paddd\t{%2, %0|%0, %2}"
23312   [(set_attr "type" "sseiadd")
23313    (set_attr "mode" "TI")])
23315 (define_insn "addv2di3"
23316   [(set (match_operand:V2DI 0 "register_operand" "=x")
23317         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23318                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23319   "TARGET_SSE2"
23320   "paddq\t{%2, %0|%0, %2}"
23321   [(set_attr "type" "sseiadd")
23322    (set_attr "mode" "TI")])
23324 (define_insn "ssaddv16qi3"
23325   [(set (match_operand:V16QI 0 "register_operand" "=x")
23326         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23327                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23328   "TARGET_SSE2"
23329   "paddsb\t{%2, %0|%0, %2}"
23330   [(set_attr "type" "sseiadd")
23331    (set_attr "mode" "TI")])
23333 (define_insn "ssaddv8hi3"
23334   [(set (match_operand:V8HI 0 "register_operand" "=x")
23335         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23336                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23337   "TARGET_SSE2"
23338   "paddsw\t{%2, %0|%0, %2}"
23339   [(set_attr "type" "sseiadd")
23340    (set_attr "mode" "TI")])
23342 (define_insn "usaddv16qi3"
23343   [(set (match_operand:V16QI 0 "register_operand" "=x")
23344         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23345                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23346   "TARGET_SSE2"
23347   "paddusb\t{%2, %0|%0, %2}"
23348   [(set_attr "type" "sseiadd")
23349    (set_attr "mode" "TI")])
23351 (define_insn "usaddv8hi3"
23352   [(set (match_operand:V8HI 0 "register_operand" "=x")
23353         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23354                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23355   "TARGET_SSE2"
23356   "paddusw\t{%2, %0|%0, %2}"
23357   [(set_attr "type" "sseiadd")
23358    (set_attr "mode" "TI")])
23360 (define_insn "subv16qi3"
23361   [(set (match_operand:V16QI 0 "register_operand" "=x")
23362         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23363                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23364   "TARGET_SSE2"
23365   "psubb\t{%2, %0|%0, %2}"
23366   [(set_attr "type" "sseiadd")
23367    (set_attr "mode" "TI")])
23369 (define_insn "subv8hi3"
23370   [(set (match_operand:V8HI 0 "register_operand" "=x")
23371         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23372                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23373   "TARGET_SSE2"
23374   "psubw\t{%2, %0|%0, %2}"
23375   [(set_attr "type" "sseiadd")
23376    (set_attr "mode" "TI")])
23378 (define_insn "subv4si3"
23379   [(set (match_operand:V4SI 0 "register_operand" "=x")
23380         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23381                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23382   "TARGET_SSE2"
23383   "psubd\t{%2, %0|%0, %2}"
23384   [(set_attr "type" "sseiadd")
23385    (set_attr "mode" "TI")])
23387 (define_insn "subv2di3"
23388   [(set (match_operand:V2DI 0 "register_operand" "=x")
23389         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23390                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23391   "TARGET_SSE2"
23392   "psubq\t{%2, %0|%0, %2}"
23393   [(set_attr "type" "sseiadd")
23394    (set_attr "mode" "TI")])
23396 (define_insn "sssubv16qi3"
23397   [(set (match_operand:V16QI 0 "register_operand" "=x")
23398         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23399                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23400   "TARGET_SSE2"
23401   "psubsb\t{%2, %0|%0, %2}"
23402   [(set_attr "type" "sseiadd")
23403    (set_attr "mode" "TI")])
23405 (define_insn "sssubv8hi3"
23406   [(set (match_operand:V8HI 0 "register_operand" "=x")
23407         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23408                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23409   "TARGET_SSE2"
23410   "psubsw\t{%2, %0|%0, %2}"
23411   [(set_attr "type" "sseiadd")
23412    (set_attr "mode" "TI")])
23414 (define_insn "ussubv16qi3"
23415   [(set (match_operand:V16QI 0 "register_operand" "=x")
23416         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23417                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23418   "TARGET_SSE2"
23419   "psubusb\t{%2, %0|%0, %2}"
23420   [(set_attr "type" "sseiadd")
23421    (set_attr "mode" "TI")])
23423 (define_insn "ussubv8hi3"
23424   [(set (match_operand:V8HI 0 "register_operand" "=x")
23425         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23426                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23427   "TARGET_SSE2"
23428   "psubusw\t{%2, %0|%0, %2}"
23429   [(set_attr "type" "sseiadd")
23430    (set_attr "mode" "TI")])
23432 (define_insn "mulv8hi3"
23433   [(set (match_operand:V8HI 0 "register_operand" "=x")
23434         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23435                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23436   "TARGET_SSE2"
23437   "pmullw\t{%2, %0|%0, %2}"
23438   [(set_attr "type" "sseimul")
23439    (set_attr "mode" "TI")])
23441 (define_insn "smulv8hi3_highpart"
23442   [(set (match_operand:V8HI 0 "register_operand" "=x")
23443         (truncate:V8HI
23444          (lshiftrt:V8SI
23445           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23446                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23447           (const_int 16))))]
23448   "TARGET_SSE2"
23449   "pmulhw\t{%2, %0|%0, %2}"
23450   [(set_attr "type" "sseimul")
23451    (set_attr "mode" "TI")])
23453 (define_insn "umulv8hi3_highpart"
23454   [(set (match_operand:V8HI 0 "register_operand" "=x")
23455         (truncate:V8HI
23456          (lshiftrt:V8SI
23457           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23458                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23459           (const_int 16))))]
23460   "TARGET_SSE2"
23461   "pmulhuw\t{%2, %0|%0, %2}"
23462   [(set_attr "type" "sseimul")
23463    (set_attr "mode" "TI")])
23465 (define_insn "sse2_umulsidi3"
23466   [(set (match_operand:DI 0 "register_operand" "=y")
23467         (mult:DI (zero_extend:DI (vec_select:SI
23468                                   (match_operand:V2SI 1 "register_operand" "0")
23469                                   (parallel [(const_int 0)])))
23470                  (zero_extend:DI (vec_select:SI
23471                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23472                                   (parallel [(const_int 0)])))))]
23473   "TARGET_SSE2"
23474   "pmuludq\t{%2, %0|%0, %2}"
23475   [(set_attr "type" "mmxmul")
23476    (set_attr "mode" "DI")])
23478 (define_insn "sse2_umulv2siv2di3"
23479   [(set (match_operand:V2DI 0 "register_operand" "=x")
23480         (mult:V2DI (zero_extend:V2DI
23481                      (vec_select:V2SI
23482                        (match_operand:V4SI 1 "register_operand" "0")
23483                        (parallel [(const_int 0) (const_int 2)])))
23484                    (zero_extend:V2DI
23485                      (vec_select:V2SI
23486                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23487                        (parallel [(const_int 0) (const_int 2)])))))]
23488   "TARGET_SSE2"
23489   "pmuludq\t{%2, %0|%0, %2}"
23490   [(set_attr "type" "sseimul")
23491    (set_attr "mode" "TI")])
23493 (define_insn "sse2_pmaddwd"
23494   [(set (match_operand:V4SI 0 "register_operand" "=x")
23495         (plus:V4SI
23496          (mult:V4SI
23497           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23498                                              (parallel [(const_int 0)
23499                                                         (const_int 2)
23500                                                         (const_int 4)
23501                                                         (const_int 6)])))
23502           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23503                                              (parallel [(const_int 0)
23504                                                         (const_int 2)
23505                                                         (const_int 4)
23506                                                         (const_int 6)]))))
23507          (mult:V4SI
23508           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23509                                              (parallel [(const_int 1)
23510                                                         (const_int 3)
23511                                                         (const_int 5)
23512                                                         (const_int 7)])))
23513           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23514                                              (parallel [(const_int 1)
23515                                                         (const_int 3)
23516                                                         (const_int 5)
23517                                                         (const_int 7)]))))))]
23518   "TARGET_SSE2"
23519   "pmaddwd\t{%2, %0|%0, %2}"
23520   [(set_attr "type" "sseiadd")
23521    (set_attr "mode" "TI")])
23523 ;; Same as pxor, but don't show input operands so that we don't think
23524 ;; they are live.
23525 (define_insn "sse2_clrti"
23526   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23527   "TARGET_SSE2"
23529   if (get_attr_mode (insn) == MODE_TI)
23530     return "pxor\t%0, %0";
23531   else
23532     return "xorps\t%0, %0";
23534   [(set_attr "type" "ssemov")
23535    (set_attr "memory" "none")
23536    (set (attr "mode")
23537               (if_then_else
23538                 (ne (symbol_ref "optimize_size")
23539                     (const_int 0))
23540                 (const_string "V4SF")
23541                 (const_string "TI")))])
23543 ;; MMX unsigned averages/sum of absolute differences
23545 (define_insn "sse2_uavgv16qi3"
23546   [(set (match_operand:V16QI 0 "register_operand" "=x")
23547         (ashiftrt:V16QI
23548          (plus:V16QI (plus:V16QI
23549                      (match_operand:V16QI 1 "register_operand" "0")
23550                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23551                      (const_vector:V16QI [(const_int 1) (const_int 1)
23552                                           (const_int 1) (const_int 1)
23553                                           (const_int 1) (const_int 1)
23554                                           (const_int 1) (const_int 1)
23555                                           (const_int 1) (const_int 1)
23556                                           (const_int 1) (const_int 1)
23557                                           (const_int 1) (const_int 1)
23558                                           (const_int 1) (const_int 1)]))
23559          (const_int 1)))]
23560   "TARGET_SSE2"
23561   "pavgb\t{%2, %0|%0, %2}"
23562   [(set_attr "type" "sseiadd")
23563    (set_attr "mode" "TI")])
23565 (define_insn "sse2_uavgv8hi3"
23566   [(set (match_operand:V8HI 0 "register_operand" "=x")
23567         (ashiftrt:V8HI
23568          (plus:V8HI (plus:V8HI
23569                      (match_operand:V8HI 1 "register_operand" "0")
23570                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23571                     (const_vector:V8HI [(const_int 1) (const_int 1)
23572                                         (const_int 1) (const_int 1)
23573                                         (const_int 1) (const_int 1)
23574                                         (const_int 1) (const_int 1)]))
23575          (const_int 1)))]
23576   "TARGET_SSE2"
23577   "pavgw\t{%2, %0|%0, %2}"
23578   [(set_attr "type" "sseiadd")
23579    (set_attr "mode" "TI")])
23581 ;; @@@ this isn't the right representation.
23582 (define_insn "sse2_psadbw"
23583   [(set (match_operand:V2DI 0 "register_operand" "=x")
23584         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23585                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23586                      UNSPEC_PSADBW))]
23587   "TARGET_SSE2"
23588   "psadbw\t{%2, %0|%0, %2}"
23589   [(set_attr "type" "sseiadd")
23590    (set_attr "mode" "TI")])
23593 ;; MMX insert/extract/shuffle
23595 (define_insn "sse2_pinsrw"
23596   [(set (match_operand:V8HI 0 "register_operand" "=x")
23597         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23598                         (vec_duplicate:V8HI
23599                          (truncate:HI
23600                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23601                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23602   "TARGET_SSE2"
23603   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23604   [(set_attr "type" "ssecvt")
23605    (set_attr "mode" "TI")])
23607 (define_insn "sse2_pextrw"
23608   [(set (match_operand:SI 0 "register_operand" "=r")
23609         (zero_extend:SI
23610           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23611                          (parallel
23612                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23613   "TARGET_SSE2"
23614   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23615   [(set_attr "type" "ssecvt")
23616    (set_attr "mode" "TI")])
23618 (define_insn "sse2_pshufd"
23619   [(set (match_operand:V4SI 0 "register_operand" "=x")
23620         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23621                       (match_operand:SI 2 "immediate_operand" "i")]
23622                      UNSPEC_SHUFFLE))]
23623   "TARGET_SSE2"
23624   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23625   [(set_attr "type" "ssecvt")
23626    (set_attr "mode" "TI")])
23628 (define_insn "sse2_pshuflw"
23629   [(set (match_operand:V8HI 0 "register_operand" "=x")
23630         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23631                       (match_operand:SI 2 "immediate_operand" "i")]
23632                      UNSPEC_PSHUFLW))]
23633   "TARGET_SSE2"
23634   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23635   [(set_attr "type" "ssecvt")
23636    (set_attr "mode" "TI")])
23638 (define_insn "sse2_pshufhw"
23639   [(set (match_operand:V8HI 0 "register_operand" "=x")
23640         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23641                       (match_operand:SI 2 "immediate_operand" "i")]
23642                      UNSPEC_PSHUFHW))]
23643   "TARGET_SSE2"
23644   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23645   [(set_attr "type" "ssecvt")
23646    (set_attr "mode" "TI")])
23648 ;; MMX mask-generating comparisons
23650 (define_insn "eqv16qi3"
23651   [(set (match_operand:V16QI 0 "register_operand" "=x")
23652         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23653                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23654   "TARGET_SSE2"
23655   "pcmpeqb\t{%2, %0|%0, %2}"
23656   [(set_attr "type" "ssecmp")
23657    (set_attr "mode" "TI")])
23659 (define_insn "eqv8hi3"
23660   [(set (match_operand:V8HI 0 "register_operand" "=x")
23661         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23662                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23663   "TARGET_SSE2"
23664   "pcmpeqw\t{%2, %0|%0, %2}"
23665   [(set_attr "type" "ssecmp")
23666    (set_attr "mode" "TI")])
23668 (define_insn "eqv4si3"
23669   [(set (match_operand:V4SI 0 "register_operand" "=x")
23670         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23671                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23672   "TARGET_SSE2"
23673   "pcmpeqd\t{%2, %0|%0, %2}"
23674   [(set_attr "type" "ssecmp")
23675    (set_attr "mode" "TI")])
23677 (define_insn "gtv16qi3"
23678   [(set (match_operand:V16QI 0 "register_operand" "=x")
23679         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23680                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23681   "TARGET_SSE2"
23682   "pcmpgtb\t{%2, %0|%0, %2}"
23683   [(set_attr "type" "ssecmp")
23684    (set_attr "mode" "TI")])
23686 (define_insn "gtv8hi3"
23687   [(set (match_operand:V8HI 0 "register_operand" "=x")
23688         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23689                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23690   "TARGET_SSE2"
23691   "pcmpgtw\t{%2, %0|%0, %2}"
23692   [(set_attr "type" "ssecmp")
23693    (set_attr "mode" "TI")])
23695 (define_insn "gtv4si3"
23696   [(set (match_operand:V4SI 0 "register_operand" "=x")
23697         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23698                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23699   "TARGET_SSE2"
23700   "pcmpgtd\t{%2, %0|%0, %2}"
23701   [(set_attr "type" "ssecmp")
23702    (set_attr "mode" "TI")])
23705 ;; MMX max/min insns
23707 (define_insn "umaxv16qi3"
23708   [(set (match_operand:V16QI 0 "register_operand" "=x")
23709         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23710                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23711   "TARGET_SSE2"
23712   "pmaxub\t{%2, %0|%0, %2}"
23713   [(set_attr "type" "sseiadd")
23714    (set_attr "mode" "TI")])
23716 (define_insn "smaxv8hi3"
23717   [(set (match_operand:V8HI 0 "register_operand" "=x")
23718         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23719                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23720   "TARGET_SSE2"
23721   "pmaxsw\t{%2, %0|%0, %2}"
23722   [(set_attr "type" "sseiadd")
23723    (set_attr "mode" "TI")])
23725 (define_insn "uminv16qi3"
23726   [(set (match_operand:V16QI 0 "register_operand" "=x")
23727         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23728                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23729   "TARGET_SSE2"
23730   "pminub\t{%2, %0|%0, %2}"
23731   [(set_attr "type" "sseiadd")
23732    (set_attr "mode" "TI")])
23734 (define_insn "sminv8hi3"
23735   [(set (match_operand:V8HI 0 "register_operand" "=x")
23736         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23737                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23738   "TARGET_SSE2"
23739   "pminsw\t{%2, %0|%0, %2}"
23740   [(set_attr "type" "sseiadd")
23741    (set_attr "mode" "TI")])
23744 ;; MMX shifts
23746 (define_insn "ashrv8hi3"
23747   [(set (match_operand:V8HI 0 "register_operand" "=x")
23748         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23749                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23750   "TARGET_SSE2"
23751   "psraw\t{%2, %0|%0, %2}"
23752   [(set_attr "type" "sseishft")
23753    (set_attr "mode" "TI")])
23755 (define_insn "ashrv4si3"
23756   [(set (match_operand:V4SI 0 "register_operand" "=x")
23757         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23758                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23759   "TARGET_SSE2"
23760   "psrad\t{%2, %0|%0, %2}"
23761   [(set_attr "type" "sseishft")
23762    (set_attr "mode" "TI")])
23764 (define_insn "lshrv8hi3"
23765   [(set (match_operand:V8HI 0 "register_operand" "=x")
23766         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23767                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23768   "TARGET_SSE2"
23769   "psrlw\t{%2, %0|%0, %2}"
23770   [(set_attr "type" "sseishft")
23771    (set_attr "mode" "TI")])
23773 (define_insn "lshrv4si3"
23774   [(set (match_operand:V4SI 0 "register_operand" "=x")
23775         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23776                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23777   "TARGET_SSE2"
23778   "psrld\t{%2, %0|%0, %2}"
23779   [(set_attr "type" "sseishft")
23780    (set_attr "mode" "TI")])
23782 (define_insn "lshrv2di3"
23783   [(set (match_operand:V2DI 0 "register_operand" "=x")
23784         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23785                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23786   "TARGET_SSE2"
23787   "psrlq\t{%2, %0|%0, %2}"
23788   [(set_attr "type" "sseishft")
23789    (set_attr "mode" "TI")])
23791 (define_insn "ashlv8hi3"
23792   [(set (match_operand:V8HI 0 "register_operand" "=x")
23793         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23794                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23795   "TARGET_SSE2"
23796   "psllw\t{%2, %0|%0, %2}"
23797   [(set_attr "type" "sseishft")
23798    (set_attr "mode" "TI")])
23800 (define_insn "ashlv4si3"
23801   [(set (match_operand:V4SI 0 "register_operand" "=x")
23802         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23803                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23804   "TARGET_SSE2"
23805   "pslld\t{%2, %0|%0, %2}"
23806   [(set_attr "type" "sseishft")
23807    (set_attr "mode" "TI")])
23809 (define_insn "ashlv2di3"
23810   [(set (match_operand:V2DI 0 "register_operand" "=x")
23811         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23812                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23813   "TARGET_SSE2"
23814   "psllq\t{%2, %0|%0, %2}"
23815   [(set_attr "type" "sseishft")
23816    (set_attr "mode" "TI")])
23818 (define_insn "ashrv8hi3_ti"
23819   [(set (match_operand:V8HI 0 "register_operand" "=x")
23820         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23821                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23822   "TARGET_SSE2"
23823   "psraw\t{%2, %0|%0, %2}"
23824   [(set_attr "type" "sseishft")
23825    (set_attr "mode" "TI")])
23827 (define_insn "ashrv4si3_ti"
23828   [(set (match_operand:V4SI 0 "register_operand" "=x")
23829         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23830                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23831   "TARGET_SSE2"
23832   "psrad\t{%2, %0|%0, %2}"
23833   [(set_attr "type" "sseishft")
23834    (set_attr "mode" "TI")])
23836 (define_insn "lshrv8hi3_ti"
23837   [(set (match_operand:V8HI 0 "register_operand" "=x")
23838         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23839                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23840   "TARGET_SSE2"
23841   "psrlw\t{%2, %0|%0, %2}"
23842   [(set_attr "type" "sseishft")
23843    (set_attr "mode" "TI")])
23845 (define_insn "lshrv4si3_ti"
23846   [(set (match_operand:V4SI 0 "register_operand" "=x")
23847         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23848                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23849   "TARGET_SSE2"
23850   "psrld\t{%2, %0|%0, %2}"
23851   [(set_attr "type" "sseishft")
23852    (set_attr "mode" "TI")])
23854 (define_insn "lshrv2di3_ti"
23855   [(set (match_operand:V2DI 0 "register_operand" "=x")
23856         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23857                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23858   "TARGET_SSE2"
23859   "psrlq\t{%2, %0|%0, %2}"
23860   [(set_attr "type" "sseishft")
23861    (set_attr "mode" "TI")])
23863 (define_insn "ashlv8hi3_ti"
23864   [(set (match_operand:V8HI 0 "register_operand" "=x")
23865         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23866                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23867   "TARGET_SSE2"
23868   "psllw\t{%2, %0|%0, %2}"
23869   [(set_attr "type" "sseishft")
23870    (set_attr "mode" "TI")])
23872 (define_insn "ashlv4si3_ti"
23873   [(set (match_operand:V4SI 0 "register_operand" "=x")
23874         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23875                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23876   "TARGET_SSE2"
23877   "pslld\t{%2, %0|%0, %2}"
23878   [(set_attr "type" "sseishft")
23879    (set_attr "mode" "TI")])
23881 (define_insn "ashlv2di3_ti"
23882   [(set (match_operand:V2DI 0 "register_operand" "=x")
23883         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23884                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23885   "TARGET_SSE2"
23886   "psllq\t{%2, %0|%0, %2}"
23887   [(set_attr "type" "sseishft")
23888    (set_attr "mode" "TI")])
23890 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23891 ;; we wouldn't need here it since we never generate TImode arithmetic.
23893 ;; There has to be some kind of prize for the weirdest new instruction...
23894 (define_insn "sse2_ashlti3"
23895   [(set (match_operand:TI 0 "register_operand" "=x")
23896         (unspec:TI
23897          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23898                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23899                                (const_int 8)))] UNSPEC_NOP))]
23900   "TARGET_SSE2"
23901   "pslldq\t{%2, %0|%0, %2}"
23902   [(set_attr "type" "sseishft")
23903    (set_attr "mode" "TI")])
23905 (define_insn "sse2_lshrti3"
23906   [(set (match_operand:TI 0 "register_operand" "=x")
23907         (unspec:TI
23908          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23909                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23910                                 (const_int 8)))] UNSPEC_NOP))]
23911   "TARGET_SSE2"
23912   "psrldq\t{%2, %0|%0, %2}"
23913   [(set_attr "type" "sseishft")
23914    (set_attr "mode" "TI")])
23916 ;; SSE unpack
23918 (define_insn "sse2_unpckhpd"
23919   [(set (match_operand:V2DF 0 "register_operand" "=x")
23920         (vec_concat:V2DF
23921          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23922                         (parallel [(const_int 1)]))
23923          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23924                         (parallel [(const_int 1)]))))]
23925   "TARGET_SSE2"
23926   "unpckhpd\t{%2, %0|%0, %2}"
23927   [(set_attr "type" "ssecvt")
23928    (set_attr "mode" "V2DF")])
23930 (define_insn "sse2_unpcklpd"
23931   [(set (match_operand:V2DF 0 "register_operand" "=x")
23932         (vec_concat:V2DF
23933          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23934                         (parallel [(const_int 0)]))
23935          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23936                         (parallel [(const_int 0)]))))]
23937   "TARGET_SSE2"
23938   "unpcklpd\t{%2, %0|%0, %2}"
23939   [(set_attr "type" "ssecvt")
23940    (set_attr "mode" "V2DF")])
23942 ;; MMX pack/unpack insns.
23944 (define_insn "sse2_packsswb"
23945   [(set (match_operand:V16QI 0 "register_operand" "=x")
23946         (vec_concat:V16QI
23947          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23948          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23949   "TARGET_SSE2"
23950   "packsswb\t{%2, %0|%0, %2}"
23951   [(set_attr "type" "ssecvt")
23952    (set_attr "mode" "TI")])
23954 (define_insn "sse2_packssdw"
23955   [(set (match_operand:V8HI 0 "register_operand" "=x")
23956         (vec_concat:V8HI
23957          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23958          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23959   "TARGET_SSE2"
23960   "packssdw\t{%2, %0|%0, %2}"
23961   [(set_attr "type" "ssecvt")
23962    (set_attr "mode" "TI")])
23964 (define_insn "sse2_packuswb"
23965   [(set (match_operand:V16QI 0 "register_operand" "=x")
23966         (vec_concat:V16QI
23967          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23968          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23969   "TARGET_SSE2"
23970   "packuswb\t{%2, %0|%0, %2}"
23971   [(set_attr "type" "ssecvt")
23972    (set_attr "mode" "TI")])
23974 (define_insn "sse2_punpckhbw"
23975   [(set (match_operand:V16QI 0 "register_operand" "=x")
23976         (vec_merge:V16QI
23977          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23978                            (parallel [(const_int 8) (const_int 0)
23979                                       (const_int 9) (const_int 1)
23980                                       (const_int 10) (const_int 2)
23981                                       (const_int 11) (const_int 3)
23982                                       (const_int 12) (const_int 4)
23983                                       (const_int 13) (const_int 5)
23984                                       (const_int 14) (const_int 6)
23985                                       (const_int 15) (const_int 7)]))
23986          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23987                            (parallel [(const_int 0) (const_int 8)
23988                                       (const_int 1) (const_int 9)
23989                                       (const_int 2) (const_int 10)
23990                                       (const_int 3) (const_int 11)
23991                                       (const_int 4) (const_int 12)
23992                                       (const_int 5) (const_int 13)
23993                                       (const_int 6) (const_int 14)
23994                                       (const_int 7) (const_int 15)]))
23995          (const_int 21845)))]
23996   "TARGET_SSE2"
23997   "punpckhbw\t{%2, %0|%0, %2}"
23998   [(set_attr "type" "ssecvt")
23999    (set_attr "mode" "TI")])
24001 (define_insn "sse2_punpckhwd"
24002   [(set (match_operand:V8HI 0 "register_operand" "=x")
24003         (vec_merge:V8HI
24004          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24005                           (parallel [(const_int 4) (const_int 0)
24006                                      (const_int 5) (const_int 1)
24007                                      (const_int 6) (const_int 2)
24008                                      (const_int 7) (const_int 3)]))
24009          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24010                           (parallel [(const_int 0) (const_int 4)
24011                                      (const_int 1) (const_int 5)
24012                                      (const_int 2) (const_int 6)
24013                                      (const_int 3) (const_int 7)]))
24014          (const_int 85)))]
24015   "TARGET_SSE2"
24016   "punpckhwd\t{%2, %0|%0, %2}"
24017   [(set_attr "type" "ssecvt")
24018    (set_attr "mode" "TI")])
24020 (define_insn "sse2_punpckhdq"
24021   [(set (match_operand:V4SI 0 "register_operand" "=x")
24022         (vec_merge:V4SI
24023          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24024                           (parallel [(const_int 2) (const_int 0)
24025                                      (const_int 3) (const_int 1)]))
24026          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24027                           (parallel [(const_int 0) (const_int 2)
24028                                      (const_int 1) (const_int 3)]))
24029          (const_int 5)))]
24030   "TARGET_SSE2"
24031   "punpckhdq\t{%2, %0|%0, %2}"
24032   [(set_attr "type" "ssecvt")
24033    (set_attr "mode" "TI")])
24035 (define_insn "sse2_punpcklbw"
24036   [(set (match_operand:V16QI 0 "register_operand" "=x")
24037         (vec_merge:V16QI
24038          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24039                            (parallel [(const_int 0) (const_int 8)
24040                                       (const_int 1) (const_int 9)
24041                                       (const_int 2) (const_int 10)
24042                                       (const_int 3) (const_int 11)
24043                                       (const_int 4) (const_int 12)
24044                                       (const_int 5) (const_int 13)
24045                                       (const_int 6) (const_int 14)
24046                                       (const_int 7) (const_int 15)]))
24047          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24048                            (parallel [(const_int 8) (const_int 0)
24049                                       (const_int 9) (const_int 1)
24050                                       (const_int 10) (const_int 2)
24051                                       (const_int 11) (const_int 3)
24052                                       (const_int 12) (const_int 4)
24053                                       (const_int 13) (const_int 5)
24054                                       (const_int 14) (const_int 6)
24055                                       (const_int 15) (const_int 7)]))
24056          (const_int 21845)))]
24057   "TARGET_SSE2"
24058   "punpcklbw\t{%2, %0|%0, %2}"
24059   [(set_attr "type" "ssecvt")
24060    (set_attr "mode" "TI")])
24062 (define_insn "sse2_punpcklwd"
24063   [(set (match_operand:V8HI 0 "register_operand" "=x")
24064         (vec_merge:V8HI
24065          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24066                           (parallel [(const_int 0) (const_int 4)
24067                                      (const_int 1) (const_int 5)
24068                                      (const_int 2) (const_int 6)
24069                                      (const_int 3) (const_int 7)]))
24070          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24071                           (parallel [(const_int 4) (const_int 0)
24072                                      (const_int 5) (const_int 1)
24073                                      (const_int 6) (const_int 2)
24074                                      (const_int 7) (const_int 3)]))
24075          (const_int 85)))]
24076   "TARGET_SSE2"
24077   "punpcklwd\t{%2, %0|%0, %2}"
24078   [(set_attr "type" "ssecvt")
24079    (set_attr "mode" "TI")])
24081 (define_insn "sse2_punpckldq"
24082   [(set (match_operand:V4SI 0 "register_operand" "=x")
24083         (vec_merge:V4SI
24084          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24085                           (parallel [(const_int 0) (const_int 2)
24086                                      (const_int 1) (const_int 3)]))
24087          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24088                           (parallel [(const_int 2) (const_int 0)
24089                                      (const_int 3) (const_int 1)]))
24090          (const_int 5)))]
24091   "TARGET_SSE2"
24092   "punpckldq\t{%2, %0|%0, %2}"
24093   [(set_attr "type" "ssecvt")
24094    (set_attr "mode" "TI")])
24096 (define_insn "sse2_punpcklqdq"
24097   [(set (match_operand:V2DI 0 "register_operand" "=x")
24098         (vec_merge:V2DI
24099          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24100                           (parallel [(const_int 1)
24101                                      (const_int 0)]))
24102          (match_operand:V2DI 1 "register_operand" "0")
24103          (const_int 1)))]
24104   "TARGET_SSE2"
24105   "punpcklqdq\t{%2, %0|%0, %2}"
24106   [(set_attr "type" "ssecvt")
24107    (set_attr "mode" "TI")])
24109 (define_insn "sse2_punpckhqdq"
24110   [(set (match_operand:V2DI 0 "register_operand" "=x")
24111         (vec_merge:V2DI
24112          (match_operand:V2DI 1 "register_operand" "0")
24113          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24114                           (parallel [(const_int 1)
24115                                      (const_int 0)]))
24116          (const_int 1)))]
24117   "TARGET_SSE2"
24118   "punpckhqdq\t{%2, %0|%0, %2}"
24119   [(set_attr "type" "ssecvt")
24120    (set_attr "mode" "TI")])
24122 ;; SSE2 moves
24124 (define_insn "sse2_movapd"
24125   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24126         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24127                      UNSPEC_MOVA))]
24128   "TARGET_SSE2
24129    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24130   "movapd\t{%1, %0|%0, %1}"
24131   [(set_attr "type" "ssemov")
24132    (set_attr "mode" "V2DF")])
24134 (define_insn "sse2_movupd"
24135   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24136         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24137                      UNSPEC_MOVU))]
24138   "TARGET_SSE2
24139    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24140   "movupd\t{%1, %0|%0, %1}"
24141   [(set_attr "type" "ssecvt")
24142    (set_attr "mode" "V2DF")])
24144 (define_insn "sse2_movdqa"
24145   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24146         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24147                        UNSPEC_MOVA))]
24148   "TARGET_SSE2
24149    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24150   "movdqa\t{%1, %0|%0, %1}"
24151   [(set_attr "type" "ssemov")
24152    (set_attr "mode" "TI")])
24154 (define_insn "sse2_movdqu"
24155   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24156         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24157                        UNSPEC_MOVU))]
24158   "TARGET_SSE2
24159    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24160   "movdqu\t{%1, %0|%0, %1}"
24161   [(set_attr "type" "ssecvt")
24162    (set_attr "mode" "TI")])
24164 (define_insn "sse2_movdq2q"
24165   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
24166         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
24167                        (parallel [(const_int 0)])))]
24168   "TARGET_SSE2 && !TARGET_64BIT"
24169   "@
24170    movq\t{%1, %0|%0, %1}
24171    movdq2q\t{%1, %0|%0, %1}"
24172   [(set_attr "type" "ssecvt")
24173    (set_attr "mode" "TI")])
24175 (define_insn "sse2_movdq2q_rex64"
24176   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
24177         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
24178                        (parallel [(const_int 0)])))]
24179   "TARGET_SSE2 && TARGET_64BIT"
24180   "@
24181    movq\t{%1, %0|%0, %1}
24182    movdq2q\t{%1, %0|%0, %1}
24183    movd\t{%1, %0|%0, %1}"
24184   [(set_attr "type" "ssecvt")
24185    (set_attr "mode" "TI")])
24187 (define_insn "sse2_movq2dq"
24188   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
24189         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
24190                          (const_int 0)))]
24191   "TARGET_SSE2 && !TARGET_64BIT"
24192   "@
24193    movq\t{%1, %0|%0, %1}
24194    movq2dq\t{%1, %0|%0, %1}"
24195   [(set_attr "type" "ssecvt,ssemov")
24196    (set_attr "mode" "TI")])
24198 (define_insn "sse2_movq2dq_rex64"
24199   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
24200         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
24201                          (const_int 0)))]
24202   "TARGET_SSE2 && TARGET_64BIT"
24203   "@
24204    movq\t{%1, %0|%0, %1}
24205    movq2dq\t{%1, %0|%0, %1}
24206    movd\t{%1, %0|%0, %1}"
24207   [(set_attr "type" "ssecvt,ssemov,ssecvt")
24208    (set_attr "mode" "TI")])
24210 (define_insn "sse2_movq"
24211   [(set (match_operand:V2DI 0 "register_operand" "=x")
24212         (vec_concat:V2DI (vec_select:DI
24213                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
24214                           (parallel [(const_int 0)]))
24215                          (const_int 0)))]
24216   "TARGET_SSE2"
24217   "movq\t{%1, %0|%0, %1}"
24218   [(set_attr "type" "ssemov")
24219    (set_attr "mode" "TI")])
24221 (define_insn "sse2_loadd"
24222   [(set (match_operand:V4SI 0 "register_operand" "=x")
24223         (vec_merge:V4SI
24224          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
24225          (const_vector:V4SI [(const_int 0)
24226                              (const_int 0)
24227                              (const_int 0)
24228                              (const_int 0)])
24229          (const_int 1)))]
24230   "TARGET_SSE2"
24231   "movd\t{%1, %0|%0, %1}"
24232   [(set_attr "type" "ssemov")
24233    (set_attr "mode" "TI")])
24235 (define_insn "sse2_stored"
24236   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
24237         (vec_select:SI
24238          (match_operand:V4SI 1 "register_operand" "x")
24239          (parallel [(const_int 0)])))]
24240   "TARGET_SSE2"
24241   "movd\t{%1, %0|%0, %1}"
24242   [(set_attr "type" "ssemov")
24243    (set_attr "mode" "TI")])
24245 (define_insn "sse2_movhpd"
24246   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24247         (vec_merge:V2DF
24248          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24249          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24250          (const_int 2)))]
24251   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24252   "movhpd\t{%2, %0|%0, %2}"
24253   [(set_attr "type" "ssecvt")
24254    (set_attr "mode" "V2DF")])
24256 (define_expand "sse2_loadsd"
24257   [(match_operand:V2DF 0 "register_operand" "")
24258    (match_operand:DF 1 "memory_operand" "")]
24259   "TARGET_SSE2"
24261   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24262                                 CONST0_RTX (V2DFmode)));
24263   DONE;
24266 (define_insn "sse2_loadsd_1"
24267   [(set (match_operand:V2DF 0 "register_operand" "=x")
24268         (vec_merge:V2DF
24269          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24270          (match_operand:V2DF 2 "const0_operand" "X")
24271          (const_int 1)))]
24272   "TARGET_SSE2"
24273   "movsd\t{%1, %0|%0, %1}"
24274   [(set_attr "type" "ssecvt")
24275    (set_attr "mode" "DF")])
24277 (define_insn "sse2_movsd"
24278   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24279         (vec_merge:V2DF
24280          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24281          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24282          (const_int 1)))]
24283   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24284   "@movsd\t{%2, %0|%0, %2}
24285     movlpd\t{%2, %0|%0, %2}
24286     movlpd\t{%2, %0|%0, %2}"
24287   [(set_attr "type" "ssecvt")
24288    (set_attr "mode" "DF,V2DF,V2DF")])
24290 (define_insn "sse2_storesd"
24291   [(set (match_operand:DF 0 "memory_operand" "=m")
24292         (vec_select:DF
24293          (match_operand:V2DF 1 "register_operand" "x")
24294          (parallel [(const_int 0)])))]
24295   "TARGET_SSE2"
24296   "movsd\t{%1, %0|%0, %1}"
24297   [(set_attr "type" "ssecvt")
24298    (set_attr "mode" "DF")])
24300 (define_insn "sse2_shufpd"
24301   [(set (match_operand:V2DF 0 "register_operand" "=x")
24302         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24303                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24304                       (match_operand:SI 3 "immediate_operand" "i")]
24305                      UNSPEC_SHUFFLE))]
24306   "TARGET_SSE2"
24307   ;; @@@ check operand order for intel/nonintel syntax
24308   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24309   [(set_attr "type" "ssecvt")
24310    (set_attr "mode" "V2DF")])
24312 (define_insn "sse2_clflush"
24313   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24314                     UNSPECV_CLFLUSH)]
24315   "TARGET_SSE2"
24316   "clflush\t%a0"
24317   [(set_attr "type" "sse")
24318    (set_attr "memory" "unknown")])
24320 (define_expand "sse2_mfence"
24321   [(set (match_dup 0)
24322         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24323   "TARGET_SSE2"
24325   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24326   MEM_VOLATILE_P (operands[0]) = 1;
24329 (define_insn "*mfence_insn"
24330   [(set (match_operand:BLK 0 "" "")
24331         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24332   "TARGET_SSE2"
24333   "mfence"
24334   [(set_attr "type" "sse")
24335    (set_attr "memory" "unknown")])
24337 (define_expand "sse2_lfence"
24338   [(set (match_dup 0)
24339         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24340   "TARGET_SSE2"
24342   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24343   MEM_VOLATILE_P (operands[0]) = 1;
24346 (define_insn "*lfence_insn"
24347   [(set (match_operand:BLK 0 "" "")
24348         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24349   "TARGET_SSE2"
24350   "lfence"
24351   [(set_attr "type" "sse")
24352    (set_attr "memory" "unknown")])
24354 ;; SSE3
24356 (define_insn "mwait"
24357   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24358                      (match_operand:SI 1 "register_operand" "c")]
24359                     UNSPECV_MWAIT)]
24360   "TARGET_SSE3"
24361   "mwait\t%0, %1"
24362   [(set_attr "length" "3")])
24364 (define_insn "monitor"
24365   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24366                      (match_operand:SI 1 "register_operand" "c")
24367                      (match_operand:SI 2 "register_operand" "d")]
24368                     UNSPECV_MONITOR)]
24369   "TARGET_SSE3"
24370   "monitor\t%0, %1, %2"
24371   [(set_attr "length" "3")])
24373 ;; SSE3 arithmetic
24375 (define_insn "addsubv4sf3"
24376   [(set (match_operand:V4SF 0 "register_operand" "=x")
24377         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24378                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24379                      UNSPEC_ADDSUB))]
24380   "TARGET_SSE3"
24381   "addsubps\t{%2, %0|%0, %2}"
24382   [(set_attr "type" "sseadd")
24383    (set_attr "mode" "V4SF")])
24385 (define_insn "addsubv2df3"
24386   [(set (match_operand:V2DF 0 "register_operand" "=x")
24387         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24388                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24389                      UNSPEC_ADDSUB))]
24390   "TARGET_SSE3"
24391   "addsubpd\t{%2, %0|%0, %2}"
24392   [(set_attr "type" "sseadd")
24393    (set_attr "mode" "V2DF")])
24395 (define_insn "haddv4sf3"
24396   [(set (match_operand:V4SF 0 "register_operand" "=x")
24397         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24398                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24399                      UNSPEC_HADD))]
24400   "TARGET_SSE3"
24401   "haddps\t{%2, %0|%0, %2}"
24402   [(set_attr "type" "sseadd")
24403    (set_attr "mode" "V4SF")])
24405 (define_insn "haddv2df3"
24406   [(set (match_operand:V2DF 0 "register_operand" "=x")
24407         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24408                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24409                      UNSPEC_HADD))]
24410   "TARGET_SSE3"
24411   "haddpd\t{%2, %0|%0, %2}"
24412   [(set_attr "type" "sseadd")
24413    (set_attr "mode" "V2DF")])
24415 (define_insn "hsubv4sf3"
24416   [(set (match_operand:V4SF 0 "register_operand" "=x")
24417         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24418                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24419                      UNSPEC_HSUB))]
24420   "TARGET_SSE3"
24421   "hsubps\t{%2, %0|%0, %2}"
24422   [(set_attr "type" "sseadd")
24423    (set_attr "mode" "V4SF")])
24425 (define_insn "hsubv2df3"
24426   [(set (match_operand:V2DF 0 "register_operand" "=x")
24427         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24428                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24429                      UNSPEC_HSUB))]
24430   "TARGET_SSE3"
24431   "hsubpd\t{%2, %0|%0, %2}"
24432   [(set_attr "type" "sseadd")
24433    (set_attr "mode" "V2DF")])
24435 (define_insn "movshdup"
24436   [(set (match_operand:V4SF 0 "register_operand" "=x")
24437         (unspec:V4SF
24438          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24439   "TARGET_SSE3"
24440   "movshdup\t{%1, %0|%0, %1}"
24441   [(set_attr "type" "sse")
24442    (set_attr "mode" "V4SF")])
24444 (define_insn "movsldup"
24445   [(set (match_operand:V4SF 0 "register_operand" "=x")
24446         (unspec:V4SF
24447          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24448   "TARGET_SSE3"
24449   "movsldup\t{%1, %0|%0, %1}"
24450   [(set_attr "type" "sse")
24451    (set_attr "mode" "V4SF")])
24453 (define_insn "lddqu"
24454   [(set (match_operand:V16QI 0 "register_operand" "=x")
24455         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24456                        UNSPEC_LDQQU))]
24457   "TARGET_SSE3"
24458   "lddqu\t{%1, %0|%0, %1}"
24459   [(set_attr "type" "ssecvt")
24460    (set_attr "mode" "TI")])
24462 (define_insn "loadddup"
24463   [(set (match_operand:V2DF 0 "register_operand" "=x")
24464         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24465   "TARGET_SSE3"
24466   "movddup\t{%1, %0|%0, %1}"
24467   [(set_attr "type" "ssecvt")
24468    (set_attr "mode" "DF")])
24470 (define_insn "movddup"
24471   [(set (match_operand:V2DF 0 "register_operand" "=x")
24472         (vec_duplicate:V2DF
24473          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24474                         (parallel [(const_int 0)]))))]
24475   "TARGET_SSE3"
24476   "movddup\t{%1, %0|%0, %1}"
24477   [(set_attr "type" "ssecvt")
24478    (set_attr "mode" "DF")])