PR target/14941
[official-gcc.git] / gcc / config / i386 / i386.md
blobf2c3c44dc591b4313f28579218c20fdc671fda5e
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 FLAGS_REG)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg FLAGS_REG)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg FLAGS_REG)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg FLAGS_REG)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
603 (define_insn "*cmphi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
613 (define_insn "*cmphi_1"
614   [(set (reg FLAGS_REG)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
635 (define_insn "*cmpqi_1"
636   [(set (reg FLAGS_REG)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg FLAGS_REG)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg FLAGS_REG)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg FLAGS_REG)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg FLAGS_REG)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg FLAGS_REG)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
803 (define_insn "*cmpfp_0_sf"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "const0_operand" "X"))]
809         UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 0, 0);"
812   [(set_attr "type" "multi")
813    (set_attr "mode" "SF")])
815 (define_insn "*cmpfp_0_df"
816   [(set (match_operand:HI 0 "register_operand" "=a")
817         (unspec:HI
818           [(compare:CCFP
819              (match_operand:DF 1 "register_operand" "f")
820              (match_operand:DF 2 "const0_operand" "X"))]
821         UNSPEC_FNSTSW))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "multi")
825    (set_attr "mode" "DF")])
827 (define_insn "*cmpfp_0_xf"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:XF 1 "register_operand" "f")
832              (match_operand:XF 2 "const0_operand" "X"))]
833         UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 0, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "XF")])
839 (define_insn "*cmpfp_sf"
840   [(set (match_operand:HI 0 "register_operand" "=a")
841         (unspec:HI
842           [(compare:CCFP
843              (match_operand:SF 1 "register_operand" "f")
844              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845           UNSPEC_FNSTSW))]
846   "TARGET_80387"
847   "* return output_fp_compare (insn, operands, 0, 0);"
848   [(set_attr "type" "multi")
849    (set_attr "mode" "SF")])
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "mode" "DF")])
863 (define_insn "*cmpfp_xf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:XF 1 "register_operand" "f")
868              (match_operand:XF 2 "register_operand" "f"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "mode" "XF")])
875 (define_insn "*cmpfp_u"
876   [(set (match_operand:HI 0 "register_operand" "=a")
877         (unspec:HI
878           [(compare:CCFPU
879              (match_operand 1 "register_operand" "f")
880              (match_operand 2 "register_operand" "f"))]
881           UNSPEC_FNSTSW))]
882   "TARGET_80387
883    && FLOAT_MODE_P (GET_MODE (operands[1]))
884    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885   "* return output_fp_compare (insn, operands, 0, 1);"
886   [(set_attr "type" "multi")
887    (set (attr "mode")
888      (cond [(match_operand:SF 1 "" "")
889               (const_string "SF")
890             (match_operand:DF 1 "" "")
891               (const_string "DF")
892            ]
893            (const_string "XF")))])
895 (define_insn "*cmpfp_si"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand 1 "register_operand" "f")
900              (match_operator 3 "float_operator"
901                [(match_operand:SI 2 "memory_operand" "m")]))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387 && TARGET_USE_FIOP
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "fp_int_src" "true")
909    (set_attr "mode" "SI")])
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
914 (define_insn "x86_fnstsw_1"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "fnstsw\t%0"
919   [(set_attr "length" "2")
920    (set_attr "mode" "SI")
921    (set_attr "unit" "i387")])
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
926 (define_insn "x86_sahf_1"
927   [(set (reg:CC FLAGS_REG)
928         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929   "!TARGET_64BIT"
930   "sahf"
931   [(set_attr "length" "1")
932    (set_attr "athlon_decode" "vector")
933    (set_attr "mode" "SI")])
935 ;; Pentium Pro can do steps 1 through 3 in one go.
937 (define_insn "*cmpfp_i"
938   [(set (reg:CCFP FLAGS_REG)
939         (compare:CCFP (match_operand 0 "register_operand" "f")
940                       (match_operand 1 "register_operand" "f")))]
941   "TARGET_80387 && TARGET_CMOVE
942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943    && FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp")
947    (set (attr "mode")
948      (cond [(match_operand:SF 1 "" "")
949               (const_string "SF")
950             (match_operand:DF 1 "" "")
951               (const_string "DF")
952            ]
953            (const_string "XF")))
954    (set_attr "athlon_decode" "vector")])
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_80387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
971 (define_insn "*cmpfp_i_sse_only"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977   "* return output_fp_compare (insn, operands, 1, 0);"
978   [(set_attr "type" "ssecomi")
979    (set (attr "mode")
980      (if_then_else (match_operand:SF 1 "" "")
981         (const_string "SF")
982         (const_string "DF")))
983    (set_attr "athlon_decode" "vector")])
985 (define_insn "*cmpfp_iu"
986   [(set (reg:CCFPU FLAGS_REG)
987         (compare:CCFPU (match_operand 0 "register_operand" "f")
988                        (match_operand 1 "register_operand" "f")))]
989   "TARGET_80387 && TARGET_CMOVE
990    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && FLOAT_MODE_P (GET_MODE (operands[0]))
992    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993   "* return output_fp_compare (insn, operands, 1, 1);"
994   [(set_attr "type" "fcmp")
995    (set (attr "mode")
996      (cond [(match_operand:SF 1 "" "")
997               (const_string "SF")
998             (match_operand:DF 1 "" "")
999               (const_string "DF")
1000            ]
1001            (const_string "XF")))
1002    (set_attr "athlon_decode" "vector")])
1004 (define_insn "*cmpfp_iu_sse"
1005   [(set (reg:CCFPU FLAGS_REG)
1006         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008   "TARGET_80387
1009    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011   "* return output_fp_compare (insn, operands, 1, 1);"
1012   [(set_attr "type" "fcmp,ssecomi")
1013    (set (attr "mode")
1014      (if_then_else (match_operand:SF 1 "" "")
1015         (const_string "SF")
1016         (const_string "DF")))
1017    (set_attr "athlon_decode" "vector")])
1019 (define_insn "*cmpfp_iu_sse_only"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "x")
1022                        (match_operand 1 "nonimmediate_operand" "xm")))]
1023   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1033 ;; Move instructions.
1035 ;; General case of fullword move.
1037 (define_expand "movsi"
1038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039         (match_operand:SI 1 "general_operand" ""))]
1040   ""
1041   "ix86_expand_move (SImode, operands); DONE;")
1043 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1044 ;; general_operand.
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1052 (define_insn "*pushsi2"
1053   [(set (match_operand:SI 0 "push_operand" "=<")
1054         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055   "!TARGET_64BIT"
1056   "push{l}\t%1"
1057   [(set_attr "type" "push")
1058    (set_attr "mode" "SI")])
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062   [(set (match_operand:SI 0 "push_operand" "=X")
1063         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064   "TARGET_64BIT"
1065   "push{q}\t%q1"
1066   [(set_attr "type" "push")
1067    (set_attr "mode" "SI")])
1069 (define_insn "*pushsi2_prologue"
1070   [(set (match_operand:SI 0 "push_operand" "=<")
1071         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072    (clobber (mem:BLK (scratch)))]
1073   "!TARGET_64BIT"
1074   "push{l}\t%1"
1075   [(set_attr "type" "push")
1076    (set_attr "mode" "SI")])
1078 (define_insn "*popsi1_epilogue"
1079   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080         (mem:SI (reg:SI SP_REG)))
1081    (set (reg:SI SP_REG)
1082         (plus:SI (reg:SI SP_REG) (const_int 4)))
1083    (clobber (mem:BLK (scratch)))]
1084   "!TARGET_64BIT"
1085   "pop{l}\t%0"
1086   [(set_attr "type" "pop")
1087    (set_attr "mode" "SI")])
1089 (define_insn "popsi1"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091         (mem:SI (reg:SI SP_REG)))
1092    (set (reg:SI SP_REG)
1093         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094   "!TARGET_64BIT"
1095   "pop{l}\t%0"
1096   [(set_attr "type" "pop")
1097    (set_attr "mode" "SI")])
1099 (define_insn "*movsi_xor"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (match_operand:SI 1 "const0_operand" "i"))
1102    (clobber (reg:CC FLAGS_REG))]
1103   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104   "xor{l}\t{%0, %0|%0, %0}"
1105   [(set_attr "type" "alu1")
1106    (set_attr "mode" "SI")
1107    (set_attr "length_immediate" "0")])
1109 (define_insn "*movsi_or"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (match_operand:SI 1 "immediate_operand" "i"))
1112    (clobber (reg:CC FLAGS_REG))]
1113   "reload_completed
1114    && operands[1] == constm1_rtx
1115    && (TARGET_PENTIUM || optimize_size)"
1117   operands[1] = constm1_rtx;
1118   return "or{l}\t{%1, %0|%0, %1}";
1120   [(set_attr "type" "alu1")
1121    (set_attr "mode" "SI")
1122    (set_attr "length_immediate" "1")])
1124 (define_insn "*movsi_1"
1125   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1126         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1127   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1128    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1130   switch (get_attr_type (insn))
1131     {
1132     case TYPE_SSEMOV:
1133       if (get_attr_mode (insn) == MODE_TI)
1134         return "movdqa\t{%1, %0|%0, %1}";
1135       return "movd\t{%1, %0|%0, %1}";
1137     case TYPE_MMXMOV:
1138       if (get_attr_mode (insn) == MODE_DI)
1139         return "movq\t{%1, %0|%0, %1}";
1140       return "movd\t{%1, %0|%0, %1}";
1142     case TYPE_LEA:
1143       return "lea{l}\t{%1, %0|%0, %1}";
1145     default:
1146       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1147         abort();
1148       return "mov{l}\t{%1, %0|%0, %1}";
1149     }
1151   [(set (attr "type")
1152      (cond [(eq_attr "alternative" "2,3,4")
1153               (const_string "mmxmov")
1154             (eq_attr "alternative" "5,6,7")
1155               (const_string "ssemov")
1156             (and (ne (symbol_ref "flag_pic") (const_int 0))
1157                  (match_operand:SI 1 "symbolic_operand" ""))
1158               (const_string "lea")
1159            ]
1160            (const_string "imov")))
1161    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1163 (define_insn "*movsi_1_nointernunit"
1164   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1165         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1166   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1169   switch (get_attr_type (insn))
1170     {
1171     case TYPE_SSEMOV:
1172       if (get_attr_mode (insn) == MODE_TI)
1173         return "movdqa\t{%1, %0|%0, %1}";
1174       return "movd\t{%1, %0|%0, %1}";
1176     case TYPE_MMXMOV:
1177       if (get_attr_mode (insn) == MODE_DI)
1178         return "movq\t{%1, %0|%0, %1}";
1179       return "movd\t{%1, %0|%0, %1}";
1181     case TYPE_LEA:
1182       return "lea{l}\t{%1, %0|%0, %1}";
1184     default:
1185       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1186         abort();
1187       return "mov{l}\t{%1, %0|%0, %1}";
1188     }
1190   [(set (attr "type")
1191      (cond [(eq_attr "alternative" "2,3,4")
1192               (const_string "mmxmov")
1193             (eq_attr "alternative" "5,6,7")
1194               (const_string "ssemov")
1195             (and (ne (symbol_ref "flag_pic") (const_int 0))
1196                  (match_operand:SI 1 "symbolic_operand" ""))
1197               (const_string "lea")
1198            ]
1199            (const_string "imov")))
1200    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1202 ;; Stores and loads of ax to arbitrary constant address.
1203 ;; We fake an second form of instruction to force reload to load address
1204 ;; into register when rax is not available
1205 (define_insn "*movabssi_1_rex64"
1206   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1207         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1208   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1209   "@
1210    movabs{l}\t{%1, %P0|%P0, %1}
1211    mov{l}\t{%1, %a0|%a0, %1}"
1212   [(set_attr "type" "imov")
1213    (set_attr "modrm" "0,*")
1214    (set_attr "length_address" "8,0")
1215    (set_attr "length_immediate" "0,*")
1216    (set_attr "memory" "store")
1217    (set_attr "mode" "SI")])
1219 (define_insn "*movabssi_2_rex64"
1220   [(set (match_operand:SI 0 "register_operand" "=a,r")
1221         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1222   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1223   "@
1224    movabs{l}\t{%P1, %0|%0, %P1}
1225    mov{l}\t{%a1, %0|%0, %a1}"
1226   [(set_attr "type" "imov")
1227    (set_attr "modrm" "0,*")
1228    (set_attr "length_address" "8,0")
1229    (set_attr "length_immediate" "0")
1230    (set_attr "memory" "load")
1231    (set_attr "mode" "SI")])
1233 (define_insn "*swapsi"
1234   [(set (match_operand:SI 0 "register_operand" "+r")
1235         (match_operand:SI 1 "register_operand" "+r"))
1236    (set (match_dup 1)
1237         (match_dup 0))]
1238   ""
1239   "xchg{l}\t%1, %0"
1240   [(set_attr "type" "imov")
1241    (set_attr "pent_pair" "np")
1242    (set_attr "athlon_decode" "vector")
1243    (set_attr "mode" "SI")
1244    (set_attr "modrm" "0")])
1246 (define_expand "movhi"
1247   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1248         (match_operand:HI 1 "general_operand" ""))]
1249   ""
1250   "ix86_expand_move (HImode, operands); DONE;")
1252 (define_insn "*pushhi2"
1253   [(set (match_operand:HI 0 "push_operand" "=<,<")
1254         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1255   "!TARGET_64BIT"
1256   "@
1257    push{w}\t{|WORD PTR }%1
1258    push{w}\t%1"
1259   [(set_attr "type" "push")
1260    (set_attr "mode" "HI")])
1262 ;; For 64BIT abi we always round up to 8 bytes.
1263 (define_insn "*pushhi2_rex64"
1264   [(set (match_operand:HI 0 "push_operand" "=X")
1265         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1266   "TARGET_64BIT"
1267   "push{q}\t%q1"
1268   [(set_attr "type" "push")
1269    (set_attr "mode" "QI")])
1271 (define_insn "*movhi_1"
1272   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1273         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1274   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1276   switch (get_attr_type (insn))
1277     {
1278     case TYPE_IMOVX:
1279       /* movzwl is faster than movw on p2 due to partial word stalls,
1280          though not as fast as an aligned movl.  */
1281       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1282     default:
1283       if (get_attr_mode (insn) == MODE_SI)
1284         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1285       else
1286         return "mov{w}\t{%1, %0|%0, %1}";
1287     }
1289   [(set (attr "type")
1290      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1291               (const_string "imov")
1292             (and (eq_attr "alternative" "0")
1293                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1294                           (const_int 0))
1295                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1296                           (const_int 0))))
1297               (const_string "imov")
1298             (and (eq_attr "alternative" "1,2")
1299                  (match_operand:HI 1 "aligned_operand" ""))
1300               (const_string "imov")
1301             (and (ne (symbol_ref "TARGET_MOVX")
1302                      (const_int 0))
1303                  (eq_attr "alternative" "0,2"))
1304               (const_string "imovx")
1305            ]
1306            (const_string "imov")))
1307     (set (attr "mode")
1308       (cond [(eq_attr "type" "imovx")
1309                (const_string "SI")
1310              (and (eq_attr "alternative" "1,2")
1311                   (match_operand:HI 1 "aligned_operand" ""))
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "0")
1314                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315                            (const_int 0))
1316                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1317                            (const_int 0))))
1318                (const_string "SI")
1319             ]
1320             (const_string "HI")))])
1322 ;; Stores and loads of ax to arbitrary constant address.
1323 ;; We fake an second form of instruction to force reload to load address
1324 ;; into register when rax is not available
1325 (define_insn "*movabshi_1_rex64"
1326   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1327         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1328   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1329   "@
1330    movabs{w}\t{%1, %P0|%P0, %1}
1331    mov{w}\t{%1, %a0|%a0, %1}"
1332   [(set_attr "type" "imov")
1333    (set_attr "modrm" "0,*")
1334    (set_attr "length_address" "8,0")
1335    (set_attr "length_immediate" "0,*")
1336    (set_attr "memory" "store")
1337    (set_attr "mode" "HI")])
1339 (define_insn "*movabshi_2_rex64"
1340   [(set (match_operand:HI 0 "register_operand" "=a,r")
1341         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1342   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1343   "@
1344    movabs{w}\t{%P1, %0|%0, %P1}
1345    mov{w}\t{%a1, %0|%0, %a1}"
1346   [(set_attr "type" "imov")
1347    (set_attr "modrm" "0,*")
1348    (set_attr "length_address" "8,0")
1349    (set_attr "length_immediate" "0")
1350    (set_attr "memory" "load")
1351    (set_attr "mode" "HI")])
1353 (define_insn "*swaphi_1"
1354   [(set (match_operand:HI 0 "register_operand" "+r")
1355         (match_operand:HI 1 "register_operand" "+r"))
1356    (set (match_dup 1)
1357         (match_dup 0))]
1358   "TARGET_PARTIAL_REG_STALL"
1359   "xchg{w}\t%1, %0"
1360   [(set_attr "type" "imov")
1361    (set_attr "pent_pair" "np")
1362    (set_attr "mode" "HI")
1363    (set_attr "modrm" "0")])
1365 (define_insn "*swaphi_2"
1366   [(set (match_operand:HI 0 "register_operand" "+r")
1367         (match_operand:HI 1 "register_operand" "+r"))
1368    (set (match_dup 1)
1369         (match_dup 0))]
1370   "! TARGET_PARTIAL_REG_STALL"
1371   "xchg{l}\t%k1, %k0"
1372   [(set_attr "type" "imov")
1373    (set_attr "pent_pair" "np")
1374    (set_attr "mode" "SI")
1375    (set_attr "modrm" "0")])
1377 (define_expand "movstricthi"
1378   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1379         (match_operand:HI 1 "general_operand" ""))]
1380   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1382   /* Don't generate memory->memory moves, go through a register */
1383   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1384     operands[1] = force_reg (HImode, operands[1]);
1387 (define_insn "*movstricthi_1"
1388   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1389         (match_operand:HI 1 "general_operand" "rn,m"))]
1390   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1391    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1392   "mov{w}\t{%1, %0|%0, %1}"
1393   [(set_attr "type" "imov")
1394    (set_attr "mode" "HI")])
1396 (define_insn "*movstricthi_xor"
1397   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1398         (match_operand:HI 1 "const0_operand" "i"))
1399    (clobber (reg:CC FLAGS_REG))]
1400   "reload_completed
1401    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1402   "xor{w}\t{%0, %0|%0, %0}"
1403   [(set_attr "type" "alu1")
1404    (set_attr "mode" "HI")
1405    (set_attr "length_immediate" "0")])
1407 (define_expand "movqi"
1408   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1409         (match_operand:QI 1 "general_operand" ""))]
1410   ""
1411   "ix86_expand_move (QImode, operands); DONE;")
1413 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1414 ;; "push a byte".  But actually we use pushw, which has the effect
1415 ;; of rounding the amount pushed up to a halfword.
1417 (define_insn "*pushqi2"
1418   [(set (match_operand:QI 0 "push_operand" "=X,X")
1419         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1420   "!TARGET_64BIT"
1421   "@
1422    push{w}\t{|word ptr }%1
1423    push{w}\t%w1"
1424   [(set_attr "type" "push")
1425    (set_attr "mode" "HI")])
1427 ;; For 64BIT abi we always round up to 8 bytes.
1428 (define_insn "*pushqi2_rex64"
1429   [(set (match_operand:QI 0 "push_operand" "=X")
1430         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1431   "TARGET_64BIT"
1432   "push{q}\t%q1"
1433   [(set_attr "type" "push")
1434    (set_attr "mode" "QI")])
1436 ;; Situation is quite tricky about when to choose full sized (SImode) move
1437 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1438 ;; partial register dependency machines (such as AMD Athlon), where QImode
1439 ;; moves issue extra dependency and for partial register stalls machines
1440 ;; that don't use QImode patterns (and QImode move cause stall on the next
1441 ;; instruction).
1443 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1444 ;; register stall machines with, where we use QImode instructions, since
1445 ;; partial register stall can be caused there.  Then we use movzx.
1446 (define_insn "*movqi_1"
1447   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1448         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1449   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1451   switch (get_attr_type (insn))
1452     {
1453     case TYPE_IMOVX:
1454       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1455         abort ();
1456       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1457     default:
1458       if (get_attr_mode (insn) == MODE_SI)
1459         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1460       else
1461         return "mov{b}\t{%1, %0|%0, %1}";
1462     }
1464   [(set (attr "type")
1465      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1466               (const_string "imov")
1467             (and (eq_attr "alternative" "3")
1468                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1469                           (const_int 0))
1470                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1471                           (const_int 0))))
1472               (const_string "imov")
1473             (eq_attr "alternative" "3,5")
1474               (const_string "imovx")
1475             (and (ne (symbol_ref "TARGET_MOVX")
1476                      (const_int 0))
1477                  (eq_attr "alternative" "2"))
1478               (const_string "imovx")
1479            ]
1480            (const_string "imov")))
1481    (set (attr "mode")
1482       (cond [(eq_attr "alternative" "3,4,5")
1483                (const_string "SI")
1484              (eq_attr "alternative" "6")
1485                (const_string "QI")
1486              (eq_attr "type" "imovx")
1487                (const_string "SI")
1488              (and (eq_attr "type" "imov")
1489                   (and (eq_attr "alternative" "0,1,2")
1490                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1491                            (const_int 0))))
1492                (const_string "SI")
1493              ;; Avoid partial register stalls when not using QImode arithmetic
1494              (and (eq_attr "type" "imov")
1495                   (and (eq_attr "alternative" "0,1,2")
1496                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1497                                 (const_int 0))
1498                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1499                                 (const_int 0)))))
1500                (const_string "SI")
1501            ]
1502            (const_string "QI")))])
1504 (define_expand "reload_outqi"
1505   [(parallel [(match_operand:QI 0 "" "=m")
1506               (match_operand:QI 1 "register_operand" "r")
1507               (match_operand:QI 2 "register_operand" "=&q")])]
1508   ""
1510   rtx op0, op1, op2;
1511   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1513   if (reg_overlap_mentioned_p (op2, op0))
1514     abort ();
1515   if (! q_regs_operand (op1, QImode))
1516     {
1517       emit_insn (gen_movqi (op2, op1));
1518       op1 = op2;
1519     }
1520   emit_insn (gen_movqi (op0, op1));
1521   DONE;
1524 (define_insn "*swapqi"
1525   [(set (match_operand:QI 0 "register_operand" "+r")
1526         (match_operand:QI 1 "register_operand" "+r"))
1527    (set (match_dup 1)
1528         (match_dup 0))]
1529   ""
1530   "xchg{b}\t%1, %0"
1531   [(set_attr "type" "imov")
1532    (set_attr "pent_pair" "np")
1533    (set_attr "mode" "QI")
1534    (set_attr "modrm" "0")])
1536 (define_expand "movstrictqi"
1537   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1538         (match_operand:QI 1 "general_operand" ""))]
1539   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1541   /* Don't generate memory->memory moves, go through a register.  */
1542   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1543     operands[1] = force_reg (QImode, operands[1]);
1546 (define_insn "*movstrictqi_1"
1547   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1548         (match_operand:QI 1 "general_operand" "*qn,m"))]
1549   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1550    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1551   "mov{b}\t{%1, %0|%0, %1}"
1552   [(set_attr "type" "imov")
1553    (set_attr "mode" "QI")])
1555 (define_insn "*movstrictqi_xor"
1556   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1557         (match_operand:QI 1 "const0_operand" "i"))
1558    (clobber (reg:CC FLAGS_REG))]
1559   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1560   "xor{b}\t{%0, %0|%0, %0}"
1561   [(set_attr "type" "alu1")
1562    (set_attr "mode" "QI")
1563    (set_attr "length_immediate" "0")])
1565 (define_insn "*movsi_extv_1"
1566   [(set (match_operand:SI 0 "register_operand" "=R")
1567         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1568                          (const_int 8)
1569                          (const_int 8)))]
1570   ""
1571   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1572   [(set_attr "type" "imovx")
1573    (set_attr "mode" "SI")])
1575 (define_insn "*movhi_extv_1"
1576   [(set (match_operand:HI 0 "register_operand" "=R")
1577         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1578                          (const_int 8)
1579                          (const_int 8)))]
1580   ""
1581   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1582   [(set_attr "type" "imovx")
1583    (set_attr "mode" "SI")])
1585 (define_insn "*movqi_extv_1"
1586   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1587         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1588                          (const_int 8)
1589                          (const_int 8)))]
1590   "!TARGET_64BIT"
1592   switch (get_attr_type (insn))
1593     {
1594     case TYPE_IMOVX:
1595       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1596     default:
1597       return "mov{b}\t{%h1, %0|%0, %h1}";
1598     }
1600   [(set (attr "type")
1601      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1602                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1603                              (ne (symbol_ref "TARGET_MOVX")
1604                                  (const_int 0))))
1605         (const_string "imovx")
1606         (const_string "imov")))
1607    (set (attr "mode")
1608      (if_then_else (eq_attr "type" "imovx")
1609         (const_string "SI")
1610         (const_string "QI")))])
1612 (define_insn "*movqi_extv_1_rex64"
1613   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1614         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1615                          (const_int 8)
1616                          (const_int 8)))]
1617   "TARGET_64BIT"
1619   switch (get_attr_type (insn))
1620     {
1621     case TYPE_IMOVX:
1622       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1623     default:
1624       return "mov{b}\t{%h1, %0|%0, %h1}";
1625     }
1627   [(set (attr "type")
1628      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1629                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1630                              (ne (symbol_ref "TARGET_MOVX")
1631                                  (const_int 0))))
1632         (const_string "imovx")
1633         (const_string "imov")))
1634    (set (attr "mode")
1635      (if_then_else (eq_attr "type" "imovx")
1636         (const_string "SI")
1637         (const_string "QI")))])
1639 ;; Stores and loads of ax to arbitrary constant address.
1640 ;; We fake an second form of instruction to force reload to load address
1641 ;; into register when rax is not available
1642 (define_insn "*movabsqi_1_rex64"
1643   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1644         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1645   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1646   "@
1647    movabs{b}\t{%1, %P0|%P0, %1}
1648    mov{b}\t{%1, %a0|%a0, %1}"
1649   [(set_attr "type" "imov")
1650    (set_attr "modrm" "0,*")
1651    (set_attr "length_address" "8,0")
1652    (set_attr "length_immediate" "0,*")
1653    (set_attr "memory" "store")
1654    (set_attr "mode" "QI")])
1656 (define_insn "*movabsqi_2_rex64"
1657   [(set (match_operand:QI 0 "register_operand" "=a,r")
1658         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1659   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1660   "@
1661    movabs{b}\t{%P1, %0|%0, %P1}
1662    mov{b}\t{%a1, %0|%0, %a1}"
1663   [(set_attr "type" "imov")
1664    (set_attr "modrm" "0,*")
1665    (set_attr "length_address" "8,0")
1666    (set_attr "length_immediate" "0")
1667    (set_attr "memory" "load")
1668    (set_attr "mode" "QI")])
1670 (define_insn "*movsi_extzv_1"
1671   [(set (match_operand:SI 0 "register_operand" "=R")
1672         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1673                          (const_int 8)
1674                          (const_int 8)))]
1675   ""
1676   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1677   [(set_attr "type" "imovx")
1678    (set_attr "mode" "SI")])
1680 (define_insn "*movqi_extzv_2"
1681   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1682         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1683                                     (const_int 8)
1684                                     (const_int 8)) 0))]
1685   "!TARGET_64BIT"
1687   switch (get_attr_type (insn))
1688     {
1689     case TYPE_IMOVX:
1690       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1691     default:
1692       return "mov{b}\t{%h1, %0|%0, %h1}";
1693     }
1695   [(set (attr "type")
1696      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1697                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1698                              (ne (symbol_ref "TARGET_MOVX")
1699                                  (const_int 0))))
1700         (const_string "imovx")
1701         (const_string "imov")))
1702    (set (attr "mode")
1703      (if_then_else (eq_attr "type" "imovx")
1704         (const_string "SI")
1705         (const_string "QI")))])
1707 (define_insn "*movqi_extzv_2_rex64"
1708   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1709         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1710                                     (const_int 8)
1711                                     (const_int 8)) 0))]
1712   "TARGET_64BIT"
1714   switch (get_attr_type (insn))
1715     {
1716     case TYPE_IMOVX:
1717       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1718     default:
1719       return "mov{b}\t{%h1, %0|%0, %h1}";
1720     }
1722   [(set (attr "type")
1723      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1724                         (ne (symbol_ref "TARGET_MOVX")
1725                             (const_int 0)))
1726         (const_string "imovx")
1727         (const_string "imov")))
1728    (set (attr "mode")
1729      (if_then_else (eq_attr "type" "imovx")
1730         (const_string "SI")
1731         (const_string "QI")))])
1733 (define_insn "movsi_insv_1"
1734   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1735                          (const_int 8)
1736                          (const_int 8))
1737         (match_operand:SI 1 "general_operand" "Qmn"))]
1738   "!TARGET_64BIT"
1739   "mov{b}\t{%b1, %h0|%h0, %b1}"
1740   [(set_attr "type" "imov")
1741    (set_attr "mode" "QI")])
1743 (define_insn "movdi_insv_1_rex64"
1744   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1745                          (const_int 8)
1746                          (const_int 8))
1747         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1748   "TARGET_64BIT"
1749   "mov{b}\t{%b1, %h0|%h0, %b1}"
1750   [(set_attr "type" "imov")
1751    (set_attr "mode" "QI")])
1753 (define_insn "*movqi_insv_2"
1754   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1755                          (const_int 8)
1756                          (const_int 8))
1757         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1758                      (const_int 8)))]
1759   ""
1760   "mov{b}\t{%h1, %h0|%h0, %h1}"
1761   [(set_attr "type" "imov")
1762    (set_attr "mode" "QI")])
1764 (define_expand "movdi"
1765   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1766         (match_operand:DI 1 "general_operand" ""))]
1767   ""
1768   "ix86_expand_move (DImode, operands); DONE;")
1770 (define_insn "*pushdi"
1771   [(set (match_operand:DI 0 "push_operand" "=<")
1772         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1773   "!TARGET_64BIT"
1774   "#")
1776 (define_insn "pushdi2_rex64"
1777   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1778         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1779   "TARGET_64BIT"
1780   "@
1781    push{q}\t%1
1782    #"
1783   [(set_attr "type" "push,multi")
1784    (set_attr "mode" "DI")])
1786 ;; Convert impossible pushes of immediate to existing instructions.
1787 ;; First try to get scratch register and go through it.  In case this
1788 ;; fails, push sign extended lower part first and then overwrite
1789 ;; upper part by 32bit move.
1790 (define_peephole2
1791   [(match_scratch:DI 2 "r")
1792    (set (match_operand:DI 0 "push_operand" "")
1793         (match_operand:DI 1 "immediate_operand" ""))]
1794   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1795    && !x86_64_immediate_operand (operands[1], DImode)"
1796   [(set (match_dup 2) (match_dup 1))
1797    (set (match_dup 0) (match_dup 2))]
1798   "")
1800 ;; We need to define this as both peepholer and splitter for case
1801 ;; peephole2 pass is not run.
1802 ;; "&& 1" is needed to keep it from matching the previous pattern.
1803 (define_peephole2
1804   [(set (match_operand:DI 0 "push_operand" "")
1805         (match_operand:DI 1 "immediate_operand" ""))]
1806   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1807    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1808   [(set (match_dup 0) (match_dup 1))
1809    (set (match_dup 2) (match_dup 3))]
1810   "split_di (operands + 1, 1, operands + 2, operands + 3);
1811    operands[1] = gen_lowpart (DImode, operands[2]);
1812    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1813                                                     GEN_INT (4)));
1814   ")
1816 (define_split
1817   [(set (match_operand:DI 0 "push_operand" "")
1818         (match_operand:DI 1 "immediate_operand" ""))]
1819   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1820    && !symbolic_operand (operands[1], DImode)
1821    && !x86_64_immediate_operand (operands[1], DImode)"
1822   [(set (match_dup 0) (match_dup 1))
1823    (set (match_dup 2) (match_dup 3))]
1824   "split_di (operands + 1, 1, operands + 2, operands + 3);
1825    operands[1] = gen_lowpart (DImode, operands[2]);
1826    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1827                                                     GEN_INT (4)));
1828   ")
1830 (define_insn "*pushdi2_prologue_rex64"
1831   [(set (match_operand:DI 0 "push_operand" "=<")
1832         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1833    (clobber (mem:BLK (scratch)))]
1834   "TARGET_64BIT"
1835   "push{q}\t%1"
1836   [(set_attr "type" "push")
1837    (set_attr "mode" "DI")])
1839 (define_insn "*popdi1_epilogue_rex64"
1840   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1841         (mem:DI (reg:DI SP_REG)))
1842    (set (reg:DI SP_REG)
1843         (plus:DI (reg:DI SP_REG) (const_int 8)))
1844    (clobber (mem:BLK (scratch)))]
1845   "TARGET_64BIT"
1846   "pop{q}\t%0"
1847   [(set_attr "type" "pop")
1848    (set_attr "mode" "DI")])
1850 (define_insn "popdi1"
1851   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1852         (mem:DI (reg:DI SP_REG)))
1853    (set (reg:DI SP_REG)
1854         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1855   "TARGET_64BIT"
1856   "pop{q}\t%0"
1857   [(set_attr "type" "pop")
1858    (set_attr "mode" "DI")])
1860 (define_insn "*movdi_xor_rex64"
1861   [(set (match_operand:DI 0 "register_operand" "=r")
1862         (match_operand:DI 1 "const0_operand" "i"))
1863    (clobber (reg:CC FLAGS_REG))]
1864   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1865    && reload_completed"
1866   "xor{l}\t{%k0, %k0|%k0, %k0}"
1867   [(set_attr "type" "alu1")
1868    (set_attr "mode" "SI")
1869    (set_attr "length_immediate" "0")])
1871 (define_insn "*movdi_or_rex64"
1872   [(set (match_operand:DI 0 "register_operand" "=r")
1873         (match_operand:DI 1 "const_int_operand" "i"))
1874    (clobber (reg:CC FLAGS_REG))]
1875   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1876    && reload_completed
1877    && operands[1] == constm1_rtx"
1879   operands[1] = constm1_rtx;
1880   return "or{q}\t{%1, %0|%0, %1}";
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "DI")
1884    (set_attr "length_immediate" "1")])
1886 (define_insn "*movdi_2"
1887   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1888         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1889   "!TARGET_64BIT
1890    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1891   "@
1892    #
1893    #
1894    movq\t{%1, %0|%0, %1}
1895    movq\t{%1, %0|%0, %1}
1896    movq\t{%1, %0|%0, %1}
1897    movdqa\t{%1, %0|%0, %1}
1898    movq\t{%1, %0|%0, %1}"
1899   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1900    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1902 (define_split
1903   [(set (match_operand:DI 0 "push_operand" "")
1904         (match_operand:DI 1 "general_operand" ""))]
1905   "!TARGET_64BIT && reload_completed
1906    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1907   [(const_int 0)]
1908   "ix86_split_long_move (operands); DONE;")
1910 ;; %%% This multiword shite has got to go.
1911 (define_split
1912   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1913         (match_operand:DI 1 "general_operand" ""))]
1914   "!TARGET_64BIT && reload_completed
1915    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1916    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1917   [(const_int 0)]
1918   "ix86_split_long_move (operands); DONE;")
1920 (define_insn "*movdi_1_rex64"
1921   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1922         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1923   "TARGET_64BIT
1924    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1925    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1927   switch (get_attr_type (insn))
1928     {
1929     case TYPE_SSECVT:
1930       if (which_alternative == 11)
1931         return "movq2dq\t{%1, %0|%0, %1}";
1932       else
1933         return "movdq2q\t{%1, %0|%0, %1}";
1934     case TYPE_SSEMOV:
1935       if (get_attr_mode (insn) == MODE_TI)
1936           return "movdqa\t{%1, %0|%0, %1}";
1937       /* FALLTHRU */
1938     case TYPE_MMXMOV:
1939       /* Moves from and into integer register is done using movd opcode with
1940          REX prefix.  */
1941       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1942           return "movd\t{%1, %0|%0, %1}";
1943       return "movq\t{%1, %0|%0, %1}";
1944     case TYPE_MULTI:
1945       return "#";
1946     case TYPE_LEA:
1947       return "lea{q}\t{%a1, %0|%0, %a1}";
1948     default:
1949       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1950         abort ();
1951       if (get_attr_mode (insn) == MODE_SI)
1952         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1953       else if (which_alternative == 2)
1954         return "movabs{q}\t{%1, %0|%0, %1}";
1955       else
1956         return "mov{q}\t{%1, %0|%0, %1}";
1957     }
1959   [(set (attr "type")
1960      (cond [(eq_attr "alternative" "5,6,7")
1961               (const_string "mmxmov")
1962             (eq_attr "alternative" "8,9,10")
1963               (const_string "ssemov")
1964             (eq_attr "alternative" "11,12")
1965               (const_string "ssecvt")
1966             (eq_attr "alternative" "4")
1967               (const_string "multi")
1968             (and (ne (symbol_ref "flag_pic") (const_int 0))
1969                  (match_operand:DI 1 "symbolic_operand" ""))
1970               (const_string "lea")
1971            ]
1972            (const_string "imov")))
1973    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1974    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1975    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1977 (define_insn "*movdi_1_rex64_nointerunit"
1978   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1979         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1980   "TARGET_64BIT
1981    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1982    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1984   switch (get_attr_type (insn))
1985     {
1986     case TYPE_SSEMOV:
1987       if (get_attr_mode (insn) == MODE_TI)
1988           return "movdqa\t{%1, %0|%0, %1}";
1989       /* FALLTHRU */
1990     case TYPE_MMXMOV:
1991       return "movq\t{%1, %0|%0, %1}";
1992     case TYPE_MULTI:
1993       return "#";
1994     case TYPE_LEA:
1995       return "lea{q}\t{%a1, %0|%0, %a1}";
1996     default:
1997       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1998         abort ();
1999       if (get_attr_mode (insn) == MODE_SI)
2000         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2001       else if (which_alternative == 2)
2002         return "movabs{q}\t{%1, %0|%0, %1}";
2003       else
2004         return "mov{q}\t{%1, %0|%0, %1}";
2005     }
2007   [(set (attr "type")
2008      (cond [(eq_attr "alternative" "5,6,7")
2009               (const_string "mmxmov")
2010             (eq_attr "alternative" "8,9,10")
2011               (const_string "ssemov")
2012             (eq_attr "alternative" "4")
2013               (const_string "multi")
2014             (and (ne (symbol_ref "flag_pic") (const_int 0))
2015                  (match_operand:DI 1 "symbolic_operand" ""))
2016               (const_string "lea")
2017            ]
2018            (const_string "imov")))
2019    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2020    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2021    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2023 ;; Stores and loads of ax to arbitrary constant address.
2024 ;; We fake an second form of instruction to force reload to load address
2025 ;; into register when rax is not available
2026 (define_insn "*movabsdi_1_rex64"
2027   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2028         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2029   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2030   "@
2031    movabs{q}\t{%1, %P0|%P0, %1}
2032    mov{q}\t{%1, %a0|%a0, %1}"
2033   [(set_attr "type" "imov")
2034    (set_attr "modrm" "0,*")
2035    (set_attr "length_address" "8,0")
2036    (set_attr "length_immediate" "0,*")
2037    (set_attr "memory" "store")
2038    (set_attr "mode" "DI")])
2040 (define_insn "*movabsdi_2_rex64"
2041   [(set (match_operand:DI 0 "register_operand" "=a,r")
2042         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2043   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2044   "@
2045    movabs{q}\t{%P1, %0|%0, %P1}
2046    mov{q}\t{%a1, %0|%0, %a1}"
2047   [(set_attr "type" "imov")
2048    (set_attr "modrm" "0,*")
2049    (set_attr "length_address" "8,0")
2050    (set_attr "length_immediate" "0")
2051    (set_attr "memory" "load")
2052    (set_attr "mode" "DI")])
2054 ;; Convert impossible stores of immediate to existing instructions.
2055 ;; First try to get scratch register and go through it.  In case this
2056 ;; fails, move by 32bit parts.
2057 (define_peephole2
2058   [(match_scratch:DI 2 "r")
2059    (set (match_operand:DI 0 "memory_operand" "")
2060         (match_operand:DI 1 "immediate_operand" ""))]
2061   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2062    && !x86_64_immediate_operand (operands[1], DImode)"
2063   [(set (match_dup 2) (match_dup 1))
2064    (set (match_dup 0) (match_dup 2))]
2065   "")
2067 ;; We need to define this as both peepholer and splitter for case
2068 ;; peephole2 pass is not run.
2069 ;; "&& 1" is needed to keep it from matching the previous pattern.
2070 (define_peephole2
2071   [(set (match_operand:DI 0 "memory_operand" "")
2072         (match_operand:DI 1 "immediate_operand" ""))]
2073   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2074    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2075   [(set (match_dup 2) (match_dup 3))
2076    (set (match_dup 4) (match_dup 5))]
2077   "split_di (operands, 2, operands + 2, operands + 4);")
2079 (define_split
2080   [(set (match_operand:DI 0 "memory_operand" "")
2081         (match_operand:DI 1 "immediate_operand" ""))]
2082   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2083    && !symbolic_operand (operands[1], DImode)
2084    && !x86_64_immediate_operand (operands[1], DImode)"
2085   [(set (match_dup 2) (match_dup 3))
2086    (set (match_dup 4) (match_dup 5))]
2087   "split_di (operands, 2, operands + 2, operands + 4);")
2089 (define_insn "*swapdi_rex64"
2090   [(set (match_operand:DI 0 "register_operand" "+r")
2091         (match_operand:DI 1 "register_operand" "+r"))
2092    (set (match_dup 1)
2093         (match_dup 0))]
2094   "TARGET_64BIT"
2095   "xchg{q}\t%1, %0"
2096   [(set_attr "type" "imov")
2097    (set_attr "pent_pair" "np")
2098    (set_attr "athlon_decode" "vector")
2099    (set_attr "mode" "DI")
2100    (set_attr "modrm" "0")])
2102   
2103 (define_expand "movsf"
2104   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2105         (match_operand:SF 1 "general_operand" ""))]
2106   ""
2107   "ix86_expand_move (SFmode, operands); DONE;")
2109 (define_insn "*pushsf"
2110   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2111         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2112   "!TARGET_64BIT"
2114   switch (which_alternative)
2115     {
2116     case 1:
2117       return "push{l}\t%1";
2119     default:
2120       /* This insn should be already split before reg-stack.  */
2121       abort ();
2122     }
2124   [(set_attr "type" "multi,push,multi")
2125    (set_attr "mode" "SF,SI,SF")])
2127 (define_insn "*pushsf_rex64"
2128   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2129         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2130   "TARGET_64BIT"
2132   switch (which_alternative)
2133     {
2134     case 1:
2135       return "push{q}\t%q1";
2137     default:
2138       /* This insn should be already split before reg-stack.  */
2139       abort ();
2140     }
2142   [(set_attr "type" "multi,push,multi")
2143    (set_attr "mode" "SF,DI,SF")])
2145 (define_split
2146   [(set (match_operand:SF 0 "push_operand" "")
2147         (match_operand:SF 1 "memory_operand" ""))]
2148   "reload_completed
2149    && GET_CODE (operands[1]) == MEM
2150    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2151    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2152   [(set (match_dup 0)
2153         (match_dup 1))]
2154   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2157 ;; %%% Kill this when call knows how to work this out.
2158 (define_split
2159   [(set (match_operand:SF 0 "push_operand" "")
2160         (match_operand:SF 1 "any_fp_register_operand" ""))]
2161   "!TARGET_64BIT"
2162   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2163    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2165 (define_split
2166   [(set (match_operand:SF 0 "push_operand" "")
2167         (match_operand:SF 1 "any_fp_register_operand" ""))]
2168   "TARGET_64BIT"
2169   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2170    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2172 (define_insn "*movsf_1"
2173   [(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")
2174         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2175   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2176    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2177    && (reload_in_progress || reload_completed
2178        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2179        || GET_CODE (operands[1]) != CONST_DOUBLE
2180        || memory_operand (operands[0], SFmode))" 
2182   switch (which_alternative)
2183     {
2184     case 0:
2185       return output_387_reg_move (insn, operands);
2187     case 1:
2188       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2189         return "fstp%z0\t%y0";
2190       else
2191         return "fst%z0\t%y0";
2193     case 2:
2194       return standard_80387_constant_opcode (operands[1]);
2196     case 3:
2197     case 4:
2198       return "mov{l}\t{%1, %0|%0, %1}";
2199     case 5:
2200       if (get_attr_mode (insn) == MODE_TI)
2201         return "pxor\t%0, %0";
2202       else
2203         return "xorps\t%0, %0";
2204     case 6:
2205       if (get_attr_mode (insn) == MODE_V4SF)
2206         return "movaps\t{%1, %0|%0, %1}";
2207       else
2208         return "movss\t{%1, %0|%0, %1}";
2209     case 7:
2210     case 8:
2211       return "movss\t{%1, %0|%0, %1}";
2213     case 9:
2214     case 10:
2215       return "movd\t{%1, %0|%0, %1}";
2217     case 11:
2218       return "movq\t{%1, %0|%0, %1}";
2220     default:
2221       abort();
2222     }
2224   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2225    (set (attr "mode")
2226         (cond [(eq_attr "alternative" "3,4,9,10")
2227                  (const_string "SI")
2228                (eq_attr "alternative" "5")
2229                  (if_then_else
2230                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2231                                  (const_int 0))
2232                              (ne (symbol_ref "TARGET_SSE2")
2233                                  (const_int 0)))
2234                         (eq (symbol_ref "optimize_size")
2235                             (const_int 0)))
2236                    (const_string "TI")
2237                    (const_string "V4SF"))
2238                /* For architectures resolving dependencies on
2239                   whole SSE registers use APS move to break dependency
2240                   chains, otherwise use short move to avoid extra work. 
2242                   Do the same for architectures resolving dependencies on
2243                   the parts.  While in DF mode it is better to always handle
2244                   just register parts, the SF mode is different due to lack
2245                   of instructions to load just part of the register.  It is
2246                   better to maintain the whole registers in single format
2247                   to avoid problems on using packed logical operations.  */
2248                (eq_attr "alternative" "6")
2249                  (if_then_else
2250                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2251                             (const_int 0))
2252                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2253                             (const_int 0)))
2254                    (const_string "V4SF")
2255                    (const_string "SF"))
2256                (eq_attr "alternative" "11")
2257                  (const_string "DI")]
2258                (const_string "SF")))])
2260 (define_insn "*movsf_1_nointerunit"
2261   [(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")
2262         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2263   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2264    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2265    && (reload_in_progress || reload_completed
2266        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2267        || GET_CODE (operands[1]) != CONST_DOUBLE
2268        || memory_operand (operands[0], SFmode))" 
2270   switch (which_alternative)
2271     {
2272     case 0:
2273       return output_387_reg_move (insn, operands);
2275     case 1:
2276       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2277         return "fstp%z0\t%y0";
2278       else
2279         return "fst%z0\t%y0";
2281     case 2:
2282       return standard_80387_constant_opcode (operands[1]);
2284     case 3:
2285     case 4:
2286       return "mov{l}\t{%1, %0|%0, %1}";
2287     case 5:
2288       if (get_attr_mode (insn) == MODE_TI)
2289         return "pxor\t%0, %0";
2290       else
2291         return "xorps\t%0, %0";
2292     case 6:
2293       if (get_attr_mode (insn) == MODE_V4SF)
2294         return "movaps\t{%1, %0|%0, %1}";
2295       else
2296         return "movss\t{%1, %0|%0, %1}";
2297     case 7:
2298     case 8:
2299       return "movss\t{%1, %0|%0, %1}";
2301     case 9:
2302     case 10:
2303       return "movd\t{%1, %0|%0, %1}";
2305     case 11:
2306       return "movq\t{%1, %0|%0, %1}";
2308     default:
2309       abort();
2310     }
2312   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2313    (set (attr "mode")
2314         (cond [(eq_attr "alternative" "3,4,9,10")
2315                  (const_string "SI")
2316                (eq_attr "alternative" "5")
2317                  (if_then_else
2318                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2319                                  (const_int 0))
2320                              (ne (symbol_ref "TARGET_SSE2")
2321                                  (const_int 0)))
2322                         (eq (symbol_ref "optimize_size")
2323                             (const_int 0)))
2324                    (const_string "TI")
2325                    (const_string "V4SF"))
2326                /* For architectures resolving dependencies on
2327                   whole SSE registers use APS move to break dependency
2328                   chains, otherwise use short move to avoid extra work. 
2330                   Do the same for architectures resolving dependencies on
2331                   the parts.  While in DF mode it is better to always handle
2332                   just register parts, the SF mode is different due to lack
2333                   of instructions to load just part of the register.  It is
2334                   better to maintain the whole registers in single format
2335                   to avoid problems on using packed logical operations.  */
2336                (eq_attr "alternative" "6")
2337                  (if_then_else
2338                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2339                             (const_int 0))
2340                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2341                             (const_int 0)))
2342                    (const_string "V4SF")
2343                    (const_string "SF"))
2344                (eq_attr "alternative" "11")
2345                  (const_string "DI")]
2346                (const_string "SF")))])
2348 (define_insn "*swapsf"
2349   [(set (match_operand:SF 0 "register_operand" "+f")
2350         (match_operand:SF 1 "register_operand" "+f"))
2351    (set (match_dup 1)
2352         (match_dup 0))]
2353   "reload_completed || !TARGET_SSE"
2355   if (STACK_TOP_P (operands[0]))
2356     return "fxch\t%1";
2357   else
2358     return "fxch\t%0";
2360   [(set_attr "type" "fxch")
2361    (set_attr "mode" "SF")])
2363 (define_expand "movdf"
2364   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2365         (match_operand:DF 1 "general_operand" ""))]
2366   ""
2367   "ix86_expand_move (DFmode, operands); DONE;")
2369 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2370 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2371 ;; On the average, pushdf using integers can be still shorter.  Allow this
2372 ;; pattern for optimize_size too.
2374 (define_insn "*pushdf_nointeger"
2375   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2376         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2377   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2379   /* This insn should be already split before reg-stack.  */
2380   abort ();
2382   [(set_attr "type" "multi")
2383    (set_attr "mode" "DF,SI,SI,DF")])
2385 (define_insn "*pushdf_integer"
2386   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2387         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2388   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2390   /* This insn should be already split before reg-stack.  */
2391   abort ();
2393   [(set_attr "type" "multi")
2394    (set_attr "mode" "DF,SI,DF")])
2396 ;; %%% Kill this when call knows how to work this out.
2397 (define_split
2398   [(set (match_operand:DF 0 "push_operand" "")
2399         (match_operand:DF 1 "any_fp_register_operand" ""))]
2400   "!TARGET_64BIT && reload_completed"
2401   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2402    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2403   "")
2405 (define_split
2406   [(set (match_operand:DF 0 "push_operand" "")
2407         (match_operand:DF 1 "any_fp_register_operand" ""))]
2408   "TARGET_64BIT && reload_completed"
2409   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2410    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2411   "")
2413 (define_split
2414   [(set (match_operand:DF 0 "push_operand" "")
2415         (match_operand:DF 1 "general_operand" ""))]
2416   "reload_completed"
2417   [(const_int 0)]
2418   "ix86_split_long_move (operands); DONE;")
2420 ;; Moving is usually shorter when only FP registers are used. This separate
2421 ;; movdf pattern avoids the use of integer registers for FP operations
2422 ;; when optimizing for size.
2424 (define_insn "*movdf_nointeger"
2425   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2426         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2427   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2428    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2429    && (reload_in_progress || reload_completed
2430        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2431        || GET_CODE (operands[1]) != CONST_DOUBLE
2432        || memory_operand (operands[0], DFmode))" 
2434   switch (which_alternative)
2435     {
2436     case 0:
2437       return output_387_reg_move (insn, operands);
2439     case 1:
2440       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2441         return "fstp%z0\t%y0";
2442       else
2443         return "fst%z0\t%y0";
2445     case 2:
2446       return standard_80387_constant_opcode (operands[1]);
2448     case 3:
2449     case 4:
2450       return "#";
2451     case 5:
2452       switch (get_attr_mode (insn))
2453         {
2454         case MODE_V4SF:
2455           return "xorps\t%0, %0";
2456         case MODE_V2DF:
2457           return "xorpd\t%0, %0";
2458         case MODE_TI:
2459           return "pxor\t%0, %0";
2460         default:
2461           abort ();
2462         }
2463     case 6:
2464       switch (get_attr_mode (insn))
2465         {
2466         case MODE_V4SF:
2467           return "movaps\t{%1, %0|%0, %1}";
2468         case MODE_V2DF:
2469           return "movapd\t{%1, %0|%0, %1}";
2470         case MODE_DF:
2471           return "movsd\t{%1, %0|%0, %1}";
2472         default:
2473           abort ();
2474         }
2475     case 7:
2476       if (get_attr_mode (insn) == MODE_V2DF)
2477         return "movlpd\t{%1, %0|%0, %1}";
2478       else
2479         return "movsd\t{%1, %0|%0, %1}";
2480     case 8:
2481       return "movsd\t{%1, %0|%0, %1}";
2483     default:
2484       abort();
2485     }
2487   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2488    (set (attr "mode")
2489         (cond [(eq_attr "alternative" "3,4")
2490                  (const_string "SI")
2491                /* xorps is one byte shorter.  */
2492                (eq_attr "alternative" "5")
2493                  (cond [(ne (symbol_ref "optimize_size")
2494                             (const_int 0))
2495                           (const_string "V4SF")
2496                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2497                             (const_int 0))
2498                           (const_string "TI")]
2499                        (const_string "V2DF"))
2500                /* For architectures resolving dependencies on
2501                   whole SSE registers use APD move to break dependency
2502                   chains, otherwise use short move to avoid extra work.
2504                   movaps encodes one byte shorter.  */
2505                (eq_attr "alternative" "6")
2506                  (cond
2507                   [(ne (symbol_ref "optimize_size")
2508                        (const_int 0))
2509                      (const_string "V4SF")
2510                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2511                        (const_int 0))
2512                      (const_string "V2DF")]
2513                    (const_string "DF"))
2514                /* For architectures resolving dependencies on register
2515                   parts we may avoid extra work to zero out upper part
2516                   of register.  */
2517                (eq_attr "alternative" "7")
2518                  (if_then_else
2519                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2520                        (const_int 0))
2521                    (const_string "V2DF")
2522                    (const_string "DF"))]
2523                (const_string "DF")))])
2525 (define_insn "*movdf_integer"
2526   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2527         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2528   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2529    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2530    && (reload_in_progress || reload_completed
2531        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2532        || GET_CODE (operands[1]) != CONST_DOUBLE
2533        || memory_operand (operands[0], DFmode))" 
2535   switch (which_alternative)
2536     {
2537     case 0:
2538       return output_387_reg_move (insn, operands);
2540     case 1:
2541       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2542         return "fstp%z0\t%y0";
2543       else
2544         return "fst%z0\t%y0";
2546     case 2:
2547       return standard_80387_constant_opcode (operands[1]);
2549     case 3:
2550     case 4:
2551       return "#";
2553     case 5:
2554       switch (get_attr_mode (insn))
2555         {
2556         case MODE_V4SF:
2557           return "xorps\t%0, %0";
2558         case MODE_V2DF:
2559           return "xorpd\t%0, %0";
2560         case MODE_TI:
2561           return "pxor\t%0, %0";
2562         default:
2563           abort ();
2564         }
2565     case 6:
2566       switch (get_attr_mode (insn))
2567         {
2568         case MODE_V4SF:
2569           return "movaps\t{%1, %0|%0, %1}";
2570         case MODE_V2DF:
2571           return "movapd\t{%1, %0|%0, %1}";
2572         case MODE_DF:
2573           return "movsd\t{%1, %0|%0, %1}";
2574         default:
2575           abort ();
2576         }
2577     case 7:
2578       if (get_attr_mode (insn) == MODE_V2DF)
2579         return "movlpd\t{%1, %0|%0, %1}";
2580       else
2581         return "movsd\t{%1, %0|%0, %1}";
2582     case 8:
2583       return "movsd\t{%1, %0|%0, %1}";
2585     default:
2586       abort();
2587     }
2589   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2590    (set (attr "mode")
2591         (cond [(eq_attr "alternative" "3,4")
2592                  (const_string "SI")
2593                /* xorps is one byte shorter.  */
2594                (eq_attr "alternative" "5")
2595                  (cond [(ne (symbol_ref "optimize_size")
2596                             (const_int 0))
2597                           (const_string "V4SF")
2598                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2599                             (const_int 0))
2600                           (const_string "TI")]
2601                        (const_string "V2DF"))
2602                /* For architectures resolving dependencies on
2603                   whole SSE registers use APD move to break dependency
2604                   chains, otherwise use short move to avoid extra work.  
2606                   movaps encodes one byte shorter.  */
2607                (eq_attr "alternative" "6")
2608                  (cond
2609                   [(ne (symbol_ref "optimize_size")
2610                        (const_int 0))
2611                      (const_string "V4SF")
2612                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2613                        (const_int 0))
2614                      (const_string "V2DF")]
2615                    (const_string "DF"))
2616                /* For architectures resolving dependencies on register
2617                   parts we may avoid extra work to zero out upper part
2618                   of register.  */
2619                (eq_attr "alternative" "7")
2620                  (if_then_else
2621                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2622                        (const_int 0))
2623                    (const_string "V2DF")
2624                    (const_string "DF"))]
2625                (const_string "DF")))])
2627 (define_split
2628   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2629         (match_operand:DF 1 "general_operand" ""))]
2630   "reload_completed
2631    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2632    && ! (ANY_FP_REG_P (operands[0]) || 
2633          (GET_CODE (operands[0]) == SUBREG
2634           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2635    && ! (ANY_FP_REG_P (operands[1]) || 
2636          (GET_CODE (operands[1]) == SUBREG
2637           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2638   [(const_int 0)]
2639   "ix86_split_long_move (operands); DONE;")
2641 (define_insn "*swapdf"
2642   [(set (match_operand:DF 0 "register_operand" "+f")
2643         (match_operand:DF 1 "register_operand" "+f"))
2644    (set (match_dup 1)
2645         (match_dup 0))]
2646   "reload_completed || !TARGET_SSE2"
2648   if (STACK_TOP_P (operands[0]))
2649     return "fxch\t%1";
2650   else
2651     return "fxch\t%0";
2653   [(set_attr "type" "fxch")
2654    (set_attr "mode" "DF")])
2656 (define_expand "movxf"
2657   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2658         (match_operand:XF 1 "general_operand" ""))]
2659   ""
2660   "ix86_expand_move (XFmode, operands); DONE;")
2662 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references.
2666 ;; (assuming that any given constant is pushed only once, but this ought to be
2667 ;;  handled elsewhere).
2669 (define_insn "*pushxf_nointeger"
2670   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2671         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2672   "optimize_size"
2674   /* This insn should be already split before reg-stack.  */
2675   abort ();
2677   [(set_attr "type" "multi")
2678    (set_attr "mode" "XF,SI,SI")])
2680 (define_insn "*pushxf_integer"
2681   [(set (match_operand:XF 0 "push_operand" "=<,<")
2682         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2683   "!optimize_size"
2685   /* This insn should be already split before reg-stack.  */
2686   abort ();
2688   [(set_attr "type" "multi")
2689    (set_attr "mode" "XF,SI")])
2691 (define_split
2692   [(set (match_operand 0 "push_operand" "")
2693         (match_operand 1 "general_operand" ""))]
2694   "reload_completed
2695    && (GET_MODE (operands[0]) == XFmode
2696        || GET_MODE (operands[0]) == DFmode)
2697    && !ANY_FP_REG_P (operands[1])"
2698   [(const_int 0)]
2699   "ix86_split_long_move (operands); DONE;")
2701 (define_split
2702   [(set (match_operand:XF 0 "push_operand" "")
2703         (match_operand:XF 1 "any_fp_register_operand" ""))]
2704   "!TARGET_64BIT"
2705   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2706    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2707   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2709 (define_split
2710   [(set (match_operand:XF 0 "push_operand" "")
2711         (match_operand:XF 1 "any_fp_register_operand" ""))]
2712   "TARGET_64BIT"
2713   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2714    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2715   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2717 ;; Do not use integer registers when optimizing for size
2718 (define_insn "*movxf_nointeger"
2719   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2720         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2721   "optimize_size
2722    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2723    && (reload_in_progress || reload_completed
2724        || GET_CODE (operands[1]) != CONST_DOUBLE
2725        || memory_operand (operands[0], XFmode))" 
2727   switch (which_alternative)
2728     {
2729     case 0:
2730       return output_387_reg_move (insn, operands);
2732     case 1:
2733       /* There is no non-popping store to memory for XFmode.  So if
2734          we need one, follow the store with a load.  */
2735       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2736         return "fstp%z0\t%y0\;fld%z0\t%y0";
2737       else
2738         return "fstp%z0\t%y0";
2740     case 2:
2741       return standard_80387_constant_opcode (operands[1]);
2743     case 3: case 4:
2744       return "#";
2745     }
2746   abort();
2748   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2749    (set_attr "mode" "XF,XF,XF,SI,SI")])
2751 (define_insn "*movxf_integer"
2752   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2753         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2754   "!optimize_size
2755    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2756    && (reload_in_progress || reload_completed
2757        || GET_CODE (operands[1]) != CONST_DOUBLE
2758        || memory_operand (operands[0], XFmode))" 
2760   switch (which_alternative)
2761     {
2762     case 0:
2763       return output_387_reg_move (insn, operands);
2765     case 1:
2766       /* There is no non-popping store to memory for XFmode.  So if
2767          we need one, follow the store with a load.  */
2768       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2769         return "fstp%z0\t%y0\;fld%z0\t%y0";
2770       else
2771         return "fstp%z0\t%y0";
2773     case 2:
2774       return standard_80387_constant_opcode (operands[1]);
2776     case 3: case 4:
2777       return "#";
2778     }
2779   abort();
2781   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2782    (set_attr "mode" "XF,XF,XF,SI,SI")])
2784 (define_split
2785   [(set (match_operand 0 "nonimmediate_operand" "")
2786         (match_operand 1 "general_operand" ""))]
2787   "reload_completed
2788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789    && GET_MODE (operands[0]) == XFmode
2790    && ! (ANY_FP_REG_P (operands[0]) || 
2791          (GET_CODE (operands[0]) == SUBREG
2792           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2793    && ! (ANY_FP_REG_P (operands[1]) || 
2794          (GET_CODE (operands[1]) == SUBREG
2795           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2796   [(const_int 0)]
2797   "ix86_split_long_move (operands); DONE;")
2799 (define_split
2800   [(set (match_operand 0 "register_operand" "")
2801         (match_operand 1 "memory_operand" ""))]
2802   "reload_completed
2803    && GET_CODE (operands[1]) == MEM
2804    && (GET_MODE (operands[0]) == XFmode
2805        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2806    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2807    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2808   [(set (match_dup 0) (match_dup 1))]
2810   rtx c = get_pool_constant (XEXP (operands[1], 0));
2811   rtx r = operands[0];
2813   if (GET_CODE (r) == SUBREG)
2814     r = SUBREG_REG (r);
2816   if (SSE_REG_P (r))
2817     {
2818       if (!standard_sse_constant_p (c))
2819         FAIL;
2820     }
2821   else if (FP_REG_P (r))
2822     {
2823       if (!standard_80387_constant_p (c))
2824         FAIL;
2825     }
2826   else if (MMX_REG_P (r))
2827     FAIL;
2829   operands[1] = c;
2832 (define_insn "swapxf"
2833   [(set (match_operand:XF 0 "register_operand" "+f")
2834         (match_operand:XF 1 "register_operand" "+f"))
2835    (set (match_dup 1)
2836         (match_dup 0))]
2837   ""
2839   if (STACK_TOP_P (operands[0]))
2840     return "fxch\t%1";
2841   else
2842     return "fxch\t%0";
2844   [(set_attr "type" "fxch")
2845    (set_attr "mode" "XF")])
2847 ;; Zero extension instructions
2849 (define_expand "zero_extendhisi2"
2850   [(set (match_operand:SI 0 "register_operand" "")
2851      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2852   ""
2854   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2855     {
2856       operands[1] = force_reg (HImode, operands[1]);
2857       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2858       DONE;
2859     }
2862 (define_insn "zero_extendhisi2_and"
2863   [(set (match_operand:SI 0 "register_operand" "=r")
2864      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2865    (clobber (reg:CC FLAGS_REG))]
2866   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2867   "#"
2868   [(set_attr "type" "alu1")
2869    (set_attr "mode" "SI")])
2871 (define_split
2872   [(set (match_operand:SI 0 "register_operand" "")
2873         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2874    (clobber (reg:CC FLAGS_REG))]
2875   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2876   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2877               (clobber (reg:CC FLAGS_REG))])]
2878   "")
2880 (define_insn "*zero_extendhisi2_movzwl"
2881   [(set (match_operand:SI 0 "register_operand" "=r")
2882      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2883   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2884   "movz{wl|x}\t{%1, %0|%0, %1}"
2885   [(set_attr "type" "imovx")
2886    (set_attr "mode" "SI")])
2888 (define_expand "zero_extendqihi2"
2889   [(parallel
2890     [(set (match_operand:HI 0 "register_operand" "")
2891        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2892      (clobber (reg:CC FLAGS_REG))])]
2893   ""
2894   "")
2896 (define_insn "*zero_extendqihi2_and"
2897   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2898      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2899    (clobber (reg:CC FLAGS_REG))]
2900   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2901   "#"
2902   [(set_attr "type" "alu1")
2903    (set_attr "mode" "HI")])
2905 (define_insn "*zero_extendqihi2_movzbw_and"
2906   [(set (match_operand:HI 0 "register_operand" "=r,r")
2907      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2908    (clobber (reg:CC FLAGS_REG))]
2909   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2910   "#"
2911   [(set_attr "type" "imovx,alu1")
2912    (set_attr "mode" "HI")])
2914 (define_insn "*zero_extendqihi2_movzbw"
2915   [(set (match_operand:HI 0 "register_operand" "=r")
2916      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2917   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2918   "movz{bw|x}\t{%1, %0|%0, %1}"
2919   [(set_attr "type" "imovx")
2920    (set_attr "mode" "HI")])
2922 ;; For the movzbw case strip only the clobber
2923 (define_split
2924   [(set (match_operand:HI 0 "register_operand" "")
2925         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2926    (clobber (reg:CC FLAGS_REG))]
2927   "reload_completed 
2928    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2929    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2930   [(set (match_operand:HI 0 "register_operand" "")
2931         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2933 ;; When source and destination does not overlap, clear destination
2934 ;; first and then do the movb
2935 (define_split
2936   [(set (match_operand:HI 0 "register_operand" "")
2937         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2938    (clobber (reg:CC FLAGS_REG))]
2939   "reload_completed
2940    && ANY_QI_REG_P (operands[0])
2941    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2942    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2943   [(set (match_dup 0) (const_int 0))
2944    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2945   "operands[2] = gen_lowpart (QImode, operands[0]);")
2947 ;; Rest is handled by single and.
2948 (define_split
2949   [(set (match_operand:HI 0 "register_operand" "")
2950         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2951    (clobber (reg:CC FLAGS_REG))]
2952   "reload_completed
2953    && true_regnum (operands[0]) == true_regnum (operands[1])"
2954   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2955               (clobber (reg:CC FLAGS_REG))])]
2956   "")
2958 (define_expand "zero_extendqisi2"
2959   [(parallel
2960     [(set (match_operand:SI 0 "register_operand" "")
2961        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2962      (clobber (reg:CC FLAGS_REG))])]
2963   ""
2964   "")
2966 (define_insn "*zero_extendqisi2_and"
2967   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2968      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2969    (clobber (reg:CC FLAGS_REG))]
2970   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2971   "#"
2972   [(set_attr "type" "alu1")
2973    (set_attr "mode" "SI")])
2975 (define_insn "*zero_extendqisi2_movzbw_and"
2976   [(set (match_operand:SI 0 "register_operand" "=r,r")
2977      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2978    (clobber (reg:CC FLAGS_REG))]
2979   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2980   "#"
2981   [(set_attr "type" "imovx,alu1")
2982    (set_attr "mode" "SI")])
2984 (define_insn "*zero_extendqisi2_movzbw"
2985   [(set (match_operand:SI 0 "register_operand" "=r")
2986      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2987   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2988   "movz{bl|x}\t{%1, %0|%0, %1}"
2989   [(set_attr "type" "imovx")
2990    (set_attr "mode" "SI")])
2992 ;; For the movzbl case strip only the clobber
2993 (define_split
2994   [(set (match_operand:SI 0 "register_operand" "")
2995         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2996    (clobber (reg:CC FLAGS_REG))]
2997   "reload_completed 
2998    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2999    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3000   [(set (match_dup 0)
3001         (zero_extend:SI (match_dup 1)))])
3003 ;; When source and destination does not overlap, clear destination
3004 ;; first and then do the movb
3005 (define_split
3006   [(set (match_operand:SI 0 "register_operand" "")
3007         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3008    (clobber (reg:CC FLAGS_REG))]
3009   "reload_completed
3010    && ANY_QI_REG_P (operands[0])
3011    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3012    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3013    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3014   [(set (match_dup 0) (const_int 0))
3015    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3016   "operands[2] = gen_lowpart (QImode, operands[0]);")
3018 ;; Rest is handled by single and.
3019 (define_split
3020   [(set (match_operand:SI 0 "register_operand" "")
3021         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "reload_completed
3024    && true_regnum (operands[0]) == true_regnum (operands[1])"
3025   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3026               (clobber (reg:CC FLAGS_REG))])]
3027   "")
3029 ;; %%% Kill me once multi-word ops are sane.
3030 (define_expand "zero_extendsidi2"
3031   [(set (match_operand:DI 0 "register_operand" "=r")
3032      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3033   ""
3034   "if (!TARGET_64BIT)
3035      {
3036        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3037        DONE;
3038      }
3039   ")
3041 (define_insn "zero_extendsidi2_32"
3042   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3043         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3044    (clobber (reg:CC FLAGS_REG))]
3045   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3046   "@
3047    #
3048    #
3049    #
3050    movd\t{%1, %0|%0, %1}
3051    movd\t{%1, %0|%0, %1}"
3052   [(set_attr "mode" "SI,SI,SI,DI,TI")
3053    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3055 (define_insn "*zero_extendsidi2_32_1"
3056   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3057         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3058    (clobber (reg:CC FLAGS_REG))]
3059   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3060   "@
3061    #
3062    #
3063    #
3064    movd\t{%1, %0|%0, %1}
3065    movd\t{%1, %0|%0, %1}"
3066   [(set_attr "mode" "SI,SI,SI,DI,TI")
3067    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3069 (define_insn "zero_extendsidi2_rex64"
3070   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3071      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3072   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3073   "@
3074    mov\t{%k1, %k0|%k0, %k1}
3075    #
3076    movd\t{%1, %0|%0, %1}
3077    movd\t{%1, %0|%0, %1}"
3078   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3079    (set_attr "mode" "SI,DI,DI,TI")])
3081 (define_insn "*zero_extendsidi2_rex64_1"
3082   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3083      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3084   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3085   "@
3086    mov\t{%k1, %k0|%k0, %k1}
3087    #
3088    movd\t{%1, %0|%0, %1}
3089    movd\t{%1, %0|%0, %1}"
3090   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3091    (set_attr "mode" "SI,DI,SI,SI")])
3093 (define_split
3094   [(set (match_operand:DI 0 "memory_operand" "")
3095      (zero_extend:DI (match_dup 0)))]
3096   "TARGET_64BIT"
3097   [(set (match_dup 4) (const_int 0))]
3098   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3100 (define_split 
3101   [(set (match_operand:DI 0 "register_operand" "")
3102         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3103    (clobber (reg:CC FLAGS_REG))]
3104   "!TARGET_64BIT && reload_completed
3105    && true_regnum (operands[0]) == true_regnum (operands[1])"
3106   [(set (match_dup 4) (const_int 0))]
3107   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3109 (define_split 
3110   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3111         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3112    (clobber (reg:CC FLAGS_REG))]
3113   "!TARGET_64BIT && reload_completed
3114    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3115   [(set (match_dup 3) (match_dup 1))
3116    (set (match_dup 4) (const_int 0))]
3117   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3119 (define_insn "zero_extendhidi2"
3120   [(set (match_operand:DI 0 "register_operand" "=r,r")
3121      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3122   "TARGET_64BIT"
3123   "@
3124    movz{wl|x}\t{%1, %k0|%k0, %1}
3125    movz{wq|x}\t{%1, %0|%0, %1}"
3126   [(set_attr "type" "imovx")
3127    (set_attr "mode" "SI,DI")])
3129 (define_insn "zero_extendqidi2"
3130   [(set (match_operand:DI 0 "register_operand" "=r,r")
3131      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3132   "TARGET_64BIT"
3133   "@
3134    movz{bl|x}\t{%1, %k0|%k0, %1}
3135    movz{bq|x}\t{%1, %0|%0, %1}"
3136   [(set_attr "type" "imovx")
3137    (set_attr "mode" "SI,DI")])
3139 ;; Sign extension instructions
3141 (define_expand "extendsidi2"
3142   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3143                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3144               (clobber (reg:CC FLAGS_REG))
3145               (clobber (match_scratch:SI 2 ""))])]
3146   ""
3148   if (TARGET_64BIT)
3149     {
3150       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3151       DONE;
3152     }
3155 (define_insn "*extendsidi2_1"
3156   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3157         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3158    (clobber (reg:CC FLAGS_REG))
3159    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3160   "!TARGET_64BIT"
3161   "#")
3163 (define_insn "extendsidi2_rex64"
3164   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3165         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3166   "TARGET_64BIT"
3167   "@
3168    {cltq|cdqe}
3169    movs{lq|x}\t{%1,%0|%0, %1}"
3170   [(set_attr "type" "imovx")
3171    (set_attr "mode" "DI")
3172    (set_attr "prefix_0f" "0")
3173    (set_attr "modrm" "0,1")])
3175 (define_insn "extendhidi2"
3176   [(set (match_operand:DI 0 "register_operand" "=r")
3177         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3178   "TARGET_64BIT"
3179   "movs{wq|x}\t{%1,%0|%0, %1}"
3180   [(set_attr "type" "imovx")
3181    (set_attr "mode" "DI")])
3183 (define_insn "extendqidi2"
3184   [(set (match_operand:DI 0 "register_operand" "=r")
3185         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3186   "TARGET_64BIT"
3187   "movs{bq|x}\t{%1,%0|%0, %1}"
3188    [(set_attr "type" "imovx")
3189     (set_attr "mode" "DI")])
3191 ;; Extend to memory case when source register does die.
3192 (define_split 
3193   [(set (match_operand:DI 0 "memory_operand" "")
3194         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3195    (clobber (reg:CC FLAGS_REG))
3196    (clobber (match_operand:SI 2 "register_operand" ""))]
3197   "(reload_completed
3198     && dead_or_set_p (insn, operands[1])
3199     && !reg_mentioned_p (operands[1], operands[0]))"
3200   [(set (match_dup 3) (match_dup 1))
3201    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3202               (clobber (reg:CC FLAGS_REG))])
3203    (set (match_dup 4) (match_dup 1))]
3204   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3206 ;; Extend to memory case when source register does not die.
3207 (define_split 
3208   [(set (match_operand:DI 0 "memory_operand" "")
3209         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3210    (clobber (reg:CC FLAGS_REG))
3211    (clobber (match_operand:SI 2 "register_operand" ""))]
3212   "reload_completed"
3213   [(const_int 0)]
3215   split_di (&operands[0], 1, &operands[3], &operands[4]);
3217   emit_move_insn (operands[3], operands[1]);
3219   /* Generate a cltd if possible and doing so it profitable.  */
3220   if (true_regnum (operands[1]) == 0
3221       && true_regnum (operands[2]) == 1
3222       && (optimize_size || TARGET_USE_CLTD))
3223     {
3224       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3225     }
3226   else
3227     {
3228       emit_move_insn (operands[2], operands[1]);
3229       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3230     }
3231   emit_move_insn (operands[4], operands[2]);
3232   DONE;
3235 ;; Extend to register case.  Optimize case where source and destination
3236 ;; registers match and cases where we can use cltd.
3237 (define_split 
3238   [(set (match_operand:DI 0 "register_operand" "")
3239         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3240    (clobber (reg:CC FLAGS_REG))
3241    (clobber (match_scratch:SI 2 ""))]
3242   "reload_completed"
3243   [(const_int 0)]
3245   split_di (&operands[0], 1, &operands[3], &operands[4]);
3247   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3248     emit_move_insn (operands[3], operands[1]);
3250   /* Generate a cltd if possible and doing so it profitable.  */
3251   if (true_regnum (operands[3]) == 0
3252       && (optimize_size || TARGET_USE_CLTD))
3253     {
3254       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3255       DONE;
3256     }
3258   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3259     emit_move_insn (operands[4], operands[1]);
3261   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3262   DONE;
3265 (define_insn "extendhisi2"
3266   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3267         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3268   ""
3270   switch (get_attr_prefix_0f (insn))
3271     {
3272     case 0:
3273       return "{cwtl|cwde}";
3274     default:
3275       return "movs{wl|x}\t{%1,%0|%0, %1}";
3276     }
3278   [(set_attr "type" "imovx")
3279    (set_attr "mode" "SI")
3280    (set (attr "prefix_0f")
3281      ;; movsx is short decodable while cwtl is vector decoded.
3282      (if_then_else (and (eq_attr "cpu" "!k6")
3283                         (eq_attr "alternative" "0"))
3284         (const_string "0")
3285         (const_string "1")))
3286    (set (attr "modrm")
3287      (if_then_else (eq_attr "prefix_0f" "0")
3288         (const_string "0")
3289         (const_string "1")))])
3291 (define_insn "*extendhisi2_zext"
3292   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3293         (zero_extend:DI
3294           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3295   "TARGET_64BIT"
3297   switch (get_attr_prefix_0f (insn))
3298     {
3299     case 0:
3300       return "{cwtl|cwde}";
3301     default:
3302       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3303     }
3305   [(set_attr "type" "imovx")
3306    (set_attr "mode" "SI")
3307    (set (attr "prefix_0f")
3308      ;; movsx is short decodable while cwtl is vector decoded.
3309      (if_then_else (and (eq_attr "cpu" "!k6")
3310                         (eq_attr "alternative" "0"))
3311         (const_string "0")
3312         (const_string "1")))
3313    (set (attr "modrm")
3314      (if_then_else (eq_attr "prefix_0f" "0")
3315         (const_string "0")
3316         (const_string "1")))])
3318 (define_insn "extendqihi2"
3319   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3320         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3321   ""
3323   switch (get_attr_prefix_0f (insn))
3324     {
3325     case 0:
3326       return "{cbtw|cbw}";
3327     default:
3328       return "movs{bw|x}\t{%1,%0|%0, %1}";
3329     }
3331   [(set_attr "type" "imovx")
3332    (set_attr "mode" "HI")
3333    (set (attr "prefix_0f")
3334      ;; movsx is short decodable while cwtl is vector decoded.
3335      (if_then_else (and (eq_attr "cpu" "!k6")
3336                         (eq_attr "alternative" "0"))
3337         (const_string "0")
3338         (const_string "1")))
3339    (set (attr "modrm")
3340      (if_then_else (eq_attr "prefix_0f" "0")
3341         (const_string "0")
3342         (const_string "1")))])
3344 (define_insn "extendqisi2"
3345   [(set (match_operand:SI 0 "register_operand" "=r")
3346         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3347   ""
3348   "movs{bl|x}\t{%1,%0|%0, %1}"
3349    [(set_attr "type" "imovx")
3350     (set_attr "mode" "SI")])
3352 (define_insn "*extendqisi2_zext"
3353   [(set (match_operand:DI 0 "register_operand" "=r")
3354         (zero_extend:DI
3355           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3356   "TARGET_64BIT"
3357   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3358    [(set_attr "type" "imovx")
3359     (set_attr "mode" "SI")])
3361 ;; Conversions between float and double.
3363 ;; These are all no-ops in the model used for the 80387.  So just
3364 ;; emit moves.
3366 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3367 (define_insn "*dummy_extendsfdf2"
3368   [(set (match_operand:DF 0 "push_operand" "=<")
3369         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3370   "0"
3371   "#")
3373 (define_split
3374   [(set (match_operand:DF 0 "push_operand" "")
3375         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3376   "!TARGET_64BIT"
3377   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3378    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3380 (define_split
3381   [(set (match_operand:DF 0 "push_operand" "")
3382         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3383   "TARGET_64BIT"
3384   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3385    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3387 (define_insn "*dummy_extendsfxf2"
3388   [(set (match_operand:XF 0 "push_operand" "=<")
3389         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3390   "0"
3391   "#")
3393 (define_split
3394   [(set (match_operand:XF 0 "push_operand" "")
3395         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3396   ""
3397   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3398    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3399   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3401 (define_split
3402   [(set (match_operand:XF 0 "push_operand" "")
3403         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3404   "TARGET_64BIT"
3405   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3406    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3407   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3409 (define_split
3410   [(set (match_operand:XF 0 "push_operand" "")
3411         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3412   ""
3413   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3414    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3415   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3417 (define_split
3418   [(set (match_operand:XF 0 "push_operand" "")
3419         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3420   "TARGET_64BIT"
3421   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3422    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3423   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3425 (define_expand "extendsfdf2"
3426   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3427         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3428   "TARGET_80387 || TARGET_SSE2"
3430   /* ??? Needed for compress_float_constant since all fp constants
3431      are LEGITIMATE_CONSTANT_P.  */
3432   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3433     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3434   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3435     operands[1] = force_reg (SFmode, operands[1]);
3438 (define_insn "*extendsfdf2_1"
3439   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3440         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3441   "(TARGET_80387 || TARGET_SSE2)
3442    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3444   switch (which_alternative)
3445     {
3446     case 0:
3447       return output_387_reg_move (insn, operands);
3449     case 1:
3450       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3451         return "fstp%z0\t%y0";
3452       else
3453         return "fst%z0\t%y0";
3455     case 2:
3456       return "cvtss2sd\t{%1, %0|%0, %1}";
3458     default:
3459       abort ();
3460     }
3462   [(set_attr "type" "fmov,fmov,ssecvt")
3463    (set_attr "mode" "SF,XF,DF")])
3465 (define_insn "*extendsfdf2_1_sse_only"
3466   [(set (match_operand:DF 0 "register_operand" "=Y")
3467         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3468   "!TARGET_80387 && TARGET_SSE2
3469    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3470   "cvtss2sd\t{%1, %0|%0, %1}"
3471   [(set_attr "type" "ssecvt")
3472    (set_attr "mode" "DF")])
3474 (define_expand "extendsfxf2"
3475   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3476         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3477   "TARGET_80387"
3479   /* ??? Needed for compress_float_constant since all fp constants
3480      are LEGITIMATE_CONSTANT_P.  */
3481   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3482     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3483   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3484     operands[1] = force_reg (SFmode, operands[1]);
3487 (define_insn "*extendsfxf2_1"
3488   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3489         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3490   "TARGET_80387
3491    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3493   switch (which_alternative)
3494     {
3495     case 0:
3496       return output_387_reg_move (insn, operands);
3498     case 1:
3499       /* There is no non-popping store to memory for XFmode.  So if
3500          we need one, follow the store with a load.  */
3501       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3502         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3503       else
3504         return "fstp%z0\t%y0";
3506     default:
3507       abort ();
3508     }
3510   [(set_attr "type" "fmov")
3511    (set_attr "mode" "SF,XF")])
3513 (define_expand "extenddfxf2"
3514   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3515         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3516   "TARGET_80387"
3518   /* ??? Needed for compress_float_constant since all fp constants
3519      are LEGITIMATE_CONSTANT_P.  */
3520   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3521     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3522   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3523     operands[1] = force_reg (DFmode, operands[1]);
3526 (define_insn "*extenddfxf2_1"
3527   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3528         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3529   "TARGET_80387
3530    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3532   switch (which_alternative)
3533     {
3534     case 0:
3535       return output_387_reg_move (insn, operands);
3537     case 1:
3538       /* There is no non-popping store to memory for XFmode.  So if
3539          we need one, follow the store with a load.  */
3540       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3541         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3542       else
3543         return "fstp%z0\t%y0";
3545     default:
3546       abort ();
3547     }
3549   [(set_attr "type" "fmov")
3550    (set_attr "mode" "DF,XF")])
3552 ;; %%% This seems bad bad news.
3553 ;; This cannot output into an f-reg because there is no way to be sure
3554 ;; of truncating in that case.  Otherwise this is just like a simple move
3555 ;; insn.  So we pretend we can output to a reg in order to get better
3556 ;; register preferencing, but we really use a stack slot.
3558 (define_expand "truncdfsf2"
3559   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3560                    (float_truncate:SF
3561                     (match_operand:DF 1 "register_operand" "")))
3562               (clobber (match_dup 2))])]
3563   "TARGET_80387 || TARGET_SSE2"
3564   "
3565    if (!TARGET_80387)
3566      {
3567         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3568         DONE;
3569      }
3570    else if (flag_unsafe_math_optimizations)
3571      {
3572         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3573         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3574         if (reg != operands[0])
3575           emit_move_insn (operands[0], reg);
3576         DONE;
3577      }
3578    else
3579      operands[2] = assign_386_stack_local (SFmode, 0);
3582 (define_insn "truncdfsf2_noop"
3583   [(set (match_operand:SF 0 "register_operand" "=f")
3584         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3585   "TARGET_80387 && flag_unsafe_math_optimizations"
3587   return output_387_reg_move (insn, operands);
3589   [(set_attr "type" "fmov")
3590    (set_attr "mode" "SF")])
3592 (define_insn "*truncdfsf2_1"
3593   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3594         (float_truncate:SF
3595          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3596    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3597   "TARGET_80387 && !TARGET_SSE2"
3599   switch (which_alternative)
3600     {
3601     case 0:
3602       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3603         return "fstp%z0\t%y0";
3604       else
3605         return "fst%z0\t%y0";
3606     default:
3607       abort ();
3608     }
3610   [(set_attr "type" "fmov,multi,multi,multi")
3611    (set_attr "mode" "SF,SF,SF,SF")])
3613 (define_insn "*truncdfsf2_1_sse"
3614   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3615         (float_truncate:SF
3616          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3617    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3618   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3620   switch (which_alternative)
3621     {
3622     case 0:
3623       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624         return "fstp%z0\t%y0";
3625       else
3626         return "fst%z0\t%y0";
3627     case 4:
3628       return "#";
3629     default:
3630       abort ();
3631     }
3633   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3634    (set_attr "mode" "SF,SF,SF,SF,DF")])
3636 (define_insn "*truncdfsf2_1_sse_nooverlap"
3637   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3638         (float_truncate:SF
3639          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3640    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3641   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3643   switch (which_alternative)
3644     {
3645     case 0:
3646       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3647         return "fstp%z0\t%y0";
3648       else
3649         return "fst%z0\t%y0";
3650     case 4:
3651       return "#";
3652     default:
3653       abort ();
3654     }
3656   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3657    (set_attr "mode" "SF,SF,SF,SF,DF")])
3659 (define_insn "*truncdfsf2_2"
3660   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3661         (float_truncate:SF
3662          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3663   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3664    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3666   switch (which_alternative)
3667     {
3668     case 0:
3669     case 1:
3670       return "cvtsd2ss\t{%1, %0|%0, %1}";
3671     case 2:
3672       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3673         return "fstp%z0\t%y0";
3674       else
3675         return "fst%z0\t%y0";
3676     default:
3677       abort ();
3678     }
3680   [(set_attr "type" "ssecvt,ssecvt,fmov")
3681    (set_attr "athlon_decode" "vector,double,*")
3682    (set_attr "mode" "SF,SF,SF")])
3684 (define_insn "*truncdfsf2_2_nooverlap"
3685   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3686         (float_truncate:SF
3687          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3688   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3689    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3691   switch (which_alternative)
3692     {
3693     case 0:
3694       return "#";
3695     case 1:
3696       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697         return "fstp%z0\t%y0";
3698       else
3699         return "fst%z0\t%y0";
3700     default:
3701       abort ();
3702     }
3704   [(set_attr "type" "ssecvt,fmov")
3705    (set_attr "mode" "DF,SF")])
3707 (define_insn "*truncdfsf2_3"
3708   [(set (match_operand:SF 0 "memory_operand" "=m")
3709         (float_truncate:SF
3710          (match_operand:DF 1 "register_operand" "f")))]
3711   "TARGET_80387"
3713   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3714     return "fstp%z0\t%y0";
3715   else
3716     return "fst%z0\t%y0";
3718   [(set_attr "type" "fmov")
3719    (set_attr "mode" "SF")])
3721 (define_insn "truncdfsf2_sse_only"
3722   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3723         (float_truncate:SF
3724          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3725   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3726   "cvtsd2ss\t{%1, %0|%0, %1}"
3727   [(set_attr "type" "ssecvt")
3728    (set_attr "athlon_decode" "vector,double")
3729    (set_attr "mode" "SF")])
3731 (define_insn "*truncdfsf2_sse_only_nooverlap"
3732   [(set (match_operand:SF 0 "register_operand" "=&Y")
3733         (float_truncate:SF
3734          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3735   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3736   "#"
3737   [(set_attr "type" "ssecvt")
3738    (set_attr "mode" "DF")])
3740 (define_split
3741   [(set (match_operand:SF 0 "memory_operand" "")
3742         (float_truncate:SF
3743          (match_operand:DF 1 "register_operand" "")))
3744    (clobber (match_operand:SF 2 "memory_operand" ""))]
3745   "TARGET_80387"
3746   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3747   "")
3749 ; Avoid possible reformatting penalty on the destination by first
3750 ; zeroing it out
3751 (define_split
3752   [(set (match_operand:SF 0 "register_operand" "")
3753         (float_truncate:SF
3754          (match_operand:DF 1 "nonimmediate_operand" "")))
3755    (clobber (match_operand 2 "" ""))]
3756   "TARGET_80387 && reload_completed
3757    && SSE_REG_P (operands[0])
3758    && !STACK_REG_P (operands[1])"
3759   [(const_int 0)]
3761   rtx src, dest;
3762   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3763     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3764   else
3765     {
3766       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3767       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3768       /* simplify_gen_subreg refuses to widen memory references.  */
3769       if (GET_CODE (src) == SUBREG)
3770         alter_subreg (&src);
3771       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3772         abort ();
3773       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3774       emit_insn (gen_cvtsd2ss (dest, dest, src));
3775     }
3776   DONE;
3779 (define_split
3780   [(set (match_operand:SF 0 "register_operand" "")
3781         (float_truncate:SF
3782          (match_operand:DF 1 "nonimmediate_operand" "")))]
3783   "TARGET_80387 && reload_completed
3784    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3785   [(const_int 0)]
3787   rtx src, dest;
3788   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3789   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3790   /* simplify_gen_subreg refuses to widen memory references.  */
3791   if (GET_CODE (src) == SUBREG)
3792     alter_subreg (&src);
3793   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3794     abort ();
3795   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3796   emit_insn (gen_cvtsd2ss (dest, dest, src));
3797   DONE;
3800 (define_split
3801   [(set (match_operand:SF 0 "register_operand" "")
3802         (float_truncate:SF
3803          (match_operand:DF 1 "fp_register_operand" "")))
3804    (clobber (match_operand:SF 2 "memory_operand" ""))]
3805   "TARGET_80387 && reload_completed"
3806   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3807    (set (match_dup 0) (match_dup 2))]
3808   "")
3810 (define_expand "truncxfsf2"
3811   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3812                    (float_truncate:SF
3813                     (match_operand:XF 1 "register_operand" "")))
3814               (clobber (match_dup 2))])]
3815   "TARGET_80387"
3816   "
3817   if (flag_unsafe_math_optimizations)
3818     {
3819       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3820       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3821       if (reg != operands[0])
3822         emit_move_insn (operands[0], reg);
3823       DONE;
3824     }
3825   else
3826     operands[2] = assign_386_stack_local (SFmode, 0);
3827   ")
3829 (define_insn "truncxfsf2_noop"
3830   [(set (match_operand:SF 0 "register_operand" "=f")
3831         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3832   "TARGET_80387 && flag_unsafe_math_optimizations"
3834   return output_387_reg_move (insn, operands);
3836   [(set_attr "type" "fmov")
3837    (set_attr "mode" "SF")])
3839 (define_insn "*truncxfsf2_1"
3840   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3841         (float_truncate:SF
3842          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3843    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3844   "TARGET_80387"
3846   switch (which_alternative)
3847     {
3848     case 0:
3849       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850         return "fstp%z0\t%y0";
3851       else
3852         return "fst%z0\t%y0";
3853     default:
3854       abort();
3855     }
3857   [(set_attr "type" "fmov,multi,multi,multi")
3858    (set_attr "mode" "SF")])
3860 (define_insn "*truncxfsf2_2"
3861   [(set (match_operand:SF 0 "memory_operand" "=m")
3862         (float_truncate:SF
3863          (match_operand:XF 1 "register_operand" "f")))]
3864   "TARGET_80387"
3866   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3867     return "fstp%z0\t%y0";
3868   else
3869     return "fst%z0\t%y0";
3871   [(set_attr "type" "fmov")
3872    (set_attr "mode" "SF")])
3874 (define_split
3875   [(set (match_operand:SF 0 "memory_operand" "")
3876         (float_truncate:SF
3877          (match_operand:XF 1 "register_operand" "")))
3878    (clobber (match_operand:SF 2 "memory_operand" ""))]
3879   "TARGET_80387"
3880   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3881   "")
3883 (define_split
3884   [(set (match_operand:SF 0 "register_operand" "")
3885         (float_truncate:SF
3886          (match_operand:XF 1 "register_operand" "")))
3887    (clobber (match_operand:SF 2 "memory_operand" ""))]
3888   "TARGET_80387 && reload_completed"
3889   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3890    (set (match_dup 0) (match_dup 2))]
3891   "")
3893 (define_expand "truncxfdf2"
3894   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3895                    (float_truncate:DF
3896                     (match_operand:XF 1 "register_operand" "")))
3897               (clobber (match_dup 2))])]
3898   "TARGET_80387"
3899   "
3900   if (flag_unsafe_math_optimizations)
3901     {
3902       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3903       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3904       if (reg != operands[0])
3905         emit_move_insn (operands[0], reg);
3906       DONE;
3907     }
3908   else
3909     operands[2] = assign_386_stack_local (DFmode, 0);
3910   ")
3912 (define_insn "truncxfdf2_noop"
3913   [(set (match_operand:DF 0 "register_operand" "=f")
3914         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3915   "TARGET_80387 && flag_unsafe_math_optimizations"
3917   return output_387_reg_move (insn, operands);
3919   [(set_attr "type" "fmov")
3920    (set_attr "mode" "DF")])
3922 (define_insn "*truncxfdf2_1"
3923   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3924         (float_truncate:DF
3925          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3926    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3927   "TARGET_80387"
3929   switch (which_alternative)
3930     {
3931     case 0:
3932       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933         return "fstp%z0\t%y0";
3934       else
3935         return "fst%z0\t%y0";
3936     default:
3937       abort();
3938     }
3939   abort ();
3941   [(set_attr "type" "fmov,multi,multi,multi")
3942    (set_attr "mode" "DF")])
3944 (define_insn "*truncxfdf2_2"
3945   [(set (match_operand:DF 0 "memory_operand" "=m")
3946         (float_truncate:DF
3947           (match_operand:XF 1 "register_operand" "f")))]
3948   "TARGET_80387"
3950   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3951     return "fstp%z0\t%y0";
3952   else
3953     return "fst%z0\t%y0";
3955   [(set_attr "type" "fmov")
3956    (set_attr "mode" "DF")])
3958 (define_split
3959   [(set (match_operand:DF 0 "memory_operand" "")
3960         (float_truncate:DF
3961          (match_operand:XF 1 "register_operand" "")))
3962    (clobber (match_operand:DF 2 "memory_operand" ""))]
3963   "TARGET_80387"
3964   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3965   "")
3967 (define_split
3968   [(set (match_operand:DF 0 "register_operand" "")
3969         (float_truncate:DF
3970          (match_operand:XF 1 "register_operand" "")))
3971    (clobber (match_operand:DF 2 "memory_operand" ""))]
3972   "TARGET_80387 && reload_completed"
3973   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3974    (set (match_dup 0) (match_dup 2))]
3975   "")
3978 ;; %%% Break up all these bad boys.
3980 ;; Signed conversion to DImode.
3982 (define_expand "fix_truncxfdi2"
3983   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3984                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3985               (clobber (reg:CC FLAGS_REG))])]
3986   "TARGET_80387"
3987   "")
3989 (define_expand "fix_truncdfdi2"
3990   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3991                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3992               (clobber (reg:CC FLAGS_REG))])]
3993   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
3995   if (TARGET_64BIT && TARGET_SSE2)
3996    {
3997      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3998      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
3999      if (out != operands[0])
4000         emit_move_insn (operands[0], out);
4001      DONE;
4002    }
4005 (define_expand "fix_truncsfdi2"
4006   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4007                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4008               (clobber (reg:CC FLAGS_REG))])] 
4009   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4011   if (TARGET_SSE && TARGET_64BIT)
4012    {
4013      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4014      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4015      if (out != operands[0])
4016         emit_move_insn (operands[0], out);
4017      DONE;
4018    }
4021 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4022 ;; of the machinery.
4023 (define_insn_and_split "*fix_truncdi_1"
4024   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4025         (fix:DI (match_operand 1 "register_operand" "f,f")))
4026    (clobber (reg:CC FLAGS_REG))]
4027   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4028    && !reload_completed && !reload_in_progress
4029    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4030   "#"
4031   "&& 1"
4032   [(const_int 0)]
4034   ix86_optimize_mode_switching = 1;
4035   operands[2] = assign_386_stack_local (HImode, 1);
4036   operands[3] = assign_386_stack_local (HImode, 2);
4037   if (memory_operand (operands[0], VOIDmode))
4038     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4039                                        operands[2], operands[3]));
4040   else
4041     {
4042       operands[4] = assign_386_stack_local (DImode, 0);
4043       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4044                                            operands[2], operands[3],
4045                                            operands[4]));
4046     }
4047   DONE;
4049   [(set_attr "type" "fistp")
4050    (set_attr "i387_cw" "trunc")
4051    (set_attr "mode" "DI")])
4053 (define_insn "fix_truncdi_nomemory"
4054   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4055         (fix:DI (match_operand 1 "register_operand" "f,f")))
4056    (use (match_operand:HI 2 "memory_operand" "m,m"))
4057    (use (match_operand:HI 3 "memory_operand" "m,m"))
4058    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4059    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4060   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4061    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4062   "#"
4063   [(set_attr "type" "fistp")
4064    (set_attr "i387_cw" "trunc")
4065    (set_attr "mode" "DI")])
4067 (define_insn "fix_truncdi_memory"
4068   [(set (match_operand:DI 0 "memory_operand" "=m")
4069         (fix:DI (match_operand 1 "register_operand" "f")))
4070    (use (match_operand:HI 2 "memory_operand" "m"))
4071    (use (match_operand:HI 3 "memory_operand" "m"))
4072    (clobber (match_scratch:DF 4 "=&1f"))]
4073   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4074    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4075   "* return output_fix_trunc (insn, operands);"
4076   [(set_attr "type" "fistp")
4077    (set_attr "i387_cw" "trunc")
4078    (set_attr "mode" "DI")])
4080 (define_split 
4081   [(set (match_operand:DI 0 "register_operand" "")
4082         (fix:DI (match_operand 1 "register_operand" "")))
4083    (use (match_operand:HI 2 "memory_operand" ""))
4084    (use (match_operand:HI 3 "memory_operand" ""))
4085    (clobber (match_operand:DI 4 "memory_operand" ""))
4086    (clobber (match_scratch 5 ""))]
4087   "reload_completed"
4088   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4089               (use (match_dup 2))
4090               (use (match_dup 3))
4091               (clobber (match_dup 5))])
4092    (set (match_dup 0) (match_dup 4))]
4093   "")
4095 (define_split 
4096   [(set (match_operand:DI 0 "memory_operand" "")
4097         (fix:DI (match_operand 1 "register_operand" "")))
4098    (use (match_operand:HI 2 "memory_operand" ""))
4099    (use (match_operand:HI 3 "memory_operand" ""))
4100    (clobber (match_operand:DI 4 "memory_operand" ""))
4101    (clobber (match_scratch 5 ""))]
4102   "reload_completed"
4103   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4104               (use (match_dup 2))
4105               (use (match_dup 3))
4106               (clobber (match_dup 5))])]
4107   "")
4109 ;; When SSE available, it is always faster to use it!
4110 (define_insn "fix_truncsfdi_sse"
4111   [(set (match_operand:DI 0 "register_operand" "=r,r")
4112         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4113   "TARGET_64BIT && TARGET_SSE"
4114   "cvttss2si{q}\t{%1, %0|%0, %1}"
4115   [(set_attr "type" "sseicvt")
4116    (set_attr "mode" "SF")
4117    (set_attr "athlon_decode" "double,vector")])
4119 ;; Avoid vector decoded form of the instruction.
4120 (define_peephole2
4121   [(match_scratch:SF 2 "x")
4122    (set (match_operand:DI 0 "register_operand" "")
4123         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4124   "TARGET_K8 && !optimize_size"
4125   [(set (match_dup 2) (match_dup 1))
4126    (set (match_dup 0) (fix:DI (match_dup 2)))]
4127   "")
4129 (define_insn "fix_truncdfdi_sse"
4130   [(set (match_operand:DI 0 "register_operand" "=r,r")
4131         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4132   "TARGET_64BIT && TARGET_SSE2"
4133   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4134   [(set_attr "type" "sseicvt,sseicvt")
4135    (set_attr "mode" "DF")
4136    (set_attr "athlon_decode" "double,vector")])
4138 ;; Avoid vector decoded form of the instruction.
4139 (define_peephole2
4140   [(match_scratch:DF 2 "Y")
4141    (set (match_operand:DI 0 "register_operand" "")
4142         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4143   "TARGET_K8 && !optimize_size"
4144   [(set (match_dup 2) (match_dup 1))
4145    (set (match_dup 0) (fix:DI (match_dup 2)))]
4146   "")
4148 ;; Signed conversion to SImode.
4150 (define_expand "fix_truncxfsi2"
4151   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4152                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4153               (clobber (reg:CC FLAGS_REG))])]
4154   "TARGET_80387"
4155   "")
4157 (define_expand "fix_truncdfsi2"
4158   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4160               (clobber (reg:CC FLAGS_REG))])]
4161   "TARGET_80387 || TARGET_SSE2"
4163   if (TARGET_SSE2)
4164    {
4165      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4166      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4167      if (out != operands[0])
4168         emit_move_insn (operands[0], out);
4169      DONE;
4170    }
4173 (define_expand "fix_truncsfsi2"
4174   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4175                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4176               (clobber (reg:CC FLAGS_REG))])] 
4177   "TARGET_80387 || TARGET_SSE"
4179   if (TARGET_SSE)
4180    {
4181      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4182      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4183      if (out != operands[0])
4184         emit_move_insn (operands[0], out);
4185      DONE;
4186    }
4189 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4190 ;; of the machinery.
4191 (define_insn_and_split "*fix_truncsi_1"
4192   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4193         (fix:SI (match_operand 1 "register_operand" "f,f")))
4194    (clobber (reg:CC FLAGS_REG))]
4195   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4196    && !reload_completed && !reload_in_progress
4197    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4198   "#"
4199   "&& 1"
4200   [(const_int 0)]
4202   ix86_optimize_mode_switching = 1;
4203   operands[2] = assign_386_stack_local (HImode, 1);
4204   operands[3] = assign_386_stack_local (HImode, 2);
4205   if (memory_operand (operands[0], VOIDmode))
4206     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4207                                        operands[2], operands[3]));
4208   else
4209     {
4210       operands[4] = assign_386_stack_local (SImode, 0);
4211       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4212                                            operands[2], operands[3],
4213                                            operands[4]));
4214     }
4215   DONE;
4217   [(set_attr "type" "fistp")
4218    (set_attr "i387_cw" "trunc")
4219    (set_attr "mode" "SI")])
4221 (define_insn "fix_truncsi_nomemory"
4222   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4223         (fix:SI (match_operand 1 "register_operand" "f,f")))
4224    (use (match_operand:HI 2 "memory_operand" "m,m"))
4225    (use (match_operand:HI 3 "memory_operand" "m,m"))
4226    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4227   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4228    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4229   "#"
4230   [(set_attr "type" "fistp")
4231    (set_attr "i387_cw" "trunc")
4232    (set_attr "mode" "SI")])
4234 (define_insn "fix_truncsi_memory"
4235   [(set (match_operand:SI 0 "memory_operand" "=m")
4236         (fix:SI (match_operand 1 "register_operand" "f")))
4237    (use (match_operand:HI 2 "memory_operand" "m"))
4238    (use (match_operand:HI 3 "memory_operand" "m"))]
4239   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4240    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4241   "* return output_fix_trunc (insn, operands);"
4242   [(set_attr "type" "fistp")
4243    (set_attr "i387_cw" "trunc")
4244    (set_attr "mode" "SI")])
4246 ;; When SSE available, it is always faster to use it!
4247 (define_insn "fix_truncsfsi_sse"
4248   [(set (match_operand:SI 0 "register_operand" "=r,r")
4249         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4250   "TARGET_SSE"
4251   "cvttss2si\t{%1, %0|%0, %1}"
4252   [(set_attr "type" "sseicvt")
4253    (set_attr "mode" "DF")
4254    (set_attr "athlon_decode" "double,vector")])
4256 ;; Avoid vector decoded form of the instruction.
4257 (define_peephole2
4258   [(match_scratch:SF 2 "x")
4259    (set (match_operand:SI 0 "register_operand" "")
4260         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4261   "TARGET_K8 && !optimize_size"
4262   [(set (match_dup 2) (match_dup 1))
4263    (set (match_dup 0) (fix:SI (match_dup 2)))]
4264   "")
4266 (define_insn "fix_truncdfsi_sse"
4267   [(set (match_operand:SI 0 "register_operand" "=r,r")
4268         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4269   "TARGET_SSE2"
4270   "cvttsd2si\t{%1, %0|%0, %1}"
4271   [(set_attr "type" "sseicvt")
4272    (set_attr "mode" "DF")
4273    (set_attr "athlon_decode" "double,vector")])
4275 ;; Avoid vector decoded form of the instruction.
4276 (define_peephole2
4277   [(match_scratch:DF 2 "Y")
4278    (set (match_operand:SI 0 "register_operand" "")
4279         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4280   "TARGET_K8 && !optimize_size"
4281   [(set (match_dup 2) (match_dup 1))
4282    (set (match_dup 0) (fix:SI (match_dup 2)))]
4283   "")
4285 (define_split 
4286   [(set (match_operand:SI 0 "register_operand" "")
4287         (fix:SI (match_operand 1 "register_operand" "")))
4288    (use (match_operand:HI 2 "memory_operand" ""))
4289    (use (match_operand:HI 3 "memory_operand" ""))
4290    (clobber (match_operand:SI 4 "memory_operand" ""))]
4291   "reload_completed"
4292   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4293               (use (match_dup 2))
4294               (use (match_dup 3))])
4295    (set (match_dup 0) (match_dup 4))]
4296   "")
4298 (define_split 
4299   [(set (match_operand:SI 0 "memory_operand" "")
4300         (fix:SI (match_operand 1 "register_operand" "")))
4301    (use (match_operand:HI 2 "memory_operand" ""))
4302    (use (match_operand:HI 3 "memory_operand" ""))
4303    (clobber (match_operand:SI 4 "memory_operand" ""))]
4304   "reload_completed"
4305   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4306               (use (match_dup 2))
4307               (use (match_dup 3))])]
4308   "")
4310 ;; Signed conversion to HImode.
4312 (define_expand "fix_truncxfhi2"
4313   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4314                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4315               (clobber (reg:CC FLAGS_REG))])] 
4316   "TARGET_80387"
4317   "")
4319 (define_expand "fix_truncdfhi2"
4320   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4321                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4322               (clobber (reg:CC FLAGS_REG))])]
4323   "TARGET_80387 && !TARGET_SSE2"
4324   "")
4326 (define_expand "fix_truncsfhi2"
4327   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4329                (clobber (reg:CC FLAGS_REG))])]
4330   "TARGET_80387 && !TARGET_SSE"
4331   "")
4333 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4334 ;; of the machinery.
4335 (define_insn_and_split "*fix_trunchi_1"
4336   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4337         (fix:HI (match_operand 1 "register_operand" "f,f")))
4338    (clobber (reg:CC FLAGS_REG))]
4339   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4340    && !reload_completed && !reload_in_progress
4341    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4342   "#"
4343   "&& 1"
4344   [(const_int 0)]
4346   ix86_optimize_mode_switching = 1;
4347   operands[2] = assign_386_stack_local (HImode, 1);
4348   operands[3] = assign_386_stack_local (HImode, 2);
4349   if (memory_operand (operands[0], VOIDmode))
4350     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4351                                        operands[2], operands[3]));
4352   else
4353     {
4354       operands[4] = assign_386_stack_local (HImode, 0);
4355       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4356                                            operands[2], operands[3],
4357                                            operands[4]));
4358     }
4359   DONE;
4361   [(set_attr "type" "fistp")
4362    (set_attr "i387_cw" "trunc")
4363    (set_attr "mode" "HI")])
4365 (define_insn "fix_trunchi_nomemory"
4366   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4367         (fix:HI (match_operand 1 "register_operand" "f,f")))
4368    (use (match_operand:HI 2 "memory_operand" "m,m"))
4369    (use (match_operand:HI 3 "memory_operand" "m,m"))
4370    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4371   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4372    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4373   "#"
4374   [(set_attr "type" "fistp")
4375    (set_attr "i387_cw" "trunc")
4376    (set_attr "mode" "HI")])
4378 (define_insn "fix_trunchi_memory"
4379   [(set (match_operand:HI 0 "memory_operand" "=m")
4380         (fix:HI (match_operand 1 "register_operand" "f")))
4381    (use (match_operand:HI 2 "memory_operand" "m"))
4382    (use (match_operand:HI 3 "memory_operand" "m"))]
4383   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4384    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4385   "* return output_fix_trunc (insn, operands);"
4386   [(set_attr "type" "fistp")
4387    (set_attr "i387_cw" "trunc")
4388    (set_attr "mode" "HI")])
4390 (define_split 
4391   [(set (match_operand:HI 0 "memory_operand" "")
4392         (fix:HI (match_operand 1 "register_operand" "")))
4393    (use (match_operand:HI 2 "memory_operand" ""))
4394    (use (match_operand:HI 3 "memory_operand" ""))
4395    (clobber (match_operand:HI 4 "memory_operand" ""))]
4396   "reload_completed"
4397   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4398               (use (match_dup 2))
4399               (use (match_dup 3))])]
4400   "")
4402 (define_split 
4403   [(set (match_operand:HI 0 "register_operand" "")
4404         (fix:HI (match_operand 1 "register_operand" "")))
4405    (use (match_operand:HI 2 "memory_operand" ""))
4406    (use (match_operand:HI 3 "memory_operand" ""))
4407    (clobber (match_operand:HI 4 "memory_operand" ""))]
4408   "reload_completed"
4409   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4410               (use (match_dup 2))
4411               (use (match_dup 3))
4412               (clobber (match_dup 4))])
4413    (set (match_dup 0) (match_dup 4))]
4414   "")
4416 (define_insn "x86_fnstcw_1"
4417   [(set (match_operand:HI 0 "memory_operand" "=m")
4418         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4419   "TARGET_80387"
4420   "fnstcw\t%0"
4421   [(set_attr "length" "2")
4422    (set_attr "mode" "HI")
4423    (set_attr "unit" "i387")])
4425 (define_insn "x86_fldcw_1"
4426   [(set (reg:HI FPSR_REG)
4427         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4428   "TARGET_80387"
4429   "fldcw\t%0"
4430   [(set_attr "length" "2")
4431    (set_attr "mode" "HI")
4432    (set_attr "unit" "i387")
4433    (set_attr "athlon_decode" "vector")])
4435 ;; Conversion between fixed point and floating point.
4437 ;; Even though we only accept memory inputs, the backend _really_
4438 ;; wants to be able to do this between registers.
4440 (define_expand "floathisf2"
4441   [(set (match_operand:SF 0 "register_operand" "")
4442         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4443   "TARGET_SSE || TARGET_80387"
4445   if (TARGET_SSE && TARGET_SSE_MATH)
4446     {
4447       emit_insn (gen_floatsisf2 (operands[0],
4448                                  convert_to_mode (SImode, operands[1], 0)));
4449       DONE;
4450     }
4453 (define_insn "*floathisf2_1"
4454   [(set (match_operand:SF 0 "register_operand" "=f,f")
4455         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4456   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4457   "@
4458    fild%z1\t%1
4459    #"
4460   [(set_attr "type" "fmov,multi")
4461    (set_attr "mode" "SF")
4462    (set_attr "fp_int_src" "true")])
4464 (define_expand "floatsisf2"
4465   [(set (match_operand:SF 0 "register_operand" "")
4466         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4467   "TARGET_SSE || TARGET_80387"
4468   "")
4470 (define_insn "*floatsisf2_i387"
4471   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4472         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4473   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4474   "@
4475    fild%z1\t%1
4476    #
4477    cvtsi2ss\t{%1, %0|%0, %1}
4478    cvtsi2ss\t{%1, %0|%0, %1}"
4479   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4480    (set_attr "mode" "SF")
4481    (set_attr "athlon_decode" "*,*,vector,double")
4482    (set_attr "fp_int_src" "true")])
4484 (define_insn "*floatsisf2_sse"
4485   [(set (match_operand:SF 0 "register_operand" "=x,x")
4486         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4487   "TARGET_SSE"
4488   "cvtsi2ss\t{%1, %0|%0, %1}"
4489   [(set_attr "type" "sseicvt")
4490    (set_attr "mode" "SF")
4491    (set_attr "athlon_decode" "vector,double")
4492    (set_attr "fp_int_src" "true")])
4494 ; Avoid possible reformatting penalty on the destination by first
4495 ; zeroing it out
4496 (define_split
4497   [(set (match_operand:SF 0 "register_operand" "")
4498         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4499   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4500    && SSE_REG_P (operands[0])"
4501   [(const_int 0)]
4503   rtx dest;
4504   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4505   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4506   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4507   DONE;
4510 (define_expand "floatdisf2"
4511   [(set (match_operand:SF 0 "register_operand" "")
4512         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4513   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4514   "")
4516 (define_insn "*floatdisf2_i387_only"
4517   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4518         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4519   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4520   "@
4521    fild%z1\t%1
4522    #"
4523   [(set_attr "type" "fmov,multi")
4524    (set_attr "mode" "SF")
4525    (set_attr "fp_int_src" "true")])
4527 (define_insn "*floatdisf2_i387"
4528   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4529         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4530   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4531   "@
4532    fild%z1\t%1
4533    #
4534    cvtsi2ss{q}\t{%1, %0|%0, %1}
4535    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4536   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4537    (set_attr "mode" "SF")
4538    (set_attr "athlon_decode" "*,*,vector,double")
4539    (set_attr "fp_int_src" "true")])
4541 (define_insn "*floatdisf2_sse"
4542   [(set (match_operand:SF 0 "register_operand" "=x,x")
4543         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4544   "TARGET_64BIT && TARGET_SSE"
4545   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4546   [(set_attr "type" "sseicvt")
4547    (set_attr "mode" "SF")
4548    (set_attr "athlon_decode" "vector,double")
4549    (set_attr "fp_int_src" "true")])
4551 ; Avoid possible reformatting penalty on the destination by first
4552 ; zeroing it out
4553 (define_split
4554   [(set (match_operand:SF 0 "register_operand" "")
4555         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4556   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4557    && SSE_REG_P (operands[0])"
4558   [(const_int 0)]
4560   rtx dest;
4561   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4562   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4563   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4564   DONE;
4567 (define_expand "floathidf2"
4568   [(set (match_operand:DF 0 "register_operand" "")
4569         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4570   "TARGET_SSE2 || TARGET_80387"
4572   if (TARGET_SSE && TARGET_SSE_MATH)
4573     {
4574       emit_insn (gen_floatsidf2 (operands[0],
4575                                  convert_to_mode (SImode, operands[1], 0)));
4576       DONE;
4577     }
4580 (define_insn "*floathidf2_1"
4581   [(set (match_operand:DF 0 "register_operand" "=f,f")
4582         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4583   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4584   "@
4585    fild%z1\t%1
4586    #"
4587   [(set_attr "type" "fmov,multi")
4588    (set_attr "mode" "DF")
4589    (set_attr "fp_int_src" "true")])
4591 (define_expand "floatsidf2"
4592   [(set (match_operand:DF 0 "register_operand" "")
4593         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4594   "TARGET_80387 || TARGET_SSE2"
4595   "")
4597 (define_insn "*floatsidf2_i387"
4598   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4599         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4600   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4601   "@
4602    fild%z1\t%1
4603    #
4604    cvtsi2sd\t{%1, %0|%0, %1}
4605    cvtsi2sd\t{%1, %0|%0, %1}"
4606   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4607    (set_attr "mode" "DF")
4608    (set_attr "athlon_decode" "*,*,double,direct")
4609    (set_attr "fp_int_src" "true")])
4611 (define_insn "*floatsidf2_sse"
4612   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4613         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4614   "TARGET_SSE2"
4615   "cvtsi2sd\t{%1, %0|%0, %1}"
4616   [(set_attr "type" "sseicvt")
4617    (set_attr "mode" "DF")
4618    (set_attr "athlon_decode" "double,direct")
4619    (set_attr "fp_int_src" "true")])
4621 (define_expand "floatdidf2"
4622   [(set (match_operand:DF 0 "register_operand" "")
4623         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4624   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4625   "")
4627 (define_insn "*floatdidf2_i387_only"
4628   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4629         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4630   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4631   "@
4632    fild%z1\t%1
4633    #"
4634   [(set_attr "type" "fmov,multi")
4635    (set_attr "mode" "DF")
4636    (set_attr "fp_int_src" "true")])
4638 (define_insn "*floatdidf2_i387"
4639   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4640         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4641   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4642   "@
4643    fild%z1\t%1
4644    #
4645    cvtsi2sd{q}\t{%1, %0|%0, %1}
4646    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4647   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4648    (set_attr "mode" "DF")
4649    (set_attr "athlon_decode" "*,*,double,direct")
4650    (set_attr "fp_int_src" "true")])
4652 (define_insn "*floatdidf2_sse"
4653   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4654         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4655   "TARGET_SSE2"
4656   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4657   [(set_attr "type" "sseicvt")
4658    (set_attr "mode" "DF")
4659    (set_attr "athlon_decode" "double,direct")
4660    (set_attr "fp_int_src" "true")])
4662 (define_insn "floathixf2"
4663   [(set (match_operand:XF 0 "register_operand" "=f,f")
4664         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4665   "TARGET_80387"
4666   "@
4667    fild%z1\t%1
4668    #"
4669   [(set_attr "type" "fmov,multi")
4670    (set_attr "mode" "XF")
4671    (set_attr "fp_int_src" "true")])
4673 (define_insn "floatsixf2"
4674   [(set (match_operand:XF 0 "register_operand" "=f,f")
4675         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4676   "TARGET_80387"
4677   "@
4678    fild%z1\t%1
4679    #"
4680   [(set_attr "type" "fmov,multi")
4681    (set_attr "mode" "XF")
4682    (set_attr "fp_int_src" "true")])
4684 (define_insn "floatdixf2"
4685   [(set (match_operand:XF 0 "register_operand" "=f,f")
4686         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4687   "TARGET_80387"
4688   "@
4689    fild%z1\t%1
4690    #"
4691   [(set_attr "type" "fmov,multi")
4692    (set_attr "mode" "XF")
4693    (set_attr "fp_int_src" "true")])
4695 ;; %%% Kill these when reload knows how to do it.
4696 (define_split
4697   [(set (match_operand 0 "fp_register_operand" "")
4698         (float (match_operand 1 "register_operand" "")))]
4699   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4700   [(const_int 0)]
4702   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4703   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4704   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4705   ix86_free_from_memory (GET_MODE (operands[1]));
4706   DONE;
4709 (define_expand "floatunssisf2"
4710   [(use (match_operand:SF 0 "register_operand" ""))
4711    (use (match_operand:SI 1 "register_operand" ""))]
4712   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4713   "x86_emit_floatuns (operands); DONE;")
4715 (define_expand "floatunsdisf2"
4716   [(use (match_operand:SF 0 "register_operand" ""))
4717    (use (match_operand:DI 1 "register_operand" ""))]
4718   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4719   "x86_emit_floatuns (operands); DONE;")
4721 (define_expand "floatunsdidf2"
4722   [(use (match_operand:DF 0 "register_operand" ""))
4723    (use (match_operand:DI 1 "register_operand" ""))]
4724   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4725   "x86_emit_floatuns (operands); DONE;")
4727 ;; SSE extract/set expanders
4729 (define_expand "vec_setv2df"
4730   [(match_operand:V2DF 0 "register_operand" "")
4731    (match_operand:DF 1 "register_operand" "")
4732    (match_operand 2 "const_int_operand" "")]
4733   "TARGET_SSE2"
4735   switch (INTVAL (operands[2]))
4736     {
4737     case 0:
4738       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4739                                  simplify_gen_subreg (V2DFmode, operands[1],
4740                                                       DFmode, 0)));
4741       break;
4742     case 1:
4743       {
4744         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4746         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4747       }
4748       break;
4749     default:
4750       abort ();
4751     }
4752   DONE;
4755 (define_expand "vec_extractv2df"
4756   [(match_operand:DF 0 "register_operand" "")
4757    (match_operand:V2DF 1 "register_operand" "")
4758    (match_operand 2 "const_int_operand" "")]
4759   "TARGET_SSE2"
4761   switch (INTVAL (operands[2]))
4762     {
4763     case 0:
4764       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4765       break;
4766     case 1:
4767       {
4768         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4770         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4771       }
4772       break;
4773     default:
4774       abort ();
4775     }
4776   DONE;
4779 (define_expand "vec_initv2df"
4780   [(match_operand:V2DF 0 "register_operand" "")
4781    (match_operand 1 "" "")]
4782   "TARGET_SSE2"
4784   ix86_expand_vector_init (operands[0], operands[1]);
4785   DONE;
4788 (define_expand "vec_setv4sf"
4789   [(match_operand:V4SF 0 "register_operand" "")
4790    (match_operand:SF 1 "register_operand" "")
4791    (match_operand 2 "const_int_operand" "")]
4792   "TARGET_SSE"
4794   switch (INTVAL (operands[2]))
4795     {
4796     case 0:
4797       emit_insn (gen_sse_movss (operands[0], operands[0],
4798                                 simplify_gen_subreg (V4SFmode, operands[1],
4799                                                      SFmode, 0)));
4800       break;
4801     case 1:
4802       {
4803         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4804         rtx tmp = gen_reg_rtx (V4SFmode);
4806         emit_move_insn (tmp, operands[0]);
4807         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4808         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4809         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4810                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4811       }
4812       break;
4813     case 2:
4814       {
4815         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4816         rtx tmp = gen_reg_rtx (V4SFmode);
4818         emit_move_insn (tmp, operands[0]);
4819         emit_insn (gen_sse_movss (tmp, tmp, op1));
4820         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4821                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4822       }
4823       break;
4824     case 3:
4825       {
4826         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4827         rtx tmp = gen_reg_rtx (V4SFmode);
4829         emit_move_insn (tmp, operands[0]);
4830         emit_insn (gen_sse_movss (tmp, tmp, op1));
4831         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4832                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4833       }
4834       break;
4835     default:
4836       abort ();
4837     }
4838   DONE;
4841 (define_expand "vec_extractv4sf"
4842   [(match_operand:SF 0 "register_operand" "")
4843    (match_operand:V4SF 1 "register_operand" "")
4844    (match_operand 2 "const_int_operand" "")]
4845   "TARGET_SSE"
4847   switch (INTVAL (operands[2]))
4848     {
4849     case 0:
4850       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4851       break;
4852     case 1:
4853       {
4854         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4855         rtx tmp = gen_reg_rtx (V4SFmode);
4857         emit_move_insn (tmp, operands[1]);
4858         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4859                                    const1_rtx));
4860       }
4861       break;
4862     case 2:
4863       {
4864         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4865         rtx tmp = gen_reg_rtx (V4SFmode);
4867         emit_move_insn (tmp, operands[1]);
4868         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4869       }
4870       break;
4871     case 3:
4872       {
4873         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4874         rtx tmp = gen_reg_rtx (V4SFmode);
4876         emit_move_insn (tmp, operands[1]);
4877         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4878                                    GEN_INT (3)));
4879       }
4880       break;
4881     default:
4882       abort ();
4883     }
4884   DONE;
4887 (define_expand "vec_initv4sf"
4888   [(match_operand:V4SF 0 "register_operand" "")
4889    (match_operand 1 "" "")]
4890   "TARGET_SSE"
4892   ix86_expand_vector_init (operands[0], operands[1]);
4893   DONE;
4896 ;; Add instructions
4898 ;; %%% splits for addsidi3
4899 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4900 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4901 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4903 (define_expand "adddi3"
4904   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4905         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4906                  (match_operand:DI 2 "x86_64_general_operand" "")))
4907    (clobber (reg:CC FLAGS_REG))]
4908   ""
4909   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4911 (define_insn "*adddi3_1"
4912   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4913         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4914                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4915    (clobber (reg:CC FLAGS_REG))]
4916   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4917   "#")
4919 (define_split
4920   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4921         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4922                  (match_operand:DI 2 "general_operand" "")))
4923    (clobber (reg:CC FLAGS_REG))]
4924   "!TARGET_64BIT && reload_completed"
4925   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4926                                           UNSPEC_ADD_CARRY))
4927               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4928    (parallel [(set (match_dup 3)
4929                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4930                                      (match_dup 4))
4931                             (match_dup 5)))
4932               (clobber (reg:CC FLAGS_REG))])]
4933   "split_di (operands+0, 1, operands+0, operands+3);
4934    split_di (operands+1, 1, operands+1, operands+4);
4935    split_di (operands+2, 1, operands+2, operands+5);")
4937 (define_insn "adddi3_carry_rex64"
4938   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4939           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4940                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4941                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4942    (clobber (reg:CC FLAGS_REG))]
4943   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4944   "adc{q}\t{%2, %0|%0, %2}"
4945   [(set_attr "type" "alu")
4946    (set_attr "pent_pair" "pu")
4947    (set_attr "mode" "DI")])
4949 (define_insn "*adddi3_cc_rex64"
4950   [(set (reg:CC FLAGS_REG)
4951         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4952                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4953                    UNSPEC_ADD_CARRY))
4954    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4955         (plus:DI (match_dup 1) (match_dup 2)))]
4956   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4957   "add{q}\t{%2, %0|%0, %2}"
4958   [(set_attr "type" "alu")
4959    (set_attr "mode" "DI")])
4961 (define_insn "addqi3_carry"
4962   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4963           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4964                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4965                    (match_operand:QI 2 "general_operand" "qi,qm")))
4966    (clobber (reg:CC FLAGS_REG))]
4967   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4968   "adc{b}\t{%2, %0|%0, %2}"
4969   [(set_attr "type" "alu")
4970    (set_attr "pent_pair" "pu")
4971    (set_attr "mode" "QI")])
4973 (define_insn "addhi3_carry"
4974   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4975           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4976                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4977                    (match_operand:HI 2 "general_operand" "ri,rm")))
4978    (clobber (reg:CC FLAGS_REG))]
4979   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4980   "adc{w}\t{%2, %0|%0, %2}"
4981   [(set_attr "type" "alu")
4982    (set_attr "pent_pair" "pu")
4983    (set_attr "mode" "HI")])
4985 (define_insn "addsi3_carry"
4986   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4987           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4988                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4989                    (match_operand:SI 2 "general_operand" "ri,rm")))
4990    (clobber (reg:CC FLAGS_REG))]
4991   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4992   "adc{l}\t{%2, %0|%0, %2}"
4993   [(set_attr "type" "alu")
4994    (set_attr "pent_pair" "pu")
4995    (set_attr "mode" "SI")])
4997 (define_insn "*addsi3_carry_zext"
4998   [(set (match_operand:DI 0 "register_operand" "=r")
4999           (zero_extend:DI 
5000             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5001                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5002                      (match_operand:SI 2 "general_operand" "rim"))))
5003    (clobber (reg:CC FLAGS_REG))]
5004   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5005   "adc{l}\t{%2, %k0|%k0, %2}"
5006   [(set_attr "type" "alu")
5007    (set_attr "pent_pair" "pu")
5008    (set_attr "mode" "SI")])
5010 (define_insn "*addsi3_cc"
5011   [(set (reg:CC FLAGS_REG)
5012         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5013                     (match_operand:SI 2 "general_operand" "ri,rm")]
5014                    UNSPEC_ADD_CARRY))
5015    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5016         (plus:SI (match_dup 1) (match_dup 2)))]
5017   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5018   "add{l}\t{%2, %0|%0, %2}"
5019   [(set_attr "type" "alu")
5020    (set_attr "mode" "SI")])
5022 (define_insn "addqi3_cc"
5023   [(set (reg:CC FLAGS_REG)
5024         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5025                     (match_operand:QI 2 "general_operand" "qi,qm")]
5026                    UNSPEC_ADD_CARRY))
5027    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5028         (plus:QI (match_dup 1) (match_dup 2)))]
5029   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5030   "add{b}\t{%2, %0|%0, %2}"
5031   [(set_attr "type" "alu")
5032    (set_attr "mode" "QI")])
5034 (define_expand "addsi3"
5035   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5036                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5037                             (match_operand:SI 2 "general_operand" "")))
5038               (clobber (reg:CC FLAGS_REG))])]
5039   ""
5040   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5042 (define_insn "*lea_1"
5043   [(set (match_operand:SI 0 "register_operand" "=r")
5044         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5045   "!TARGET_64BIT"
5046   "lea{l}\t{%a1, %0|%0, %a1}"
5047   [(set_attr "type" "lea")
5048    (set_attr "mode" "SI")])
5050 (define_insn "*lea_1_rex64"
5051   [(set (match_operand:SI 0 "register_operand" "=r")
5052         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5053   "TARGET_64BIT"
5054   "lea{l}\t{%a1, %0|%0, %a1}"
5055   [(set_attr "type" "lea")
5056    (set_attr "mode" "SI")])
5058 (define_insn "*lea_1_zext"
5059   [(set (match_operand:DI 0 "register_operand" "=r")
5060         (zero_extend:DI
5061          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5062   "TARGET_64BIT"
5063   "lea{l}\t{%a1, %k0|%k0, %a1}"
5064   [(set_attr "type" "lea")
5065    (set_attr "mode" "SI")])
5067 (define_insn "*lea_2_rex64"
5068   [(set (match_operand:DI 0 "register_operand" "=r")
5069         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5070   "TARGET_64BIT"
5071   "lea{q}\t{%a1, %0|%0, %a1}"
5072   [(set_attr "type" "lea")
5073    (set_attr "mode" "DI")])
5075 ;; The lea patterns for non-Pmodes needs to be matched by several
5076 ;; insns converted to real lea by splitters.
5078 (define_insn_and_split "*lea_general_1"
5079   [(set (match_operand 0 "register_operand" "=r")
5080         (plus (plus (match_operand 1 "index_register_operand" "r")
5081                     (match_operand 2 "register_operand" "r"))
5082               (match_operand 3 "immediate_operand" "i")))]
5083   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5084     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5085    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5086    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5087    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5088    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5089        || GET_MODE (operands[3]) == VOIDmode)"
5090   "#"
5091   "&& reload_completed"
5092   [(const_int 0)]
5094   rtx pat;
5095   operands[0] = gen_lowpart (SImode, operands[0]);
5096   operands[1] = gen_lowpart (Pmode, operands[1]);
5097   operands[2] = gen_lowpart (Pmode, operands[2]);
5098   operands[3] = gen_lowpart (Pmode, operands[3]);
5099   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5100                       operands[3]);
5101   if (Pmode != SImode)
5102     pat = gen_rtx_SUBREG (SImode, pat, 0);
5103   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5104   DONE;
5106   [(set_attr "type" "lea")
5107    (set_attr "mode" "SI")])
5109 (define_insn_and_split "*lea_general_1_zext"
5110   [(set (match_operand:DI 0 "register_operand" "=r")
5111         (zero_extend:DI
5112           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5113                             (match_operand:SI 2 "register_operand" "r"))
5114                    (match_operand:SI 3 "immediate_operand" "i"))))]
5115   "TARGET_64BIT"
5116   "#"
5117   "&& reload_completed"
5118   [(set (match_dup 0)
5119         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5120                                                      (match_dup 2))
5121                                             (match_dup 3)) 0)))]
5123   operands[1] = gen_lowpart (Pmode, operands[1]);
5124   operands[2] = gen_lowpart (Pmode, operands[2]);
5125   operands[3] = gen_lowpart (Pmode, operands[3]);
5127   [(set_attr "type" "lea")
5128    (set_attr "mode" "SI")])
5130 (define_insn_and_split "*lea_general_2"
5131   [(set (match_operand 0 "register_operand" "=r")
5132         (plus (mult (match_operand 1 "index_register_operand" "r")
5133                     (match_operand 2 "const248_operand" "i"))
5134               (match_operand 3 "nonmemory_operand" "ri")))]
5135   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5136     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5137    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5138    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5139    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5140        || GET_MODE (operands[3]) == VOIDmode)"
5141   "#"
5142   "&& reload_completed"
5143   [(const_int 0)]
5145   rtx pat;
5146   operands[0] = gen_lowpart (SImode, operands[0]);
5147   operands[1] = gen_lowpart (Pmode, operands[1]);
5148   operands[3] = gen_lowpart (Pmode, operands[3]);
5149   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5150                       operands[3]);
5151   if (Pmode != SImode)
5152     pat = gen_rtx_SUBREG (SImode, pat, 0);
5153   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5154   DONE;
5156   [(set_attr "type" "lea")
5157    (set_attr "mode" "SI")])
5159 (define_insn_and_split "*lea_general_2_zext"
5160   [(set (match_operand:DI 0 "register_operand" "=r")
5161         (zero_extend:DI
5162           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5163                             (match_operand:SI 2 "const248_operand" "n"))
5164                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5165   "TARGET_64BIT"
5166   "#"
5167   "&& reload_completed"
5168   [(set (match_dup 0)
5169         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5170                                                      (match_dup 2))
5171                                             (match_dup 3)) 0)))]
5173   operands[1] = gen_lowpart (Pmode, operands[1]);
5174   operands[3] = gen_lowpart (Pmode, operands[3]);
5176   [(set_attr "type" "lea")
5177    (set_attr "mode" "SI")])
5179 (define_insn_and_split "*lea_general_3"
5180   [(set (match_operand 0 "register_operand" "=r")
5181         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5182                           (match_operand 2 "const248_operand" "i"))
5183                     (match_operand 3 "register_operand" "r"))
5184               (match_operand 4 "immediate_operand" "i")))]
5185   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5186     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5187    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5188    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5189    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5190   "#"
5191   "&& reload_completed"
5192   [(const_int 0)]
5194   rtx pat;
5195   operands[0] = gen_lowpart (SImode, operands[0]);
5196   operands[1] = gen_lowpart (Pmode, operands[1]);
5197   operands[3] = gen_lowpart (Pmode, operands[3]);
5198   operands[4] = gen_lowpart (Pmode, operands[4]);
5199   pat = gen_rtx_PLUS (Pmode,
5200                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5201                                                          operands[2]),
5202                                     operands[3]),
5203                       operands[4]);
5204   if (Pmode != SImode)
5205     pat = gen_rtx_SUBREG (SImode, pat, 0);
5206   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5207   DONE;
5209   [(set_attr "type" "lea")
5210    (set_attr "mode" "SI")])
5212 (define_insn_and_split "*lea_general_3_zext"
5213   [(set (match_operand:DI 0 "register_operand" "=r")
5214         (zero_extend:DI
5215           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5216                                      (match_operand:SI 2 "const248_operand" "n"))
5217                             (match_operand:SI 3 "register_operand" "r"))
5218                    (match_operand:SI 4 "immediate_operand" "i"))))]
5219   "TARGET_64BIT"
5220   "#"
5221   "&& reload_completed"
5222   [(set (match_dup 0)
5223         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5224                                                               (match_dup 2))
5225                                                      (match_dup 3))
5226                                             (match_dup 4)) 0)))]
5228   operands[1] = gen_lowpart (Pmode, operands[1]);
5229   operands[3] = gen_lowpart (Pmode, operands[3]);
5230   operands[4] = gen_lowpart (Pmode, operands[4]);
5232   [(set_attr "type" "lea")
5233    (set_attr "mode" "SI")])
5235 (define_insn "*adddi_1_rex64"
5236   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5237         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5238                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5239    (clobber (reg:CC FLAGS_REG))]
5240   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5242   switch (get_attr_type (insn))
5243     {
5244     case TYPE_LEA:
5245       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5246       return "lea{q}\t{%a2, %0|%0, %a2}";
5248     case TYPE_INCDEC:
5249       if (! rtx_equal_p (operands[0], operands[1]))
5250         abort ();
5251       if (operands[2] == const1_rtx)
5252         return "inc{q}\t%0";
5253       else if (operands[2] == constm1_rtx)
5254         return "dec{q}\t%0";
5255       else
5256         abort ();
5258     default:
5259       if (! rtx_equal_p (operands[0], operands[1]))
5260         abort ();
5262       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5263          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5264       if (GET_CODE (operands[2]) == CONST_INT
5265           /* Avoid overflows.  */
5266           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5267           && (INTVAL (operands[2]) == 128
5268               || (INTVAL (operands[2]) < 0
5269                   && INTVAL (operands[2]) != -128)))
5270         {
5271           operands[2] = GEN_INT (-INTVAL (operands[2]));
5272           return "sub{q}\t{%2, %0|%0, %2}";
5273         }
5274       return "add{q}\t{%2, %0|%0, %2}";
5275     }
5277   [(set (attr "type")
5278      (cond [(eq_attr "alternative" "2")
5279               (const_string "lea")
5280             ; Current assemblers are broken and do not allow @GOTOFF in
5281             ; ought but a memory context.
5282             (match_operand:DI 2 "pic_symbolic_operand" "")
5283               (const_string "lea")
5284             (match_operand:DI 2 "incdec_operand" "")
5285               (const_string "incdec")
5286            ]
5287            (const_string "alu")))
5288    (set_attr "mode" "DI")])
5290 ;; Convert lea to the lea pattern to avoid flags dependency.
5291 (define_split
5292   [(set (match_operand:DI 0 "register_operand" "")
5293         (plus:DI (match_operand:DI 1 "register_operand" "")
5294                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5295    (clobber (reg:CC FLAGS_REG))]
5296   "TARGET_64BIT && reload_completed
5297    && true_regnum (operands[0]) != true_regnum (operands[1])"
5298   [(set (match_dup 0)
5299         (plus:DI (match_dup 1)
5300                  (match_dup 2)))]
5301   "")
5303 (define_insn "*adddi_2_rex64"
5304   [(set (reg FLAGS_REG)
5305         (compare
5306           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5307                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5308           (const_int 0)))                       
5309    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5310         (plus:DI (match_dup 1) (match_dup 2)))]
5311   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5312    && ix86_binary_operator_ok (PLUS, DImode, operands)
5313    /* Current assemblers are broken and do not allow @GOTOFF in
5314       ought but a memory context.  */
5315    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5317   switch (get_attr_type (insn))
5318     {
5319     case TYPE_INCDEC:
5320       if (! rtx_equal_p (operands[0], operands[1]))
5321         abort ();
5322       if (operands[2] == const1_rtx)
5323         return "inc{q}\t%0";
5324       else if (operands[2] == constm1_rtx)
5325         return "dec{q}\t%0";
5326       else
5327         abort ();
5329     default:
5330       if (! rtx_equal_p (operands[0], operands[1]))
5331         abort ();
5332       /* ???? We ought to handle there the 32bit case too
5333          - do we need new constraint?  */
5334       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5335          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5336       if (GET_CODE (operands[2]) == CONST_INT
5337           /* Avoid overflows.  */
5338           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5339           && (INTVAL (operands[2]) == 128
5340               || (INTVAL (operands[2]) < 0
5341                   && INTVAL (operands[2]) != -128)))
5342         {
5343           operands[2] = GEN_INT (-INTVAL (operands[2]));
5344           return "sub{q}\t{%2, %0|%0, %2}";
5345         }
5346       return "add{q}\t{%2, %0|%0, %2}";
5347     }
5349   [(set (attr "type")
5350      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5351         (const_string "incdec")
5352         (const_string "alu")))
5353    (set_attr "mode" "DI")])
5355 (define_insn "*adddi_3_rex64"
5356   [(set (reg FLAGS_REG)
5357         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5358                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5359    (clobber (match_scratch:DI 0 "=r"))]
5360   "TARGET_64BIT
5361    && ix86_match_ccmode (insn, CCZmode)
5362    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5363    /* Current assemblers are broken and do not allow @GOTOFF in
5364       ought but a memory context.  */
5365    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5367   switch (get_attr_type (insn))
5368     {
5369     case TYPE_INCDEC:
5370       if (! rtx_equal_p (operands[0], operands[1]))
5371         abort ();
5372       if (operands[2] == const1_rtx)
5373         return "inc{q}\t%0";
5374       else if (operands[2] == constm1_rtx)
5375         return "dec{q}\t%0";
5376       else
5377         abort ();
5379     default:
5380       if (! rtx_equal_p (operands[0], operands[1]))
5381         abort ();
5382       /* ???? We ought to handle there the 32bit case too
5383          - do we need new constraint?  */
5384       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5385          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5386       if (GET_CODE (operands[2]) == CONST_INT
5387           /* Avoid overflows.  */
5388           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5389           && (INTVAL (operands[2]) == 128
5390               || (INTVAL (operands[2]) < 0
5391                   && INTVAL (operands[2]) != -128)))
5392         {
5393           operands[2] = GEN_INT (-INTVAL (operands[2]));
5394           return "sub{q}\t{%2, %0|%0, %2}";
5395         }
5396       return "add{q}\t{%2, %0|%0, %2}";
5397     }
5399   [(set (attr "type")
5400      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5401         (const_string "incdec")
5402         (const_string "alu")))
5403    (set_attr "mode" "DI")])
5405 ; For comparisons against 1, -1 and 128, we may generate better code
5406 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5407 ; is matched then.  We can't accept general immediate, because for
5408 ; case of overflows,  the result is messed up.
5409 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5410 ; when negated.
5411 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5412 ; only for comparisons not depending on it.
5413 (define_insn "*adddi_4_rex64"
5414   [(set (reg FLAGS_REG)
5415         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5416                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5417    (clobber (match_scratch:DI 0 "=rm"))]
5418   "TARGET_64BIT
5419    &&  ix86_match_ccmode (insn, CCGCmode)"
5421   switch (get_attr_type (insn))
5422     {
5423     case TYPE_INCDEC:
5424       if (operands[2] == constm1_rtx)
5425         return "inc{q}\t%0";
5426       else if (operands[2] == const1_rtx)
5427         return "dec{q}\t%0";
5428       else
5429         abort();
5431     default:
5432       if (! rtx_equal_p (operands[0], operands[1]))
5433         abort ();
5434       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5435          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5436       if ((INTVAL (operands[2]) == -128
5437            || (INTVAL (operands[2]) > 0
5438                && INTVAL (operands[2]) != 128))
5439           /* Avoid overflows.  */
5440           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5441         return "sub{q}\t{%2, %0|%0, %2}";
5442       operands[2] = GEN_INT (-INTVAL (operands[2]));
5443       return "add{q}\t{%2, %0|%0, %2}";
5444     }
5446   [(set (attr "type")
5447      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5448         (const_string "incdec")
5449         (const_string "alu")))
5450    (set_attr "mode" "DI")])
5452 (define_insn "*adddi_5_rex64"
5453   [(set (reg FLAGS_REG)
5454         (compare
5455           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5456                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5457           (const_int 0)))                       
5458    (clobber (match_scratch:DI 0 "=r"))]
5459   "TARGET_64BIT
5460    && ix86_match_ccmode (insn, CCGOCmode)
5461    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5462    /* Current assemblers are broken and do not allow @GOTOFF in
5463       ought but a memory context.  */
5464    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5466   switch (get_attr_type (insn))
5467     {
5468     case TYPE_INCDEC:
5469       if (! rtx_equal_p (operands[0], operands[1]))
5470         abort ();
5471       if (operands[2] == const1_rtx)
5472         return "inc{q}\t%0";
5473       else if (operands[2] == constm1_rtx)
5474         return "dec{q}\t%0";
5475       else
5476         abort();
5478     default:
5479       if (! rtx_equal_p (operands[0], operands[1]))
5480         abort ();
5481       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5482          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5483       if (GET_CODE (operands[2]) == CONST_INT
5484           /* Avoid overflows.  */
5485           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5486           && (INTVAL (operands[2]) == 128
5487               || (INTVAL (operands[2]) < 0
5488                   && INTVAL (operands[2]) != -128)))
5489         {
5490           operands[2] = GEN_INT (-INTVAL (operands[2]));
5491           return "sub{q}\t{%2, %0|%0, %2}";
5492         }
5493       return "add{q}\t{%2, %0|%0, %2}";
5494     }
5496   [(set (attr "type")
5497      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5498         (const_string "incdec")
5499         (const_string "alu")))
5500    (set_attr "mode" "DI")])
5503 (define_insn "*addsi_1"
5504   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5505         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5506                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5507    (clobber (reg:CC FLAGS_REG))]
5508   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5510   switch (get_attr_type (insn))
5511     {
5512     case TYPE_LEA:
5513       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5514       return "lea{l}\t{%a2, %0|%0, %a2}";
5516     case TYPE_INCDEC:
5517       if (! rtx_equal_p (operands[0], operands[1]))
5518         abort ();
5519       if (operands[2] == const1_rtx)
5520         return "inc{l}\t%0";
5521       else if (operands[2] == constm1_rtx)
5522         return "dec{l}\t%0";
5523       else
5524         abort();
5526     default:
5527       if (! rtx_equal_p (operands[0], operands[1]))
5528         abort ();
5530       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5531          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5532       if (GET_CODE (operands[2]) == CONST_INT
5533           && (INTVAL (operands[2]) == 128
5534               || (INTVAL (operands[2]) < 0
5535                   && INTVAL (operands[2]) != -128)))
5536         {
5537           operands[2] = GEN_INT (-INTVAL (operands[2]));
5538           return "sub{l}\t{%2, %0|%0, %2}";
5539         }
5540       return "add{l}\t{%2, %0|%0, %2}";
5541     }
5543   [(set (attr "type")
5544      (cond [(eq_attr "alternative" "2")
5545               (const_string "lea")
5546             ; Current assemblers are broken and do not allow @GOTOFF in
5547             ; ought but a memory context.
5548             (match_operand:SI 2 "pic_symbolic_operand" "")
5549               (const_string "lea")
5550             (match_operand:SI 2 "incdec_operand" "")
5551               (const_string "incdec")
5552            ]
5553            (const_string "alu")))
5554    (set_attr "mode" "SI")])
5556 ;; Convert lea to the lea pattern to avoid flags dependency.
5557 (define_split
5558   [(set (match_operand 0 "register_operand" "")
5559         (plus (match_operand 1 "register_operand" "")
5560               (match_operand 2 "nonmemory_operand" "")))
5561    (clobber (reg:CC FLAGS_REG))]
5562   "reload_completed
5563    && true_regnum (operands[0]) != true_regnum (operands[1])"
5564   [(const_int 0)]
5566   rtx pat;
5567   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5568      may confuse gen_lowpart.  */
5569   if (GET_MODE (operands[0]) != Pmode)
5570     {
5571       operands[1] = gen_lowpart (Pmode, operands[1]);
5572       operands[2] = gen_lowpart (Pmode, operands[2]);
5573     }
5574   operands[0] = gen_lowpart (SImode, operands[0]);
5575   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5576   if (Pmode != SImode)
5577     pat = gen_rtx_SUBREG (SImode, pat, 0);
5578   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5579   DONE;
5582 ;; It may seem that nonimmediate operand is proper one for operand 1.
5583 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5584 ;; we take care in ix86_binary_operator_ok to not allow two memory
5585 ;; operands so proper swapping will be done in reload.  This allow
5586 ;; patterns constructed from addsi_1 to match.
5587 (define_insn "addsi_1_zext"
5588   [(set (match_operand:DI 0 "register_operand" "=r,r")
5589         (zero_extend:DI
5590           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5591                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5592    (clobber (reg:CC FLAGS_REG))]
5593   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5595   switch (get_attr_type (insn))
5596     {
5597     case TYPE_LEA:
5598       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5599       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5601     case TYPE_INCDEC:
5602       if (operands[2] == const1_rtx)
5603         return "inc{l}\t%k0";
5604       else if (operands[2] == constm1_rtx)
5605         return "dec{l}\t%k0";
5606       else
5607         abort();
5609     default:
5610       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5611          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5612       if (GET_CODE (operands[2]) == CONST_INT
5613           && (INTVAL (operands[2]) == 128
5614               || (INTVAL (operands[2]) < 0
5615                   && INTVAL (operands[2]) != -128)))
5616         {
5617           operands[2] = GEN_INT (-INTVAL (operands[2]));
5618           return "sub{l}\t{%2, %k0|%k0, %2}";
5619         }
5620       return "add{l}\t{%2, %k0|%k0, %2}";
5621     }
5623   [(set (attr "type")
5624      (cond [(eq_attr "alternative" "1")
5625               (const_string "lea")
5626             ; Current assemblers are broken and do not allow @GOTOFF in
5627             ; ought but a memory context.
5628             (match_operand:SI 2 "pic_symbolic_operand" "")
5629               (const_string "lea")
5630             (match_operand:SI 2 "incdec_operand" "")
5631               (const_string "incdec")
5632            ]
5633            (const_string "alu")))
5634    (set_attr "mode" "SI")])
5636 ;; Convert lea to the lea pattern to avoid flags dependency.
5637 (define_split
5638   [(set (match_operand:DI 0 "register_operand" "")
5639         (zero_extend:DI
5640           (plus:SI (match_operand:SI 1 "register_operand" "")
5641                    (match_operand:SI 2 "nonmemory_operand" ""))))
5642    (clobber (reg:CC FLAGS_REG))]
5643   "TARGET_64BIT && reload_completed
5644    && true_regnum (operands[0]) != true_regnum (operands[1])"
5645   [(set (match_dup 0)
5646         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5648   operands[1] = gen_lowpart (Pmode, operands[1]);
5649   operands[2] = gen_lowpart (Pmode, operands[2]);
5652 (define_insn "*addsi_2"
5653   [(set (reg FLAGS_REG)
5654         (compare
5655           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5656                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5657           (const_int 0)))                       
5658    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5659         (plus:SI (match_dup 1) (match_dup 2)))]
5660   "ix86_match_ccmode (insn, CCGOCmode)
5661    && ix86_binary_operator_ok (PLUS, SImode, operands)
5662    /* Current assemblers are broken and do not allow @GOTOFF in
5663       ought but a memory context.  */
5664    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5666   switch (get_attr_type (insn))
5667     {
5668     case TYPE_INCDEC:
5669       if (! rtx_equal_p (operands[0], operands[1]))
5670         abort ();
5671       if (operands[2] == const1_rtx)
5672         return "inc{l}\t%0";
5673       else if (operands[2] == constm1_rtx)
5674         return "dec{l}\t%0";
5675       else
5676         abort();
5678     default:
5679       if (! rtx_equal_p (operands[0], operands[1]))
5680         abort ();
5681       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5682          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5683       if (GET_CODE (operands[2]) == CONST_INT
5684           && (INTVAL (operands[2]) == 128
5685               || (INTVAL (operands[2]) < 0
5686                   && INTVAL (operands[2]) != -128)))
5687         {
5688           operands[2] = GEN_INT (-INTVAL (operands[2]));
5689           return "sub{l}\t{%2, %0|%0, %2}";
5690         }
5691       return "add{l}\t{%2, %0|%0, %2}";
5692     }
5694   [(set (attr "type")
5695      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5696         (const_string "incdec")
5697         (const_string "alu")))
5698    (set_attr "mode" "SI")])
5700 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5701 (define_insn "*addsi_2_zext"
5702   [(set (reg FLAGS_REG)
5703         (compare
5704           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5705                    (match_operand:SI 2 "general_operand" "rmni"))
5706           (const_int 0)))                       
5707    (set (match_operand:DI 0 "register_operand" "=r")
5708         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5709   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5710    && ix86_binary_operator_ok (PLUS, SImode, operands)
5711    /* Current assemblers are broken and do not allow @GOTOFF in
5712       ought but a memory context.  */
5713    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5715   switch (get_attr_type (insn))
5716     {
5717     case TYPE_INCDEC:
5718       if (operands[2] == const1_rtx)
5719         return "inc{l}\t%k0";
5720       else if (operands[2] == constm1_rtx)
5721         return "dec{l}\t%k0";
5722       else
5723         abort();
5725     default:
5726       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5727          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5728       if (GET_CODE (operands[2]) == CONST_INT
5729           && (INTVAL (operands[2]) == 128
5730               || (INTVAL (operands[2]) < 0
5731                   && INTVAL (operands[2]) != -128)))
5732         {
5733           operands[2] = GEN_INT (-INTVAL (operands[2]));
5734           return "sub{l}\t{%2, %k0|%k0, %2}";
5735         }
5736       return "add{l}\t{%2, %k0|%k0, %2}";
5737     }
5739   [(set (attr "type")
5740      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5741         (const_string "incdec")
5742         (const_string "alu")))
5743    (set_attr "mode" "SI")])
5745 (define_insn "*addsi_3"
5746   [(set (reg FLAGS_REG)
5747         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5748                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5749    (clobber (match_scratch:SI 0 "=r"))]
5750   "ix86_match_ccmode (insn, CCZmode)
5751    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5752    /* Current assemblers are broken and do not allow @GOTOFF in
5753       ought but a memory context.  */
5754    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5756   switch (get_attr_type (insn))
5757     {
5758     case TYPE_INCDEC:
5759       if (! rtx_equal_p (operands[0], operands[1]))
5760         abort ();
5761       if (operands[2] == const1_rtx)
5762         return "inc{l}\t%0";
5763       else if (operands[2] == constm1_rtx)
5764         return "dec{l}\t%0";
5765       else
5766         abort();
5768     default:
5769       if (! rtx_equal_p (operands[0], operands[1]))
5770         abort ();
5771       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5772          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5773       if (GET_CODE (operands[2]) == CONST_INT
5774           && (INTVAL (operands[2]) == 128
5775               || (INTVAL (operands[2]) < 0
5776                   && INTVAL (operands[2]) != -128)))
5777         {
5778           operands[2] = GEN_INT (-INTVAL (operands[2]));
5779           return "sub{l}\t{%2, %0|%0, %2}";
5780         }
5781       return "add{l}\t{%2, %0|%0, %2}";
5782     }
5784   [(set (attr "type")
5785      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5786         (const_string "incdec")
5787         (const_string "alu")))
5788    (set_attr "mode" "SI")])
5790 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5791 (define_insn "*addsi_3_zext"
5792   [(set (reg FLAGS_REG)
5793         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5794                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5795    (set (match_operand:DI 0 "register_operand" "=r")
5796         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5797   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5798    && ix86_binary_operator_ok (PLUS, SImode, operands)
5799    /* Current assemblers are broken and do not allow @GOTOFF in
5800       ought but a memory context.  */
5801    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5803   switch (get_attr_type (insn))
5804     {
5805     case TYPE_INCDEC:
5806       if (operands[2] == const1_rtx)
5807         return "inc{l}\t%k0";
5808       else if (operands[2] == constm1_rtx)
5809         return "dec{l}\t%k0";
5810       else
5811         abort();
5813     default:
5814       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5815          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5816       if (GET_CODE (operands[2]) == CONST_INT
5817           && (INTVAL (operands[2]) == 128
5818               || (INTVAL (operands[2]) < 0
5819                   && INTVAL (operands[2]) != -128)))
5820         {
5821           operands[2] = GEN_INT (-INTVAL (operands[2]));
5822           return "sub{l}\t{%2, %k0|%k0, %2}";
5823         }
5824       return "add{l}\t{%2, %k0|%k0, %2}";
5825     }
5827   [(set (attr "type")
5828      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5829         (const_string "incdec")
5830         (const_string "alu")))
5831    (set_attr "mode" "SI")])
5833 ; For comparisons against 1, -1 and 128, we may generate better code
5834 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5835 ; is matched then.  We can't accept general immediate, because for
5836 ; case of overflows,  the result is messed up.
5837 ; This pattern also don't hold of 0x80000000, since the value overflows
5838 ; when negated.
5839 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5840 ; only for comparisons not depending on it.
5841 (define_insn "*addsi_4"
5842   [(set (reg FLAGS_REG)
5843         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5844                  (match_operand:SI 2 "const_int_operand" "n")))
5845    (clobber (match_scratch:SI 0 "=rm"))]
5846   "ix86_match_ccmode (insn, CCGCmode)
5847    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5849   switch (get_attr_type (insn))
5850     {
5851     case TYPE_INCDEC:
5852       if (operands[2] == constm1_rtx)
5853         return "inc{l}\t%0";
5854       else if (operands[2] == const1_rtx)
5855         return "dec{l}\t%0";
5856       else
5857         abort();
5859     default:
5860       if (! rtx_equal_p (operands[0], operands[1]))
5861         abort ();
5862       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5863          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5864       if ((INTVAL (operands[2]) == -128
5865            || (INTVAL (operands[2]) > 0
5866                && INTVAL (operands[2]) != 128)))
5867         return "sub{l}\t{%2, %0|%0, %2}";
5868       operands[2] = GEN_INT (-INTVAL (operands[2]));
5869       return "add{l}\t{%2, %0|%0, %2}";
5870     }
5872   [(set (attr "type")
5873      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5874         (const_string "incdec")
5875         (const_string "alu")))
5876    (set_attr "mode" "SI")])
5878 (define_insn "*addsi_5"
5879   [(set (reg FLAGS_REG)
5880         (compare
5881           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5882                    (match_operand:SI 2 "general_operand" "rmni"))
5883           (const_int 0)))                       
5884    (clobber (match_scratch:SI 0 "=r"))]
5885   "ix86_match_ccmode (insn, CCGOCmode)
5886    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5887    /* Current assemblers are broken and do not allow @GOTOFF in
5888       ought but a memory context.  */
5889    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5891   switch (get_attr_type (insn))
5892     {
5893     case TYPE_INCDEC:
5894       if (! rtx_equal_p (operands[0], operands[1]))
5895         abort ();
5896       if (operands[2] == const1_rtx)
5897         return "inc{l}\t%0";
5898       else if (operands[2] == constm1_rtx)
5899         return "dec{l}\t%0";
5900       else
5901         abort();
5903     default:
5904       if (! rtx_equal_p (operands[0], operands[1]))
5905         abort ();
5906       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5907          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5908       if (GET_CODE (operands[2]) == CONST_INT
5909           && (INTVAL (operands[2]) == 128
5910               || (INTVAL (operands[2]) < 0
5911                   && INTVAL (operands[2]) != -128)))
5912         {
5913           operands[2] = GEN_INT (-INTVAL (operands[2]));
5914           return "sub{l}\t{%2, %0|%0, %2}";
5915         }
5916       return "add{l}\t{%2, %0|%0, %2}";
5917     }
5919   [(set (attr "type")
5920      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5921         (const_string "incdec")
5922         (const_string "alu")))
5923    (set_attr "mode" "SI")])
5925 (define_expand "addhi3"
5926   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5927                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5928                             (match_operand:HI 2 "general_operand" "")))
5929               (clobber (reg:CC FLAGS_REG))])]
5930   "TARGET_HIMODE_MATH"
5931   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5933 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5934 ;; type optimizations enabled by define-splits.  This is not important
5935 ;; for PII, and in fact harmful because of partial register stalls.
5937 (define_insn "*addhi_1_lea"
5938   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5939         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5940                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5941    (clobber (reg:CC FLAGS_REG))]
5942   "!TARGET_PARTIAL_REG_STALL
5943    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5945   switch (get_attr_type (insn))
5946     {
5947     case TYPE_LEA:
5948       return "#";
5949     case TYPE_INCDEC:
5950       if (operands[2] == const1_rtx)
5951         return "inc{w}\t%0";
5952       else if (operands[2] == constm1_rtx)
5953         return "dec{w}\t%0";
5954       abort();
5956     default:
5957       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5958          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5959       if (GET_CODE (operands[2]) == CONST_INT
5960           && (INTVAL (operands[2]) == 128
5961               || (INTVAL (operands[2]) < 0
5962                   && INTVAL (operands[2]) != -128)))
5963         {
5964           operands[2] = GEN_INT (-INTVAL (operands[2]));
5965           return "sub{w}\t{%2, %0|%0, %2}";
5966         }
5967       return "add{w}\t{%2, %0|%0, %2}";
5968     }
5970   [(set (attr "type")
5971      (if_then_else (eq_attr "alternative" "2")
5972         (const_string "lea")
5973         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5974            (const_string "incdec")
5975            (const_string "alu"))))
5976    (set_attr "mode" "HI,HI,SI")])
5978 (define_insn "*addhi_1"
5979   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5980         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5981                  (match_operand:HI 2 "general_operand" "ri,rm")))
5982    (clobber (reg:CC FLAGS_REG))]
5983   "TARGET_PARTIAL_REG_STALL
5984    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5986   switch (get_attr_type (insn))
5987     {
5988     case TYPE_INCDEC:
5989       if (operands[2] == const1_rtx)
5990         return "inc{w}\t%0";
5991       else if (operands[2] == constm1_rtx)
5992         return "dec{w}\t%0";
5993       abort();
5995     default:
5996       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5997          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5998       if (GET_CODE (operands[2]) == CONST_INT
5999           && (INTVAL (operands[2]) == 128
6000               || (INTVAL (operands[2]) < 0
6001                   && INTVAL (operands[2]) != -128)))
6002         {
6003           operands[2] = GEN_INT (-INTVAL (operands[2]));
6004           return "sub{w}\t{%2, %0|%0, %2}";
6005         }
6006       return "add{w}\t{%2, %0|%0, %2}";
6007     }
6009   [(set (attr "type")
6010      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6011         (const_string "incdec")
6012         (const_string "alu")))
6013    (set_attr "mode" "HI")])
6015 (define_insn "*addhi_2"
6016   [(set (reg FLAGS_REG)
6017         (compare
6018           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6019                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6020           (const_int 0)))                       
6021    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6022         (plus:HI (match_dup 1) (match_dup 2)))]
6023   "ix86_match_ccmode (insn, CCGOCmode)
6024    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6026   switch (get_attr_type (insn))
6027     {
6028     case TYPE_INCDEC:
6029       if (operands[2] == const1_rtx)
6030         return "inc{w}\t%0";
6031       else if (operands[2] == constm1_rtx)
6032         return "dec{w}\t%0";
6033       abort();
6035     default:
6036       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6037          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6038       if (GET_CODE (operands[2]) == CONST_INT
6039           && (INTVAL (operands[2]) == 128
6040               || (INTVAL (operands[2]) < 0
6041                   && INTVAL (operands[2]) != -128)))
6042         {
6043           operands[2] = GEN_INT (-INTVAL (operands[2]));
6044           return "sub{w}\t{%2, %0|%0, %2}";
6045         }
6046       return "add{w}\t{%2, %0|%0, %2}";
6047     }
6049   [(set (attr "type")
6050      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6051         (const_string "incdec")
6052         (const_string "alu")))
6053    (set_attr "mode" "HI")])
6055 (define_insn "*addhi_3"
6056   [(set (reg FLAGS_REG)
6057         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6058                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6059    (clobber (match_scratch:HI 0 "=r"))]
6060   "ix86_match_ccmode (insn, CCZmode)
6061    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6063   switch (get_attr_type (insn))
6064     {
6065     case TYPE_INCDEC:
6066       if (operands[2] == const1_rtx)
6067         return "inc{w}\t%0";
6068       else if (operands[2] == constm1_rtx)
6069         return "dec{w}\t%0";
6070       abort();
6072     default:
6073       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6074          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6075       if (GET_CODE (operands[2]) == CONST_INT
6076           && (INTVAL (operands[2]) == 128
6077               || (INTVAL (operands[2]) < 0
6078                   && INTVAL (operands[2]) != -128)))
6079         {
6080           operands[2] = GEN_INT (-INTVAL (operands[2]));
6081           return "sub{w}\t{%2, %0|%0, %2}";
6082         }
6083       return "add{w}\t{%2, %0|%0, %2}";
6084     }
6086   [(set (attr "type")
6087      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6088         (const_string "incdec")
6089         (const_string "alu")))
6090    (set_attr "mode" "HI")])
6092 ; See comments above addsi_3_imm for details.
6093 (define_insn "*addhi_4"
6094   [(set (reg FLAGS_REG)
6095         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6096                  (match_operand:HI 2 "const_int_operand" "n")))
6097    (clobber (match_scratch:HI 0 "=rm"))]
6098   "ix86_match_ccmode (insn, CCGCmode)
6099    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6101   switch (get_attr_type (insn))
6102     {
6103     case TYPE_INCDEC:
6104       if (operands[2] == constm1_rtx)
6105         return "inc{w}\t%0";
6106       else if (operands[2] == const1_rtx)
6107         return "dec{w}\t%0";
6108       else
6109         abort();
6111     default:
6112       if (! rtx_equal_p (operands[0], operands[1]))
6113         abort ();
6114       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6115          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6116       if ((INTVAL (operands[2]) == -128
6117            || (INTVAL (operands[2]) > 0
6118                && INTVAL (operands[2]) != 128)))
6119         return "sub{w}\t{%2, %0|%0, %2}";
6120       operands[2] = GEN_INT (-INTVAL (operands[2]));
6121       return "add{w}\t{%2, %0|%0, %2}";
6122     }
6124   [(set (attr "type")
6125      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6126         (const_string "incdec")
6127         (const_string "alu")))
6128    (set_attr "mode" "SI")])
6131 (define_insn "*addhi_5"
6132   [(set (reg FLAGS_REG)
6133         (compare
6134           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6135                    (match_operand:HI 2 "general_operand" "rmni"))
6136           (const_int 0)))                       
6137    (clobber (match_scratch:HI 0 "=r"))]
6138   "ix86_match_ccmode (insn, CCGOCmode)
6139    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6141   switch (get_attr_type (insn))
6142     {
6143     case TYPE_INCDEC:
6144       if (operands[2] == const1_rtx)
6145         return "inc{w}\t%0";
6146       else if (operands[2] == constm1_rtx)
6147         return "dec{w}\t%0";
6148       abort();
6150     default:
6151       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6152          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6153       if (GET_CODE (operands[2]) == CONST_INT
6154           && (INTVAL (operands[2]) == 128
6155               || (INTVAL (operands[2]) < 0
6156                   && INTVAL (operands[2]) != -128)))
6157         {
6158           operands[2] = GEN_INT (-INTVAL (operands[2]));
6159           return "sub{w}\t{%2, %0|%0, %2}";
6160         }
6161       return "add{w}\t{%2, %0|%0, %2}";
6162     }
6164   [(set (attr "type")
6165      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6166         (const_string "incdec")
6167         (const_string "alu")))
6168    (set_attr "mode" "HI")])
6170 (define_expand "addqi3"
6171   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6172                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6173                             (match_operand:QI 2 "general_operand" "")))
6174               (clobber (reg:CC FLAGS_REG))])]
6175   "TARGET_QIMODE_MATH"
6176   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6178 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6179 (define_insn "*addqi_1_lea"
6180   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6181         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6182                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6183    (clobber (reg:CC FLAGS_REG))]
6184   "!TARGET_PARTIAL_REG_STALL
6185    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6187   int widen = (which_alternative == 2);
6188   switch (get_attr_type (insn))
6189     {
6190     case TYPE_LEA:
6191       return "#";
6192     case TYPE_INCDEC:
6193       if (operands[2] == const1_rtx)
6194         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6195       else if (operands[2] == constm1_rtx)
6196         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6197       abort();
6199     default:
6200       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6201          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6202       if (GET_CODE (operands[2]) == CONST_INT
6203           && (INTVAL (operands[2]) == 128
6204               || (INTVAL (operands[2]) < 0
6205                   && INTVAL (operands[2]) != -128)))
6206         {
6207           operands[2] = GEN_INT (-INTVAL (operands[2]));
6208           if (widen)
6209             return "sub{l}\t{%2, %k0|%k0, %2}";
6210           else
6211             return "sub{b}\t{%2, %0|%0, %2}";
6212         }
6213       if (widen)
6214         return "add{l}\t{%k2, %k0|%k0, %k2}";
6215       else
6216         return "add{b}\t{%2, %0|%0, %2}";
6217     }
6219   [(set (attr "type")
6220      (if_then_else (eq_attr "alternative" "3")
6221         (const_string "lea")
6222         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6223            (const_string "incdec")
6224            (const_string "alu"))))
6225    (set_attr "mode" "QI,QI,SI,SI")])
6227 (define_insn "*addqi_1"
6228   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6229         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6230                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6231    (clobber (reg:CC FLAGS_REG))]
6232   "TARGET_PARTIAL_REG_STALL
6233    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6235   int widen = (which_alternative == 2);
6236   switch (get_attr_type (insn))
6237     {
6238     case TYPE_INCDEC:
6239       if (operands[2] == const1_rtx)
6240         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6241       else if (operands[2] == constm1_rtx)
6242         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6243       abort();
6245     default:
6246       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6247          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6248       if (GET_CODE (operands[2]) == CONST_INT
6249           && (INTVAL (operands[2]) == 128
6250               || (INTVAL (operands[2]) < 0
6251                   && INTVAL (operands[2]) != -128)))
6252         {
6253           operands[2] = GEN_INT (-INTVAL (operands[2]));
6254           if (widen)
6255             return "sub{l}\t{%2, %k0|%k0, %2}";
6256           else
6257             return "sub{b}\t{%2, %0|%0, %2}";
6258         }
6259       if (widen)
6260         return "add{l}\t{%k2, %k0|%k0, %k2}";
6261       else
6262         return "add{b}\t{%2, %0|%0, %2}";
6263     }
6265   [(set (attr "type")
6266      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6267         (const_string "incdec")
6268         (const_string "alu")))
6269    (set_attr "mode" "QI,QI,SI")])
6271 (define_insn "*addqi_1_slp"
6272   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6273         (plus:QI (match_dup 0)
6274                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6275    (clobber (reg:CC FLAGS_REG))]
6276   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6277    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6279   switch (get_attr_type (insn))
6280     {
6281     case TYPE_INCDEC:
6282       if (operands[1] == const1_rtx)
6283         return "inc{b}\t%0";
6284       else if (operands[1] == constm1_rtx)
6285         return "dec{b}\t%0";
6286       abort();
6288     default:
6289       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6290       if (GET_CODE (operands[1]) == CONST_INT
6291           && INTVAL (operands[1]) < 0)
6292         {
6293           operands[1] = GEN_INT (-INTVAL (operands[1]));
6294           return "sub{b}\t{%1, %0|%0, %1}";
6295         }
6296       return "add{b}\t{%1, %0|%0, %1}";
6297     }
6299   [(set (attr "type")
6300      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6301         (const_string "incdec")
6302         (const_string "alu1")))
6303    (set_attr "mode" "QI")])
6305 (define_insn "*addqi_2"
6306   [(set (reg FLAGS_REG)
6307         (compare
6308           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6309                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6310           (const_int 0)))
6311    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6312         (plus:QI (match_dup 1) (match_dup 2)))]
6313   "ix86_match_ccmode (insn, CCGOCmode)
6314    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6316   switch (get_attr_type (insn))
6317     {
6318     case TYPE_INCDEC:
6319       if (operands[2] == const1_rtx)
6320         return "inc{b}\t%0";
6321       else if (operands[2] == constm1_rtx
6322                || (GET_CODE (operands[2]) == CONST_INT
6323                    && INTVAL (operands[2]) == 255))
6324         return "dec{b}\t%0";
6325       abort();
6327     default:
6328       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6329       if (GET_CODE (operands[2]) == CONST_INT
6330           && INTVAL (operands[2]) < 0)
6331         {
6332           operands[2] = GEN_INT (-INTVAL (operands[2]));
6333           return "sub{b}\t{%2, %0|%0, %2}";
6334         }
6335       return "add{b}\t{%2, %0|%0, %2}";
6336     }
6338   [(set (attr "type")
6339      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6340         (const_string "incdec")
6341         (const_string "alu")))
6342    (set_attr "mode" "QI")])
6344 (define_insn "*addqi_3"
6345   [(set (reg FLAGS_REG)
6346         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6347                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6348    (clobber (match_scratch:QI 0 "=q"))]
6349   "ix86_match_ccmode (insn, CCZmode)
6350    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6352   switch (get_attr_type (insn))
6353     {
6354     case TYPE_INCDEC:
6355       if (operands[2] == const1_rtx)
6356         return "inc{b}\t%0";
6357       else if (operands[2] == constm1_rtx
6358                || (GET_CODE (operands[2]) == CONST_INT
6359                    && INTVAL (operands[2]) == 255))
6360         return "dec{b}\t%0";
6361       abort();
6363     default:
6364       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6365       if (GET_CODE (operands[2]) == CONST_INT
6366           && INTVAL (operands[2]) < 0)
6367         {
6368           operands[2] = GEN_INT (-INTVAL (operands[2]));
6369           return "sub{b}\t{%2, %0|%0, %2}";
6370         }
6371       return "add{b}\t{%2, %0|%0, %2}";
6372     }
6374   [(set (attr "type")
6375      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6376         (const_string "incdec")
6377         (const_string "alu")))
6378    (set_attr "mode" "QI")])
6380 ; See comments above addsi_3_imm for details.
6381 (define_insn "*addqi_4"
6382   [(set (reg FLAGS_REG)
6383         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6384                  (match_operand:QI 2 "const_int_operand" "n")))
6385    (clobber (match_scratch:QI 0 "=qm"))]
6386   "ix86_match_ccmode (insn, CCGCmode)
6387    && (INTVAL (operands[2]) & 0xff) != 0x80"
6389   switch (get_attr_type (insn))
6390     {
6391     case TYPE_INCDEC:
6392       if (operands[2] == constm1_rtx
6393           || (GET_CODE (operands[2]) == CONST_INT
6394               && INTVAL (operands[2]) == 255))
6395         return "inc{b}\t%0";
6396       else if (operands[2] == const1_rtx)
6397         return "dec{b}\t%0";
6398       else
6399         abort();
6401     default:
6402       if (! rtx_equal_p (operands[0], operands[1]))
6403         abort ();
6404       if (INTVAL (operands[2]) < 0)
6405         {
6406           operands[2] = GEN_INT (-INTVAL (operands[2]));
6407           return "add{b}\t{%2, %0|%0, %2}";
6408         }
6409       return "sub{b}\t{%2, %0|%0, %2}";
6410     }
6412   [(set (attr "type")
6413      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6414         (const_string "incdec")
6415         (const_string "alu")))
6416    (set_attr "mode" "QI")])
6419 (define_insn "*addqi_5"
6420   [(set (reg FLAGS_REG)
6421         (compare
6422           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6423                    (match_operand:QI 2 "general_operand" "qmni"))
6424           (const_int 0)))
6425    (clobber (match_scratch:QI 0 "=q"))]
6426   "ix86_match_ccmode (insn, CCGOCmode)
6427    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6429   switch (get_attr_type (insn))
6430     {
6431     case TYPE_INCDEC:
6432       if (operands[2] == const1_rtx)
6433         return "inc{b}\t%0";
6434       else if (operands[2] == constm1_rtx
6435                || (GET_CODE (operands[2]) == CONST_INT
6436                    && INTVAL (operands[2]) == 255))
6437         return "dec{b}\t%0";
6438       abort();
6440     default:
6441       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6442       if (GET_CODE (operands[2]) == CONST_INT
6443           && INTVAL (operands[2]) < 0)
6444         {
6445           operands[2] = GEN_INT (-INTVAL (operands[2]));
6446           return "sub{b}\t{%2, %0|%0, %2}";
6447         }
6448       return "add{b}\t{%2, %0|%0, %2}";
6449     }
6451   [(set (attr "type")
6452      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6453         (const_string "incdec")
6454         (const_string "alu")))
6455    (set_attr "mode" "QI")])
6458 (define_insn "addqi_ext_1"
6459   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6460                          (const_int 8)
6461                          (const_int 8))
6462         (plus:SI
6463           (zero_extract:SI
6464             (match_operand 1 "ext_register_operand" "0")
6465             (const_int 8)
6466             (const_int 8))
6467           (match_operand:QI 2 "general_operand" "Qmn")))
6468    (clobber (reg:CC FLAGS_REG))]
6469   "!TARGET_64BIT"
6471   switch (get_attr_type (insn))
6472     {
6473     case TYPE_INCDEC:
6474       if (operands[2] == const1_rtx)
6475         return "inc{b}\t%h0";
6476       else if (operands[2] == constm1_rtx
6477                || (GET_CODE (operands[2]) == CONST_INT
6478                    && INTVAL (operands[2]) == 255))
6479         return "dec{b}\t%h0";
6480       abort();
6482     default:
6483       return "add{b}\t{%2, %h0|%h0, %2}";
6484     }
6486   [(set (attr "type")
6487      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6488         (const_string "incdec")
6489         (const_string "alu")))
6490    (set_attr "mode" "QI")])
6492 (define_insn "*addqi_ext_1_rex64"
6493   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6494                          (const_int 8)
6495                          (const_int 8))
6496         (plus:SI
6497           (zero_extract:SI
6498             (match_operand 1 "ext_register_operand" "0")
6499             (const_int 8)
6500             (const_int 8))
6501           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6502    (clobber (reg:CC FLAGS_REG))]
6503   "TARGET_64BIT"
6505   switch (get_attr_type (insn))
6506     {
6507     case TYPE_INCDEC:
6508       if (operands[2] == const1_rtx)
6509         return "inc{b}\t%h0";
6510       else if (operands[2] == constm1_rtx
6511                || (GET_CODE (operands[2]) == CONST_INT
6512                    && INTVAL (operands[2]) == 255))
6513         return "dec{b}\t%h0";
6514       abort();
6516     default:
6517       return "add{b}\t{%2, %h0|%h0, %2}";
6518     }
6520   [(set (attr "type")
6521      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6522         (const_string "incdec")
6523         (const_string "alu")))
6524    (set_attr "mode" "QI")])
6526 (define_insn "*addqi_ext_2"
6527   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6528                          (const_int 8)
6529                          (const_int 8))
6530         (plus:SI
6531           (zero_extract:SI
6532             (match_operand 1 "ext_register_operand" "%0")
6533             (const_int 8)
6534             (const_int 8))
6535           (zero_extract:SI
6536             (match_operand 2 "ext_register_operand" "Q")
6537             (const_int 8)
6538             (const_int 8))))
6539    (clobber (reg:CC FLAGS_REG))]
6540   ""
6541   "add{b}\t{%h2, %h0|%h0, %h2}"
6542   [(set_attr "type" "alu")
6543    (set_attr "mode" "QI")])
6545 ;; The patterns that match these are at the end of this file.
6547 (define_expand "addxf3"
6548   [(set (match_operand:XF 0 "register_operand" "")
6549         (plus:XF (match_operand:XF 1 "register_operand" "")
6550                  (match_operand:XF 2 "register_operand" "")))]
6551   "TARGET_80387"
6552   "")
6554 (define_expand "adddf3"
6555   [(set (match_operand:DF 0 "register_operand" "")
6556         (plus:DF (match_operand:DF 1 "register_operand" "")
6557                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6558   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6559   "")
6561 (define_expand "addsf3"
6562   [(set (match_operand:SF 0 "register_operand" "")
6563         (plus:SF (match_operand:SF 1 "register_operand" "")
6564                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6565   "TARGET_80387 || TARGET_SSE_MATH"
6566   "")
6568 ;; Subtract instructions
6570 ;; %%% splits for subsidi3
6572 (define_expand "subdi3"
6573   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6574                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6575                              (match_operand:DI 2 "x86_64_general_operand" "")))
6576               (clobber (reg:CC FLAGS_REG))])]
6577   ""
6578   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6580 (define_insn "*subdi3_1"
6581   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6582         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6583                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6584    (clobber (reg:CC FLAGS_REG))]
6585   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6586   "#")
6588 (define_split
6589   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6590         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6591                   (match_operand:DI 2 "general_operand" "")))
6592    (clobber (reg:CC FLAGS_REG))]
6593   "!TARGET_64BIT && reload_completed"
6594   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6595               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6596    (parallel [(set (match_dup 3)
6597                    (minus:SI (match_dup 4)
6598                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6599                                       (match_dup 5))))
6600               (clobber (reg:CC FLAGS_REG))])]
6601   "split_di (operands+0, 1, operands+0, operands+3);
6602    split_di (operands+1, 1, operands+1, operands+4);
6603    split_di (operands+2, 1, operands+2, operands+5);")
6605 (define_insn "subdi3_carry_rex64"
6606   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6607           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6608             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6609                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6610    (clobber (reg:CC FLAGS_REG))]
6611   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6612   "sbb{q}\t{%2, %0|%0, %2}"
6613   [(set_attr "type" "alu")
6614    (set_attr "pent_pair" "pu")
6615    (set_attr "mode" "DI")])
6617 (define_insn "*subdi_1_rex64"
6618   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6619         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6620                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6621    (clobber (reg:CC FLAGS_REG))]
6622   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6623   "sub{q}\t{%2, %0|%0, %2}"
6624   [(set_attr "type" "alu")
6625    (set_attr "mode" "DI")])
6627 (define_insn "*subdi_2_rex64"
6628   [(set (reg FLAGS_REG)
6629         (compare
6630           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6631                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6632           (const_int 0)))
6633    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6634         (minus:DI (match_dup 1) (match_dup 2)))]
6635   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6636    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6637   "sub{q}\t{%2, %0|%0, %2}"
6638   [(set_attr "type" "alu")
6639    (set_attr "mode" "DI")])
6641 (define_insn "*subdi_3_rex63"
6642   [(set (reg FLAGS_REG)
6643         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6644                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6645    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6646         (minus:DI (match_dup 1) (match_dup 2)))]
6647   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6648    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6649   "sub{q}\t{%2, %0|%0, %2}"
6650   [(set_attr "type" "alu")
6651    (set_attr "mode" "DI")])
6653 (define_insn "subqi3_carry"
6654   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6655           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6656             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6657                (match_operand:QI 2 "general_operand" "qi,qm"))))
6658    (clobber (reg:CC FLAGS_REG))]
6659   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6660   "sbb{b}\t{%2, %0|%0, %2}"
6661   [(set_attr "type" "alu")
6662    (set_attr "pent_pair" "pu")
6663    (set_attr "mode" "QI")])
6665 (define_insn "subhi3_carry"
6666   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6667           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6668             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6669                (match_operand:HI 2 "general_operand" "ri,rm"))))
6670    (clobber (reg:CC FLAGS_REG))]
6671   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6672   "sbb{w}\t{%2, %0|%0, %2}"
6673   [(set_attr "type" "alu")
6674    (set_attr "pent_pair" "pu")
6675    (set_attr "mode" "HI")])
6677 (define_insn "subsi3_carry"
6678   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6679           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6680             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6681                (match_operand:SI 2 "general_operand" "ri,rm"))))
6682    (clobber (reg:CC FLAGS_REG))]
6683   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6684   "sbb{l}\t{%2, %0|%0, %2}"
6685   [(set_attr "type" "alu")
6686    (set_attr "pent_pair" "pu")
6687    (set_attr "mode" "SI")])
6689 (define_insn "subsi3_carry_zext"
6690   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6691           (zero_extend:DI
6692             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6693               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6694                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6695    (clobber (reg:CC FLAGS_REG))]
6696   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6697   "sbb{l}\t{%2, %k0|%k0, %2}"
6698   [(set_attr "type" "alu")
6699    (set_attr "pent_pair" "pu")
6700    (set_attr "mode" "SI")])
6702 (define_expand "subsi3"
6703   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6704                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6705                              (match_operand:SI 2 "general_operand" "")))
6706               (clobber (reg:CC FLAGS_REG))])]
6707   ""
6708   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6710 (define_insn "*subsi_1"
6711   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6712         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6713                   (match_operand:SI 2 "general_operand" "ri,rm")))
6714    (clobber (reg:CC FLAGS_REG))]
6715   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6716   "sub{l}\t{%2, %0|%0, %2}"
6717   [(set_attr "type" "alu")
6718    (set_attr "mode" "SI")])
6720 (define_insn "*subsi_1_zext"
6721   [(set (match_operand:DI 0 "register_operand" "=r")
6722         (zero_extend:DI
6723           (minus:SI (match_operand:SI 1 "register_operand" "0")
6724                     (match_operand:SI 2 "general_operand" "rim"))))
6725    (clobber (reg:CC FLAGS_REG))]
6726   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6727   "sub{l}\t{%2, %k0|%k0, %2}"
6728   [(set_attr "type" "alu")
6729    (set_attr "mode" "SI")])
6731 (define_insn "*subsi_2"
6732   [(set (reg FLAGS_REG)
6733         (compare
6734           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6735                     (match_operand:SI 2 "general_operand" "ri,rm"))
6736           (const_int 0)))
6737    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6738         (minus:SI (match_dup 1) (match_dup 2)))]
6739   "ix86_match_ccmode (insn, CCGOCmode)
6740    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6741   "sub{l}\t{%2, %0|%0, %2}"
6742   [(set_attr "type" "alu")
6743    (set_attr "mode" "SI")])
6745 (define_insn "*subsi_2_zext"
6746   [(set (reg FLAGS_REG)
6747         (compare
6748           (minus:SI (match_operand:SI 1 "register_operand" "0")
6749                     (match_operand:SI 2 "general_operand" "rim"))
6750           (const_int 0)))
6751    (set (match_operand:DI 0 "register_operand" "=r")
6752         (zero_extend:DI
6753           (minus:SI (match_dup 1)
6754                     (match_dup 2))))]
6755   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6756    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6757   "sub{l}\t{%2, %k0|%k0, %2}"
6758   [(set_attr "type" "alu")
6759    (set_attr "mode" "SI")])
6761 (define_insn "*subsi_3"
6762   [(set (reg FLAGS_REG)
6763         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6764                  (match_operand:SI 2 "general_operand" "ri,rm")))
6765    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6766         (minus:SI (match_dup 1) (match_dup 2)))]
6767   "ix86_match_ccmode (insn, CCmode)
6768    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6769   "sub{l}\t{%2, %0|%0, %2}"
6770   [(set_attr "type" "alu")
6771    (set_attr "mode" "SI")])
6773 (define_insn "*subsi_3_zext"
6774   [(set (reg FLAGS_REG)
6775         (compare (match_operand:SI 1 "register_operand" "0")
6776                  (match_operand:SI 2 "general_operand" "rim")))
6777    (set (match_operand:DI 0 "register_operand" "=r")
6778         (zero_extend:DI
6779           (minus:SI (match_dup 1)
6780                     (match_dup 2))))]
6781   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6782    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6783   "sub{q}\t{%2, %0|%0, %2}"
6784   [(set_attr "type" "alu")
6785    (set_attr "mode" "DI")])
6787 (define_expand "subhi3"
6788   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6789                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6790                              (match_operand:HI 2 "general_operand" "")))
6791               (clobber (reg:CC FLAGS_REG))])]
6792   "TARGET_HIMODE_MATH"
6793   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6795 (define_insn "*subhi_1"
6796   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6797         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6798                   (match_operand:HI 2 "general_operand" "ri,rm")))
6799    (clobber (reg:CC FLAGS_REG))]
6800   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6801   "sub{w}\t{%2, %0|%0, %2}"
6802   [(set_attr "type" "alu")
6803    (set_attr "mode" "HI")])
6805 (define_insn "*subhi_2"
6806   [(set (reg FLAGS_REG)
6807         (compare
6808           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6809                     (match_operand:HI 2 "general_operand" "ri,rm"))
6810           (const_int 0)))
6811    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6812         (minus:HI (match_dup 1) (match_dup 2)))]
6813   "ix86_match_ccmode (insn, CCGOCmode)
6814    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6815   "sub{w}\t{%2, %0|%0, %2}"
6816   [(set_attr "type" "alu")
6817    (set_attr "mode" "HI")])
6819 (define_insn "*subhi_3"
6820   [(set (reg FLAGS_REG)
6821         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6822                  (match_operand:HI 2 "general_operand" "ri,rm")))
6823    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6824         (minus:HI (match_dup 1) (match_dup 2)))]
6825   "ix86_match_ccmode (insn, CCmode)
6826    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6827   "sub{w}\t{%2, %0|%0, %2}"
6828   [(set_attr "type" "alu")
6829    (set_attr "mode" "HI")])
6831 (define_expand "subqi3"
6832   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6833                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6834                              (match_operand:QI 2 "general_operand" "")))
6835               (clobber (reg:CC FLAGS_REG))])]
6836   "TARGET_QIMODE_MATH"
6837   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6839 (define_insn "*subqi_1"
6840   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6841         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6842                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6843    (clobber (reg:CC FLAGS_REG))]
6844   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6845   "sub{b}\t{%2, %0|%0, %2}"
6846   [(set_attr "type" "alu")
6847    (set_attr "mode" "QI")])
6849 (define_insn "*subqi_1_slp"
6850   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6851         (minus:QI (match_dup 0)
6852                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6853    (clobber (reg:CC FLAGS_REG))]
6854   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6855    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6856   "sub{b}\t{%1, %0|%0, %1}"
6857   [(set_attr "type" "alu1")
6858    (set_attr "mode" "QI")])
6860 (define_insn "*subqi_2"
6861   [(set (reg FLAGS_REG)
6862         (compare
6863           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6864                     (match_operand:QI 2 "general_operand" "qi,qm"))
6865           (const_int 0)))
6866    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6867         (minus:HI (match_dup 1) (match_dup 2)))]
6868   "ix86_match_ccmode (insn, CCGOCmode)
6869    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6870   "sub{b}\t{%2, %0|%0, %2}"
6871   [(set_attr "type" "alu")
6872    (set_attr "mode" "QI")])
6874 (define_insn "*subqi_3"
6875   [(set (reg FLAGS_REG)
6876         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6877                  (match_operand:QI 2 "general_operand" "qi,qm")))
6878    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6879         (minus:HI (match_dup 1) (match_dup 2)))]
6880   "ix86_match_ccmode (insn, CCmode)
6881    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6882   "sub{b}\t{%2, %0|%0, %2}"
6883   [(set_attr "type" "alu")
6884    (set_attr "mode" "QI")])
6886 ;; The patterns that match these are at the end of this file.
6888 (define_expand "subxf3"
6889   [(set (match_operand:XF 0 "register_operand" "")
6890         (minus:XF (match_operand:XF 1 "register_operand" "")
6891                   (match_operand:XF 2 "register_operand" "")))]
6892   "TARGET_80387"
6893   "")
6895 (define_expand "subdf3"
6896   [(set (match_operand:DF 0 "register_operand" "")
6897         (minus:DF (match_operand:DF 1 "register_operand" "")
6898                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6899   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6900   "")
6902 (define_expand "subsf3"
6903   [(set (match_operand:SF 0 "register_operand" "")
6904         (minus:SF (match_operand:SF 1 "register_operand" "")
6905                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6906   "TARGET_80387 || TARGET_SSE_MATH"
6907   "")
6909 ;; Multiply instructions
6911 (define_expand "muldi3"
6912   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6913                    (mult:DI (match_operand:DI 1 "register_operand" "")
6914                             (match_operand:DI 2 "x86_64_general_operand" "")))
6915               (clobber (reg:CC FLAGS_REG))])]
6916   "TARGET_64BIT"
6917   "")
6919 (define_insn "*muldi3_1_rex64"
6920   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6921         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6922                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6923    (clobber (reg:CC FLAGS_REG))]
6924   "TARGET_64BIT
6925    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6926   "@
6927    imul{q}\t{%2, %1, %0|%0, %1, %2}
6928    imul{q}\t{%2, %1, %0|%0, %1, %2}
6929    imul{q}\t{%2, %0|%0, %2}"
6930   [(set_attr "type" "imul")
6931    (set_attr "prefix_0f" "0,0,1")
6932    (set (attr "athlon_decode")
6933         (cond [(eq_attr "cpu" "athlon")
6934                   (const_string "vector")
6935                (eq_attr "alternative" "1")
6936                   (const_string "vector")
6937                (and (eq_attr "alternative" "2")
6938                     (match_operand 1 "memory_operand" ""))
6939                   (const_string "vector")]
6940               (const_string "direct")))
6941    (set_attr "mode" "DI")])
6943 (define_expand "mulsi3"
6944   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6945                    (mult:SI (match_operand:SI 1 "register_operand" "")
6946                             (match_operand:SI 2 "general_operand" "")))
6947               (clobber (reg:CC FLAGS_REG))])]
6948   ""
6949   "")
6951 (define_insn "*mulsi3_1"
6952   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6953         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6954                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6955    (clobber (reg:CC FLAGS_REG))]
6956   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6957   "@
6958    imul{l}\t{%2, %1, %0|%0, %1, %2}
6959    imul{l}\t{%2, %1, %0|%0, %1, %2}
6960    imul{l}\t{%2, %0|%0, %2}"
6961   [(set_attr "type" "imul")
6962    (set_attr "prefix_0f" "0,0,1")
6963    (set (attr "athlon_decode")
6964         (cond [(eq_attr "cpu" "athlon")
6965                   (const_string "vector")
6966                (eq_attr "alternative" "1")
6967                   (const_string "vector")
6968                (and (eq_attr "alternative" "2")
6969                     (match_operand 1 "memory_operand" ""))
6970                   (const_string "vector")]
6971               (const_string "direct")))
6972    (set_attr "mode" "SI")])
6974 (define_insn "*mulsi3_1_zext"
6975   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6976         (zero_extend:DI
6977           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6978                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6979    (clobber (reg:CC FLAGS_REG))]
6980   "TARGET_64BIT
6981    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6982   "@
6983    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6984    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6985    imul{l}\t{%2, %k0|%k0, %2}"
6986   [(set_attr "type" "imul")
6987    (set_attr "prefix_0f" "0,0,1")
6988    (set (attr "athlon_decode")
6989         (cond [(eq_attr "cpu" "athlon")
6990                   (const_string "vector")
6991                (eq_attr "alternative" "1")
6992                   (const_string "vector")
6993                (and (eq_attr "alternative" "2")
6994                     (match_operand 1 "memory_operand" ""))
6995                   (const_string "vector")]
6996               (const_string "direct")))
6997    (set_attr "mode" "SI")])
6999 (define_expand "mulhi3"
7000   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7001                    (mult:HI (match_operand:HI 1 "register_operand" "")
7002                             (match_operand:HI 2 "general_operand" "")))
7003               (clobber (reg:CC FLAGS_REG))])]
7004   "TARGET_HIMODE_MATH"
7005   "")
7007 (define_insn "*mulhi3_1"
7008   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7009         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7010                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7011    (clobber (reg:CC FLAGS_REG))]
7012   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7013   "@
7014    imul{w}\t{%2, %1, %0|%0, %1, %2}
7015    imul{w}\t{%2, %1, %0|%0, %1, %2}
7016    imul{w}\t{%2, %0|%0, %2}"
7017   [(set_attr "type" "imul")
7018    (set_attr "prefix_0f" "0,0,1")
7019    (set (attr "athlon_decode")
7020         (cond [(eq_attr "cpu" "athlon")
7021                   (const_string "vector")
7022                (eq_attr "alternative" "1,2")
7023                   (const_string "vector")]
7024               (const_string "direct")))
7025    (set_attr "mode" "HI")])
7027 (define_expand "mulqi3"
7028   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7029                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7030                             (match_operand:QI 2 "register_operand" "")))
7031               (clobber (reg:CC FLAGS_REG))])]
7032   "TARGET_QIMODE_MATH"
7033   "")
7035 (define_insn "*mulqi3_1"
7036   [(set (match_operand:QI 0 "register_operand" "=a")
7037         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7038                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7039    (clobber (reg:CC FLAGS_REG))]
7040   "TARGET_QIMODE_MATH
7041    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7042   "mul{b}\t%2"
7043   [(set_attr "type" "imul")
7044    (set_attr "length_immediate" "0")
7045    (set (attr "athlon_decode")
7046      (if_then_else (eq_attr "cpu" "athlon")
7047         (const_string "vector")
7048         (const_string "direct")))
7049    (set_attr "mode" "QI")])
7051 (define_expand "umulqihi3"
7052   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7053                    (mult:HI (zero_extend:HI
7054                               (match_operand:QI 1 "nonimmediate_operand" ""))
7055                             (zero_extend:HI
7056                               (match_operand:QI 2 "register_operand" ""))))
7057               (clobber (reg:CC FLAGS_REG))])]
7058   "TARGET_QIMODE_MATH"
7059   "")
7061 (define_insn "*umulqihi3_1"
7062   [(set (match_operand:HI 0 "register_operand" "=a")
7063         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7064                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7065    (clobber (reg:CC FLAGS_REG))]
7066   "TARGET_QIMODE_MATH
7067    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7068   "mul{b}\t%2"
7069   [(set_attr "type" "imul")
7070    (set_attr "length_immediate" "0")
7071    (set (attr "athlon_decode")
7072      (if_then_else (eq_attr "cpu" "athlon")
7073         (const_string "vector")
7074         (const_string "direct")))
7075    (set_attr "mode" "QI")])
7077 (define_expand "mulqihi3"
7078   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7079                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7080                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7081               (clobber (reg:CC FLAGS_REG))])]
7082   "TARGET_QIMODE_MATH"
7083   "")
7085 (define_insn "*mulqihi3_insn"
7086   [(set (match_operand:HI 0 "register_operand" "=a")
7087         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7088                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7089    (clobber (reg:CC FLAGS_REG))]
7090   "TARGET_QIMODE_MATH
7091    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7092   "imul{b}\t%2"
7093   [(set_attr "type" "imul")
7094    (set_attr "length_immediate" "0")
7095    (set (attr "athlon_decode")
7096      (if_then_else (eq_attr "cpu" "athlon")
7097         (const_string "vector")
7098         (const_string "direct")))
7099    (set_attr "mode" "QI")])
7101 (define_expand "umulditi3"
7102   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7103                    (mult:TI (zero_extend:TI
7104                               (match_operand:DI 1 "nonimmediate_operand" ""))
7105                             (zero_extend:TI
7106                               (match_operand:DI 2 "register_operand" ""))))
7107               (clobber (reg:CC FLAGS_REG))])]
7108   "TARGET_64BIT"
7109   "")
7111 (define_insn "*umulditi3_insn"
7112   [(set (match_operand:TI 0 "register_operand" "=A")
7113         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7114                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7115    (clobber (reg:CC FLAGS_REG))]
7116   "TARGET_64BIT
7117    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7118   "mul{q}\t%2"
7119   [(set_attr "type" "imul")
7120    (set_attr "length_immediate" "0")
7121    (set (attr "athlon_decode")
7122      (if_then_else (eq_attr "cpu" "athlon")
7123         (const_string "vector")
7124         (const_string "double")))
7125    (set_attr "mode" "DI")])
7127 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7128 (define_expand "umulsidi3"
7129   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7130                    (mult:DI (zero_extend:DI
7131                               (match_operand:SI 1 "nonimmediate_operand" ""))
7132                             (zero_extend:DI
7133                               (match_operand:SI 2 "register_operand" ""))))
7134               (clobber (reg:CC FLAGS_REG))])]
7135   "!TARGET_64BIT"
7136   "")
7138 (define_insn "*umulsidi3_insn"
7139   [(set (match_operand:DI 0 "register_operand" "=A")
7140         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7141                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7142    (clobber (reg:CC FLAGS_REG))]
7143   "!TARGET_64BIT
7144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7145   "mul{l}\t%2"
7146   [(set_attr "type" "imul")
7147    (set_attr "length_immediate" "0")
7148    (set (attr "athlon_decode")
7149      (if_then_else (eq_attr "cpu" "athlon")
7150         (const_string "vector")
7151         (const_string "double")))
7152    (set_attr "mode" "SI")])
7154 (define_expand "mulditi3"
7155   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7156                    (mult:TI (sign_extend:TI
7157                               (match_operand:DI 1 "nonimmediate_operand" ""))
7158                             (sign_extend:TI
7159                               (match_operand:DI 2 "register_operand" ""))))
7160               (clobber (reg:CC FLAGS_REG))])]
7161   "TARGET_64BIT"
7162   "")
7164 (define_insn "*mulditi3_insn"
7165   [(set (match_operand:TI 0 "register_operand" "=A")
7166         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7167                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7168    (clobber (reg:CC FLAGS_REG))]
7169   "TARGET_64BIT
7170    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7171   "imul{q}\t%2"
7172   [(set_attr "type" "imul")
7173    (set_attr "length_immediate" "0")
7174    (set (attr "athlon_decode")
7175      (if_then_else (eq_attr "cpu" "athlon")
7176         (const_string "vector")
7177         (const_string "double")))
7178    (set_attr "mode" "DI")])
7180 (define_expand "mulsidi3"
7181   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7182                    (mult:DI (sign_extend:DI
7183                               (match_operand:SI 1 "nonimmediate_operand" ""))
7184                             (sign_extend:DI
7185                               (match_operand:SI 2 "register_operand" ""))))
7186               (clobber (reg:CC FLAGS_REG))])]
7187   "!TARGET_64BIT"
7188   "")
7190 (define_insn "*mulsidi3_insn"
7191   [(set (match_operand:DI 0 "register_operand" "=A")
7192         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7193                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7194    (clobber (reg:CC FLAGS_REG))]
7195   "!TARGET_64BIT
7196    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7197   "imul{l}\t%2"
7198   [(set_attr "type" "imul")
7199    (set_attr "length_immediate" "0")
7200    (set (attr "athlon_decode")
7201      (if_then_else (eq_attr "cpu" "athlon")
7202         (const_string "vector")
7203         (const_string "double")))
7204    (set_attr "mode" "SI")])
7206 (define_expand "umuldi3_highpart"
7207   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7208                    (truncate:DI
7209                      (lshiftrt:TI
7210                        (mult:TI (zero_extend:TI
7211                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7212                                 (zero_extend:TI
7213                                   (match_operand:DI 2 "register_operand" "")))
7214                        (const_int 64))))
7215               (clobber (match_scratch:DI 3 ""))
7216               (clobber (reg:CC FLAGS_REG))])]
7217   "TARGET_64BIT"
7218   "")
7220 (define_insn "*umuldi3_highpart_rex64"
7221   [(set (match_operand:DI 0 "register_operand" "=d")
7222         (truncate:DI
7223           (lshiftrt:TI
7224             (mult:TI (zero_extend:TI
7225                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7226                      (zero_extend:TI
7227                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7228             (const_int 64))))
7229    (clobber (match_scratch:DI 3 "=1"))
7230    (clobber (reg:CC FLAGS_REG))]
7231   "TARGET_64BIT
7232    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7233   "mul{q}\t%2"
7234   [(set_attr "type" "imul")
7235    (set_attr "length_immediate" "0")
7236    (set (attr "athlon_decode")
7237      (if_then_else (eq_attr "cpu" "athlon")
7238         (const_string "vector")
7239         (const_string "double")))
7240    (set_attr "mode" "DI")])
7242 (define_expand "umulsi3_highpart"
7243   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7244                    (truncate:SI
7245                      (lshiftrt:DI
7246                        (mult:DI (zero_extend:DI
7247                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7248                                 (zero_extend:DI
7249                                   (match_operand:SI 2 "register_operand" "")))
7250                        (const_int 32))))
7251               (clobber (match_scratch:SI 3 ""))
7252               (clobber (reg:CC FLAGS_REG))])]
7253   ""
7254   "")
7256 (define_insn "*umulsi3_highpart_insn"
7257   [(set (match_operand:SI 0 "register_operand" "=d")
7258         (truncate:SI
7259           (lshiftrt:DI
7260             (mult:DI (zero_extend:DI
7261                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7262                      (zero_extend:DI
7263                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7264             (const_int 32))))
7265    (clobber (match_scratch:SI 3 "=1"))
7266    (clobber (reg:CC FLAGS_REG))]
7267   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7268   "mul{l}\t%2"
7269   [(set_attr "type" "imul")
7270    (set_attr "length_immediate" "0")
7271    (set (attr "athlon_decode")
7272      (if_then_else (eq_attr "cpu" "athlon")
7273         (const_string "vector")
7274         (const_string "double")))
7275    (set_attr "mode" "SI")])
7277 (define_insn "*umulsi3_highpart_zext"
7278   [(set (match_operand:DI 0 "register_operand" "=d")
7279         (zero_extend:DI (truncate:SI
7280           (lshiftrt:DI
7281             (mult:DI (zero_extend:DI
7282                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7283                      (zero_extend:DI
7284                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7285             (const_int 32)))))
7286    (clobber (match_scratch:SI 3 "=1"))
7287    (clobber (reg:CC FLAGS_REG))]
7288   "TARGET_64BIT
7289    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7290   "mul{l}\t%2"
7291   [(set_attr "type" "imul")
7292    (set_attr "length_immediate" "0")
7293    (set (attr "athlon_decode")
7294      (if_then_else (eq_attr "cpu" "athlon")
7295         (const_string "vector")
7296         (const_string "double")))
7297    (set_attr "mode" "SI")])
7299 (define_expand "smuldi3_highpart"
7300   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7301                    (truncate:DI
7302                      (lshiftrt:TI
7303                        (mult:TI (sign_extend:TI
7304                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7305                                 (sign_extend:TI
7306                                   (match_operand:DI 2 "register_operand" "")))
7307                        (const_int 64))))
7308               (clobber (match_scratch:DI 3 ""))
7309               (clobber (reg:CC FLAGS_REG))])]
7310   "TARGET_64BIT"
7311   "")
7313 (define_insn "*smuldi3_highpart_rex64"
7314   [(set (match_operand:DI 0 "register_operand" "=d")
7315         (truncate:DI
7316           (lshiftrt:TI
7317             (mult:TI (sign_extend:TI
7318                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7319                      (sign_extend:TI
7320                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7321             (const_int 64))))
7322    (clobber (match_scratch:DI 3 "=1"))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_64BIT
7325    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7326   "imul{q}\t%2"
7327   [(set_attr "type" "imul")
7328    (set (attr "athlon_decode")
7329      (if_then_else (eq_attr "cpu" "athlon")
7330         (const_string "vector")
7331         (const_string "double")))
7332    (set_attr "mode" "DI")])
7334 (define_expand "smulsi3_highpart"
7335   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7336                    (truncate:SI
7337                      (lshiftrt:DI
7338                        (mult:DI (sign_extend:DI
7339                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7340                                 (sign_extend:DI
7341                                   (match_operand:SI 2 "register_operand" "")))
7342                        (const_int 32))))
7343               (clobber (match_scratch:SI 3 ""))
7344               (clobber (reg:CC FLAGS_REG))])]
7345   ""
7346   "")
7348 (define_insn "*smulsi3_highpart_insn"
7349   [(set (match_operand:SI 0 "register_operand" "=d")
7350         (truncate:SI
7351           (lshiftrt:DI
7352             (mult:DI (sign_extend:DI
7353                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7354                      (sign_extend:DI
7355                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7356             (const_int 32))))
7357    (clobber (match_scratch:SI 3 "=1"))
7358    (clobber (reg:CC FLAGS_REG))]
7359   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7360   "imul{l}\t%2"
7361   [(set_attr "type" "imul")
7362    (set (attr "athlon_decode")
7363      (if_then_else (eq_attr "cpu" "athlon")
7364         (const_string "vector")
7365         (const_string "double")))
7366    (set_attr "mode" "SI")])
7368 (define_insn "*smulsi3_highpart_zext"
7369   [(set (match_operand:DI 0 "register_operand" "=d")
7370         (zero_extend:DI (truncate:SI
7371           (lshiftrt:DI
7372             (mult:DI (sign_extend:DI
7373                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7374                      (sign_extend:DI
7375                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7376             (const_int 32)))))
7377    (clobber (match_scratch:SI 3 "=1"))
7378    (clobber (reg:CC FLAGS_REG))]
7379   "TARGET_64BIT
7380    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7381   "imul{l}\t%2"
7382   [(set_attr "type" "imul")
7383    (set (attr "athlon_decode")
7384      (if_then_else (eq_attr "cpu" "athlon")
7385         (const_string "vector")
7386         (const_string "double")))
7387    (set_attr "mode" "SI")])
7389 ;; The patterns that match these are at the end of this file.
7391 (define_expand "mulxf3"
7392   [(set (match_operand:XF 0 "register_operand" "")
7393         (mult:XF (match_operand:XF 1 "register_operand" "")
7394                  (match_operand:XF 2 "register_operand" "")))]
7395   "TARGET_80387"
7396   "")
7398 (define_expand "muldf3"
7399   [(set (match_operand:DF 0 "register_operand" "")
7400         (mult:DF (match_operand:DF 1 "register_operand" "")
7401                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7402   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7403   "")
7405 (define_expand "mulsf3"
7406   [(set (match_operand:SF 0 "register_operand" "")
7407         (mult:SF (match_operand:SF 1 "register_operand" "")
7408                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7409   "TARGET_80387 || TARGET_SSE_MATH"
7410   "")
7412 ;; Divide instructions
7414 (define_insn "divqi3"
7415   [(set (match_operand:QI 0 "register_operand" "=a")
7416         (div:QI (match_operand:HI 1 "register_operand" "0")
7417                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7418    (clobber (reg:CC FLAGS_REG))]
7419   "TARGET_QIMODE_MATH"
7420   "idiv{b}\t%2"
7421   [(set_attr "type" "idiv")
7422    (set_attr "mode" "QI")])
7424 (define_insn "udivqi3"
7425   [(set (match_operand:QI 0 "register_operand" "=a")
7426         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7427                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7428    (clobber (reg:CC FLAGS_REG))]
7429   "TARGET_QIMODE_MATH"
7430   "div{b}\t%2"
7431   [(set_attr "type" "idiv")
7432    (set_attr "mode" "QI")])
7434 ;; The patterns that match these are at the end of this file.
7436 (define_expand "divxf3"
7437   [(set (match_operand:XF 0 "register_operand" "")
7438         (div:XF (match_operand:XF 1 "register_operand" "")
7439                 (match_operand:XF 2 "register_operand" "")))]
7440   "TARGET_80387"
7441   "")
7443 (define_expand "divdf3"
7444   [(set (match_operand:DF 0 "register_operand" "")
7445         (div:DF (match_operand:DF 1 "register_operand" "")
7446                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7447    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7448    "")
7450 (define_expand "divsf3"
7451   [(set (match_operand:SF 0 "register_operand" "")
7452         (div:SF (match_operand:SF 1 "register_operand" "")
7453                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7454   "TARGET_80387 || TARGET_SSE_MATH"
7455   "")
7457 ;; Remainder instructions.
7459 (define_expand "divmoddi4"
7460   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7461                    (div:DI (match_operand:DI 1 "register_operand" "")
7462                            (match_operand:DI 2 "nonimmediate_operand" "")))
7463               (set (match_operand:DI 3 "register_operand" "")
7464                    (mod:DI (match_dup 1) (match_dup 2)))
7465               (clobber (reg:CC FLAGS_REG))])]
7466   "TARGET_64BIT"
7467   "")
7469 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7470 ;; Penalize eax case slightly because it results in worse scheduling
7471 ;; of code.
7472 (define_insn "*divmoddi4_nocltd_rex64"
7473   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7474         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7475                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7476    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7477         (mod:DI (match_dup 2) (match_dup 3)))
7478    (clobber (reg:CC FLAGS_REG))]
7479   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7480   "#"
7481   [(set_attr "type" "multi")])
7483 (define_insn "*divmoddi4_cltd_rex64"
7484   [(set (match_operand:DI 0 "register_operand" "=a")
7485         (div:DI (match_operand:DI 2 "register_operand" "a")
7486                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7487    (set (match_operand:DI 1 "register_operand" "=&d")
7488         (mod:DI (match_dup 2) (match_dup 3)))
7489    (clobber (reg:CC FLAGS_REG))]
7490   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7491   "#"
7492   [(set_attr "type" "multi")])
7494 (define_insn "*divmoddi_noext_rex64"
7495   [(set (match_operand:DI 0 "register_operand" "=a")
7496         (div:DI (match_operand:DI 1 "register_operand" "0")
7497                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7498    (set (match_operand:DI 3 "register_operand" "=d")
7499         (mod:DI (match_dup 1) (match_dup 2)))
7500    (use (match_operand:DI 4 "register_operand" "3"))
7501    (clobber (reg:CC FLAGS_REG))]
7502   "TARGET_64BIT"
7503   "idiv{q}\t%2"
7504   [(set_attr "type" "idiv")
7505    (set_attr "mode" "DI")])
7507 (define_split
7508   [(set (match_operand:DI 0 "register_operand" "")
7509         (div:DI (match_operand:DI 1 "register_operand" "")
7510                 (match_operand:DI 2 "nonimmediate_operand" "")))
7511    (set (match_operand:DI 3 "register_operand" "")
7512         (mod:DI (match_dup 1) (match_dup 2)))
7513    (clobber (reg:CC FLAGS_REG))]
7514   "TARGET_64BIT && reload_completed"
7515   [(parallel [(set (match_dup 3)
7516                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7517               (clobber (reg:CC FLAGS_REG))])
7518    (parallel [(set (match_dup 0)
7519                    (div:DI (reg:DI 0) (match_dup 2)))
7520               (set (match_dup 3)
7521                    (mod:DI (reg:DI 0) (match_dup 2)))
7522               (use (match_dup 3))
7523               (clobber (reg:CC FLAGS_REG))])]
7525   /* Avoid use of cltd in favor of a mov+shift.  */
7526   if (!TARGET_USE_CLTD && !optimize_size)
7527     {
7528       if (true_regnum (operands[1]))
7529         emit_move_insn (operands[0], operands[1]);
7530       else
7531         emit_move_insn (operands[3], operands[1]);
7532       operands[4] = operands[3];
7533     }
7534   else
7535     {
7536       if (true_regnum (operands[1]))
7537         abort();
7538       operands[4] = operands[1];
7539     }
7543 (define_expand "divmodsi4"
7544   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7545                    (div:SI (match_operand:SI 1 "register_operand" "")
7546                            (match_operand:SI 2 "nonimmediate_operand" "")))
7547               (set (match_operand:SI 3 "register_operand" "")
7548                    (mod:SI (match_dup 1) (match_dup 2)))
7549               (clobber (reg:CC FLAGS_REG))])]
7550   ""
7551   "")
7553 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7554 ;; Penalize eax case slightly because it results in worse scheduling
7555 ;; of code.
7556 (define_insn "*divmodsi4_nocltd"
7557   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7558         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7559                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7560    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7561         (mod:SI (match_dup 2) (match_dup 3)))
7562    (clobber (reg:CC FLAGS_REG))]
7563   "!optimize_size && !TARGET_USE_CLTD"
7564   "#"
7565   [(set_attr "type" "multi")])
7567 (define_insn "*divmodsi4_cltd"
7568   [(set (match_operand:SI 0 "register_operand" "=a")
7569         (div:SI (match_operand:SI 2 "register_operand" "a")
7570                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7571    (set (match_operand:SI 1 "register_operand" "=&d")
7572         (mod:SI (match_dup 2) (match_dup 3)))
7573    (clobber (reg:CC FLAGS_REG))]
7574   "optimize_size || TARGET_USE_CLTD"
7575   "#"
7576   [(set_attr "type" "multi")])
7578 (define_insn "*divmodsi_noext"
7579   [(set (match_operand:SI 0 "register_operand" "=a")
7580         (div:SI (match_operand:SI 1 "register_operand" "0")
7581                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7582    (set (match_operand:SI 3 "register_operand" "=d")
7583         (mod:SI (match_dup 1) (match_dup 2)))
7584    (use (match_operand:SI 4 "register_operand" "3"))
7585    (clobber (reg:CC FLAGS_REG))]
7586   ""
7587   "idiv{l}\t%2"
7588   [(set_attr "type" "idiv")
7589    (set_attr "mode" "SI")])
7591 (define_split
7592   [(set (match_operand:SI 0 "register_operand" "")
7593         (div:SI (match_operand:SI 1 "register_operand" "")
7594                 (match_operand:SI 2 "nonimmediate_operand" "")))
7595    (set (match_operand:SI 3 "register_operand" "")
7596         (mod:SI (match_dup 1) (match_dup 2)))
7597    (clobber (reg:CC FLAGS_REG))]
7598   "reload_completed"
7599   [(parallel [(set (match_dup 3)
7600                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7601               (clobber (reg:CC FLAGS_REG))])
7602    (parallel [(set (match_dup 0)
7603                    (div:SI (reg:SI 0) (match_dup 2)))
7604               (set (match_dup 3)
7605                    (mod:SI (reg:SI 0) (match_dup 2)))
7606               (use (match_dup 3))
7607               (clobber (reg:CC FLAGS_REG))])]
7609   /* Avoid use of cltd in favor of a mov+shift.  */
7610   if (!TARGET_USE_CLTD && !optimize_size)
7611     {
7612       if (true_regnum (operands[1]))
7613         emit_move_insn (operands[0], operands[1]);
7614       else
7615         emit_move_insn (operands[3], operands[1]);
7616       operands[4] = operands[3];
7617     }
7618   else
7619     {
7620       if (true_regnum (operands[1]))
7621         abort();
7622       operands[4] = operands[1];
7623     }
7625 ;; %%% Split me.
7626 (define_insn "divmodhi4"
7627   [(set (match_operand:HI 0 "register_operand" "=a")
7628         (div:HI (match_operand:HI 1 "register_operand" "0")
7629                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7630    (set (match_operand:HI 3 "register_operand" "=&d")
7631         (mod:HI (match_dup 1) (match_dup 2)))
7632    (clobber (reg:CC FLAGS_REG))]
7633   "TARGET_HIMODE_MATH"
7634   "cwtd\;idiv{w}\t%2"
7635   [(set_attr "type" "multi")
7636    (set_attr "length_immediate" "0")
7637    (set_attr "mode" "SI")])
7639 (define_insn "udivmoddi4"
7640   [(set (match_operand:DI 0 "register_operand" "=a")
7641         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7642                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7643    (set (match_operand:DI 3 "register_operand" "=&d")
7644         (umod:DI (match_dup 1) (match_dup 2)))
7645    (clobber (reg:CC FLAGS_REG))]
7646   "TARGET_64BIT"
7647   "xor{q}\t%3, %3\;div{q}\t%2"
7648   [(set_attr "type" "multi")
7649    (set_attr "length_immediate" "0")
7650    (set_attr "mode" "DI")])
7652 (define_insn "*udivmoddi4_noext"
7653   [(set (match_operand:DI 0 "register_operand" "=a")
7654         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7655                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7656    (set (match_operand:DI 3 "register_operand" "=d")
7657         (umod:DI (match_dup 1) (match_dup 2)))
7658    (use (match_dup 3))
7659    (clobber (reg:CC FLAGS_REG))]
7660   "TARGET_64BIT"
7661   "div{q}\t%2"
7662   [(set_attr "type" "idiv")
7663    (set_attr "mode" "DI")])
7665 (define_split
7666   [(set (match_operand:DI 0 "register_operand" "")
7667         (udiv:DI (match_operand:DI 1 "register_operand" "")
7668                  (match_operand:DI 2 "nonimmediate_operand" "")))
7669    (set (match_operand:DI 3 "register_operand" "")
7670         (umod:DI (match_dup 1) (match_dup 2)))
7671    (clobber (reg:CC FLAGS_REG))]
7672   "TARGET_64BIT && reload_completed"
7673   [(set (match_dup 3) (const_int 0))
7674    (parallel [(set (match_dup 0)
7675                    (udiv:DI (match_dup 1) (match_dup 2)))
7676               (set (match_dup 3)
7677                    (umod:DI (match_dup 1) (match_dup 2)))
7678               (use (match_dup 3))
7679               (clobber (reg:CC FLAGS_REG))])]
7680   "")
7682 (define_insn "udivmodsi4"
7683   [(set (match_operand:SI 0 "register_operand" "=a")
7684         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7685                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7686    (set (match_operand:SI 3 "register_operand" "=&d")
7687         (umod:SI (match_dup 1) (match_dup 2)))
7688    (clobber (reg:CC FLAGS_REG))]
7689   ""
7690   "xor{l}\t%3, %3\;div{l}\t%2"
7691   [(set_attr "type" "multi")
7692    (set_attr "length_immediate" "0")
7693    (set_attr "mode" "SI")])
7695 (define_insn "*udivmodsi4_noext"
7696   [(set (match_operand:SI 0 "register_operand" "=a")
7697         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7698                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7699    (set (match_operand:SI 3 "register_operand" "=d")
7700         (umod:SI (match_dup 1) (match_dup 2)))
7701    (use (match_dup 3))
7702    (clobber (reg:CC FLAGS_REG))]
7703   ""
7704   "div{l}\t%2"
7705   [(set_attr "type" "idiv")
7706    (set_attr "mode" "SI")])
7708 (define_split
7709   [(set (match_operand:SI 0 "register_operand" "")
7710         (udiv:SI (match_operand:SI 1 "register_operand" "")
7711                  (match_operand:SI 2 "nonimmediate_operand" "")))
7712    (set (match_operand:SI 3 "register_operand" "")
7713         (umod:SI (match_dup 1) (match_dup 2)))
7714    (clobber (reg:CC FLAGS_REG))]
7715   "reload_completed"
7716   [(set (match_dup 3) (const_int 0))
7717    (parallel [(set (match_dup 0)
7718                    (udiv:SI (match_dup 1) (match_dup 2)))
7719               (set (match_dup 3)
7720                    (umod:SI (match_dup 1) (match_dup 2)))
7721               (use (match_dup 3))
7722               (clobber (reg:CC FLAGS_REG))])]
7723   "")
7725 (define_expand "udivmodhi4"
7726   [(set (match_dup 4) (const_int 0))
7727    (parallel [(set (match_operand:HI 0 "register_operand" "")
7728                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7729                             (match_operand:HI 2 "nonimmediate_operand" "")))
7730               (set (match_operand:HI 3 "register_operand" "")
7731                    (umod:HI (match_dup 1) (match_dup 2)))
7732               (use (match_dup 4))
7733               (clobber (reg:CC FLAGS_REG))])]
7734   "TARGET_HIMODE_MATH"
7735   "operands[4] = gen_reg_rtx (HImode);")
7737 (define_insn "*udivmodhi_noext"
7738   [(set (match_operand:HI 0 "register_operand" "=a")
7739         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7740                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7741    (set (match_operand:HI 3 "register_operand" "=d")
7742         (umod:HI (match_dup 1) (match_dup 2)))
7743    (use (match_operand:HI 4 "register_operand" "3"))
7744    (clobber (reg:CC FLAGS_REG))]
7745   ""
7746   "div{w}\t%2"
7747   [(set_attr "type" "idiv")
7748    (set_attr "mode" "HI")])
7750 ;; We cannot use div/idiv for double division, because it causes
7751 ;; "division by zero" on the overflow and that's not what we expect
7752 ;; from truncate.  Because true (non truncating) double division is
7753 ;; never generated, we can't create this insn anyway.
7755 ;(define_insn ""
7756 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7757 ;       (truncate:SI
7758 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7759 ;                  (zero_extend:DI
7760 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7761 ;   (set (match_operand:SI 3 "register_operand" "=d")
7762 ;       (truncate:SI
7763 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7764 ;   (clobber (reg:CC FLAGS_REG))]
7765 ;  ""
7766 ;  "div{l}\t{%2, %0|%0, %2}"
7767 ;  [(set_attr "type" "idiv")])
7769 ;;- Logical AND instructions
7771 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7772 ;; Note that this excludes ah.
7774 (define_insn "*testdi_1_rex64"
7775   [(set (reg FLAGS_REG)
7776         (compare
7777           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7778                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7779           (const_int 0)))]
7780   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7781    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7782   "@
7783    test{l}\t{%k1, %k0|%k0, %k1}
7784    test{l}\t{%k1, %k0|%k0, %k1}
7785    test{q}\t{%1, %0|%0, %1}
7786    test{q}\t{%1, %0|%0, %1}
7787    test{q}\t{%1, %0|%0, %1}"
7788   [(set_attr "type" "test")
7789    (set_attr "modrm" "0,1,0,1,1")
7790    (set_attr "mode" "SI,SI,DI,DI,DI")
7791    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7793 (define_insn "testsi_1"
7794   [(set (reg FLAGS_REG)
7795         (compare
7796           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7797                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7798           (const_int 0)))]
7799   "ix86_match_ccmode (insn, CCNOmode)
7800    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7801   "test{l}\t{%1, %0|%0, %1}"
7802   [(set_attr "type" "test")
7803    (set_attr "modrm" "0,1,1")
7804    (set_attr "mode" "SI")
7805    (set_attr "pent_pair" "uv,np,uv")])
7807 (define_expand "testsi_ccno_1"
7808   [(set (reg:CCNO FLAGS_REG)
7809         (compare:CCNO
7810           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7811                   (match_operand:SI 1 "nonmemory_operand" ""))
7812           (const_int 0)))]
7813   ""
7814   "")
7816 (define_insn "*testhi_1"
7817   [(set (reg FLAGS_REG)
7818         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7819                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7820                  (const_int 0)))]
7821   "ix86_match_ccmode (insn, CCNOmode)
7822    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7823   "test{w}\t{%1, %0|%0, %1}"
7824   [(set_attr "type" "test")
7825    (set_attr "modrm" "0,1,1")
7826    (set_attr "mode" "HI")
7827    (set_attr "pent_pair" "uv,np,uv")])
7829 (define_expand "testqi_ccz_1"
7830   [(set (reg:CCZ FLAGS_REG)
7831         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7832                              (match_operand:QI 1 "nonmemory_operand" ""))
7833                  (const_int 0)))]
7834   ""
7835   "")
7837 (define_insn "*testqi_1_maybe_si"
7838   [(set (reg FLAGS_REG)
7839         (compare
7840           (and:QI
7841             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7842             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7843           (const_int 0)))]
7844    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7845     && ix86_match_ccmode (insn,
7846                          GET_CODE (operands[1]) == CONST_INT
7847                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7849   if (which_alternative == 3)
7850     {
7851       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7852         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7853       return "test{l}\t{%1, %k0|%k0, %1}";
7854     }
7855   return "test{b}\t{%1, %0|%0, %1}";
7857   [(set_attr "type" "test")
7858    (set_attr "modrm" "0,1,1,1")
7859    (set_attr "mode" "QI,QI,QI,SI")
7860    (set_attr "pent_pair" "uv,np,uv,np")])
7862 (define_insn "*testqi_1"
7863   [(set (reg FLAGS_REG)
7864         (compare
7865           (and:QI
7866             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7867             (match_operand:QI 1 "general_operand" "n,n,qn"))
7868           (const_int 0)))]
7869   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7870    && ix86_match_ccmode (insn, CCNOmode)"
7871   "test{b}\t{%1, %0|%0, %1}"
7872   [(set_attr "type" "test")
7873    (set_attr "modrm" "0,1,1")
7874    (set_attr "mode" "QI")
7875    (set_attr "pent_pair" "uv,np,uv")])
7877 (define_expand "testqi_ext_ccno_0"
7878   [(set (reg:CCNO FLAGS_REG)
7879         (compare:CCNO
7880           (and:SI
7881             (zero_extract:SI
7882               (match_operand 0 "ext_register_operand" "")
7883               (const_int 8)
7884               (const_int 8))
7885             (match_operand 1 "const_int_operand" ""))
7886           (const_int 0)))]
7887   ""
7888   "")
7890 (define_insn "*testqi_ext_0"
7891   [(set (reg FLAGS_REG)
7892         (compare
7893           (and:SI
7894             (zero_extract:SI
7895               (match_operand 0 "ext_register_operand" "Q")
7896               (const_int 8)
7897               (const_int 8))
7898             (match_operand 1 "const_int_operand" "n"))
7899           (const_int 0)))]
7900   "ix86_match_ccmode (insn, CCNOmode)"
7901   "test{b}\t{%1, %h0|%h0, %1}"
7902   [(set_attr "type" "test")
7903    (set_attr "mode" "QI")
7904    (set_attr "length_immediate" "1")
7905    (set_attr "pent_pair" "np")])
7907 (define_insn "*testqi_ext_1"
7908   [(set (reg FLAGS_REG)
7909         (compare
7910           (and:SI
7911             (zero_extract:SI
7912               (match_operand 0 "ext_register_operand" "Q")
7913               (const_int 8)
7914               (const_int 8))
7915             (zero_extend:SI
7916               (match_operand:QI 1 "general_operand" "Qm")))
7917           (const_int 0)))]
7918   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7919    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7920   "test{b}\t{%1, %h0|%h0, %1}"
7921   [(set_attr "type" "test")
7922    (set_attr "mode" "QI")])
7924 (define_insn "*testqi_ext_1_rex64"
7925   [(set (reg FLAGS_REG)
7926         (compare
7927           (and:SI
7928             (zero_extract:SI
7929               (match_operand 0 "ext_register_operand" "Q")
7930               (const_int 8)
7931               (const_int 8))
7932             (zero_extend:SI
7933               (match_operand:QI 1 "register_operand" "Q")))
7934           (const_int 0)))]
7935   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7936   "test{b}\t{%1, %h0|%h0, %1}"
7937   [(set_attr "type" "test")
7938    (set_attr "mode" "QI")])
7940 (define_insn "*testqi_ext_2"
7941   [(set (reg FLAGS_REG)
7942         (compare
7943           (and:SI
7944             (zero_extract:SI
7945               (match_operand 0 "ext_register_operand" "Q")
7946               (const_int 8)
7947               (const_int 8))
7948             (zero_extract:SI
7949               (match_operand 1 "ext_register_operand" "Q")
7950               (const_int 8)
7951               (const_int 8)))
7952           (const_int 0)))]
7953   "ix86_match_ccmode (insn, CCNOmode)"
7954   "test{b}\t{%h1, %h0|%h0, %h1}"
7955   [(set_attr "type" "test")
7956    (set_attr "mode" "QI")])
7958 ;; Combine likes to form bit extractions for some tests.  Humor it.
7959 (define_insn "*testqi_ext_3"
7960   [(set (reg FLAGS_REG)
7961         (compare (zero_extract:SI
7962                    (match_operand 0 "nonimmediate_operand" "rm")
7963                    (match_operand:SI 1 "const_int_operand" "")
7964                    (match_operand:SI 2 "const_int_operand" ""))
7965                  (const_int 0)))]
7966   "ix86_match_ccmode (insn, CCNOmode)
7967    && (GET_MODE (operands[0]) == SImode
7968        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7969        || GET_MODE (operands[0]) == HImode
7970        || GET_MODE (operands[0]) == QImode)"
7971   "#")
7973 (define_insn "*testqi_ext_3_rex64"
7974   [(set (reg FLAGS_REG)
7975         (compare (zero_extract:DI
7976                    (match_operand 0 "nonimmediate_operand" "rm")
7977                    (match_operand:DI 1 "const_int_operand" "")
7978                    (match_operand:DI 2 "const_int_operand" ""))
7979                  (const_int 0)))]
7980   "TARGET_64BIT
7981    && ix86_match_ccmode (insn, CCNOmode)
7982    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7983    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7984    /* Ensure that resulting mask is zero or sign extended operand.  */
7985    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7986        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7987            && INTVAL (operands[1]) > 32))
7988    && (GET_MODE (operands[0]) == SImode
7989        || GET_MODE (operands[0]) == DImode
7990        || GET_MODE (operands[0]) == HImode
7991        || GET_MODE (operands[0]) == QImode)"
7992   "#")
7994 (define_split
7995   [(set (match_operand 0 "flags_reg_operand" "")
7996         (match_operator 1 "compare_operator"
7997           [(zero_extract
7998              (match_operand 2 "nonimmediate_operand" "")
7999              (match_operand 3 "const_int_operand" "")
8000              (match_operand 4 "const_int_operand" ""))
8001            (const_int 0)]))]
8002   "ix86_match_ccmode (insn, CCNOmode)"
8003   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8005   rtx val = operands[2];
8006   HOST_WIDE_INT len = INTVAL (operands[3]);
8007   HOST_WIDE_INT pos = INTVAL (operands[4]);
8008   HOST_WIDE_INT mask;
8009   enum machine_mode mode, submode;
8011   mode = GET_MODE (val);
8012   if (GET_CODE (val) == MEM)
8013     {
8014       /* ??? Combine likes to put non-volatile mem extractions in QImode
8015          no matter the size of the test.  So find a mode that works.  */
8016       if (! MEM_VOLATILE_P (val))
8017         {
8018           mode = smallest_mode_for_size (pos + len, MODE_INT);
8019           val = adjust_address (val, mode, 0);
8020         }
8021     }
8022   else if (GET_CODE (val) == SUBREG
8023            && (submode = GET_MODE (SUBREG_REG (val)),
8024                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8025            && pos + len <= GET_MODE_BITSIZE (submode))
8026     {
8027       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8028       mode = submode;
8029       val = SUBREG_REG (val);
8030     }
8031   else if (mode == HImode && pos + len <= 8)
8032     {
8033       /* Small HImode tests can be converted to QImode.  */
8034       mode = QImode;
8035       val = gen_lowpart (QImode, val);
8036     }
8038   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8039   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8041   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8044 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8045 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8046 ;; this is relatively important trick.
8047 ;; Do the conversion only post-reload to avoid limiting of the register class
8048 ;; to QI regs.
8049 (define_split
8050   [(set (match_operand 0 "flags_reg_operand" "")
8051         (match_operator 1 "compare_operator"
8052           [(and (match_operand 2 "register_operand" "")
8053                 (match_operand 3 "const_int_operand" ""))
8054            (const_int 0)]))]
8055    "reload_completed
8056     && QI_REG_P (operands[2])
8057     && GET_MODE (operands[2]) != QImode
8058     && ((ix86_match_ccmode (insn, CCZmode)
8059          && !(INTVAL (operands[3]) & ~(255 << 8)))
8060         || (ix86_match_ccmode (insn, CCNOmode)
8061             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8062   [(set (match_dup 0)
8063         (match_op_dup 1
8064           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8065                    (match_dup 3))
8066            (const_int 0)]))]
8067   "operands[2] = gen_lowpart (SImode, operands[2]);
8068    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8070 (define_split
8071   [(set (match_operand 0 "flags_reg_operand" "")
8072         (match_operator 1 "compare_operator"
8073           [(and (match_operand 2 "nonimmediate_operand" "")
8074                 (match_operand 3 "const_int_operand" ""))
8075            (const_int 0)]))]
8076    "reload_completed
8077     && GET_MODE (operands[2]) != QImode
8078     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8079     && ((ix86_match_ccmode (insn, CCZmode)
8080          && !(INTVAL (operands[3]) & ~255))
8081         || (ix86_match_ccmode (insn, CCNOmode)
8082             && !(INTVAL (operands[3]) & ~127)))"
8083   [(set (match_dup 0)
8084         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8085                          (const_int 0)]))]
8086   "operands[2] = gen_lowpart (QImode, operands[2]);
8087    operands[3] = gen_lowpart (QImode, operands[3]);")
8090 ;; %%% This used to optimize known byte-wide and operations to memory,
8091 ;; and sometimes to QImode registers.  If this is considered useful,
8092 ;; it should be done with splitters.
8094 (define_expand "anddi3"
8095   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8096         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8097                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8098    (clobber (reg:CC FLAGS_REG))]
8099   "TARGET_64BIT"
8100   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8102 (define_insn "*anddi_1_rex64"
8103   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8104         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8105                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8106    (clobber (reg:CC FLAGS_REG))]
8107   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8109   switch (get_attr_type (insn))
8110     {
8111     case TYPE_IMOVX:
8112       {
8113         enum machine_mode mode;
8115         if (GET_CODE (operands[2]) != CONST_INT)
8116           abort ();
8117         if (INTVAL (operands[2]) == 0xff)
8118           mode = QImode;
8119         else if (INTVAL (operands[2]) == 0xffff)
8120           mode = HImode;
8121         else
8122           abort ();
8123         
8124         operands[1] = gen_lowpart (mode, operands[1]);
8125         if (mode == QImode)
8126           return "movz{bq|x}\t{%1,%0|%0, %1}";
8127         else
8128           return "movz{wq|x}\t{%1,%0|%0, %1}";
8129       }
8131     default:
8132       if (! rtx_equal_p (operands[0], operands[1]))
8133         abort ();
8134       if (get_attr_mode (insn) == MODE_SI)
8135         return "and{l}\t{%k2, %k0|%k0, %k2}";
8136       else
8137         return "and{q}\t{%2, %0|%0, %2}";
8138     }
8140   [(set_attr "type" "alu,alu,alu,imovx")
8141    (set_attr "length_immediate" "*,*,*,0")
8142    (set_attr "mode" "SI,DI,DI,DI")])
8144 (define_insn "*anddi_2"
8145   [(set (reg FLAGS_REG)
8146         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8147                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8148                  (const_int 0)))
8149    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8150         (and:DI (match_dup 1) (match_dup 2)))]
8151   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8152    && ix86_binary_operator_ok (AND, DImode, operands)"
8153   "@
8154    and{l}\t{%k2, %k0|%k0, %k2}
8155    and{q}\t{%2, %0|%0, %2}
8156    and{q}\t{%2, %0|%0, %2}"
8157   [(set_attr "type" "alu")
8158    (set_attr "mode" "SI,DI,DI")])
8160 (define_expand "andsi3"
8161   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8162         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8163                 (match_operand:SI 2 "general_operand" "")))
8164    (clobber (reg:CC FLAGS_REG))]
8165   ""
8166   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8168 (define_insn "*andsi_1"
8169   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8170         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8171                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8172    (clobber (reg:CC FLAGS_REG))]
8173   "ix86_binary_operator_ok (AND, SImode, operands)"
8175   switch (get_attr_type (insn))
8176     {
8177     case TYPE_IMOVX:
8178       {
8179         enum machine_mode mode;
8181         if (GET_CODE (operands[2]) != CONST_INT)
8182           abort ();
8183         if (INTVAL (operands[2]) == 0xff)
8184           mode = QImode;
8185         else if (INTVAL (operands[2]) == 0xffff)
8186           mode = HImode;
8187         else
8188           abort ();
8189         
8190         operands[1] = gen_lowpart (mode, operands[1]);
8191         if (mode == QImode)
8192           return "movz{bl|x}\t{%1,%0|%0, %1}";
8193         else
8194           return "movz{wl|x}\t{%1,%0|%0, %1}";
8195       }
8197     default:
8198       if (! rtx_equal_p (operands[0], operands[1]))
8199         abort ();
8200       return "and{l}\t{%2, %0|%0, %2}";
8201     }
8203   [(set_attr "type" "alu,alu,imovx")
8204    (set_attr "length_immediate" "*,*,0")
8205    (set_attr "mode" "SI")])
8207 (define_split
8208   [(set (match_operand 0 "register_operand" "")
8209         (and (match_dup 0)
8210              (const_int -65536)))
8211    (clobber (reg:CC FLAGS_REG))]
8212   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8213   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8214   "operands[1] = gen_lowpart (HImode, operands[0]);")
8216 (define_split
8217   [(set (match_operand 0 "ext_register_operand" "")
8218         (and (match_dup 0)
8219              (const_int -256)))
8220    (clobber (reg:CC FLAGS_REG))]
8221   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8222   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8223   "operands[1] = gen_lowpart (QImode, operands[0]);")
8225 (define_split
8226   [(set (match_operand 0 "ext_register_operand" "")
8227         (and (match_dup 0)
8228              (const_int -65281)))
8229    (clobber (reg:CC FLAGS_REG))]
8230   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8231   [(parallel [(set (zero_extract:SI (match_dup 0)
8232                                     (const_int 8)
8233                                     (const_int 8))
8234                    (xor:SI 
8235                      (zero_extract:SI (match_dup 0)
8236                                       (const_int 8)
8237                                       (const_int 8))
8238                      (zero_extract:SI (match_dup 0)
8239                                       (const_int 8)
8240                                       (const_int 8))))
8241               (clobber (reg:CC FLAGS_REG))])]
8242   "operands[0] = gen_lowpart (SImode, operands[0]);")
8244 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8245 (define_insn "*andsi_1_zext"
8246   [(set (match_operand:DI 0 "register_operand" "=r")
8247         (zero_extend:DI
8248           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8249                   (match_operand:SI 2 "general_operand" "rim"))))
8250    (clobber (reg:CC FLAGS_REG))]
8251   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8252   "and{l}\t{%2, %k0|%k0, %2}"
8253   [(set_attr "type" "alu")
8254    (set_attr "mode" "SI")])
8256 (define_insn "*andsi_2"
8257   [(set (reg FLAGS_REG)
8258         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8259                          (match_operand:SI 2 "general_operand" "rim,ri"))
8260                  (const_int 0)))
8261    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8262         (and:SI (match_dup 1) (match_dup 2)))]
8263   "ix86_match_ccmode (insn, CCNOmode)
8264    && ix86_binary_operator_ok (AND, SImode, operands)"
8265   "and{l}\t{%2, %0|%0, %2}"
8266   [(set_attr "type" "alu")
8267    (set_attr "mode" "SI")])
8269 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8270 (define_insn "*andsi_2_zext"
8271   [(set (reg FLAGS_REG)
8272         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8273                          (match_operand:SI 2 "general_operand" "rim"))
8274                  (const_int 0)))
8275    (set (match_operand:DI 0 "register_operand" "=r")
8276         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8277   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8278    && ix86_binary_operator_ok (AND, SImode, operands)"
8279   "and{l}\t{%2, %k0|%k0, %2}"
8280   [(set_attr "type" "alu")
8281    (set_attr "mode" "SI")])
8283 (define_expand "andhi3"
8284   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8285         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8286                 (match_operand:HI 2 "general_operand" "")))
8287    (clobber (reg:CC FLAGS_REG))]
8288   "TARGET_HIMODE_MATH"
8289   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8291 (define_insn "*andhi_1"
8292   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8293         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8294                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8295    (clobber (reg:CC FLAGS_REG))]
8296   "ix86_binary_operator_ok (AND, HImode, operands)"
8298   switch (get_attr_type (insn))
8299     {
8300     case TYPE_IMOVX:
8301       if (GET_CODE (operands[2]) != CONST_INT)
8302         abort ();
8303       if (INTVAL (operands[2]) == 0xff)
8304         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8305       abort ();
8307     default:
8308       if (! rtx_equal_p (operands[0], operands[1]))
8309         abort ();
8311       return "and{w}\t{%2, %0|%0, %2}";
8312     }
8314   [(set_attr "type" "alu,alu,imovx")
8315    (set_attr "length_immediate" "*,*,0")
8316    (set_attr "mode" "HI,HI,SI")])
8318 (define_insn "*andhi_2"
8319   [(set (reg FLAGS_REG)
8320         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8321                          (match_operand:HI 2 "general_operand" "rim,ri"))
8322                  (const_int 0)))
8323    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8324         (and:HI (match_dup 1) (match_dup 2)))]
8325   "ix86_match_ccmode (insn, CCNOmode)
8326    && ix86_binary_operator_ok (AND, HImode, operands)"
8327   "and{w}\t{%2, %0|%0, %2}"
8328   [(set_attr "type" "alu")
8329    (set_attr "mode" "HI")])
8331 (define_expand "andqi3"
8332   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8333         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8334                 (match_operand:QI 2 "general_operand" "")))
8335    (clobber (reg:CC FLAGS_REG))]
8336   "TARGET_QIMODE_MATH"
8337   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8339 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8340 (define_insn "*andqi_1"
8341   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8342         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8343                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8344    (clobber (reg:CC FLAGS_REG))]
8345   "ix86_binary_operator_ok (AND, QImode, operands)"
8346   "@
8347    and{b}\t{%2, %0|%0, %2}
8348    and{b}\t{%2, %0|%0, %2}
8349    and{l}\t{%k2, %k0|%k0, %k2}"
8350   [(set_attr "type" "alu")
8351    (set_attr "mode" "QI,QI,SI")])
8353 (define_insn "*andqi_1_slp"
8354   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8355         (and:QI (match_dup 0)
8356                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8357    (clobber (reg:CC FLAGS_REG))]
8358   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8359    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8360   "and{b}\t{%1, %0|%0, %1}"
8361   [(set_attr "type" "alu1")
8362    (set_attr "mode" "QI")])
8364 (define_insn "*andqi_2_maybe_si"
8365   [(set (reg FLAGS_REG)
8366         (compare (and:QI
8367                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8368                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8369                  (const_int 0)))
8370    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8371         (and:QI (match_dup 1) (match_dup 2)))]
8372   "ix86_binary_operator_ok (AND, QImode, operands)
8373    && ix86_match_ccmode (insn,
8374                          GET_CODE (operands[2]) == CONST_INT
8375                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8377   if (which_alternative == 2)
8378     {
8379       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8380         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8381       return "and{l}\t{%2, %k0|%k0, %2}";
8382     }
8383   return "and{b}\t{%2, %0|%0, %2}";
8385   [(set_attr "type" "alu")
8386    (set_attr "mode" "QI,QI,SI")])
8388 (define_insn "*andqi_2"
8389   [(set (reg FLAGS_REG)
8390         (compare (and:QI
8391                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8392                    (match_operand:QI 2 "general_operand" "qim,qi"))
8393                  (const_int 0)))
8394    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8395         (and:QI (match_dup 1) (match_dup 2)))]
8396   "ix86_match_ccmode (insn, CCNOmode)
8397    && ix86_binary_operator_ok (AND, QImode, operands)"
8398   "and{b}\t{%2, %0|%0, %2}"
8399   [(set_attr "type" "alu")
8400    (set_attr "mode" "QI")])
8402 (define_insn "*andqi_2_slp"
8403   [(set (reg FLAGS_REG)
8404         (compare (and:QI
8405                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8406                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8407                  (const_int 0)))
8408    (set (strict_low_part (match_dup 0))
8409         (and:QI (match_dup 0) (match_dup 1)))]
8410   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8411    && ix86_match_ccmode (insn, CCNOmode)
8412    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8413   "and{b}\t{%1, %0|%0, %1}"
8414   [(set_attr "type" "alu1")
8415    (set_attr "mode" "QI")])
8417 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8418 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8419 ;; for a QImode operand, which of course failed.
8421 (define_insn "andqi_ext_0"
8422   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8423                          (const_int 8)
8424                          (const_int 8))
8425         (and:SI 
8426           (zero_extract:SI
8427             (match_operand 1 "ext_register_operand" "0")
8428             (const_int 8)
8429             (const_int 8))
8430           (match_operand 2 "const_int_operand" "n")))
8431    (clobber (reg:CC FLAGS_REG))]
8432   ""
8433   "and{b}\t{%2, %h0|%h0, %2}"
8434   [(set_attr "type" "alu")
8435    (set_attr "length_immediate" "1")
8436    (set_attr "mode" "QI")])
8438 ;; Generated by peephole translating test to and.  This shows up
8439 ;; often in fp comparisons.
8441 (define_insn "*andqi_ext_0_cc"
8442   [(set (reg FLAGS_REG)
8443         (compare
8444           (and:SI
8445             (zero_extract:SI
8446               (match_operand 1 "ext_register_operand" "0")
8447               (const_int 8)
8448               (const_int 8))
8449             (match_operand 2 "const_int_operand" "n"))
8450           (const_int 0)))
8451    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8452                          (const_int 8)
8453                          (const_int 8))
8454         (and:SI 
8455           (zero_extract:SI
8456             (match_dup 1)
8457             (const_int 8)
8458             (const_int 8))
8459           (match_dup 2)))]
8460   "ix86_match_ccmode (insn, CCNOmode)"
8461   "and{b}\t{%2, %h0|%h0, %2}"
8462   [(set_attr "type" "alu")
8463    (set_attr "length_immediate" "1")
8464    (set_attr "mode" "QI")])
8466 (define_insn "*andqi_ext_1"
8467   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8468                          (const_int 8)
8469                          (const_int 8))
8470         (and:SI 
8471           (zero_extract:SI
8472             (match_operand 1 "ext_register_operand" "0")
8473             (const_int 8)
8474             (const_int 8))
8475           (zero_extend:SI
8476             (match_operand:QI 2 "general_operand" "Qm"))))
8477    (clobber (reg:CC FLAGS_REG))]
8478   "!TARGET_64BIT"
8479   "and{b}\t{%2, %h0|%h0, %2}"
8480   [(set_attr "type" "alu")
8481    (set_attr "length_immediate" "0")
8482    (set_attr "mode" "QI")])
8484 (define_insn "*andqi_ext_1_rex64"
8485   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8486                          (const_int 8)
8487                          (const_int 8))
8488         (and:SI 
8489           (zero_extract:SI
8490             (match_operand 1 "ext_register_operand" "0")
8491             (const_int 8)
8492             (const_int 8))
8493           (zero_extend:SI
8494             (match_operand 2 "ext_register_operand" "Q"))))
8495    (clobber (reg:CC FLAGS_REG))]
8496   "TARGET_64BIT"
8497   "and{b}\t{%2, %h0|%h0, %2}"
8498   [(set_attr "type" "alu")
8499    (set_attr "length_immediate" "0")
8500    (set_attr "mode" "QI")])
8502 (define_insn "*andqi_ext_2"
8503   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8504                          (const_int 8)
8505                          (const_int 8))
8506         (and:SI
8507           (zero_extract:SI
8508             (match_operand 1 "ext_register_operand" "%0")
8509             (const_int 8)
8510             (const_int 8))
8511           (zero_extract:SI
8512             (match_operand 2 "ext_register_operand" "Q")
8513             (const_int 8)
8514             (const_int 8))))
8515    (clobber (reg:CC FLAGS_REG))]
8516   ""
8517   "and{b}\t{%h2, %h0|%h0, %h2}"
8518   [(set_attr "type" "alu")
8519    (set_attr "length_immediate" "0")
8520    (set_attr "mode" "QI")])
8522 ;; Convert wide AND instructions with immediate operand to shorter QImode
8523 ;; equivalents when possible.
8524 ;; Don't do the splitting with memory operands, since it introduces risk
8525 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8526 ;; for size, but that can (should?) be handled by generic code instead.
8527 (define_split
8528   [(set (match_operand 0 "register_operand" "")
8529         (and (match_operand 1 "register_operand" "")
8530              (match_operand 2 "const_int_operand" "")))
8531    (clobber (reg:CC FLAGS_REG))]
8532    "reload_completed
8533     && QI_REG_P (operands[0])
8534     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8535     && !(~INTVAL (operands[2]) & ~(255 << 8))
8536     && GET_MODE (operands[0]) != QImode"
8537   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8538                    (and:SI (zero_extract:SI (match_dup 1)
8539                                             (const_int 8) (const_int 8))
8540                            (match_dup 2)))
8541               (clobber (reg:CC FLAGS_REG))])]
8542   "operands[0] = gen_lowpart (SImode, operands[0]);
8543    operands[1] = gen_lowpart (SImode, operands[1]);
8544    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8546 ;; Since AND can be encoded with sign extended immediate, this is only
8547 ;; profitable when 7th bit is not set.
8548 (define_split
8549   [(set (match_operand 0 "register_operand" "")
8550         (and (match_operand 1 "general_operand" "")
8551              (match_operand 2 "const_int_operand" "")))
8552    (clobber (reg:CC FLAGS_REG))]
8553    "reload_completed
8554     && ANY_QI_REG_P (operands[0])
8555     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8556     && !(~INTVAL (operands[2]) & ~255)
8557     && !(INTVAL (operands[2]) & 128)
8558     && GET_MODE (operands[0]) != QImode"
8559   [(parallel [(set (strict_low_part (match_dup 0))
8560                    (and:QI (match_dup 1)
8561                            (match_dup 2)))
8562               (clobber (reg:CC FLAGS_REG))])]
8563   "operands[0] = gen_lowpart (QImode, operands[0]);
8564    operands[1] = gen_lowpart (QImode, operands[1]);
8565    operands[2] = gen_lowpart (QImode, operands[2]);")
8567 ;; Logical inclusive OR instructions
8569 ;; %%% This used to optimize known byte-wide and operations to memory.
8570 ;; If this is considered useful, it should be done with splitters.
8572 (define_expand "iordi3"
8573   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8574         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8575                 (match_operand:DI 2 "x86_64_general_operand" "")))
8576    (clobber (reg:CC FLAGS_REG))]
8577   "TARGET_64BIT"
8578   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8580 (define_insn "*iordi_1_rex64"
8581   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8582         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8583                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8584    (clobber (reg:CC FLAGS_REG))]
8585   "TARGET_64BIT
8586    && ix86_binary_operator_ok (IOR, DImode, operands)"
8587   "or{q}\t{%2, %0|%0, %2}"
8588   [(set_attr "type" "alu")
8589    (set_attr "mode" "DI")])
8591 (define_insn "*iordi_2_rex64"
8592   [(set (reg FLAGS_REG)
8593         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8594                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8595                  (const_int 0)))
8596    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8597         (ior:DI (match_dup 1) (match_dup 2)))]
8598   "TARGET_64BIT
8599    && ix86_match_ccmode (insn, CCNOmode)
8600    && ix86_binary_operator_ok (IOR, DImode, operands)"
8601   "or{q}\t{%2, %0|%0, %2}"
8602   [(set_attr "type" "alu")
8603    (set_attr "mode" "DI")])
8605 (define_insn "*iordi_3_rex64"
8606   [(set (reg FLAGS_REG)
8607         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8608                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8609                  (const_int 0)))
8610    (clobber (match_scratch:DI 0 "=r"))]
8611   "TARGET_64BIT
8612    && ix86_match_ccmode (insn, CCNOmode)
8613    && ix86_binary_operator_ok (IOR, DImode, operands)"
8614   "or{q}\t{%2, %0|%0, %2}"
8615   [(set_attr "type" "alu")
8616    (set_attr "mode" "DI")])
8619 (define_expand "iorsi3"
8620   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8621         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8622                 (match_operand:SI 2 "general_operand" "")))
8623    (clobber (reg:CC FLAGS_REG))]
8624   ""
8625   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8627 (define_insn "*iorsi_1"
8628   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8629         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8630                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8631    (clobber (reg:CC FLAGS_REG))]
8632   "ix86_binary_operator_ok (IOR, SImode, operands)"
8633   "or{l}\t{%2, %0|%0, %2}"
8634   [(set_attr "type" "alu")
8635    (set_attr "mode" "SI")])
8637 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8638 (define_insn "*iorsi_1_zext"
8639   [(set (match_operand:DI 0 "register_operand" "=rm")
8640         (zero_extend:DI
8641           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8642                   (match_operand:SI 2 "general_operand" "rim"))))
8643    (clobber (reg:CC FLAGS_REG))]
8644   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8645   "or{l}\t{%2, %k0|%k0, %2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "mode" "SI")])
8649 (define_insn "*iorsi_1_zext_imm"
8650   [(set (match_operand:DI 0 "register_operand" "=rm")
8651         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8652                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "TARGET_64BIT"
8655   "or{l}\t{%2, %k0|%k0, %2}"
8656   [(set_attr "type" "alu")
8657    (set_attr "mode" "SI")])
8659 (define_insn "*iorsi_2"
8660   [(set (reg FLAGS_REG)
8661         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8662                          (match_operand:SI 2 "general_operand" "rim,ri"))
8663                  (const_int 0)))
8664    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8665         (ior:SI (match_dup 1) (match_dup 2)))]
8666   "ix86_match_ccmode (insn, CCNOmode)
8667    && ix86_binary_operator_ok (IOR, SImode, operands)"
8668   "or{l}\t{%2, %0|%0, %2}"
8669   [(set_attr "type" "alu")
8670    (set_attr "mode" "SI")])
8672 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8673 ;; ??? Special case for immediate operand is missing - it is tricky.
8674 (define_insn "*iorsi_2_zext"
8675   [(set (reg FLAGS_REG)
8676         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8677                          (match_operand:SI 2 "general_operand" "rim"))
8678                  (const_int 0)))
8679    (set (match_operand:DI 0 "register_operand" "=r")
8680         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8681   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8682    && ix86_binary_operator_ok (IOR, SImode, operands)"
8683   "or{l}\t{%2, %k0|%k0, %2}"
8684   [(set_attr "type" "alu")
8685    (set_attr "mode" "SI")])
8687 (define_insn "*iorsi_2_zext_imm"
8688   [(set (reg FLAGS_REG)
8689         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8690                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8691                  (const_int 0)))
8692    (set (match_operand:DI 0 "register_operand" "=r")
8693         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8694   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8695    && ix86_binary_operator_ok (IOR, SImode, operands)"
8696   "or{l}\t{%2, %k0|%k0, %2}"
8697   [(set_attr "type" "alu")
8698    (set_attr "mode" "SI")])
8700 (define_insn "*iorsi_3"
8701   [(set (reg FLAGS_REG)
8702         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8703                          (match_operand:SI 2 "general_operand" "rim"))
8704                  (const_int 0)))
8705    (clobber (match_scratch:SI 0 "=r"))]
8706   "ix86_match_ccmode (insn, CCNOmode)
8707    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8708   "or{l}\t{%2, %0|%0, %2}"
8709   [(set_attr "type" "alu")
8710    (set_attr "mode" "SI")])
8712 (define_expand "iorhi3"
8713   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8714         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8715                 (match_operand:HI 2 "general_operand" "")))
8716    (clobber (reg:CC FLAGS_REG))]
8717   "TARGET_HIMODE_MATH"
8718   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8720 (define_insn "*iorhi_1"
8721   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8722         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8723                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8724    (clobber (reg:CC FLAGS_REG))]
8725   "ix86_binary_operator_ok (IOR, HImode, operands)"
8726   "or{w}\t{%2, %0|%0, %2}"
8727   [(set_attr "type" "alu")
8728    (set_attr "mode" "HI")])
8730 (define_insn "*iorhi_2"
8731   [(set (reg FLAGS_REG)
8732         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8733                          (match_operand:HI 2 "general_operand" "rim,ri"))
8734                  (const_int 0)))
8735    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8736         (ior:HI (match_dup 1) (match_dup 2)))]
8737   "ix86_match_ccmode (insn, CCNOmode)
8738    && ix86_binary_operator_ok (IOR, HImode, operands)"
8739   "or{w}\t{%2, %0|%0, %2}"
8740   [(set_attr "type" "alu")
8741    (set_attr "mode" "HI")])
8743 (define_insn "*iorhi_3"
8744   [(set (reg FLAGS_REG)
8745         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8746                          (match_operand:HI 2 "general_operand" "rim"))
8747                  (const_int 0)))
8748    (clobber (match_scratch:HI 0 "=r"))]
8749   "ix86_match_ccmode (insn, CCNOmode)
8750    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8751   "or{w}\t{%2, %0|%0, %2}"
8752   [(set_attr "type" "alu")
8753    (set_attr "mode" "HI")])
8755 (define_expand "iorqi3"
8756   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8757         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8758                 (match_operand:QI 2 "general_operand" "")))
8759    (clobber (reg:CC FLAGS_REG))]
8760   "TARGET_QIMODE_MATH"
8761   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8763 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8764 (define_insn "*iorqi_1"
8765   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8766         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8767                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8768    (clobber (reg:CC FLAGS_REG))]
8769   "ix86_binary_operator_ok (IOR, QImode, operands)"
8770   "@
8771    or{b}\t{%2, %0|%0, %2}
8772    or{b}\t{%2, %0|%0, %2}
8773    or{l}\t{%k2, %k0|%k0, %k2}"
8774   [(set_attr "type" "alu")
8775    (set_attr "mode" "QI,QI,SI")])
8777 (define_insn "*iorqi_1_slp"
8778   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8779         (ior:QI (match_dup 0)
8780                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8781    (clobber (reg:CC FLAGS_REG))]
8782   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8783    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8784   "or{b}\t{%1, %0|%0, %1}"
8785   [(set_attr "type" "alu1")
8786    (set_attr "mode" "QI")])
8788 (define_insn "*iorqi_2"
8789   [(set (reg FLAGS_REG)
8790         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8791                          (match_operand:QI 2 "general_operand" "qim,qi"))
8792                  (const_int 0)))
8793    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8794         (ior:QI (match_dup 1) (match_dup 2)))]
8795   "ix86_match_ccmode (insn, CCNOmode)
8796    && ix86_binary_operator_ok (IOR, QImode, operands)"
8797   "or{b}\t{%2, %0|%0, %2}"
8798   [(set_attr "type" "alu")
8799    (set_attr "mode" "QI")])
8801 (define_insn "*iorqi_2_slp"
8802   [(set (reg FLAGS_REG)
8803         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8804                          (match_operand:QI 1 "general_operand" "qim,qi"))
8805                  (const_int 0)))
8806    (set (strict_low_part (match_dup 0))
8807         (ior:QI (match_dup 0) (match_dup 1)))]
8808   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8809    && ix86_match_ccmode (insn, CCNOmode)
8810    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8811   "or{b}\t{%1, %0|%0, %1}"
8812   [(set_attr "type" "alu1")
8813    (set_attr "mode" "QI")])
8815 (define_insn "*iorqi_3"
8816   [(set (reg FLAGS_REG)
8817         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8818                          (match_operand:QI 2 "general_operand" "qim"))
8819                  (const_int 0)))
8820    (clobber (match_scratch:QI 0 "=q"))]
8821   "ix86_match_ccmode (insn, CCNOmode)
8822    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8823   "or{b}\t{%2, %0|%0, %2}"
8824   [(set_attr "type" "alu")
8825    (set_attr "mode" "QI")])
8827 (define_insn "iorqi_ext_0"
8828   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8829                          (const_int 8)
8830                          (const_int 8))
8831         (ior:SI 
8832           (zero_extract:SI
8833             (match_operand 1 "ext_register_operand" "0")
8834             (const_int 8)
8835             (const_int 8))
8836           (match_operand 2 "const_int_operand" "n")))
8837    (clobber (reg:CC FLAGS_REG))]
8838   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8839   "or{b}\t{%2, %h0|%h0, %2}"
8840   [(set_attr "type" "alu")
8841    (set_attr "length_immediate" "1")
8842    (set_attr "mode" "QI")])
8844 (define_insn "*iorqi_ext_1"
8845   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8846                          (const_int 8)
8847                          (const_int 8))
8848         (ior:SI 
8849           (zero_extract:SI
8850             (match_operand 1 "ext_register_operand" "0")
8851             (const_int 8)
8852             (const_int 8))
8853           (zero_extend:SI
8854             (match_operand:QI 2 "general_operand" "Qm"))))
8855    (clobber (reg:CC FLAGS_REG))]
8856   "!TARGET_64BIT
8857    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8858   "or{b}\t{%2, %h0|%h0, %2}"
8859   [(set_attr "type" "alu")
8860    (set_attr "length_immediate" "0")
8861    (set_attr "mode" "QI")])
8863 (define_insn "*iorqi_ext_1_rex64"
8864   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8865                          (const_int 8)
8866                          (const_int 8))
8867         (ior:SI 
8868           (zero_extract:SI
8869             (match_operand 1 "ext_register_operand" "0")
8870             (const_int 8)
8871             (const_int 8))
8872           (zero_extend:SI
8873             (match_operand 2 "ext_register_operand" "Q"))))
8874    (clobber (reg:CC FLAGS_REG))]
8875   "TARGET_64BIT
8876    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8877   "or{b}\t{%2, %h0|%h0, %2}"
8878   [(set_attr "type" "alu")
8879    (set_attr "length_immediate" "0")
8880    (set_attr "mode" "QI")])
8882 (define_insn "*iorqi_ext_2"
8883   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8884                          (const_int 8)
8885                          (const_int 8))
8886         (ior:SI 
8887           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8888                            (const_int 8)
8889                            (const_int 8))
8890           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8891                            (const_int 8)
8892                            (const_int 8))))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8895   "ior{b}\t{%h2, %h0|%h0, %h2}"
8896   [(set_attr "type" "alu")
8897    (set_attr "length_immediate" "0")
8898    (set_attr "mode" "QI")])
8900 (define_split
8901   [(set (match_operand 0 "register_operand" "")
8902         (ior (match_operand 1 "register_operand" "")
8903              (match_operand 2 "const_int_operand" "")))
8904    (clobber (reg:CC FLAGS_REG))]
8905    "reload_completed
8906     && QI_REG_P (operands[0])
8907     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8908     && !(INTVAL (operands[2]) & ~(255 << 8))
8909     && GET_MODE (operands[0]) != QImode"
8910   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8911                    (ior:SI (zero_extract:SI (match_dup 1)
8912                                             (const_int 8) (const_int 8))
8913                            (match_dup 2)))
8914               (clobber (reg:CC FLAGS_REG))])]
8915   "operands[0] = gen_lowpart (SImode, operands[0]);
8916    operands[1] = gen_lowpart (SImode, operands[1]);
8917    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8919 ;; Since OR can be encoded with sign extended immediate, this is only
8920 ;; profitable when 7th bit is set.
8921 (define_split
8922   [(set (match_operand 0 "register_operand" "")
8923         (ior (match_operand 1 "general_operand" "")
8924              (match_operand 2 "const_int_operand" "")))
8925    (clobber (reg:CC FLAGS_REG))]
8926    "reload_completed
8927     && ANY_QI_REG_P (operands[0])
8928     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8929     && !(INTVAL (operands[2]) & ~255)
8930     && (INTVAL (operands[2]) & 128)
8931     && GET_MODE (operands[0]) != QImode"
8932   [(parallel [(set (strict_low_part (match_dup 0))
8933                    (ior:QI (match_dup 1)
8934                            (match_dup 2)))
8935               (clobber (reg:CC FLAGS_REG))])]
8936   "operands[0] = gen_lowpart (QImode, operands[0]);
8937    operands[1] = gen_lowpart (QImode, operands[1]);
8938    operands[2] = gen_lowpart (QImode, operands[2]);")
8940 ;; Logical XOR instructions
8942 ;; %%% This used to optimize known byte-wide and operations to memory.
8943 ;; If this is considered useful, it should be done with splitters.
8945 (define_expand "xordi3"
8946   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8947         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8948                 (match_operand:DI 2 "x86_64_general_operand" "")))
8949    (clobber (reg:CC FLAGS_REG))]
8950   "TARGET_64BIT"
8951   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8953 (define_insn "*xordi_1_rex64"
8954   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8955         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8956                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8957    (clobber (reg:CC FLAGS_REG))]
8958   "TARGET_64BIT
8959    && ix86_binary_operator_ok (XOR, DImode, operands)"
8960   "@
8961    xor{q}\t{%2, %0|%0, %2}
8962    xor{q}\t{%2, %0|%0, %2}"
8963   [(set_attr "type" "alu")
8964    (set_attr "mode" "DI,DI")])
8966 (define_insn "*xordi_2_rex64"
8967   [(set (reg FLAGS_REG)
8968         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8969                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8970                  (const_int 0)))
8971    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8972         (xor:DI (match_dup 1) (match_dup 2)))]
8973   "TARGET_64BIT
8974    && ix86_match_ccmode (insn, CCNOmode)
8975    && ix86_binary_operator_ok (XOR, DImode, operands)"
8976   "@
8977    xor{q}\t{%2, %0|%0, %2}
8978    xor{q}\t{%2, %0|%0, %2}"
8979   [(set_attr "type" "alu")
8980    (set_attr "mode" "DI,DI")])
8982 (define_insn "*xordi_3_rex64"
8983   [(set (reg FLAGS_REG)
8984         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8985                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8986                  (const_int 0)))
8987    (clobber (match_scratch:DI 0 "=r"))]
8988   "TARGET_64BIT
8989    && ix86_match_ccmode (insn, CCNOmode)
8990    && ix86_binary_operator_ok (XOR, DImode, operands)"
8991   "xor{q}\t{%2, %0|%0, %2}"
8992   [(set_attr "type" "alu")
8993    (set_attr "mode" "DI")])
8995 (define_expand "xorsi3"
8996   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8997         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8998                 (match_operand:SI 2 "general_operand" "")))
8999    (clobber (reg:CC FLAGS_REG))]
9000   ""
9001   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9003 (define_insn "*xorsi_1"
9004   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9005         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9006                 (match_operand:SI 2 "general_operand" "ri,rm")))
9007    (clobber (reg:CC FLAGS_REG))]
9008   "ix86_binary_operator_ok (XOR, SImode, operands)"
9009   "xor{l}\t{%2, %0|%0, %2}"
9010   [(set_attr "type" "alu")
9011    (set_attr "mode" "SI")])
9013 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9014 ;; Add speccase for immediates
9015 (define_insn "*xorsi_1_zext"
9016   [(set (match_operand:DI 0 "register_operand" "=r")
9017         (zero_extend:DI
9018           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9019                   (match_operand:SI 2 "general_operand" "rim"))))
9020    (clobber (reg:CC FLAGS_REG))]
9021   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9022   "xor{l}\t{%2, %k0|%k0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "SI")])
9026 (define_insn "*xorsi_1_zext_imm"
9027   [(set (match_operand:DI 0 "register_operand" "=r")
9028         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9029                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9030    (clobber (reg:CC FLAGS_REG))]
9031   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9032   "xor{l}\t{%2, %k0|%k0, %2}"
9033   [(set_attr "type" "alu")
9034    (set_attr "mode" "SI")])
9036 (define_insn "*xorsi_2"
9037   [(set (reg FLAGS_REG)
9038         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9039                          (match_operand:SI 2 "general_operand" "rim,ri"))
9040                  (const_int 0)))
9041    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9042         (xor:SI (match_dup 1) (match_dup 2)))]
9043   "ix86_match_ccmode (insn, CCNOmode)
9044    && ix86_binary_operator_ok (XOR, SImode, operands)"
9045   "xor{l}\t{%2, %0|%0, %2}"
9046   [(set_attr "type" "alu")
9047    (set_attr "mode" "SI")])
9049 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9050 ;; ??? Special case for immediate operand is missing - it is tricky.
9051 (define_insn "*xorsi_2_zext"
9052   [(set (reg FLAGS_REG)
9053         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9054                          (match_operand:SI 2 "general_operand" "rim"))
9055                  (const_int 0)))
9056    (set (match_operand:DI 0 "register_operand" "=r")
9057         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9058   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9059    && ix86_binary_operator_ok (XOR, SImode, operands)"
9060   "xor{l}\t{%2, %k0|%k0, %2}"
9061   [(set_attr "type" "alu")
9062    (set_attr "mode" "SI")])
9064 (define_insn "*xorsi_2_zext_imm"
9065   [(set (reg FLAGS_REG)
9066         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9067                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9068                  (const_int 0)))
9069    (set (match_operand:DI 0 "register_operand" "=r")
9070         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9071   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9072    && ix86_binary_operator_ok (XOR, SImode, operands)"
9073   "xor{l}\t{%2, %k0|%k0, %2}"
9074   [(set_attr "type" "alu")
9075    (set_attr "mode" "SI")])
9077 (define_insn "*xorsi_3"
9078   [(set (reg FLAGS_REG)
9079         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9080                          (match_operand:SI 2 "general_operand" "rim"))
9081                  (const_int 0)))
9082    (clobber (match_scratch:SI 0 "=r"))]
9083   "ix86_match_ccmode (insn, CCNOmode)
9084    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9085   "xor{l}\t{%2, %0|%0, %2}"
9086   [(set_attr "type" "alu")
9087    (set_attr "mode" "SI")])
9089 (define_expand "xorhi3"
9090   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9091         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9092                 (match_operand:HI 2 "general_operand" "")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "TARGET_HIMODE_MATH"
9095   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9097 (define_insn "*xorhi_1"
9098   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9099         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9100                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9101    (clobber (reg:CC FLAGS_REG))]
9102   "ix86_binary_operator_ok (XOR, HImode, operands)"
9103   "xor{w}\t{%2, %0|%0, %2}"
9104   [(set_attr "type" "alu")
9105    (set_attr "mode" "HI")])
9107 (define_insn "*xorhi_2"
9108   [(set (reg FLAGS_REG)
9109         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9110                          (match_operand:HI 2 "general_operand" "rim,ri"))
9111                  (const_int 0)))
9112    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9113         (xor:HI (match_dup 1) (match_dup 2)))]
9114   "ix86_match_ccmode (insn, CCNOmode)
9115    && ix86_binary_operator_ok (XOR, HImode, operands)"
9116   "xor{w}\t{%2, %0|%0, %2}"
9117   [(set_attr "type" "alu")
9118    (set_attr "mode" "HI")])
9120 (define_insn "*xorhi_3"
9121   [(set (reg FLAGS_REG)
9122         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9123                          (match_operand:HI 2 "general_operand" "rim"))
9124                  (const_int 0)))
9125    (clobber (match_scratch:HI 0 "=r"))]
9126   "ix86_match_ccmode (insn, CCNOmode)
9127    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9128   "xor{w}\t{%2, %0|%0, %2}"
9129   [(set_attr "type" "alu")
9130    (set_attr "mode" "HI")])
9132 (define_expand "xorqi3"
9133   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9134         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9135                 (match_operand:QI 2 "general_operand" "")))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "TARGET_QIMODE_MATH"
9138   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9140 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9141 (define_insn "*xorqi_1"
9142   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9143         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9144                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9145    (clobber (reg:CC FLAGS_REG))]
9146   "ix86_binary_operator_ok (XOR, QImode, operands)"
9147   "@
9148    xor{b}\t{%2, %0|%0, %2}
9149    xor{b}\t{%2, %0|%0, %2}
9150    xor{l}\t{%k2, %k0|%k0, %k2}"
9151   [(set_attr "type" "alu")
9152    (set_attr "mode" "QI,QI,SI")])
9154 (define_insn "*xorqi_1_slp"
9155   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9156         (xor:QI (match_dup 0)
9157                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9158    (clobber (reg:CC FLAGS_REG))]
9159   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9160    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9161   "xor{b}\t{%1, %0|%0, %1}"
9162   [(set_attr "type" "alu1")
9163    (set_attr "mode" "QI")])
9165 (define_insn "xorqi_ext_0"
9166   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9167                          (const_int 8)
9168                          (const_int 8))
9169         (xor:SI 
9170           (zero_extract:SI
9171             (match_operand 1 "ext_register_operand" "0")
9172             (const_int 8)
9173             (const_int 8))
9174           (match_operand 2 "const_int_operand" "n")))
9175    (clobber (reg:CC FLAGS_REG))]
9176   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9177   "xor{b}\t{%2, %h0|%h0, %2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "length_immediate" "1")
9180    (set_attr "mode" "QI")])
9182 (define_insn "*xorqi_ext_1"
9183   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9184                          (const_int 8)
9185                          (const_int 8))
9186         (xor:SI 
9187           (zero_extract:SI
9188             (match_operand 1 "ext_register_operand" "0")
9189             (const_int 8)
9190             (const_int 8))
9191           (zero_extend:SI
9192             (match_operand:QI 2 "general_operand" "Qm"))))
9193    (clobber (reg:CC FLAGS_REG))]
9194   "!TARGET_64BIT
9195    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9196   "xor{b}\t{%2, %h0|%h0, %2}"
9197   [(set_attr "type" "alu")
9198    (set_attr "length_immediate" "0")
9199    (set_attr "mode" "QI")])
9201 (define_insn "*xorqi_ext_1_rex64"
9202   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9203                          (const_int 8)
9204                          (const_int 8))
9205         (xor:SI 
9206           (zero_extract:SI
9207             (match_operand 1 "ext_register_operand" "0")
9208             (const_int 8)
9209             (const_int 8))
9210           (zero_extend:SI
9211             (match_operand 2 "ext_register_operand" "Q"))))
9212    (clobber (reg:CC FLAGS_REG))]
9213   "TARGET_64BIT
9214    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9215   "xor{b}\t{%2, %h0|%h0, %2}"
9216   [(set_attr "type" "alu")
9217    (set_attr "length_immediate" "0")
9218    (set_attr "mode" "QI")])
9220 (define_insn "*xorqi_ext_2"
9221   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9222                          (const_int 8)
9223                          (const_int 8))
9224         (xor:SI 
9225           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9226                            (const_int 8)
9227                            (const_int 8))
9228           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9229                            (const_int 8)
9230                            (const_int 8))))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9233   "xor{b}\t{%h2, %h0|%h0, %h2}"
9234   [(set_attr "type" "alu")
9235    (set_attr "length_immediate" "0")
9236    (set_attr "mode" "QI")])
9238 (define_insn "*xorqi_cc_1"
9239   [(set (reg FLAGS_REG)
9240         (compare
9241           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9242                   (match_operand:QI 2 "general_operand" "qim,qi"))
9243           (const_int 0)))
9244    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9245         (xor:QI (match_dup 1) (match_dup 2)))]
9246   "ix86_match_ccmode (insn, CCNOmode)
9247    && ix86_binary_operator_ok (XOR, QImode, operands)"
9248   "xor{b}\t{%2, %0|%0, %2}"
9249   [(set_attr "type" "alu")
9250    (set_attr "mode" "QI")])
9252 (define_insn "*xorqi_2_slp"
9253   [(set (reg FLAGS_REG)
9254         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9255                          (match_operand:QI 1 "general_operand" "qim,qi"))
9256                  (const_int 0)))
9257    (set (strict_low_part (match_dup 0))
9258         (xor:QI (match_dup 0) (match_dup 1)))]
9259   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9260    && ix86_match_ccmode (insn, CCNOmode)
9261    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9262   "xor{b}\t{%1, %0|%0, %1}"
9263   [(set_attr "type" "alu1")
9264    (set_attr "mode" "QI")])
9266 (define_insn "*xorqi_cc_2"
9267   [(set (reg FLAGS_REG)
9268         (compare
9269           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9270                   (match_operand:QI 2 "general_operand" "qim"))
9271           (const_int 0)))
9272    (clobber (match_scratch:QI 0 "=q"))]
9273   "ix86_match_ccmode (insn, CCNOmode)
9274    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9275   "xor{b}\t{%2, %0|%0, %2}"
9276   [(set_attr "type" "alu")
9277    (set_attr "mode" "QI")])
9279 (define_insn "*xorqi_cc_ext_1"
9280   [(set (reg FLAGS_REG)
9281         (compare
9282           (xor:SI
9283             (zero_extract:SI
9284               (match_operand 1 "ext_register_operand" "0")
9285               (const_int 8)
9286               (const_int 8))
9287             (match_operand:QI 2 "general_operand" "qmn"))
9288           (const_int 0)))
9289    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9290                          (const_int 8)
9291                          (const_int 8))
9292         (xor:SI 
9293           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9294           (match_dup 2)))]
9295   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9296   "xor{b}\t{%2, %h0|%h0, %2}"
9297   [(set_attr "type" "alu")
9298    (set_attr "mode" "QI")])
9300 (define_insn "*xorqi_cc_ext_1_rex64"
9301   [(set (reg FLAGS_REG)
9302         (compare
9303           (xor:SI
9304             (zero_extract:SI
9305               (match_operand 1 "ext_register_operand" "0")
9306               (const_int 8)
9307               (const_int 8))
9308             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9309           (const_int 0)))
9310    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9311                          (const_int 8)
9312                          (const_int 8))
9313         (xor:SI 
9314           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9315           (match_dup 2)))]
9316   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9317   "xor{b}\t{%2, %h0|%h0, %2}"
9318   [(set_attr "type" "alu")
9319    (set_attr "mode" "QI")])
9321 (define_expand "xorqi_cc_ext_1"
9322   [(parallel [
9323      (set (reg:CCNO FLAGS_REG)
9324           (compare:CCNO
9325             (xor:SI
9326               (zero_extract:SI
9327                 (match_operand 1 "ext_register_operand" "")
9328                 (const_int 8)
9329                 (const_int 8))
9330               (match_operand:QI 2 "general_operand" ""))
9331             (const_int 0)))
9332      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9333                            (const_int 8)
9334                            (const_int 8))
9335           (xor:SI 
9336             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9337             (match_dup 2)))])]
9338   ""
9339   "")
9341 (define_split
9342   [(set (match_operand 0 "register_operand" "")
9343         (xor (match_operand 1 "register_operand" "")
9344              (match_operand 2 "const_int_operand" "")))
9345    (clobber (reg:CC FLAGS_REG))]
9346    "reload_completed
9347     && QI_REG_P (operands[0])
9348     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9349     && !(INTVAL (operands[2]) & ~(255 << 8))
9350     && GET_MODE (operands[0]) != QImode"
9351   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9352                    (xor:SI (zero_extract:SI (match_dup 1)
9353                                             (const_int 8) (const_int 8))
9354                            (match_dup 2)))
9355               (clobber (reg:CC FLAGS_REG))])]
9356   "operands[0] = gen_lowpart (SImode, operands[0]);
9357    operands[1] = gen_lowpart (SImode, operands[1]);
9358    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9360 ;; Since XOR can be encoded with sign extended immediate, this is only
9361 ;; profitable when 7th bit is set.
9362 (define_split
9363   [(set (match_operand 0 "register_operand" "")
9364         (xor (match_operand 1 "general_operand" "")
9365              (match_operand 2 "const_int_operand" "")))
9366    (clobber (reg:CC FLAGS_REG))]
9367    "reload_completed
9368     && ANY_QI_REG_P (operands[0])
9369     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9370     && !(INTVAL (operands[2]) & ~255)
9371     && (INTVAL (operands[2]) & 128)
9372     && GET_MODE (operands[0]) != QImode"
9373   [(parallel [(set (strict_low_part (match_dup 0))
9374                    (xor:QI (match_dup 1)
9375                            (match_dup 2)))
9376               (clobber (reg:CC FLAGS_REG))])]
9377   "operands[0] = gen_lowpart (QImode, operands[0]);
9378    operands[1] = gen_lowpart (QImode, operands[1]);
9379    operands[2] = gen_lowpart (QImode, operands[2]);")
9381 ;; Negation instructions
9383 (define_expand "negdi2"
9384   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9385                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9386               (clobber (reg:CC FLAGS_REG))])]
9387   ""
9388   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9390 (define_insn "*negdi2_1"
9391   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9392         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9393    (clobber (reg:CC FLAGS_REG))]
9394   "!TARGET_64BIT
9395    && ix86_unary_operator_ok (NEG, DImode, operands)"
9396   "#")
9398 (define_split
9399   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9400         (neg:DI (match_operand:DI 1 "general_operand" "")))
9401    (clobber (reg:CC FLAGS_REG))]
9402   "!TARGET_64BIT && reload_completed"
9403   [(parallel
9404     [(set (reg:CCZ FLAGS_REG)
9405           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9406      (set (match_dup 0) (neg:SI (match_dup 2)))])
9407    (parallel
9408     [(set (match_dup 1)
9409           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9410                             (match_dup 3))
9411                    (const_int 0)))
9412      (clobber (reg:CC FLAGS_REG))])
9413    (parallel
9414     [(set (match_dup 1)
9415           (neg:SI (match_dup 1)))
9416      (clobber (reg:CC FLAGS_REG))])]
9417   "split_di (operands+1, 1, operands+2, operands+3);
9418    split_di (operands+0, 1, operands+0, operands+1);")
9420 (define_insn "*negdi2_1_rex64"
9421   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9422         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9423    (clobber (reg:CC FLAGS_REG))]
9424   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9425   "neg{q}\t%0"
9426   [(set_attr "type" "negnot")
9427    (set_attr "mode" "DI")])
9429 ;; The problem with neg is that it does not perform (compare x 0),
9430 ;; it really performs (compare 0 x), which leaves us with the zero
9431 ;; flag being the only useful item.
9433 (define_insn "*negdi2_cmpz_rex64"
9434   [(set (reg:CCZ FLAGS_REG)
9435         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9436                      (const_int 0)))
9437    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9438         (neg:DI (match_dup 1)))]
9439   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9440   "neg{q}\t%0"
9441   [(set_attr "type" "negnot")
9442    (set_attr "mode" "DI")])
9445 (define_expand "negsi2"
9446   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9447                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9448               (clobber (reg:CC FLAGS_REG))])]
9449   ""
9450   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9452 (define_insn "*negsi2_1"
9453   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9454         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9455    (clobber (reg:CC FLAGS_REG))]
9456   "ix86_unary_operator_ok (NEG, SImode, operands)"
9457   "neg{l}\t%0"
9458   [(set_attr "type" "negnot")
9459    (set_attr "mode" "SI")])
9461 ;; Combine is quite creative about this pattern.
9462 (define_insn "*negsi2_1_zext"
9463   [(set (match_operand:DI 0 "register_operand" "=r")
9464         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9465                                         (const_int 32)))
9466                      (const_int 32)))
9467    (clobber (reg:CC FLAGS_REG))]
9468   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9469   "neg{l}\t%k0"
9470   [(set_attr "type" "negnot")
9471    (set_attr "mode" "SI")])
9473 ;; The problem with neg is that it does not perform (compare x 0),
9474 ;; it really performs (compare 0 x), which leaves us with the zero
9475 ;; flag being the only useful item.
9477 (define_insn "*negsi2_cmpz"
9478   [(set (reg:CCZ FLAGS_REG)
9479         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9480                      (const_int 0)))
9481    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9482         (neg:SI (match_dup 1)))]
9483   "ix86_unary_operator_ok (NEG, SImode, operands)"
9484   "neg{l}\t%0"
9485   [(set_attr "type" "negnot")
9486    (set_attr "mode" "SI")])
9488 (define_insn "*negsi2_cmpz_zext"
9489   [(set (reg:CCZ FLAGS_REG)
9490         (compare:CCZ (lshiftrt:DI
9491                        (neg:DI (ashift:DI
9492                                  (match_operand:DI 1 "register_operand" "0")
9493                                  (const_int 32)))
9494                        (const_int 32))
9495                      (const_int 0)))
9496    (set (match_operand:DI 0 "register_operand" "=r")
9497         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9498                                         (const_int 32)))
9499                      (const_int 32)))]
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 (define_expand "neghi2"
9506   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9507                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9508               (clobber (reg:CC FLAGS_REG))])]
9509   "TARGET_HIMODE_MATH"
9510   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9512 (define_insn "*neghi2_1"
9513   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9514         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9515    (clobber (reg:CC FLAGS_REG))]
9516   "ix86_unary_operator_ok (NEG, HImode, operands)"
9517   "neg{w}\t%0"
9518   [(set_attr "type" "negnot")
9519    (set_attr "mode" "HI")])
9521 (define_insn "*neghi2_cmpz"
9522   [(set (reg:CCZ FLAGS_REG)
9523         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9524                      (const_int 0)))
9525    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9526         (neg:HI (match_dup 1)))]
9527   "ix86_unary_operator_ok (NEG, HImode, operands)"
9528   "neg{w}\t%0"
9529   [(set_attr "type" "negnot")
9530    (set_attr "mode" "HI")])
9532 (define_expand "negqi2"
9533   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9534                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9535               (clobber (reg:CC FLAGS_REG))])]
9536   "TARGET_QIMODE_MATH"
9537   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9539 (define_insn "*negqi2_1"
9540   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9541         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9542    (clobber (reg:CC FLAGS_REG))]
9543   "ix86_unary_operator_ok (NEG, QImode, operands)"
9544   "neg{b}\t%0"
9545   [(set_attr "type" "negnot")
9546    (set_attr "mode" "QI")])
9548 (define_insn "*negqi2_cmpz"
9549   [(set (reg:CCZ FLAGS_REG)
9550         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9551                      (const_int 0)))
9552    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9553         (neg:QI (match_dup 1)))]
9554   "ix86_unary_operator_ok (NEG, QImode, operands)"
9555   "neg{b}\t%0"
9556   [(set_attr "type" "negnot")
9557    (set_attr "mode" "QI")])
9559 ;; Changing of sign for FP values is doable using integer unit too.
9561 (define_expand "negsf2"
9562   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9563                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9564               (clobber (reg:CC FLAGS_REG))])]
9565   "TARGET_80387"
9566   "if (TARGET_SSE)
9567      {
9568        /* In case operand is in memory,  we will not use SSE.  */
9569        if (memory_operand (operands[0], VOIDmode)
9570            && rtx_equal_p (operands[0], operands[1]))
9571          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9572        else
9573         {
9574           /* Using SSE is tricky, since we need bitwise negation of -0
9575              in register.  */
9576           rtx reg = gen_reg_rtx (SFmode);
9577           rtx dest = operands[0];
9578           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9580           operands[1] = force_reg (SFmode, operands[1]);
9581           operands[0] = force_reg (SFmode, operands[0]);
9582           reg = force_reg (V4SFmode,
9583                            gen_rtx_CONST_VECTOR (V4SFmode,
9584                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9585                                         CONST0_RTX (SFmode),
9586                                         CONST0_RTX (SFmode))));
9587           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9588           if (dest != operands[0])
9589             emit_move_insn (dest, operands[0]);
9590         }
9591        DONE;
9592      }
9593    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9595 (define_insn "negsf2_memory"
9596   [(set (match_operand:SF 0 "memory_operand" "=m")
9597         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9598    (clobber (reg:CC FLAGS_REG))]
9599   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9600   "#")
9602 (define_insn "negsf2_ifs"
9603   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9604         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9605    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9606    (clobber (reg:CC FLAGS_REG))]
9607   "TARGET_SSE
9608    && (reload_in_progress || reload_completed
9609        || (register_operand (operands[0], VOIDmode)
9610            && register_operand (operands[1], VOIDmode)))"
9611   "#")
9613 (define_split
9614   [(set (match_operand:SF 0 "memory_operand" "")
9615         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9616    (use (match_operand:SF 2 "" ""))
9617    (clobber (reg:CC FLAGS_REG))]
9618   ""
9619   [(parallel [(set (match_dup 0)
9620                    (neg:SF (match_dup 1)))
9621               (clobber (reg:CC FLAGS_REG))])])
9623 (define_split
9624   [(set (match_operand:SF 0 "register_operand" "")
9625         (neg:SF (match_operand:SF 1 "register_operand" "")))
9626    (use (match_operand:V4SF 2 "" ""))
9627    (clobber (reg:CC FLAGS_REG))]
9628   "reload_completed && !SSE_REG_P (operands[0])"
9629   [(parallel [(set (match_dup 0)
9630                    (neg:SF (match_dup 1)))
9631               (clobber (reg:CC FLAGS_REG))])])
9633 (define_split
9634   [(set (match_operand:SF 0 "register_operand" "")
9635         (neg:SF (match_operand:SF 1 "register_operand" "")))
9636    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9637    (clobber (reg:CC FLAGS_REG))]
9638   "reload_completed && SSE_REG_P (operands[0])"
9639   [(set (match_dup 0)
9640         (xor:V4SF (match_dup 1)
9641                   (match_dup 2)))]
9643   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9644   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9645   if (operands_match_p (operands[0], operands[2]))
9646     {
9647       rtx tmp;
9648       tmp = operands[1];
9649       operands[1] = operands[2];
9650       operands[2] = tmp;
9651     }
9655 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9656 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9657 ;; to itself.
9658 (define_insn "*negsf2_if"
9659   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9660         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9661    (clobber (reg:CC FLAGS_REG))]
9662   "TARGET_80387 && !TARGET_SSE
9663    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9664   "#")
9666 (define_split
9667   [(set (match_operand:SF 0 "fp_register_operand" "")
9668         (neg:SF (match_operand:SF 1 "register_operand" "")))
9669    (clobber (reg:CC FLAGS_REG))]
9670   "TARGET_80387 && reload_completed"
9671   [(set (match_dup 0)
9672         (neg:SF (match_dup 1)))]
9673   "")
9675 (define_split
9676   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9677         (neg:SF (match_operand:SF 1 "register_operand" "")))
9678    (clobber (reg:CC FLAGS_REG))]
9679   "TARGET_80387 && reload_completed"
9680   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9681               (clobber (reg:CC FLAGS_REG))])]
9682   "operands[1] = gen_int_mode (0x80000000, SImode);
9683    operands[0] = gen_lowpart (SImode, operands[0]);")
9685 (define_split
9686   [(set (match_operand 0 "memory_operand" "")
9687         (neg (match_operand 1 "memory_operand" "")))
9688    (clobber (reg:CC FLAGS_REG))]
9689   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9690   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9691               (clobber (reg:CC FLAGS_REG))])]
9693   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9695   if (GET_MODE (operands[1]) == XFmode)
9696     size = 10;
9697   operands[0] = adjust_address (operands[0], QImode, size - 1);
9698   operands[1] = gen_int_mode (0x80, QImode);
9701 (define_expand "negdf2"
9702   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9703                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9704               (clobber (reg:CC FLAGS_REG))])]
9705   "TARGET_80387"
9706   "if (TARGET_SSE2)
9707      {
9708        /* In case operand is in memory,  we will not use SSE.  */
9709        if (memory_operand (operands[0], VOIDmode)
9710            && rtx_equal_p (operands[0], operands[1]))
9711          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9712        else
9713         {
9714           /* Using SSE is tricky, since we need bitwise negation of -0
9715              in register.  */
9716           rtx reg;
9717 #if HOST_BITS_PER_WIDE_INT >= 64
9718           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9719 #else
9720           rtx imm = immed_double_const (0, 0x80000000, DImode);
9721 #endif
9722           rtx dest = operands[0];
9724           operands[1] = force_reg (DFmode, operands[1]);
9725           operands[0] = force_reg (DFmode, operands[0]);
9726           imm = gen_lowpart (DFmode, imm);
9727           reg = force_reg (V2DFmode,
9728                            gen_rtx_CONST_VECTOR (V2DFmode,
9729                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9730           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9731           if (dest != operands[0])
9732             emit_move_insn (dest, operands[0]);
9733         }
9734        DONE;
9735      }
9736    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9738 (define_insn "negdf2_memory"
9739   [(set (match_operand:DF 0 "memory_operand" "=m")
9740         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9741    (clobber (reg:CC FLAGS_REG))]
9742   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9743   "#")
9745 (define_insn "negdf2_ifs"
9746   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9747         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9748    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9749    (clobber (reg:CC FLAGS_REG))]
9750   "!TARGET_64BIT && TARGET_SSE2
9751    && (reload_in_progress || reload_completed
9752        || (register_operand (operands[0], VOIDmode)
9753            && register_operand (operands[1], VOIDmode)))"
9754   "#")
9756 (define_insn "*negdf2_ifs_rex64"
9757   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9758         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9759    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9760    (clobber (reg:CC FLAGS_REG))]
9761   "TARGET_64BIT && TARGET_SSE2
9762    && (reload_in_progress || reload_completed
9763        || (register_operand (operands[0], VOIDmode)
9764            && register_operand (operands[1], VOIDmode)))"
9765   "#")
9767 (define_split
9768   [(set (match_operand:DF 0 "memory_operand" "")
9769         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9770    (use (match_operand:V2DF 2 "" ""))
9771    (clobber (reg:CC FLAGS_REG))]
9772   ""
9773   [(parallel [(set (match_dup 0)
9774                    (neg:DF (match_dup 1)))
9775               (clobber (reg:CC FLAGS_REG))])])
9777 (define_split
9778   [(set (match_operand:DF 0 "register_operand" "")
9779         (neg:DF (match_operand:DF 1 "register_operand" "")))
9780    (use (match_operand:V2DF 2 "" ""))
9781    (clobber (reg:CC FLAGS_REG))]
9782   "reload_completed && !SSE_REG_P (operands[0])
9783    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9784   [(parallel [(set (match_dup 0)
9785                    (neg:DF (match_dup 1)))
9786               (clobber (reg:CC FLAGS_REG))])])
9788 (define_split
9789   [(set (match_operand:DF 0 "register_operand" "")
9790         (neg:DF (match_operand:DF 1 "register_operand" "")))
9791    (use (match_operand:V2DF 2 "" ""))
9792    (clobber (reg:CC FLAGS_REG))]
9793   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9794   [(parallel [(set (match_dup 0)
9795                    (xor:DI (match_dup 1) (match_dup 2)))
9796               (clobber (reg:CC FLAGS_REG))])]
9797    "operands[0] = gen_lowpart (DImode, operands[0]);
9798     operands[1] = gen_lowpart (DImode, operands[1]);
9799     operands[2] = gen_lowpart (DImode, operands[2]);")
9801 (define_split
9802   [(set (match_operand:DF 0 "register_operand" "")
9803         (neg:DF (match_operand:DF 1 "register_operand" "")))
9804    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9805    (clobber (reg:CC FLAGS_REG))]
9806   "reload_completed && SSE_REG_P (operands[0])"
9807   [(set (match_dup 0)
9808         (xor:V2DF (match_dup 1)
9809                   (match_dup 2)))]
9811   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9812   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9813   /* Avoid possible reformatting on the operands.  */
9814   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9815     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9816   if (operands_match_p (operands[0], operands[2]))
9817     {
9818       rtx tmp;
9819       tmp = operands[1];
9820       operands[1] = operands[2];
9821       operands[2] = tmp;
9822     }
9825 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9826 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9827 ;; to itself.
9828 (define_insn "*negdf2_if"
9829   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9830         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9831    (clobber (reg:CC FLAGS_REG))]
9832   "!TARGET_64BIT && TARGET_80387
9833    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9834   "#")
9836 ;; FIXME: We should to allow integer registers here.  Problem is that
9837 ;; we need another scratch register to get constant from.
9838 ;; Forcing constant to mem if no register available in peep2 should be
9839 ;; safe even for PIC mode, because of RIP relative addressing.
9840 (define_insn "*negdf2_if_rex64"
9841   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9842         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9843    (clobber (reg:CC FLAGS_REG))]
9844   "TARGET_64BIT && TARGET_80387
9845    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9846   "#")
9848 (define_split
9849   [(set (match_operand:DF 0 "fp_register_operand" "")
9850         (neg:DF (match_operand:DF 1 "register_operand" "")))
9851    (clobber (reg:CC FLAGS_REG))]
9852   "TARGET_80387 && reload_completed"
9853   [(set (match_dup 0)
9854         (neg:DF (match_dup 1)))]
9855   "")
9857 (define_split
9858   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9859         (neg:DF (match_operand:DF 1 "register_operand" "")))
9860    (clobber (reg:CC FLAGS_REG))]
9861   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9862   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9863               (clobber (reg:CC FLAGS_REG))])]
9864   "operands[4] = gen_int_mode (0x80000000, SImode);
9865    split_di (operands+0, 1, operands+2, operands+3);")
9867 (define_expand "negxf2"
9868   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9869                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9870               (clobber (reg:CC FLAGS_REG))])]
9871   "TARGET_80387"
9872   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9874 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9875 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9876 ;; to itself.
9877 (define_insn "*negxf2_if"
9878   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9879         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9880    (clobber (reg:CC FLAGS_REG))]
9881   "TARGET_80387
9882    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9883   "#")
9885 (define_split
9886   [(set (match_operand:XF 0 "fp_register_operand" "")
9887         (neg:XF (match_operand:XF 1 "register_operand" "")))
9888    (clobber (reg:CC FLAGS_REG))]
9889   "TARGET_80387 && reload_completed"
9890   [(set (match_dup 0)
9891         (neg:XF (match_dup 1)))]
9892   "")
9894 (define_split
9895   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9896         (neg:XF (match_operand:XF 1 "register_operand" "")))
9897    (clobber (reg:CC FLAGS_REG))]
9898   "TARGET_80387 && reload_completed"
9899   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9900               (clobber (reg:CC FLAGS_REG))])]
9901   "operands[1] = GEN_INT (0x8000);
9902    operands[0] = gen_rtx_REG (SImode,
9903                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9905 ;; Conditionalize these after reload. If they matches before reload, we 
9906 ;; lose the clobber and ability to use integer instructions.
9908 (define_insn "*negsf2_1"
9909   [(set (match_operand:SF 0 "register_operand" "=f")
9910         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9911   "TARGET_80387 && reload_completed"
9912   "fchs"
9913   [(set_attr "type" "fsgn")
9914    (set_attr "mode" "SF")])
9916 (define_insn "*negdf2_1"
9917   [(set (match_operand:DF 0 "register_operand" "=f")
9918         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9919   "TARGET_80387 && reload_completed"
9920   "fchs"
9921   [(set_attr "type" "fsgn")
9922    (set_attr "mode" "DF")])
9924 (define_insn "*negextendsfdf2"
9925   [(set (match_operand:DF 0 "register_operand" "=f")
9926         (neg:DF (float_extend:DF
9927                   (match_operand:SF 1 "register_operand" "0"))))]
9928   "TARGET_80387"
9929   "fchs"
9930   [(set_attr "type" "fsgn")
9931    (set_attr "mode" "DF")])
9933 (define_insn "*negxf2_1"
9934   [(set (match_operand:XF 0 "register_operand" "=f")
9935         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9936   "TARGET_80387 && reload_completed"
9937   "fchs"
9938   [(set_attr "type" "fsgn")
9939    (set_attr "mode" "XF")])
9941 (define_insn "*negextenddfxf2"
9942   [(set (match_operand:XF 0 "register_operand" "=f")
9943         (neg:XF (float_extend:XF
9944                   (match_operand:DF 1 "register_operand" "0"))))]
9945   "TARGET_80387"
9946   "fchs"
9947   [(set_attr "type" "fsgn")
9948    (set_attr "mode" "XF")])
9950 (define_insn "*negextendsfxf2"
9951   [(set (match_operand:XF 0 "register_operand" "=f")
9952         (neg:XF (float_extend:XF
9953                   (match_operand:SF 1 "register_operand" "0"))))]
9954   "TARGET_80387"
9955   "fchs"
9956   [(set_attr "type" "fsgn")
9957    (set_attr "mode" "XF")])
9959 ;; Absolute value instructions
9961 (define_expand "abssf2"
9962   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9963                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9964               (clobber (reg:CC FLAGS_REG))])]
9965   "TARGET_80387"
9966   "if (TARGET_SSE)
9967      {
9968        /* In case operand is in memory,  we will not use SSE.  */
9969        if (memory_operand (operands[0], VOIDmode)
9970            && rtx_equal_p (operands[0], operands[1]))
9971          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9972        else
9973         {
9974           /* Using SSE is tricky, since we need bitwise negation of -0
9975              in register.  */
9976           rtx reg = gen_reg_rtx (V4SFmode);
9977           rtx dest = operands[0];
9978           rtx imm;
9980           operands[1] = force_reg (SFmode, operands[1]);
9981           operands[0] = force_reg (SFmode, operands[0]);
9982           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9983           reg = force_reg (V4SFmode,
9984                            gen_rtx_CONST_VECTOR (V4SFmode,
9985                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
9986                                       CONST0_RTX (SFmode),
9987                                       CONST0_RTX (SFmode))));
9988           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9989           if (dest != operands[0])
9990             emit_move_insn (dest, operands[0]);
9991         }
9992        DONE;
9993      }
9994    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9996 (define_insn "abssf2_memory"
9997   [(set (match_operand:SF 0 "memory_operand" "=m")
9998         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9999    (clobber (reg:CC FLAGS_REG))]
10000   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10001   "#")
10003 (define_insn "abssf2_ifs"
10004   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10005         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10006    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10007    (clobber (reg:CC FLAGS_REG))]
10008   "TARGET_SSE
10009    && (reload_in_progress || reload_completed
10010        || (register_operand (operands[0], VOIDmode)
10011             && register_operand (operands[1], VOIDmode)))"
10012   "#")
10014 (define_split
10015   [(set (match_operand:SF 0 "memory_operand" "")
10016         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10017    (use (match_operand:V4SF 2 "" ""))
10018    (clobber (reg:CC FLAGS_REG))]
10019   ""
10020   [(parallel [(set (match_dup 0)
10021                    (abs:SF (match_dup 1)))
10022               (clobber (reg:CC FLAGS_REG))])])
10024 (define_split
10025   [(set (match_operand:SF 0 "register_operand" "")
10026         (abs:SF (match_operand:SF 1 "register_operand" "")))
10027    (use (match_operand:V4SF 2 "" ""))
10028    (clobber (reg:CC FLAGS_REG))]
10029   "reload_completed && !SSE_REG_P (operands[0])"
10030   [(parallel [(set (match_dup 0)
10031                    (abs:SF (match_dup 1)))
10032               (clobber (reg:CC FLAGS_REG))])])
10034 (define_split
10035   [(set (match_operand:SF 0 "register_operand" "")
10036         (abs:SF (match_operand:SF 1 "register_operand" "")))
10037    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10038    (clobber (reg:CC FLAGS_REG))]
10039   "reload_completed && SSE_REG_P (operands[0])"
10040   [(set (match_dup 0)
10041         (and:V4SF (match_dup 1)
10042                   (match_dup 2)))]
10044   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10045   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10046   if (operands_match_p (operands[0], operands[2]))
10047     {
10048       rtx tmp;
10049       tmp = operands[1];
10050       operands[1] = operands[2];
10051       operands[2] = tmp;
10052     }
10055 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10056 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10057 ;; to itself.
10058 (define_insn "*abssf2_if"
10059   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10060         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10061    (clobber (reg:CC FLAGS_REG))]
10062   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10063   "#")
10065 (define_split
10066   [(set (match_operand:SF 0 "fp_register_operand" "")
10067         (abs:SF (match_operand:SF 1 "register_operand" "")))
10068    (clobber (reg:CC FLAGS_REG))]
10069   "TARGET_80387 && reload_completed"
10070   [(set (match_dup 0)
10071         (abs:SF (match_dup 1)))]
10072   "")
10074 (define_split
10075   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10076         (abs:SF (match_operand:SF 1 "register_operand" "")))
10077    (clobber (reg:CC FLAGS_REG))]
10078   "TARGET_80387 && reload_completed"
10079   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10080               (clobber (reg:CC FLAGS_REG))])]
10081   "operands[1] = gen_int_mode (~0x80000000, SImode);
10082    operands[0] = gen_lowpart (SImode, operands[0]);")
10084 (define_split
10085   [(set (match_operand 0 "memory_operand" "")
10086         (abs (match_operand 1 "memory_operand" "")))
10087    (clobber (reg:CC FLAGS_REG))]
10088   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10089   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10090               (clobber (reg:CC FLAGS_REG))])]
10092   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10094   if (GET_MODE (operands[1]) == XFmode)
10095     size = 10;
10096   operands[0] = adjust_address (operands[0], QImode, size - 1);
10097   operands[1] = gen_int_mode (~0x80, QImode);
10100 (define_expand "absdf2"
10101   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10102                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10103               (clobber (reg:CC FLAGS_REG))])]
10104   "TARGET_80387"
10105   "if (TARGET_SSE2)
10106      {
10107        /* In case operand is in memory,  we will not use SSE.  */
10108        if (memory_operand (operands[0], VOIDmode)
10109            && rtx_equal_p (operands[0], operands[1]))
10110          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10111        else
10112         {
10113           /* Using SSE is tricky, since we need bitwise negation of -0
10114              in register.  */
10115           rtx reg = gen_reg_rtx (V2DFmode);
10116 #if HOST_BITS_PER_WIDE_INT >= 64
10117           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10118 #else
10119           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10120 #endif
10121           rtx dest = operands[0];
10123           operands[1] = force_reg (DFmode, operands[1]);
10124           operands[0] = force_reg (DFmode, operands[0]);
10126           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10127           imm = gen_lowpart (DFmode, imm);
10128           reg = force_reg (V2DFmode,
10129                            gen_rtx_CONST_VECTOR (V2DFmode,
10130                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10131           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10132           if (dest != operands[0])
10133             emit_move_insn (dest, operands[0]);
10134         }
10135        DONE;
10136      }
10137    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10139 (define_insn "absdf2_memory"
10140   [(set (match_operand:DF 0 "memory_operand" "=m")
10141         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10142    (clobber (reg:CC FLAGS_REG))]
10143   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10144   "#")
10146 (define_insn "absdf2_ifs"
10147   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10148         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10149    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10150    (clobber (reg:CC FLAGS_REG))]
10151   "!TARGET_64BIT && TARGET_SSE2
10152    && (reload_in_progress || reload_completed
10153        || (register_operand (operands[0], VOIDmode)
10154            && register_operand (operands[1], VOIDmode)))"
10155   "#")
10157 (define_insn "*absdf2_ifs_rex64"
10158   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10159         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10160    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10161    (clobber (reg:CC FLAGS_REG))]
10162   "TARGET_64BIT && TARGET_SSE2
10163    && (reload_in_progress || reload_completed
10164        || (register_operand (operands[0], VOIDmode)
10165            && register_operand (operands[1], VOIDmode)))"
10166   "#")
10168 (define_split
10169   [(set (match_operand:DF 0 "memory_operand" "")
10170         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10171    (use (match_operand:V2DF 2 "" ""))
10172    (clobber (reg:CC FLAGS_REG))]
10173   ""
10174   [(parallel [(set (match_dup 0)
10175                    (abs:DF (match_dup 1)))
10176               (clobber (reg:CC FLAGS_REG))])])
10178 (define_split
10179   [(set (match_operand:DF 0 "register_operand" "")
10180         (abs:DF (match_operand:DF 1 "register_operand" "")))
10181    (use (match_operand:V2DF 2 "" ""))
10182    (clobber (reg:CC FLAGS_REG))]
10183   "reload_completed && !SSE_REG_P (operands[0])"
10184   [(parallel [(set (match_dup 0)
10185                    (abs:DF (match_dup 1)))
10186               (clobber (reg:CC FLAGS_REG))])])
10188 (define_split
10189   [(set (match_operand:DF 0 "register_operand" "")
10190         (abs:DF (match_operand:DF 1 "register_operand" "")))
10191    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10192    (clobber (reg:CC FLAGS_REG))]
10193   "reload_completed && SSE_REG_P (operands[0])"
10194   [(set (match_dup 0)
10195         (and:V2DF (match_dup 1)
10196                   (match_dup 2)))]
10198   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10199   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10200   /* Avoid possible reformatting on the operands.  */
10201   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10202     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10203   if (operands_match_p (operands[0], operands[2]))
10204     {
10205       rtx tmp;
10206       tmp = operands[1];
10207       operands[1] = operands[2];
10208       operands[2] = tmp;
10209     }
10213 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10214 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10215 ;; to itself.
10216 (define_insn "*absdf2_if"
10217   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10218         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10219    (clobber (reg:CC FLAGS_REG))]
10220   "!TARGET_64BIT && TARGET_80387
10221    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10222   "#")
10224 ;; FIXME: We should to allow integer registers here.  Problem is that
10225 ;; we need another scratch register to get constant from.
10226 ;; Forcing constant to mem if no register available in peep2 should be
10227 ;; safe even for PIC mode, because of RIP relative addressing.
10228 (define_insn "*absdf2_if_rex64"
10229   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10230         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10231    (clobber (reg:CC FLAGS_REG))]
10232   "TARGET_64BIT && TARGET_80387
10233    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10234   "#")
10236 (define_split
10237   [(set (match_operand:DF 0 "fp_register_operand" "")
10238         (abs:DF (match_operand:DF 1 "register_operand" "")))
10239    (clobber (reg:CC FLAGS_REG))]
10240   "TARGET_80387 && reload_completed"
10241   [(set (match_dup 0)
10242         (abs:DF (match_dup 1)))]
10243   "")
10245 (define_split
10246   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10247         (abs:DF (match_operand:DF 1 "register_operand" "")))
10248    (clobber (reg:CC FLAGS_REG))]
10249   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10250   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10251               (clobber (reg:CC FLAGS_REG))])]
10252   "operands[4] = gen_int_mode (~0x80000000, SImode);
10253    split_di (operands+0, 1, operands+2, operands+3);")
10255 (define_expand "absxf2"
10256   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10257                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10258               (clobber (reg:CC FLAGS_REG))])]
10259   "TARGET_80387"
10260   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10262 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10263 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10264 ;; to itself.
10265 (define_insn "*absxf2_if"
10266   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10267         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10268    (clobber (reg:CC FLAGS_REG))]
10269   "TARGET_80387
10270    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10271   "#")
10273 (define_split
10274   [(set (match_operand:XF 0 "fp_register_operand" "")
10275         (abs:XF (match_operand:XF 1 "register_operand" "")))
10276    (clobber (reg:CC FLAGS_REG))]
10277   "TARGET_80387 && reload_completed"
10278   [(set (match_dup 0)
10279         (abs:XF (match_dup 1)))]
10280   "")
10282 (define_split
10283   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10284         (abs:XF (match_operand:XF 1 "register_operand" "")))
10285    (clobber (reg:CC FLAGS_REG))]
10286   "TARGET_80387 && reload_completed"
10287   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10288               (clobber (reg:CC FLAGS_REG))])]
10289   "operands[1] = GEN_INT (~0x8000);
10290    operands[0] = gen_rtx_REG (SImode,
10291                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10293 (define_insn "*abssf2_1"
10294   [(set (match_operand:SF 0 "register_operand" "=f")
10295         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10296   "TARGET_80387 && reload_completed"
10297   "fabs"
10298   [(set_attr "type" "fsgn")
10299    (set_attr "mode" "SF")])
10301 (define_insn "*absdf2_1"
10302   [(set (match_operand:DF 0 "register_operand" "=f")
10303         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10304   "TARGET_80387 && reload_completed"
10305   "fabs"
10306   [(set_attr "type" "fsgn")
10307    (set_attr "mode" "DF")])
10309 (define_insn "*absextendsfdf2"
10310   [(set (match_operand:DF 0 "register_operand" "=f")
10311         (abs:DF (float_extend:DF
10312                   (match_operand:SF 1 "register_operand" "0"))))]
10313   "TARGET_80387"
10314   "fabs"
10315   [(set_attr "type" "fsgn")
10316    (set_attr "mode" "DF")])
10318 (define_insn "*absxf2_1"
10319   [(set (match_operand:XF 0 "register_operand" "=f")
10320         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10321   "TARGET_80387 && reload_completed"
10322   "fabs"
10323   [(set_attr "type" "fsgn")
10324    (set_attr "mode" "DF")])
10326 (define_insn "*absextenddfxf2"
10327   [(set (match_operand:XF 0 "register_operand" "=f")
10328         (abs:XF (float_extend:XF
10329           (match_operand:DF 1 "register_operand" "0"))))]
10330   "TARGET_80387"
10331   "fabs"
10332   [(set_attr "type" "fsgn")
10333    (set_attr "mode" "XF")])
10335 (define_insn "*absextendsfxf2"
10336   [(set (match_operand:XF 0 "register_operand" "=f")
10337         (abs:XF (float_extend:XF
10338           (match_operand:SF 1 "register_operand" "0"))))]
10339   "TARGET_80387"
10340   "fabs"
10341   [(set_attr "type" "fsgn")
10342    (set_attr "mode" "XF")])
10344 ;; One complement instructions
10346 (define_expand "one_cmpldi2"
10347   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10348         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10349   "TARGET_64BIT"
10350   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10352 (define_insn "*one_cmpldi2_1_rex64"
10353   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10354         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10355   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10356   "not{q}\t%0"
10357   [(set_attr "type" "negnot")
10358    (set_attr "mode" "DI")])
10360 (define_insn "*one_cmpldi2_2_rex64"
10361   [(set (reg FLAGS_REG)
10362         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10363                  (const_int 0)))
10364    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10365         (not:DI (match_dup 1)))]
10366   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10367    && ix86_unary_operator_ok (NOT, DImode, operands)"
10368   "#"
10369   [(set_attr "type" "alu1")
10370    (set_attr "mode" "DI")])
10372 (define_split
10373   [(set (match_operand 0 "flags_reg_operand" "")
10374         (match_operator 2 "compare_operator"
10375           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10376            (const_int 0)]))
10377    (set (match_operand:DI 1 "nonimmediate_operand" "")
10378         (not:DI (match_dup 3)))]
10379   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10380   [(parallel [(set (match_dup 0)
10381                    (match_op_dup 2
10382                      [(xor:DI (match_dup 3) (const_int -1))
10383                       (const_int 0)]))
10384               (set (match_dup 1)
10385                    (xor:DI (match_dup 3) (const_int -1)))])]
10386   "")
10388 (define_expand "one_cmplsi2"
10389   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10390         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10391   ""
10392   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10394 (define_insn "*one_cmplsi2_1"
10395   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10396         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10397   "ix86_unary_operator_ok (NOT, SImode, operands)"
10398   "not{l}\t%0"
10399   [(set_attr "type" "negnot")
10400    (set_attr "mode" "SI")])
10402 ;; ??? Currently never generated - xor is used instead.
10403 (define_insn "*one_cmplsi2_1_zext"
10404   [(set (match_operand:DI 0 "register_operand" "=r")
10405         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10406   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10407   "not{l}\t%k0"
10408   [(set_attr "type" "negnot")
10409    (set_attr "mode" "SI")])
10411 (define_insn "*one_cmplsi2_2"
10412   [(set (reg FLAGS_REG)
10413         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10414                  (const_int 0)))
10415    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10416         (not:SI (match_dup 1)))]
10417   "ix86_match_ccmode (insn, CCNOmode)
10418    && ix86_unary_operator_ok (NOT, SImode, operands)"
10419   "#"
10420   [(set_attr "type" "alu1")
10421    (set_attr "mode" "SI")])
10423 (define_split
10424   [(set (match_operand 0 "flags_reg_operand" "")
10425         (match_operator 2 "compare_operator"
10426           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10427            (const_int 0)]))
10428    (set (match_operand:SI 1 "nonimmediate_operand" "")
10429         (not:SI (match_dup 3)))]
10430   "ix86_match_ccmode (insn, CCNOmode)"
10431   [(parallel [(set (match_dup 0)
10432                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10433                                     (const_int 0)]))
10434               (set (match_dup 1)
10435                    (xor:SI (match_dup 3) (const_int -1)))])]
10436   "")
10438 ;; ??? Currently never generated - xor is used instead.
10439 (define_insn "*one_cmplsi2_2_zext"
10440   [(set (reg FLAGS_REG)
10441         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10442                  (const_int 0)))
10443    (set (match_operand:DI 0 "register_operand" "=r")
10444         (zero_extend:DI (not:SI (match_dup 1))))]
10445   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10446    && ix86_unary_operator_ok (NOT, SImode, operands)"
10447   "#"
10448   [(set_attr "type" "alu1")
10449    (set_attr "mode" "SI")])
10451 (define_split
10452   [(set (match_operand 0 "flags_reg_operand" "")
10453         (match_operator 2 "compare_operator"
10454           [(not:SI (match_operand:SI 3 "register_operand" ""))
10455            (const_int 0)]))
10456    (set (match_operand:DI 1 "register_operand" "")
10457         (zero_extend:DI (not:SI (match_dup 3))))]
10458   "ix86_match_ccmode (insn, CCNOmode)"
10459   [(parallel [(set (match_dup 0)
10460                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10461                                     (const_int 0)]))
10462               (set (match_dup 1)
10463                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10464   "")
10466 (define_expand "one_cmplhi2"
10467   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10468         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10469   "TARGET_HIMODE_MATH"
10470   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10472 (define_insn "*one_cmplhi2_1"
10473   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10474         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10475   "ix86_unary_operator_ok (NOT, HImode, operands)"
10476   "not{w}\t%0"
10477   [(set_attr "type" "negnot")
10478    (set_attr "mode" "HI")])
10480 (define_insn "*one_cmplhi2_2"
10481   [(set (reg FLAGS_REG)
10482         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10483                  (const_int 0)))
10484    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10485         (not:HI (match_dup 1)))]
10486   "ix86_match_ccmode (insn, CCNOmode)
10487    && ix86_unary_operator_ok (NEG, HImode, operands)"
10488   "#"
10489   [(set_attr "type" "alu1")
10490    (set_attr "mode" "HI")])
10492 (define_split
10493   [(set (match_operand 0 "flags_reg_operand" "")
10494         (match_operator 2 "compare_operator"
10495           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10496            (const_int 0)]))
10497    (set (match_operand:HI 1 "nonimmediate_operand" "")
10498         (not:HI (match_dup 3)))]
10499   "ix86_match_ccmode (insn, CCNOmode)"
10500   [(parallel [(set (match_dup 0)
10501                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10502                                     (const_int 0)]))
10503               (set (match_dup 1)
10504                    (xor:HI (match_dup 3) (const_int -1)))])]
10505   "")
10507 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10508 (define_expand "one_cmplqi2"
10509   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10510         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10511   "TARGET_QIMODE_MATH"
10512   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10514 (define_insn "*one_cmplqi2_1"
10515   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10516         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10517   "ix86_unary_operator_ok (NOT, QImode, operands)"
10518   "@
10519    not{b}\t%0
10520    not{l}\t%k0"
10521   [(set_attr "type" "negnot")
10522    (set_attr "mode" "QI,SI")])
10524 (define_insn "*one_cmplqi2_2"
10525   [(set (reg FLAGS_REG)
10526         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10527                  (const_int 0)))
10528    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10529         (not:QI (match_dup 1)))]
10530   "ix86_match_ccmode (insn, CCNOmode)
10531    && ix86_unary_operator_ok (NOT, QImode, operands)"
10532   "#"
10533   [(set_attr "type" "alu1")
10534    (set_attr "mode" "QI")])
10536 (define_split
10537   [(set (match_operand 0 "flags_reg_operand" "")
10538         (match_operator 2 "compare_operator"
10539           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10540            (const_int 0)]))
10541    (set (match_operand:QI 1 "nonimmediate_operand" "")
10542         (not:QI (match_dup 3)))]
10543   "ix86_match_ccmode (insn, CCNOmode)"
10544   [(parallel [(set (match_dup 0)
10545                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10546                                     (const_int 0)]))
10547               (set (match_dup 1)
10548                    (xor:QI (match_dup 3) (const_int -1)))])]
10549   "")
10551 ;; Arithmetic shift instructions
10553 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10554 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10555 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10556 ;; from the assembler input.
10558 ;; This instruction shifts the target reg/mem as usual, but instead of
10559 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10560 ;; is a left shift double, bits are taken from the high order bits of
10561 ;; reg, else if the insn is a shift right double, bits are taken from the
10562 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10563 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10565 ;; Since sh[lr]d does not change the `reg' operand, that is done
10566 ;; separately, making all shifts emit pairs of shift double and normal
10567 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10568 ;; support a 63 bit shift, each shift where the count is in a reg expands
10569 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10571 ;; If the shift count is a constant, we need never emit more than one
10572 ;; shift pair, instead using moves and sign extension for counts greater
10573 ;; than 31.
10575 (define_expand "ashldi3"
10576   [(set (match_operand:DI 0 "shiftdi_operand" "")
10577         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10578                    (match_operand:QI 2 "nonmemory_operand" "")))]
10579   ""
10580   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10582 (define_insn "*ashldi3_1_rex64"
10583   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10584         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10585                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10586    (clobber (reg:CC FLAGS_REG))]
10587   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10589   switch (get_attr_type (insn))
10590     {
10591     case TYPE_ALU:
10592       if (operands[2] != const1_rtx)
10593         abort ();
10594       if (!rtx_equal_p (operands[0], operands[1]))
10595         abort ();
10596       return "add{q}\t{%0, %0|%0, %0}";
10598     case TYPE_LEA:
10599       if (GET_CODE (operands[2]) != CONST_INT
10600           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10601         abort ();
10602       operands[1] = gen_rtx_MULT (DImode, operands[1],
10603                                   GEN_INT (1 << INTVAL (operands[2])));
10604       return "lea{q}\t{%a1, %0|%0, %a1}";
10606     default:
10607       if (REG_P (operands[2]))
10608         return "sal{q}\t{%b2, %0|%0, %b2}";
10609       else if (operands[2] == const1_rtx
10610                && (TARGET_SHIFT1 || optimize_size))
10611         return "sal{q}\t%0";
10612       else
10613         return "sal{q}\t{%2, %0|%0, %2}";
10614     }
10616   [(set (attr "type")
10617      (cond [(eq_attr "alternative" "1")
10618               (const_string "lea")
10619             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10620                           (const_int 0))
10621                       (match_operand 0 "register_operand" ""))
10622                  (match_operand 2 "const1_operand" ""))
10623               (const_string "alu")
10624            ]
10625            (const_string "ishift")))
10626    (set_attr "mode" "DI")])
10628 ;; Convert lea to the lea pattern to avoid flags dependency.
10629 (define_split
10630   [(set (match_operand:DI 0 "register_operand" "")
10631         (ashift:DI (match_operand:DI 1 "register_operand" "")
10632                    (match_operand:QI 2 "immediate_operand" "")))
10633    (clobber (reg:CC FLAGS_REG))]
10634   "TARGET_64BIT && reload_completed
10635    && true_regnum (operands[0]) != true_regnum (operands[1])"
10636   [(set (match_dup 0)
10637         (mult:DI (match_dup 1)
10638                  (match_dup 2)))]
10639   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10641 ;; This pattern can't accept a variable shift count, since shifts by
10642 ;; zero don't affect the flags.  We assume that shifts by constant
10643 ;; zero are optimized away.
10644 (define_insn "*ashldi3_cmp_rex64"
10645   [(set (reg FLAGS_REG)
10646         (compare
10647           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10648                      (match_operand:QI 2 "immediate_operand" "e"))
10649           (const_int 0)))
10650    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10651         (ashift:DI (match_dup 1) (match_dup 2)))]
10652   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10653    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10655   switch (get_attr_type (insn))
10656     {
10657     case TYPE_ALU:
10658       if (operands[2] != const1_rtx)
10659         abort ();
10660       return "add{q}\t{%0, %0|%0, %0}";
10662     default:
10663       if (REG_P (operands[2]))
10664         return "sal{q}\t{%b2, %0|%0, %b2}";
10665       else if (operands[2] == const1_rtx
10666                && (TARGET_SHIFT1 || optimize_size))
10667         return "sal{q}\t%0";
10668       else
10669         return "sal{q}\t{%2, %0|%0, %2}";
10670     }
10672   [(set (attr "type")
10673      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10674                           (const_int 0))
10675                       (match_operand 0 "register_operand" ""))
10676                  (match_operand 2 "const1_operand" ""))
10677               (const_string "alu")
10678            ]
10679            (const_string "ishift")))
10680    (set_attr "mode" "DI")])
10682 (define_insn "*ashldi3_1"
10683   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10684         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10685                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10686    (clobber (reg:CC FLAGS_REG))]
10687   "!TARGET_64BIT"
10688   "#"
10689   [(set_attr "type" "multi")])
10691 ;; By default we don't ask for a scratch register, because when DImode
10692 ;; values are manipulated, registers are already at a premium.  But if
10693 ;; we have one handy, we won't turn it away.
10694 (define_peephole2
10695   [(match_scratch:SI 3 "r")
10696    (parallel [(set (match_operand:DI 0 "register_operand" "")
10697                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10698                               (match_operand:QI 2 "nonmemory_operand" "")))
10699               (clobber (reg:CC FLAGS_REG))])
10700    (match_dup 3)]
10701   "!TARGET_64BIT && TARGET_CMOVE"
10702   [(const_int 0)]
10703   "ix86_split_ashldi (operands, operands[3]); DONE;")
10705 (define_split
10706   [(set (match_operand:DI 0 "register_operand" "")
10707         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10708                    (match_operand:QI 2 "nonmemory_operand" "")))
10709    (clobber (reg:CC FLAGS_REG))]
10710   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10711   [(const_int 0)]
10712   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10714 (define_insn "x86_shld_1"
10715   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10716         (ior:SI (ashift:SI (match_dup 0)
10717                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10718                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10719                   (minus:QI (const_int 32) (match_dup 2)))))
10720    (clobber (reg:CC FLAGS_REG))]
10721   ""
10722   "@
10723    shld{l}\t{%2, %1, %0|%0, %1, %2}
10724    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10725   [(set_attr "type" "ishift")
10726    (set_attr "prefix_0f" "1")
10727    (set_attr "mode" "SI")
10728    (set_attr "pent_pair" "np")
10729    (set_attr "athlon_decode" "vector")])
10731 (define_expand "x86_shift_adj_1"
10732   [(set (reg:CCZ FLAGS_REG)
10733         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10734                              (const_int 32))
10735                      (const_int 0)))
10736    (set (match_operand:SI 0 "register_operand" "")
10737         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10738                          (match_operand:SI 1 "register_operand" "")
10739                          (match_dup 0)))
10740    (set (match_dup 1)
10741         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10742                          (match_operand:SI 3 "register_operand" "r")
10743                          (match_dup 1)))]
10744   "TARGET_CMOVE"
10745   "")
10747 (define_expand "x86_shift_adj_2"
10748   [(use (match_operand:SI 0 "register_operand" ""))
10749    (use (match_operand:SI 1 "register_operand" ""))
10750    (use (match_operand:QI 2 "register_operand" ""))]
10751   ""
10753   rtx label = gen_label_rtx ();
10754   rtx tmp;
10756   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10758   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10759   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10760   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10761                               gen_rtx_LABEL_REF (VOIDmode, label),
10762                               pc_rtx);
10763   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10764   JUMP_LABEL (tmp) = label;
10766   emit_move_insn (operands[0], operands[1]);
10767   ix86_expand_clear (operands[1]);
10769   emit_label (label);
10770   LABEL_NUSES (label) = 1;
10772   DONE;
10775 (define_expand "ashlsi3"
10776   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10777         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10778                    (match_operand:QI 2 "nonmemory_operand" "")))
10779    (clobber (reg:CC FLAGS_REG))]
10780   ""
10781   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10783 (define_insn "*ashlsi3_1"
10784   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10785         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10786                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10787    (clobber (reg:CC FLAGS_REG))]
10788   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10790   switch (get_attr_type (insn))
10791     {
10792     case TYPE_ALU:
10793       if (operands[2] != const1_rtx)
10794         abort ();
10795       if (!rtx_equal_p (operands[0], operands[1]))
10796         abort ();
10797       return "add{l}\t{%0, %0|%0, %0}";
10799     case TYPE_LEA:
10800       return "#";
10802     default:
10803       if (REG_P (operands[2]))
10804         return "sal{l}\t{%b2, %0|%0, %b2}";
10805       else if (operands[2] == const1_rtx
10806                && (TARGET_SHIFT1 || optimize_size))
10807         return "sal{l}\t%0";
10808       else
10809         return "sal{l}\t{%2, %0|%0, %2}";
10810     }
10812   [(set (attr "type")
10813      (cond [(eq_attr "alternative" "1")
10814               (const_string "lea")
10815             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10816                           (const_int 0))
10817                       (match_operand 0 "register_operand" ""))
10818                  (match_operand 2 "const1_operand" ""))
10819               (const_string "alu")
10820            ]
10821            (const_string "ishift")))
10822    (set_attr "mode" "SI")])
10824 ;; Convert lea to the lea pattern to avoid flags dependency.
10825 (define_split
10826   [(set (match_operand 0 "register_operand" "")
10827         (ashift (match_operand 1 "index_register_operand" "")
10828                 (match_operand:QI 2 "const_int_operand" "")))
10829    (clobber (reg:CC FLAGS_REG))]
10830   "reload_completed
10831    && true_regnum (operands[0]) != true_regnum (operands[1])"
10832   [(const_int 0)]
10834   rtx pat;
10835   operands[0] = gen_lowpart (SImode, operands[0]);
10836   operands[1] = gen_lowpart (Pmode, operands[1]);
10837   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10838   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10839   if (Pmode != SImode)
10840     pat = gen_rtx_SUBREG (SImode, pat, 0);
10841   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10842   DONE;
10845 ;; Rare case of shifting RSP is handled by generating move and shift
10846 (define_split
10847   [(set (match_operand 0 "register_operand" "")
10848         (ashift (match_operand 1 "register_operand" "")
10849                 (match_operand:QI 2 "const_int_operand" "")))
10850    (clobber (reg:CC FLAGS_REG))]
10851   "reload_completed
10852    && true_regnum (operands[0]) != true_regnum (operands[1])"
10853   [(const_int 0)]
10855   rtx pat, clob;
10856   emit_move_insn (operands[1], operands[0]);
10857   pat = gen_rtx_SET (VOIDmode, operands[0],
10858                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10859                                      operands[0], operands[2]));
10860   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10861   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10862   DONE;
10865 (define_insn "*ashlsi3_1_zext"
10866   [(set (match_operand:DI 0 "register_operand" "=r,r")
10867         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10868                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10869    (clobber (reg:CC FLAGS_REG))]
10870   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10872   switch (get_attr_type (insn))
10873     {
10874     case TYPE_ALU:
10875       if (operands[2] != const1_rtx)
10876         abort ();
10877       return "add{l}\t{%k0, %k0|%k0, %k0}";
10879     case TYPE_LEA:
10880       return "#";
10882     default:
10883       if (REG_P (operands[2]))
10884         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10885       else if (operands[2] == const1_rtx
10886                && (TARGET_SHIFT1 || optimize_size))
10887         return "sal{l}\t%k0";
10888       else
10889         return "sal{l}\t{%2, %k0|%k0, %2}";
10890     }
10892   [(set (attr "type")
10893      (cond [(eq_attr "alternative" "1")
10894               (const_string "lea")
10895             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10896                      (const_int 0))
10897                  (match_operand 2 "const1_operand" ""))
10898               (const_string "alu")
10899            ]
10900            (const_string "ishift")))
10901    (set_attr "mode" "SI")])
10903 ;; Convert lea to the lea pattern to avoid flags dependency.
10904 (define_split
10905   [(set (match_operand:DI 0 "register_operand" "")
10906         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10907                                 (match_operand:QI 2 "const_int_operand" ""))))
10908    (clobber (reg:CC FLAGS_REG))]
10909   "TARGET_64BIT && reload_completed
10910    && true_regnum (operands[0]) != true_regnum (operands[1])"
10911   [(set (match_dup 0) (zero_extend:DI
10912                         (subreg:SI (mult:SI (match_dup 1)
10913                                             (match_dup 2)) 0)))]
10915   operands[1] = gen_lowpart (Pmode, operands[1]);
10916   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10919 ;; This pattern can't accept a variable shift count, since shifts by
10920 ;; zero don't affect the flags.  We assume that shifts by constant
10921 ;; zero are optimized away.
10922 (define_insn "*ashlsi3_cmp"
10923   [(set (reg FLAGS_REG)
10924         (compare
10925           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10926                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10927           (const_int 0)))
10928    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10929         (ashift:SI (match_dup 1) (match_dup 2)))]
10930   "ix86_match_ccmode (insn, CCGOCmode)
10931    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10933   switch (get_attr_type (insn))
10934     {
10935     case TYPE_ALU:
10936       if (operands[2] != const1_rtx)
10937         abort ();
10938       return "add{l}\t{%0, %0|%0, %0}";
10940     default:
10941       if (REG_P (operands[2]))
10942         return "sal{l}\t{%b2, %0|%0, %b2}";
10943       else if (operands[2] == const1_rtx
10944                && (TARGET_SHIFT1 || optimize_size))
10945         return "sal{l}\t%0";
10946       else
10947         return "sal{l}\t{%2, %0|%0, %2}";
10948     }
10950   [(set (attr "type")
10951      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10952                           (const_int 0))
10953                       (match_operand 0 "register_operand" ""))
10954                  (match_operand 2 "const1_operand" ""))
10955               (const_string "alu")
10956            ]
10957            (const_string "ishift")))
10958    (set_attr "mode" "SI")])
10960 (define_insn "*ashlsi3_cmp_zext"
10961   [(set (reg FLAGS_REG)
10962         (compare
10963           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10964                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10965           (const_int 0)))
10966    (set (match_operand:DI 0 "register_operand" "=r")
10967         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10968   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10969    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10971   switch (get_attr_type (insn))
10972     {
10973     case TYPE_ALU:
10974       if (operands[2] != const1_rtx)
10975         abort ();
10976       return "add{l}\t{%k0, %k0|%k0, %k0}";
10978     default:
10979       if (REG_P (operands[2]))
10980         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10981       else if (operands[2] == const1_rtx
10982                && (TARGET_SHIFT1 || optimize_size))
10983         return "sal{l}\t%k0";
10984       else
10985         return "sal{l}\t{%2, %k0|%k0, %2}";
10986     }
10988   [(set (attr "type")
10989      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10990                      (const_int 0))
10991                  (match_operand 2 "const1_operand" ""))
10992               (const_string "alu")
10993            ]
10994            (const_string "ishift")))
10995    (set_attr "mode" "SI")])
10997 (define_expand "ashlhi3"
10998   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10999         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11000                    (match_operand:QI 2 "nonmemory_operand" "")))
11001    (clobber (reg:CC FLAGS_REG))]
11002   "TARGET_HIMODE_MATH"
11003   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11005 (define_insn "*ashlhi3_1_lea"
11006   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11007         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11008                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11009    (clobber (reg:CC FLAGS_REG))]
11010   "!TARGET_PARTIAL_REG_STALL
11011    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11013   switch (get_attr_type (insn))
11014     {
11015     case TYPE_LEA:
11016       return "#";
11017     case TYPE_ALU:
11018       if (operands[2] != const1_rtx)
11019         abort ();
11020       return "add{w}\t{%0, %0|%0, %0}";
11022     default:
11023       if (REG_P (operands[2]))
11024         return "sal{w}\t{%b2, %0|%0, %b2}";
11025       else if (operands[2] == const1_rtx
11026                && (TARGET_SHIFT1 || optimize_size))
11027         return "sal{w}\t%0";
11028       else
11029         return "sal{w}\t{%2, %0|%0, %2}";
11030     }
11032   [(set (attr "type")
11033      (cond [(eq_attr "alternative" "1")
11034               (const_string "lea")
11035             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11036                           (const_int 0))
11037                       (match_operand 0 "register_operand" ""))
11038                  (match_operand 2 "const1_operand" ""))
11039               (const_string "alu")
11040            ]
11041            (const_string "ishift")))
11042    (set_attr "mode" "HI,SI")])
11044 (define_insn "*ashlhi3_1"
11045   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11046         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11047                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11048    (clobber (reg:CC FLAGS_REG))]
11049   "TARGET_PARTIAL_REG_STALL
11050    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11052   switch (get_attr_type (insn))
11053     {
11054     case TYPE_ALU:
11055       if (operands[2] != const1_rtx)
11056         abort ();
11057       return "add{w}\t{%0, %0|%0, %0}";
11059     default:
11060       if (REG_P (operands[2]))
11061         return "sal{w}\t{%b2, %0|%0, %b2}";
11062       else if (operands[2] == const1_rtx
11063                && (TARGET_SHIFT1 || optimize_size))
11064         return "sal{w}\t%0";
11065       else
11066         return "sal{w}\t{%2, %0|%0, %2}";
11067     }
11069   [(set (attr "type")
11070      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11071                           (const_int 0))
11072                       (match_operand 0 "register_operand" ""))
11073                  (match_operand 2 "const1_operand" ""))
11074               (const_string "alu")
11075            ]
11076            (const_string "ishift")))
11077    (set_attr "mode" "HI")])
11079 ;; This pattern can't accept a variable shift count, since shifts by
11080 ;; zero don't affect the flags.  We assume that shifts by constant
11081 ;; zero are optimized away.
11082 (define_insn "*ashlhi3_cmp"
11083   [(set (reg FLAGS_REG)
11084         (compare
11085           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11086                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11087           (const_int 0)))
11088    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11089         (ashift:HI (match_dup 1) (match_dup 2)))]
11090   "ix86_match_ccmode (insn, CCGOCmode)
11091    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11093   switch (get_attr_type (insn))
11094     {
11095     case TYPE_ALU:
11096       if (operands[2] != const1_rtx)
11097         abort ();
11098       return "add{w}\t{%0, %0|%0, %0}";
11100     default:
11101       if (REG_P (operands[2]))
11102         return "sal{w}\t{%b2, %0|%0, %b2}";
11103       else if (operands[2] == const1_rtx
11104                && (TARGET_SHIFT1 || optimize_size))
11105         return "sal{w}\t%0";
11106       else
11107         return "sal{w}\t{%2, %0|%0, %2}";
11108     }
11110   [(set (attr "type")
11111      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11112                           (const_int 0))
11113                       (match_operand 0 "register_operand" ""))
11114                  (match_operand 2 "const1_operand" ""))
11115               (const_string "alu")
11116            ]
11117            (const_string "ishift")))
11118    (set_attr "mode" "HI")])
11120 (define_expand "ashlqi3"
11121   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11122         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11123                    (match_operand:QI 2 "nonmemory_operand" "")))
11124    (clobber (reg:CC FLAGS_REG))]
11125   "TARGET_QIMODE_MATH"
11126   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11128 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11130 (define_insn "*ashlqi3_1_lea"
11131   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11132         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11133                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11134    (clobber (reg:CC FLAGS_REG))]
11135   "!TARGET_PARTIAL_REG_STALL
11136    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11138   switch (get_attr_type (insn))
11139     {
11140     case TYPE_LEA:
11141       return "#";
11142     case TYPE_ALU:
11143       if (operands[2] != const1_rtx)
11144         abort ();
11145       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11146         return "add{l}\t{%k0, %k0|%k0, %k0}";
11147       else
11148         return "add{b}\t{%0, %0|%0, %0}";
11150     default:
11151       if (REG_P (operands[2]))
11152         {
11153           if (get_attr_mode (insn) == MODE_SI)
11154             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11155           else
11156             return "sal{b}\t{%b2, %0|%0, %b2}";
11157         }
11158       else if (operands[2] == const1_rtx
11159                && (TARGET_SHIFT1 || optimize_size))
11160         {
11161           if (get_attr_mode (insn) == MODE_SI)
11162             return "sal{l}\t%0";
11163           else
11164             return "sal{b}\t%0";
11165         }
11166       else
11167         {
11168           if (get_attr_mode (insn) == MODE_SI)
11169             return "sal{l}\t{%2, %k0|%k0, %2}";
11170           else
11171             return "sal{b}\t{%2, %0|%0, %2}";
11172         }
11173     }
11175   [(set (attr "type")
11176      (cond [(eq_attr "alternative" "2")
11177               (const_string "lea")
11178             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11179                           (const_int 0))
11180                       (match_operand 0 "register_operand" ""))
11181                  (match_operand 2 "const1_operand" ""))
11182               (const_string "alu")
11183            ]
11184            (const_string "ishift")))
11185    (set_attr "mode" "QI,SI,SI")])
11187 (define_insn "*ashlqi3_1"
11188   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11189         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11190                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11191    (clobber (reg:CC FLAGS_REG))]
11192   "TARGET_PARTIAL_REG_STALL
11193    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11195   switch (get_attr_type (insn))
11196     {
11197     case TYPE_ALU:
11198       if (operands[2] != const1_rtx)
11199         abort ();
11200       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11201         return "add{l}\t{%k0, %k0|%k0, %k0}";
11202       else
11203         return "add{b}\t{%0, %0|%0, %0}";
11205     default:
11206       if (REG_P (operands[2]))
11207         {
11208           if (get_attr_mode (insn) == MODE_SI)
11209             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11210           else
11211             return "sal{b}\t{%b2, %0|%0, %b2}";
11212         }
11213       else if (operands[2] == const1_rtx
11214                && (TARGET_SHIFT1 || optimize_size))
11215         {
11216           if (get_attr_mode (insn) == MODE_SI)
11217             return "sal{l}\t%0";
11218           else
11219             return "sal{b}\t%0";
11220         }
11221       else
11222         {
11223           if (get_attr_mode (insn) == MODE_SI)
11224             return "sal{l}\t{%2, %k0|%k0, %2}";
11225           else
11226             return "sal{b}\t{%2, %0|%0, %2}";
11227         }
11228     }
11230   [(set (attr "type")
11231      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11232                           (const_int 0))
11233                       (match_operand 0 "register_operand" ""))
11234                  (match_operand 2 "const1_operand" ""))
11235               (const_string "alu")
11236            ]
11237            (const_string "ishift")))
11238    (set_attr "mode" "QI,SI")])
11240 ;; This pattern can't accept a variable shift count, since shifts by
11241 ;; zero don't affect the flags.  We assume that shifts by constant
11242 ;; zero are optimized away.
11243 (define_insn "*ashlqi3_cmp"
11244   [(set (reg FLAGS_REG)
11245         (compare
11246           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11247                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11248           (const_int 0)))
11249    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11250         (ashift:QI (match_dup 1) (match_dup 2)))]
11251   "ix86_match_ccmode (insn, CCGOCmode)
11252    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11254   switch (get_attr_type (insn))
11255     {
11256     case TYPE_ALU:
11257       if (operands[2] != const1_rtx)
11258         abort ();
11259       return "add{b}\t{%0, %0|%0, %0}";
11261     default:
11262       if (REG_P (operands[2]))
11263         return "sal{b}\t{%b2, %0|%0, %b2}";
11264       else if (operands[2] == const1_rtx
11265                && (TARGET_SHIFT1 || optimize_size))
11266         return "sal{b}\t%0";
11267       else
11268         return "sal{b}\t{%2, %0|%0, %2}";
11269     }
11271   [(set (attr "type")
11272      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11273                           (const_int 0))
11274                       (match_operand 0 "register_operand" ""))
11275                  (match_operand 2 "const1_operand" ""))
11276               (const_string "alu")
11277            ]
11278            (const_string "ishift")))
11279    (set_attr "mode" "QI")])
11281 ;; See comment above `ashldi3' about how this works.
11283 (define_expand "ashrdi3"
11284   [(set (match_operand:DI 0 "shiftdi_operand" "")
11285         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11286                      (match_operand:QI 2 "nonmemory_operand" "")))]
11287   ""
11288   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11290 (define_insn "*ashrdi3_63_rex64"
11291   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11292         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11293                      (match_operand:DI 2 "const_int_operand" "i,i")))
11294    (clobber (reg:CC FLAGS_REG))]
11295   "TARGET_64BIT && INTVAL (operands[2]) == 63
11296    && (TARGET_USE_CLTD || optimize_size)
11297    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11298   "@
11299    {cqto|cqo}
11300    sar{q}\t{%2, %0|%0, %2}"
11301   [(set_attr "type" "imovx,ishift")
11302    (set_attr "prefix_0f" "0,*")
11303    (set_attr "length_immediate" "0,*")
11304    (set_attr "modrm" "0,1")
11305    (set_attr "mode" "DI")])
11307 (define_insn "*ashrdi3_1_one_bit_rex64"
11308   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11309         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11310                      (match_operand:QI 2 "const1_operand" "")))
11311    (clobber (reg:CC FLAGS_REG))]
11312   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11313    && (TARGET_SHIFT1 || optimize_size)"
11314   "sar{q}\t%0"
11315   [(set_attr "type" "ishift")
11316    (set (attr "length") 
11317      (if_then_else (match_operand:DI 0 "register_operand" "") 
11318         (const_string "2")
11319         (const_string "*")))])
11321 (define_insn "*ashrdi3_1_rex64"
11322   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11323         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11324                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11325    (clobber (reg:CC FLAGS_REG))]
11326   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11327   "@
11328    sar{q}\t{%2, %0|%0, %2}
11329    sar{q}\t{%b2, %0|%0, %b2}"
11330   [(set_attr "type" "ishift")
11331    (set_attr "mode" "DI")])
11333 ;; This pattern can't accept a variable shift count, since shifts by
11334 ;; zero don't affect the flags.  We assume that shifts by constant
11335 ;; zero are optimized away.
11336 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11337   [(set (reg FLAGS_REG)
11338         (compare
11339           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11340                        (match_operand:QI 2 "const1_operand" ""))
11341           (const_int 0)))
11342    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11343         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11344   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11345    && (TARGET_SHIFT1 || optimize_size)
11346    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11347   "sar{q}\t%0"
11348   [(set_attr "type" "ishift")
11349    (set (attr "length") 
11350      (if_then_else (match_operand:DI 0 "register_operand" "") 
11351         (const_string "2")
11352         (const_string "*")))])
11354 ;; This pattern can't accept a variable shift count, since shifts by
11355 ;; zero don't affect the flags.  We assume that shifts by constant
11356 ;; zero are optimized away.
11357 (define_insn "*ashrdi3_cmp_rex64"
11358   [(set (reg FLAGS_REG)
11359         (compare
11360           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11361                        (match_operand:QI 2 "const_int_operand" "n"))
11362           (const_int 0)))
11363    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11364         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11365   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11366    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11367   "sar{q}\t{%2, %0|%0, %2}"
11368   [(set_attr "type" "ishift")
11369    (set_attr "mode" "DI")])
11371 (define_insn "*ashrdi3_1"
11372   [(set (match_operand:DI 0 "register_operand" "=r")
11373         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11374                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11375    (clobber (reg:CC FLAGS_REG))]
11376   "!TARGET_64BIT"
11377   "#"
11378   [(set_attr "type" "multi")])
11380 ;; By default we don't ask for a scratch register, because when DImode
11381 ;; values are manipulated, registers are already at a premium.  But if
11382 ;; we have one handy, we won't turn it away.
11383 (define_peephole2
11384   [(match_scratch:SI 3 "r")
11385    (parallel [(set (match_operand:DI 0 "register_operand" "")
11386                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11387                                 (match_operand:QI 2 "nonmemory_operand" "")))
11388               (clobber (reg:CC FLAGS_REG))])
11389    (match_dup 3)]
11390   "!TARGET_64BIT && TARGET_CMOVE"
11391   [(const_int 0)]
11392   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11394 (define_split
11395   [(set (match_operand:DI 0 "register_operand" "")
11396         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11397                      (match_operand:QI 2 "nonmemory_operand" "")))
11398    (clobber (reg:CC FLAGS_REG))]
11399   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11400   [(const_int 0)]
11401   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11403 (define_insn "x86_shrd_1"
11404   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11405         (ior:SI (ashiftrt:SI (match_dup 0)
11406                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11407                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11408                   (minus:QI (const_int 32) (match_dup 2)))))
11409    (clobber (reg:CC FLAGS_REG))]
11410   ""
11411   "@
11412    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11413    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11414   [(set_attr "type" "ishift")
11415    (set_attr "prefix_0f" "1")
11416    (set_attr "pent_pair" "np")
11417    (set_attr "mode" "SI")])
11419 (define_expand "x86_shift_adj_3"
11420   [(use (match_operand:SI 0 "register_operand" ""))
11421    (use (match_operand:SI 1 "register_operand" ""))
11422    (use (match_operand:QI 2 "register_operand" ""))]
11423   ""
11425   rtx label = gen_label_rtx ();
11426   rtx tmp;
11428   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11430   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11431   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11432   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11433                               gen_rtx_LABEL_REF (VOIDmode, label),
11434                               pc_rtx);
11435   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11436   JUMP_LABEL (tmp) = label;
11438   emit_move_insn (operands[0], operands[1]);
11439   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11441   emit_label (label);
11442   LABEL_NUSES (label) = 1;
11444   DONE;
11447 (define_insn "ashrsi3_31"
11448   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11449         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11450                      (match_operand:SI 2 "const_int_operand" "i,i")))
11451    (clobber (reg:CC FLAGS_REG))]
11452   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11453    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11454   "@
11455    {cltd|cdq}
11456    sar{l}\t{%2, %0|%0, %2}"
11457   [(set_attr "type" "imovx,ishift")
11458    (set_attr "prefix_0f" "0,*")
11459    (set_attr "length_immediate" "0,*")
11460    (set_attr "modrm" "0,1")
11461    (set_attr "mode" "SI")])
11463 (define_insn "*ashrsi3_31_zext"
11464   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11465         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11466                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11467    (clobber (reg:CC FLAGS_REG))]
11468   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11469    && INTVAL (operands[2]) == 31
11470    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11471   "@
11472    {cltd|cdq}
11473    sar{l}\t{%2, %k0|%k0, %2}"
11474   [(set_attr "type" "imovx,ishift")
11475    (set_attr "prefix_0f" "0,*")
11476    (set_attr "length_immediate" "0,*")
11477    (set_attr "modrm" "0,1")
11478    (set_attr "mode" "SI")])
11480 (define_expand "ashrsi3"
11481   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11482         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11483                      (match_operand:QI 2 "nonmemory_operand" "")))
11484    (clobber (reg:CC FLAGS_REG))]
11485   ""
11486   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11488 (define_insn "*ashrsi3_1_one_bit"
11489   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11490         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11491                      (match_operand:QI 2 "const1_operand" "")))
11492    (clobber (reg:CC FLAGS_REG))]
11493   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11494    && (TARGET_SHIFT1 || optimize_size)"
11495   "sar{l}\t%0"
11496   [(set_attr "type" "ishift")
11497    (set (attr "length") 
11498      (if_then_else (match_operand:SI 0 "register_operand" "") 
11499         (const_string "2")
11500         (const_string "*")))])
11502 (define_insn "*ashrsi3_1_one_bit_zext"
11503   [(set (match_operand:DI 0 "register_operand" "=r")
11504         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11505                                      (match_operand:QI 2 "const1_operand" ""))))
11506    (clobber (reg:CC FLAGS_REG))]
11507   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11508    && (TARGET_SHIFT1 || optimize_size)"
11509   "sar{l}\t%k0"
11510   [(set_attr "type" "ishift")
11511    (set_attr "length" "2")])
11513 (define_insn "*ashrsi3_1"
11514   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11515         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11516                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11517    (clobber (reg:CC FLAGS_REG))]
11518   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11519   "@
11520    sar{l}\t{%2, %0|%0, %2}
11521    sar{l}\t{%b2, %0|%0, %b2}"
11522   [(set_attr "type" "ishift")
11523    (set_attr "mode" "SI")])
11525 (define_insn "*ashrsi3_1_zext"
11526   [(set (match_operand:DI 0 "register_operand" "=r,r")
11527         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11528                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11529    (clobber (reg:CC FLAGS_REG))]
11530   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11531   "@
11532    sar{l}\t{%2, %k0|%k0, %2}
11533    sar{l}\t{%b2, %k0|%k0, %b2}"
11534   [(set_attr "type" "ishift")
11535    (set_attr "mode" "SI")])
11537 ;; This pattern can't accept a variable shift count, since shifts by
11538 ;; zero don't affect the flags.  We assume that shifts by constant
11539 ;; zero are optimized away.
11540 (define_insn "*ashrsi3_one_bit_cmp"
11541   [(set (reg FLAGS_REG)
11542         (compare
11543           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11544                        (match_operand:QI 2 "const1_operand" ""))
11545           (const_int 0)))
11546    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11547         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11548   "ix86_match_ccmode (insn, CCGOCmode)
11549    && (TARGET_SHIFT1 || optimize_size)
11550    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11551   "sar{l}\t%0"
11552   [(set_attr "type" "ishift")
11553    (set (attr "length") 
11554      (if_then_else (match_operand:SI 0 "register_operand" "") 
11555         (const_string "2")
11556         (const_string "*")))])
11558 (define_insn "*ashrsi3_one_bit_cmp_zext"
11559   [(set (reg FLAGS_REG)
11560         (compare
11561           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11562                        (match_operand:QI 2 "const1_operand" ""))
11563           (const_int 0)))
11564    (set (match_operand:DI 0 "register_operand" "=r")
11565         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11566   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11567    && (TARGET_SHIFT1 || optimize_size)
11568    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11569   "sar{l}\t%k0"
11570   [(set_attr "type" "ishift")
11571    (set_attr "length" "2")])
11573 ;; This pattern can't accept a variable shift count, since shifts by
11574 ;; zero don't affect the flags.  We assume that shifts by constant
11575 ;; zero are optimized away.
11576 (define_insn "*ashrsi3_cmp"
11577   [(set (reg FLAGS_REG)
11578         (compare
11579           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11580                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11581           (const_int 0)))
11582    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11583         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11584   "ix86_match_ccmode (insn, CCGOCmode)
11585    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11586   "sar{l}\t{%2, %0|%0, %2}"
11587   [(set_attr "type" "ishift")
11588    (set_attr "mode" "SI")])
11590 (define_insn "*ashrsi3_cmp_zext"
11591   [(set (reg FLAGS_REG)
11592         (compare
11593           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11594                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11595           (const_int 0)))
11596    (set (match_operand:DI 0 "register_operand" "=r")
11597         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11598   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11599    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11600   "sar{l}\t{%2, %k0|%k0, %2}"
11601   [(set_attr "type" "ishift")
11602    (set_attr "mode" "SI")])
11604 (define_expand "ashrhi3"
11605   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11606         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11607                      (match_operand:QI 2 "nonmemory_operand" "")))
11608    (clobber (reg:CC FLAGS_REG))]
11609   "TARGET_HIMODE_MATH"
11610   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11612 (define_insn "*ashrhi3_1_one_bit"
11613   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11614         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11615                      (match_operand:QI 2 "const1_operand" "")))
11616    (clobber (reg:CC FLAGS_REG))]
11617   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11618    && (TARGET_SHIFT1 || optimize_size)"
11619   "sar{w}\t%0"
11620   [(set_attr "type" "ishift")
11621    (set (attr "length") 
11622      (if_then_else (match_operand 0 "register_operand" "") 
11623         (const_string "2")
11624         (const_string "*")))])
11626 (define_insn "*ashrhi3_1"
11627   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11628         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11629                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11632   "@
11633    sar{w}\t{%2, %0|%0, %2}
11634    sar{w}\t{%b2, %0|%0, %b2}"
11635   [(set_attr "type" "ishift")
11636    (set_attr "mode" "HI")])
11638 ;; This pattern can't accept a variable shift count, since shifts by
11639 ;; zero don't affect the flags.  We assume that shifts by constant
11640 ;; zero are optimized away.
11641 (define_insn "*ashrhi3_one_bit_cmp"
11642   [(set (reg FLAGS_REG)
11643         (compare
11644           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11645                        (match_operand:QI 2 "const1_operand" ""))
11646           (const_int 0)))
11647    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11648         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11649   "ix86_match_ccmode (insn, CCGOCmode)
11650    && (TARGET_SHIFT1 || optimize_size)
11651    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11652   "sar{w}\t%0"
11653   [(set_attr "type" "ishift")
11654    (set (attr "length") 
11655      (if_then_else (match_operand 0 "register_operand" "") 
11656         (const_string "2")
11657         (const_string "*")))])
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags.  We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*ashrhi3_cmp"
11663   [(set (reg FLAGS_REG)
11664         (compare
11665           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11666                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11667           (const_int 0)))
11668    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11669         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11670   "ix86_match_ccmode (insn, CCGOCmode)
11671    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11672   "sar{w}\t{%2, %0|%0, %2}"
11673   [(set_attr "type" "ishift")
11674    (set_attr "mode" "HI")])
11676 (define_expand "ashrqi3"
11677   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11678         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11679                      (match_operand:QI 2 "nonmemory_operand" "")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "TARGET_QIMODE_MATH"
11682   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11684 (define_insn "*ashrqi3_1_one_bit"
11685   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11686         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11687                      (match_operand:QI 2 "const1_operand" "")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11690    && (TARGET_SHIFT1 || optimize_size)"
11691   "sar{b}\t%0"
11692   [(set_attr "type" "ishift")
11693    (set (attr "length") 
11694      (if_then_else (match_operand 0 "register_operand" "") 
11695         (const_string "2")
11696         (const_string "*")))])
11698 (define_insn "*ashrqi3_1_one_bit_slp"
11699   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11700         (ashiftrt:QI (match_dup 0)
11701                      (match_operand:QI 1 "const1_operand" "")))
11702    (clobber (reg:CC FLAGS_REG))]
11703   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11704    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11705    && (TARGET_SHIFT1 || optimize_size)"
11706   "sar{b}\t%0"
11707   [(set_attr "type" "ishift1")
11708    (set (attr "length") 
11709      (if_then_else (match_operand 0 "register_operand" "") 
11710         (const_string "2")
11711         (const_string "*")))])
11713 (define_insn "*ashrqi3_1"
11714   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11715         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11716                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11717    (clobber (reg:CC FLAGS_REG))]
11718   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11719   "@
11720    sar{b}\t{%2, %0|%0, %2}
11721    sar{b}\t{%b2, %0|%0, %b2}"
11722   [(set_attr "type" "ishift")
11723    (set_attr "mode" "QI")])
11725 (define_insn "*ashrqi3_1_slp"
11726   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11727         (ashiftrt:QI (match_dup 0)
11728                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11729    (clobber (reg:CC FLAGS_REG))]
11730   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11731    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11732   "@
11733    sar{b}\t{%1, %0|%0, %1}
11734    sar{b}\t{%b1, %0|%0, %b1}"
11735   [(set_attr "type" "ishift1")
11736    (set_attr "mode" "QI")])
11738 ;; This pattern can't accept a variable shift count, since shifts by
11739 ;; zero don't affect the flags.  We assume that shifts by constant
11740 ;; zero are optimized away.
11741 (define_insn "*ashrqi3_one_bit_cmp"
11742   [(set (reg FLAGS_REG)
11743         (compare
11744           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11745                        (match_operand:QI 2 "const1_operand" "I"))
11746           (const_int 0)))
11747    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11748         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11749   "ix86_match_ccmode (insn, CCGOCmode)
11750    && (TARGET_SHIFT1 || optimize_size)
11751    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11752   "sar{b}\t%0"
11753   [(set_attr "type" "ishift")
11754    (set (attr "length") 
11755      (if_then_else (match_operand 0 "register_operand" "") 
11756         (const_string "2")
11757         (const_string "*")))])
11759 ;; This pattern can't accept a variable shift count, since shifts by
11760 ;; zero don't affect the flags.  We assume that shifts by constant
11761 ;; zero are optimized away.
11762 (define_insn "*ashrqi3_cmp"
11763   [(set (reg FLAGS_REG)
11764         (compare
11765           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11766                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11767           (const_int 0)))
11768    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11769         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11770   "ix86_match_ccmode (insn, CCGOCmode)
11771    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11772   "sar{b}\t{%2, %0|%0, %2}"
11773   [(set_attr "type" "ishift")
11774    (set_attr "mode" "QI")])
11776 ;; Logical shift instructions
11778 ;; See comment above `ashldi3' about how this works.
11780 (define_expand "lshrdi3"
11781   [(set (match_operand:DI 0 "shiftdi_operand" "")
11782         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11783                      (match_operand:QI 2 "nonmemory_operand" "")))]
11784   ""
11785   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11787 (define_insn "*lshrdi3_1_one_bit_rex64"
11788   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11789         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11790                      (match_operand:QI 2 "const1_operand" "")))
11791    (clobber (reg:CC FLAGS_REG))]
11792   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11793    && (TARGET_SHIFT1 || optimize_size)"
11794   "shr{q}\t%0"
11795   [(set_attr "type" "ishift")
11796    (set (attr "length") 
11797      (if_then_else (match_operand:DI 0 "register_operand" "") 
11798         (const_string "2")
11799         (const_string "*")))])
11801 (define_insn "*lshrdi3_1_rex64"
11802   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11803         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11804                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11805    (clobber (reg:CC FLAGS_REG))]
11806   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11807   "@
11808    shr{q}\t{%2, %0|%0, %2}
11809    shr{q}\t{%b2, %0|%0, %b2}"
11810   [(set_attr "type" "ishift")
11811    (set_attr "mode" "DI")])
11813 ;; This pattern can't accept a variable shift count, since shifts by
11814 ;; zero don't affect the flags.  We assume that shifts by constant
11815 ;; zero are optimized away.
11816 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11817   [(set (reg FLAGS_REG)
11818         (compare
11819           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11820                        (match_operand:QI 2 "const1_operand" ""))
11821           (const_int 0)))
11822    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11823         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11824   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11825    && (TARGET_SHIFT1 || optimize_size)
11826    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11827   "shr{q}\t%0"
11828   [(set_attr "type" "ishift")
11829    (set (attr "length") 
11830      (if_then_else (match_operand:DI 0 "register_operand" "") 
11831         (const_string "2")
11832         (const_string "*")))])
11834 ;; This pattern can't accept a variable shift count, since shifts by
11835 ;; zero don't affect the flags.  We assume that shifts by constant
11836 ;; zero are optimized away.
11837 (define_insn "*lshrdi3_cmp_rex64"
11838   [(set (reg FLAGS_REG)
11839         (compare
11840           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11841                        (match_operand:QI 2 "const_int_operand" "e"))
11842           (const_int 0)))
11843    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11844         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11845   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11846    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11847   "shr{q}\t{%2, %0|%0, %2}"
11848   [(set_attr "type" "ishift")
11849    (set_attr "mode" "DI")])
11851 (define_insn "*lshrdi3_1"
11852   [(set (match_operand:DI 0 "register_operand" "=r")
11853         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11854                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11855    (clobber (reg:CC FLAGS_REG))]
11856   "!TARGET_64BIT"
11857   "#"
11858   [(set_attr "type" "multi")])
11860 ;; By default we don't ask for a scratch register, because when DImode
11861 ;; values are manipulated, registers are already at a premium.  But if
11862 ;; we have one handy, we won't turn it away.
11863 (define_peephole2
11864   [(match_scratch:SI 3 "r")
11865    (parallel [(set (match_operand:DI 0 "register_operand" "")
11866                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11867                                 (match_operand:QI 2 "nonmemory_operand" "")))
11868               (clobber (reg:CC FLAGS_REG))])
11869    (match_dup 3)]
11870   "!TARGET_64BIT && TARGET_CMOVE"
11871   [(const_int 0)]
11872   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11874 (define_split 
11875   [(set (match_operand:DI 0 "register_operand" "")
11876         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11877                      (match_operand:QI 2 "nonmemory_operand" "")))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11880   [(const_int 0)]
11881   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11883 (define_expand "lshrsi3"
11884   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11885         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11886                      (match_operand:QI 2 "nonmemory_operand" "")))
11887    (clobber (reg:CC FLAGS_REG))]
11888   ""
11889   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11891 (define_insn "*lshrsi3_1_one_bit"
11892   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11893         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11894                      (match_operand:QI 2 "const1_operand" "")))
11895    (clobber (reg:CC FLAGS_REG))]
11896   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11897    && (TARGET_SHIFT1 || optimize_size)"
11898   "shr{l}\t%0"
11899   [(set_attr "type" "ishift")
11900    (set (attr "length") 
11901      (if_then_else (match_operand:SI 0 "register_operand" "") 
11902         (const_string "2")
11903         (const_string "*")))])
11905 (define_insn "*lshrsi3_1_one_bit_zext"
11906   [(set (match_operand:DI 0 "register_operand" "=r")
11907         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11908                      (match_operand:QI 2 "const1_operand" "")))
11909    (clobber (reg:CC FLAGS_REG))]
11910   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11911    && (TARGET_SHIFT1 || optimize_size)"
11912   "shr{l}\t%k0"
11913   [(set_attr "type" "ishift")
11914    (set_attr "length" "2")])
11916 (define_insn "*lshrsi3_1"
11917   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11918         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11919                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11920    (clobber (reg:CC FLAGS_REG))]
11921   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11922   "@
11923    shr{l}\t{%2, %0|%0, %2}
11924    shr{l}\t{%b2, %0|%0, %b2}"
11925   [(set_attr "type" "ishift")
11926    (set_attr "mode" "SI")])
11928 (define_insn "*lshrsi3_1_zext"
11929   [(set (match_operand:DI 0 "register_operand" "=r,r")
11930         (zero_extend:DI
11931           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11932                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11933    (clobber (reg:CC FLAGS_REG))]
11934   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11935   "@
11936    shr{l}\t{%2, %k0|%k0, %2}
11937    shr{l}\t{%b2, %k0|%k0, %b2}"
11938   [(set_attr "type" "ishift")
11939    (set_attr "mode" "SI")])
11941 ;; This pattern can't accept a variable shift count, since shifts by
11942 ;; zero don't affect the flags.  We assume that shifts by constant
11943 ;; zero are optimized away.
11944 (define_insn "*lshrsi3_one_bit_cmp"
11945   [(set (reg FLAGS_REG)
11946         (compare
11947           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11948                        (match_operand:QI 2 "const1_operand" ""))
11949           (const_int 0)))
11950    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11951         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11952   "ix86_match_ccmode (insn, CCGOCmode)
11953    && (TARGET_SHIFT1 || optimize_size)
11954    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11955   "shr{l}\t%0"
11956   [(set_attr "type" "ishift")
11957    (set (attr "length") 
11958      (if_then_else (match_operand:SI 0 "register_operand" "") 
11959         (const_string "2")
11960         (const_string "*")))])
11962 (define_insn "*lshrsi3_cmp_one_bit_zext"
11963   [(set (reg FLAGS_REG)
11964         (compare
11965           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11966                        (match_operand:QI 2 "const1_operand" ""))
11967           (const_int 0)))
11968    (set (match_operand:DI 0 "register_operand" "=r")
11969         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11970   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11971    && (TARGET_SHIFT1 || optimize_size)
11972    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11973   "shr{l}\t%k0"
11974   [(set_attr "type" "ishift")
11975    (set_attr "length" "2")])
11977 ;; This pattern can't accept a variable shift count, since shifts by
11978 ;; zero don't affect the flags.  We assume that shifts by constant
11979 ;; zero are optimized away.
11980 (define_insn "*lshrsi3_cmp"
11981   [(set (reg FLAGS_REG)
11982         (compare
11983           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11984                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11985           (const_int 0)))
11986    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11987         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11988   "ix86_match_ccmode (insn, CCGOCmode)
11989    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11990   "shr{l}\t{%2, %0|%0, %2}"
11991   [(set_attr "type" "ishift")
11992    (set_attr "mode" "SI")])
11994 (define_insn "*lshrsi3_cmp_zext"
11995   [(set (reg FLAGS_REG)
11996         (compare
11997           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11998                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11999           (const_int 0)))
12000    (set (match_operand:DI 0 "register_operand" "=r")
12001         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12002   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12003    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12004   "shr{l}\t{%2, %k0|%k0, %2}"
12005   [(set_attr "type" "ishift")
12006    (set_attr "mode" "SI")])
12008 (define_expand "lshrhi3"
12009   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12010         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12011                      (match_operand:QI 2 "nonmemory_operand" "")))
12012    (clobber (reg:CC FLAGS_REG))]
12013   "TARGET_HIMODE_MATH"
12014   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12016 (define_insn "*lshrhi3_1_one_bit"
12017   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12018         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12019                      (match_operand:QI 2 "const1_operand" "")))
12020    (clobber (reg:CC FLAGS_REG))]
12021   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12022    && (TARGET_SHIFT1 || optimize_size)"
12023   "shr{w}\t%0"
12024   [(set_attr "type" "ishift")
12025    (set (attr "length") 
12026      (if_then_else (match_operand 0 "register_operand" "") 
12027         (const_string "2")
12028         (const_string "*")))])
12030 (define_insn "*lshrhi3_1"
12031   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12032         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12033                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12034    (clobber (reg:CC FLAGS_REG))]
12035   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12036   "@
12037    shr{w}\t{%2, %0|%0, %2}
12038    shr{w}\t{%b2, %0|%0, %b2}"
12039   [(set_attr "type" "ishift")
12040    (set_attr "mode" "HI")])
12042 ;; This pattern can't accept a variable shift count, since shifts by
12043 ;; zero don't affect the flags.  We assume that shifts by constant
12044 ;; zero are optimized away.
12045 (define_insn "*lshrhi3_one_bit_cmp"
12046   [(set (reg FLAGS_REG)
12047         (compare
12048           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12049                        (match_operand:QI 2 "const1_operand" ""))
12050           (const_int 0)))
12051    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12052         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12053   "ix86_match_ccmode (insn, CCGOCmode)
12054    && (TARGET_SHIFT1 || optimize_size)
12055    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12056   "shr{w}\t%0"
12057   [(set_attr "type" "ishift")
12058    (set (attr "length") 
12059      (if_then_else (match_operand:SI 0 "register_operand" "") 
12060         (const_string "2")
12061         (const_string "*")))])
12063 ;; This pattern can't accept a variable shift count, since shifts by
12064 ;; zero don't affect the flags.  We assume that shifts by constant
12065 ;; zero are optimized away.
12066 (define_insn "*lshrhi3_cmp"
12067   [(set (reg FLAGS_REG)
12068         (compare
12069           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12070                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12071           (const_int 0)))
12072    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12073         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12074   "ix86_match_ccmode (insn, CCGOCmode)
12075    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12076   "shr{w}\t{%2, %0|%0, %2}"
12077   [(set_attr "type" "ishift")
12078    (set_attr "mode" "HI")])
12080 (define_expand "lshrqi3"
12081   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12082         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12083                      (match_operand:QI 2 "nonmemory_operand" "")))
12084    (clobber (reg:CC FLAGS_REG))]
12085   "TARGET_QIMODE_MATH"
12086   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12088 (define_insn "*lshrqi3_1_one_bit"
12089   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12090         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12091                      (match_operand:QI 2 "const1_operand" "")))
12092    (clobber (reg:CC FLAGS_REG))]
12093   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12094    && (TARGET_SHIFT1 || optimize_size)"
12095   "shr{b}\t%0"
12096   [(set_attr "type" "ishift")
12097    (set (attr "length") 
12098      (if_then_else (match_operand 0 "register_operand" "") 
12099         (const_string "2")
12100         (const_string "*")))])
12102 (define_insn "*lshrqi3_1_one_bit_slp"
12103   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12104         (lshiftrt:QI (match_dup 0)
12105                      (match_operand:QI 1 "const1_operand" "")))
12106    (clobber (reg:CC FLAGS_REG))]
12107   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12108    && (TARGET_SHIFT1 || optimize_size)"
12109   "shr{b}\t%0"
12110   [(set_attr "type" "ishift1")
12111    (set (attr "length") 
12112      (if_then_else (match_operand 0 "register_operand" "") 
12113         (const_string "2")
12114         (const_string "*")))])
12116 (define_insn "*lshrqi3_1"
12117   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12118         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12119                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12120    (clobber (reg:CC FLAGS_REG))]
12121   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12122   "@
12123    shr{b}\t{%2, %0|%0, %2}
12124    shr{b}\t{%b2, %0|%0, %b2}"
12125   [(set_attr "type" "ishift")
12126    (set_attr "mode" "QI")])
12128 (define_insn "*lshrqi3_1_slp"
12129   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12130         (lshiftrt:QI (match_dup 0)
12131                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12132    (clobber (reg:CC FLAGS_REG))]
12133   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12134    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12135   "@
12136    shr{b}\t{%1, %0|%0, %1}
12137    shr{b}\t{%b1, %0|%0, %b1}"
12138   [(set_attr "type" "ishift1")
12139    (set_attr "mode" "QI")])
12141 ;; This pattern can't accept a variable shift count, since shifts by
12142 ;; zero don't affect the flags.  We assume that shifts by constant
12143 ;; zero are optimized away.
12144 (define_insn "*lshrqi2_one_bit_cmp"
12145   [(set (reg FLAGS_REG)
12146         (compare
12147           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12148                        (match_operand:QI 2 "const1_operand" ""))
12149           (const_int 0)))
12150    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12151         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12152   "ix86_match_ccmode (insn, CCGOCmode)
12153    && (TARGET_SHIFT1 || optimize_size)
12154    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12155   "shr{b}\t%0"
12156   [(set_attr "type" "ishift")
12157    (set (attr "length") 
12158      (if_then_else (match_operand:SI 0 "register_operand" "") 
12159         (const_string "2")
12160         (const_string "*")))])
12162 ;; This pattern can't accept a variable shift count, since shifts by
12163 ;; zero don't affect the flags.  We assume that shifts by constant
12164 ;; zero are optimized away.
12165 (define_insn "*lshrqi2_cmp"
12166   [(set (reg FLAGS_REG)
12167         (compare
12168           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12169                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12170           (const_int 0)))
12171    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12172         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12173   "ix86_match_ccmode (insn, CCGOCmode)
12174    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12175   "shr{b}\t{%2, %0|%0, %2}"
12176   [(set_attr "type" "ishift")
12177    (set_attr "mode" "QI")])
12179 ;; Rotate instructions
12181 (define_expand "rotldi3"
12182   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12183         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12184                    (match_operand:QI 2 "nonmemory_operand" "")))
12185    (clobber (reg:CC FLAGS_REG))]
12186   "TARGET_64BIT"
12187   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12189 (define_insn "*rotlsi3_1_one_bit_rex64"
12190   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12191         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12192                    (match_operand:QI 2 "const1_operand" "")))
12193    (clobber (reg:CC FLAGS_REG))]
12194   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12195    && (TARGET_SHIFT1 || optimize_size)"
12196   "rol{q}\t%0"
12197   [(set_attr "type" "rotate")
12198    (set (attr "length") 
12199      (if_then_else (match_operand:DI 0 "register_operand" "") 
12200         (const_string "2")
12201         (const_string "*")))])
12203 (define_insn "*rotldi3_1_rex64"
12204   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12205         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12206                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12207    (clobber (reg:CC FLAGS_REG))]
12208   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12209   "@
12210    rol{q}\t{%2, %0|%0, %2}
12211    rol{q}\t{%b2, %0|%0, %b2}"
12212   [(set_attr "type" "rotate")
12213    (set_attr "mode" "DI")])
12215 (define_expand "rotlsi3"
12216   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12217         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12218                    (match_operand:QI 2 "nonmemory_operand" "")))
12219    (clobber (reg:CC FLAGS_REG))]
12220   ""
12221   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12223 (define_insn "*rotlsi3_1_one_bit"
12224   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12225         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12226                    (match_operand:QI 2 "const1_operand" "")))
12227    (clobber (reg:CC FLAGS_REG))]
12228   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12229    && (TARGET_SHIFT1 || optimize_size)"
12230   "rol{l}\t%0"
12231   [(set_attr "type" "rotate")
12232    (set (attr "length") 
12233      (if_then_else (match_operand:SI 0 "register_operand" "") 
12234         (const_string "2")
12235         (const_string "*")))])
12237 (define_insn "*rotlsi3_1_one_bit_zext"
12238   [(set (match_operand:DI 0 "register_operand" "=r")
12239         (zero_extend:DI
12240           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12241                      (match_operand:QI 2 "const1_operand" ""))))
12242    (clobber (reg:CC FLAGS_REG))]
12243   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12244    && (TARGET_SHIFT1 || optimize_size)"
12245   "rol{l}\t%k0"
12246   [(set_attr "type" "rotate")
12247    (set_attr "length" "2")])
12249 (define_insn "*rotlsi3_1"
12250   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12251         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12252                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12253    (clobber (reg:CC FLAGS_REG))]
12254   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12255   "@
12256    rol{l}\t{%2, %0|%0, %2}
12257    rol{l}\t{%b2, %0|%0, %b2}"
12258   [(set_attr "type" "rotate")
12259    (set_attr "mode" "SI")])
12261 (define_insn "*rotlsi3_1_zext"
12262   [(set (match_operand:DI 0 "register_operand" "=r,r")
12263         (zero_extend:DI
12264           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12265                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12266    (clobber (reg:CC FLAGS_REG))]
12267   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12268   "@
12269    rol{l}\t{%2, %k0|%k0, %2}
12270    rol{l}\t{%b2, %k0|%k0, %b2}"
12271   [(set_attr "type" "rotate")
12272    (set_attr "mode" "SI")])
12274 (define_expand "rotlhi3"
12275   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12276         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12277                    (match_operand:QI 2 "nonmemory_operand" "")))
12278    (clobber (reg:CC FLAGS_REG))]
12279   "TARGET_HIMODE_MATH"
12280   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12282 (define_insn "*rotlhi3_1_one_bit"
12283   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12284         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12285                    (match_operand:QI 2 "const1_operand" "")))
12286    (clobber (reg:CC FLAGS_REG))]
12287   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12288    && (TARGET_SHIFT1 || optimize_size)"
12289   "rol{w}\t%0"
12290   [(set_attr "type" "rotate")
12291    (set (attr "length") 
12292      (if_then_else (match_operand 0 "register_operand" "") 
12293         (const_string "2")
12294         (const_string "*")))])
12296 (define_insn "*rotlhi3_1"
12297   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12298         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12299                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12300    (clobber (reg:CC FLAGS_REG))]
12301   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12302   "@
12303    rol{w}\t{%2, %0|%0, %2}
12304    rol{w}\t{%b2, %0|%0, %b2}"
12305   [(set_attr "type" "rotate")
12306    (set_attr "mode" "HI")])
12308 (define_expand "rotlqi3"
12309   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12310         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12311                    (match_operand:QI 2 "nonmemory_operand" "")))
12312    (clobber (reg:CC FLAGS_REG))]
12313   "TARGET_QIMODE_MATH"
12314   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12316 (define_insn "*rotlqi3_1_one_bit_slp"
12317   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12318         (rotate:QI (match_dup 0)
12319                    (match_operand:QI 1 "const1_operand" "")))
12320    (clobber (reg:CC FLAGS_REG))]
12321   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12322    && (TARGET_SHIFT1 || optimize_size)"
12323   "rol{b}\t%0"
12324   [(set_attr "type" "rotate1")
12325    (set (attr "length") 
12326      (if_then_else (match_operand 0 "register_operand" "") 
12327         (const_string "2")
12328         (const_string "*")))])
12330 (define_insn "*rotlqi3_1_one_bit"
12331   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12332         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12333                    (match_operand:QI 2 "const1_operand" "")))
12334    (clobber (reg:CC FLAGS_REG))]
12335   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12336    && (TARGET_SHIFT1 || optimize_size)"
12337   "rol{b}\t%0"
12338   [(set_attr "type" "rotate")
12339    (set (attr "length") 
12340      (if_then_else (match_operand 0 "register_operand" "") 
12341         (const_string "2")
12342         (const_string "*")))])
12344 (define_insn "*rotlqi3_1_slp"
12345   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12346         (rotate:QI (match_dup 0)
12347                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12350    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12351   "@
12352    rol{b}\t{%1, %0|%0, %1}
12353    rol{b}\t{%b1, %0|%0, %b1}"
12354   [(set_attr "type" "rotate1")
12355    (set_attr "mode" "QI")])
12357 (define_insn "*rotlqi3_1"
12358   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12359         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12360                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12361    (clobber (reg:CC FLAGS_REG))]
12362   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12363   "@
12364    rol{b}\t{%2, %0|%0, %2}
12365    rol{b}\t{%b2, %0|%0, %b2}"
12366   [(set_attr "type" "rotate")
12367    (set_attr "mode" "QI")])
12369 (define_expand "rotrdi3"
12370   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12371         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12372                      (match_operand:QI 2 "nonmemory_operand" "")))
12373    (clobber (reg:CC FLAGS_REG))]
12374   "TARGET_64BIT"
12375   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12377 (define_insn "*rotrdi3_1_one_bit_rex64"
12378   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12379         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12380                      (match_operand:QI 2 "const1_operand" "")))
12381    (clobber (reg:CC FLAGS_REG))]
12382   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12383    && (TARGET_SHIFT1 || optimize_size)"
12384   "ror{q}\t%0"
12385   [(set_attr "type" "rotate")
12386    (set (attr "length") 
12387      (if_then_else (match_operand:DI 0 "register_operand" "") 
12388         (const_string "2")
12389         (const_string "*")))])
12391 (define_insn "*rotrdi3_1_rex64"
12392   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12393         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12394                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12395    (clobber (reg:CC FLAGS_REG))]
12396   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12397   "@
12398    ror{q}\t{%2, %0|%0, %2}
12399    ror{q}\t{%b2, %0|%0, %b2}"
12400   [(set_attr "type" "rotate")
12401    (set_attr "mode" "DI")])
12403 (define_expand "rotrsi3"
12404   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12405         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12406                      (match_operand:QI 2 "nonmemory_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   ""
12409   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12411 (define_insn "*rotrsi3_1_one_bit"
12412   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12413         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12414                      (match_operand:QI 2 "const1_operand" "")))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12417    && (TARGET_SHIFT1 || optimize_size)"
12418   "ror{l}\t%0"
12419   [(set_attr "type" "rotate")
12420    (set (attr "length") 
12421      (if_then_else (match_operand:SI 0 "register_operand" "") 
12422         (const_string "2")
12423         (const_string "*")))])
12425 (define_insn "*rotrsi3_1_one_bit_zext"
12426   [(set (match_operand:DI 0 "register_operand" "=r")
12427         (zero_extend:DI
12428           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12429                        (match_operand:QI 2 "const1_operand" ""))))
12430    (clobber (reg:CC FLAGS_REG))]
12431   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12432    && (TARGET_SHIFT1 || optimize_size)"
12433   "ror{l}\t%k0"
12434   [(set_attr "type" "rotate")
12435    (set (attr "length") 
12436      (if_then_else (match_operand:SI 0 "register_operand" "") 
12437         (const_string "2")
12438         (const_string "*")))])
12440 (define_insn "*rotrsi3_1"
12441   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12442         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12443                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12444    (clobber (reg:CC FLAGS_REG))]
12445   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12446   "@
12447    ror{l}\t{%2, %0|%0, %2}
12448    ror{l}\t{%b2, %0|%0, %b2}"
12449   [(set_attr "type" "rotate")
12450    (set_attr "mode" "SI")])
12452 (define_insn "*rotrsi3_1_zext"
12453   [(set (match_operand:DI 0 "register_operand" "=r,r")
12454         (zero_extend:DI
12455           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12456                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12457    (clobber (reg:CC FLAGS_REG))]
12458   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12459   "@
12460    ror{l}\t{%2, %k0|%k0, %2}
12461    ror{l}\t{%b2, %k0|%k0, %b2}"
12462   [(set_attr "type" "rotate")
12463    (set_attr "mode" "SI")])
12465 (define_expand "rotrhi3"
12466   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12467         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12468                      (match_operand:QI 2 "nonmemory_operand" "")))
12469    (clobber (reg:CC FLAGS_REG))]
12470   "TARGET_HIMODE_MATH"
12471   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12473 (define_insn "*rotrhi3_one_bit"
12474   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12475         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12476                      (match_operand:QI 2 "const1_operand" "")))
12477    (clobber (reg:CC FLAGS_REG))]
12478   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12479    && (TARGET_SHIFT1 || optimize_size)"
12480   "ror{w}\t%0"
12481   [(set_attr "type" "rotate")
12482    (set (attr "length") 
12483      (if_then_else (match_operand 0 "register_operand" "") 
12484         (const_string "2")
12485         (const_string "*")))])
12487 (define_insn "*rotrhi3"
12488   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12489         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12490                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12491    (clobber (reg:CC FLAGS_REG))]
12492   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12493   "@
12494    ror{w}\t{%2, %0|%0, %2}
12495    ror{w}\t{%b2, %0|%0, %b2}"
12496   [(set_attr "type" "rotate")
12497    (set_attr "mode" "HI")])
12499 (define_expand "rotrqi3"
12500   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12501         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12502                      (match_operand:QI 2 "nonmemory_operand" "")))
12503    (clobber (reg:CC FLAGS_REG))]
12504   "TARGET_QIMODE_MATH"
12505   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12507 (define_insn "*rotrqi3_1_one_bit"
12508   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12509         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12510                      (match_operand:QI 2 "const1_operand" "")))
12511    (clobber (reg:CC FLAGS_REG))]
12512   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12513    && (TARGET_SHIFT1 || optimize_size)"
12514   "ror{b}\t%0"
12515   [(set_attr "type" "rotate")
12516    (set (attr "length") 
12517      (if_then_else (match_operand 0 "register_operand" "") 
12518         (const_string "2")
12519         (const_string "*")))])
12521 (define_insn "*rotrqi3_1_one_bit_slp"
12522   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12523         (rotatert:QI (match_dup 0)
12524                      (match_operand:QI 1 "const1_operand" "")))
12525    (clobber (reg:CC FLAGS_REG))]
12526   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12527    && (TARGET_SHIFT1 || optimize_size)"
12528   "ror{b}\t%0"
12529   [(set_attr "type" "rotate1")
12530    (set (attr "length") 
12531      (if_then_else (match_operand 0 "register_operand" "") 
12532         (const_string "2")
12533         (const_string "*")))])
12535 (define_insn "*rotrqi3_1"
12536   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12537         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12538                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12539    (clobber (reg:CC FLAGS_REG))]
12540   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12541   "@
12542    ror{b}\t{%2, %0|%0, %2}
12543    ror{b}\t{%b2, %0|%0, %b2}"
12544   [(set_attr "type" "rotate")
12545    (set_attr "mode" "QI")])
12547 (define_insn "*rotrqi3_1_slp"
12548   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12549         (rotatert:QI (match_dup 0)
12550                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12551    (clobber (reg:CC FLAGS_REG))]
12552   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12553    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12554   "@
12555    ror{b}\t{%1, %0|%0, %1}
12556    ror{b}\t{%b1, %0|%0, %b1}"
12557   [(set_attr "type" "rotate1")
12558    (set_attr "mode" "QI")])
12560 ;; Bit set / bit test instructions
12562 (define_expand "extv"
12563   [(set (match_operand:SI 0 "register_operand" "")
12564         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12565                          (match_operand:SI 2 "immediate_operand" "")
12566                          (match_operand:SI 3 "immediate_operand" "")))]
12567   ""
12569   /* Handle extractions from %ah et al.  */
12570   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12571     FAIL;
12573   /* From mips.md: extract_bit_field doesn't verify that our source
12574      matches the predicate, so check it again here.  */
12575   if (! register_operand (operands[1], VOIDmode))
12576     FAIL;
12579 (define_expand "extzv"
12580   [(set (match_operand:SI 0 "register_operand" "")
12581         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12582                          (match_operand:SI 2 "immediate_operand" "")
12583                          (match_operand:SI 3 "immediate_operand" "")))]
12584   ""
12586   /* Handle extractions from %ah et al.  */
12587   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12588     FAIL;
12590   /* From mips.md: extract_bit_field doesn't verify that our source
12591      matches the predicate, so check it again here.  */
12592   if (! register_operand (operands[1], VOIDmode))
12593     FAIL;
12596 (define_expand "insv"
12597   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12598                       (match_operand 1 "immediate_operand" "")
12599                       (match_operand 2 "immediate_operand" ""))
12600         (match_operand 3 "register_operand" ""))]
12601   ""
12603   /* Handle extractions from %ah et al.  */
12604   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12605     FAIL;
12607   /* From mips.md: insert_bit_field doesn't verify that our source
12608      matches the predicate, so check it again here.  */
12609   if (! register_operand (operands[0], VOIDmode))
12610     FAIL;
12612   if (TARGET_64BIT)
12613     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12614   else
12615     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12617   DONE;
12620 ;; %%% bts, btr, btc, bt.
12622 ;; Store-flag instructions.
12624 ;; For all sCOND expanders, also expand the compare or test insn that
12625 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12627 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12628 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12629 ;; way, which can later delete the movzx if only QImode is needed.
12631 (define_expand "seq"
12632   [(set (match_operand:QI 0 "register_operand" "")
12633         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12634   ""
12635   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12637 (define_expand "sne"
12638   [(set (match_operand:QI 0 "register_operand" "")
12639         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12640   ""
12641   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12643 (define_expand "sgt"
12644   [(set (match_operand:QI 0 "register_operand" "")
12645         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12646   ""
12647   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12649 (define_expand "sgtu"
12650   [(set (match_operand:QI 0 "register_operand" "")
12651         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12652   ""
12653   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12655 (define_expand "slt"
12656   [(set (match_operand:QI 0 "register_operand" "")
12657         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12658   ""
12659   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12661 (define_expand "sltu"
12662   [(set (match_operand:QI 0 "register_operand" "")
12663         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12664   ""
12665   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12667 (define_expand "sge"
12668   [(set (match_operand:QI 0 "register_operand" "")
12669         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12670   ""
12671   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12673 (define_expand "sgeu"
12674   [(set (match_operand:QI 0 "register_operand" "")
12675         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12676   ""
12677   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12679 (define_expand "sle"
12680   [(set (match_operand:QI 0 "register_operand" "")
12681         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12682   ""
12683   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12685 (define_expand "sleu"
12686   [(set (match_operand:QI 0 "register_operand" "")
12687         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12688   ""
12689   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12691 (define_expand "sunordered"
12692   [(set (match_operand:QI 0 "register_operand" "")
12693         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12694   "TARGET_80387 || TARGET_SSE"
12695   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12697 (define_expand "sordered"
12698   [(set (match_operand:QI 0 "register_operand" "")
12699         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12700   "TARGET_80387"
12701   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12703 (define_expand "suneq"
12704   [(set (match_operand:QI 0 "register_operand" "")
12705         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12706   "TARGET_80387 || TARGET_SSE"
12707   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12709 (define_expand "sunge"
12710   [(set (match_operand:QI 0 "register_operand" "")
12711         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12712   "TARGET_80387 || TARGET_SSE"
12713   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12715 (define_expand "sungt"
12716   [(set (match_operand:QI 0 "register_operand" "")
12717         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12718   "TARGET_80387 || TARGET_SSE"
12719   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12721 (define_expand "sunle"
12722   [(set (match_operand:QI 0 "register_operand" "")
12723         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12724   "TARGET_80387 || TARGET_SSE"
12725   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12727 (define_expand "sunlt"
12728   [(set (match_operand:QI 0 "register_operand" "")
12729         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12730   "TARGET_80387 || TARGET_SSE"
12731   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12733 (define_expand "sltgt"
12734   [(set (match_operand:QI 0 "register_operand" "")
12735         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12736   "TARGET_80387 || TARGET_SSE"
12737   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12739 (define_insn "*setcc_1"
12740   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12741         (match_operator:QI 1 "ix86_comparison_operator"
12742           [(reg FLAGS_REG) (const_int 0)]))]
12743   ""
12744   "set%C1\t%0"
12745   [(set_attr "type" "setcc")
12746    (set_attr "mode" "QI")])
12748 (define_insn "*setcc_2"
12749   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12750         (match_operator:QI 1 "ix86_comparison_operator"
12751           [(reg FLAGS_REG) (const_int 0)]))]
12752   ""
12753   "set%C1\t%0"
12754   [(set_attr "type" "setcc")
12755    (set_attr "mode" "QI")])
12757 ;; In general it is not safe to assume too much about CCmode registers,
12758 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12759 ;; conditions this is safe on x86, so help combine not create
12761 ;;      seta    %al
12762 ;;      testb   %al, %al
12763 ;;      sete    %al
12765 (define_split 
12766   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12767         (ne:QI (match_operator 1 "ix86_comparison_operator"
12768                  [(reg FLAGS_REG) (const_int 0)])
12769             (const_int 0)))]
12770   ""
12771   [(set (match_dup 0) (match_dup 1))]
12773   PUT_MODE (operands[1], QImode);
12776 (define_split 
12777   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12778         (ne:QI (match_operator 1 "ix86_comparison_operator"
12779                  [(reg FLAGS_REG) (const_int 0)])
12780             (const_int 0)))]
12781   ""
12782   [(set (match_dup 0) (match_dup 1))]
12784   PUT_MODE (operands[1], QImode);
12787 (define_split 
12788   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12789         (eq:QI (match_operator 1 "ix86_comparison_operator"
12790                  [(reg FLAGS_REG) (const_int 0)])
12791             (const_int 0)))]
12792   ""
12793   [(set (match_dup 0) (match_dup 1))]
12795   rtx new_op1 = copy_rtx (operands[1]);
12796   operands[1] = new_op1;
12797   PUT_MODE (new_op1, QImode);
12798   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12799                                              GET_MODE (XEXP (new_op1, 0))));
12801   /* Make sure that (a) the CCmode we have for the flags is strong
12802      enough for the reversed compare or (b) we have a valid FP compare.  */
12803   if (! ix86_comparison_operator (new_op1, VOIDmode))
12804     FAIL;
12807 (define_split 
12808   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12809         (eq:QI (match_operator 1 "ix86_comparison_operator"
12810                  [(reg FLAGS_REG) (const_int 0)])
12811             (const_int 0)))]
12812   ""
12813   [(set (match_dup 0) (match_dup 1))]
12815   rtx new_op1 = copy_rtx (operands[1]);
12816   operands[1] = new_op1;
12817   PUT_MODE (new_op1, QImode);
12818   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12819                                              GET_MODE (XEXP (new_op1, 0))));
12821   /* Make sure that (a) the CCmode we have for the flags is strong
12822      enough for the reversed compare or (b) we have a valid FP compare.  */
12823   if (! ix86_comparison_operator (new_op1, VOIDmode))
12824     FAIL;
12827 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12828 ;; subsequent logical operations are used to imitate conditional moves.
12829 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12830 ;; it directly.  Further holding this value in pseudo register might bring
12831 ;; problem in implicit normalization in spill code.
12832 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12833 ;; instructions after reload by splitting the conditional move patterns.
12835 (define_insn "*sse_setccsf"
12836   [(set (match_operand:SF 0 "register_operand" "=x")
12837         (match_operator:SF 1 "sse_comparison_operator"
12838           [(match_operand:SF 2 "register_operand" "0")
12839            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12840   "TARGET_SSE && reload_completed"
12841   "cmp%D1ss\t{%3, %0|%0, %3}"
12842   [(set_attr "type" "ssecmp")
12843    (set_attr "mode" "SF")])
12845 (define_insn "*sse_setccdf"
12846   [(set (match_operand:DF 0 "register_operand" "=Y")
12847         (match_operator:DF 1 "sse_comparison_operator"
12848           [(match_operand:DF 2 "register_operand" "0")
12849            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12850   "TARGET_SSE2 && reload_completed"
12851   "cmp%D1sd\t{%3, %0|%0, %3}"
12852   [(set_attr "type" "ssecmp")
12853    (set_attr "mode" "DF")])
12855 ;; Basic conditional jump instructions.
12856 ;; We ignore the overflow flag for signed branch instructions.
12858 ;; For all bCOND expanders, also expand the compare or test insn that
12859 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12861 (define_expand "beq"
12862   [(set (pc)
12863         (if_then_else (match_dup 1)
12864                       (label_ref (match_operand 0 "" ""))
12865                       (pc)))]
12866   ""
12867   "ix86_expand_branch (EQ, operands[0]); DONE;")
12869 (define_expand "bne"
12870   [(set (pc)
12871         (if_then_else (match_dup 1)
12872                       (label_ref (match_operand 0 "" ""))
12873                       (pc)))]
12874   ""
12875   "ix86_expand_branch (NE, operands[0]); DONE;")
12877 (define_expand "bgt"
12878   [(set (pc)
12879         (if_then_else (match_dup 1)
12880                       (label_ref (match_operand 0 "" ""))
12881                       (pc)))]
12882   ""
12883   "ix86_expand_branch (GT, operands[0]); DONE;")
12885 (define_expand "bgtu"
12886   [(set (pc)
12887         (if_then_else (match_dup 1)
12888                       (label_ref (match_operand 0 "" ""))
12889                       (pc)))]
12890   ""
12891   "ix86_expand_branch (GTU, operands[0]); DONE;")
12893 (define_expand "blt"
12894   [(set (pc)
12895         (if_then_else (match_dup 1)
12896                       (label_ref (match_operand 0 "" ""))
12897                       (pc)))]
12898   ""
12899   "ix86_expand_branch (LT, operands[0]); DONE;")
12901 (define_expand "bltu"
12902   [(set (pc)
12903         (if_then_else (match_dup 1)
12904                       (label_ref (match_operand 0 "" ""))
12905                       (pc)))]
12906   ""
12907   "ix86_expand_branch (LTU, operands[0]); DONE;")
12909 (define_expand "bge"
12910   [(set (pc)
12911         (if_then_else (match_dup 1)
12912                       (label_ref (match_operand 0 "" ""))
12913                       (pc)))]
12914   ""
12915   "ix86_expand_branch (GE, operands[0]); DONE;")
12917 (define_expand "bgeu"
12918   [(set (pc)
12919         (if_then_else (match_dup 1)
12920                       (label_ref (match_operand 0 "" ""))
12921                       (pc)))]
12922   ""
12923   "ix86_expand_branch (GEU, operands[0]); DONE;")
12925 (define_expand "ble"
12926   [(set (pc)
12927         (if_then_else (match_dup 1)
12928                       (label_ref (match_operand 0 "" ""))
12929                       (pc)))]
12930   ""
12931   "ix86_expand_branch (LE, operands[0]); DONE;")
12933 (define_expand "bleu"
12934   [(set (pc)
12935         (if_then_else (match_dup 1)
12936                       (label_ref (match_operand 0 "" ""))
12937                       (pc)))]
12938   ""
12939   "ix86_expand_branch (LEU, operands[0]); DONE;")
12941 (define_expand "bunordered"
12942   [(set (pc)
12943         (if_then_else (match_dup 1)
12944                       (label_ref (match_operand 0 "" ""))
12945                       (pc)))]
12946   "TARGET_80387 || TARGET_SSE"
12947   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12949 (define_expand "bordered"
12950   [(set (pc)
12951         (if_then_else (match_dup 1)
12952                       (label_ref (match_operand 0 "" ""))
12953                       (pc)))]
12954   "TARGET_80387 || TARGET_SSE"
12955   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12957 (define_expand "buneq"
12958   [(set (pc)
12959         (if_then_else (match_dup 1)
12960                       (label_ref (match_operand 0 "" ""))
12961                       (pc)))]
12962   "TARGET_80387 || TARGET_SSE"
12963   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12965 (define_expand "bunge"
12966   [(set (pc)
12967         (if_then_else (match_dup 1)
12968                       (label_ref (match_operand 0 "" ""))
12969                       (pc)))]
12970   "TARGET_80387 || TARGET_SSE"
12971   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12973 (define_expand "bungt"
12974   [(set (pc)
12975         (if_then_else (match_dup 1)
12976                       (label_ref (match_operand 0 "" ""))
12977                       (pc)))]
12978   "TARGET_80387 || TARGET_SSE"
12979   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12981 (define_expand "bunle"
12982   [(set (pc)
12983         (if_then_else (match_dup 1)
12984                       (label_ref (match_operand 0 "" ""))
12985                       (pc)))]
12986   "TARGET_80387 || TARGET_SSE"
12987   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12989 (define_expand "bunlt"
12990   [(set (pc)
12991         (if_then_else (match_dup 1)
12992                       (label_ref (match_operand 0 "" ""))
12993                       (pc)))]
12994   "TARGET_80387 || TARGET_SSE"
12995   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12997 (define_expand "bltgt"
12998   [(set (pc)
12999         (if_then_else (match_dup 1)
13000                       (label_ref (match_operand 0 "" ""))
13001                       (pc)))]
13002   "TARGET_80387 || TARGET_SSE"
13003   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13005 (define_insn "*jcc_1"
13006   [(set (pc)
13007         (if_then_else (match_operator 1 "ix86_comparison_operator"
13008                                       [(reg FLAGS_REG) (const_int 0)])
13009                       (label_ref (match_operand 0 "" ""))
13010                       (pc)))]
13011   ""
13012   "%+j%C1\t%l0"
13013   [(set_attr "type" "ibr")
13014    (set_attr "modrm" "0")
13015    (set (attr "length")
13016            (if_then_else (and (ge (minus (match_dup 0) (pc))
13017                                   (const_int -126))
13018                               (lt (minus (match_dup 0) (pc))
13019                                   (const_int 128)))
13020              (const_int 2)
13021              (const_int 6)))])
13023 (define_insn "*jcc_2"
13024   [(set (pc)
13025         (if_then_else (match_operator 1 "ix86_comparison_operator"
13026                                       [(reg FLAGS_REG) (const_int 0)])
13027                       (pc)
13028                       (label_ref (match_operand 0 "" ""))))]
13029   ""
13030   "%+j%c1\t%l0"
13031   [(set_attr "type" "ibr")
13032    (set_attr "modrm" "0")
13033    (set (attr "length")
13034            (if_then_else (and (ge (minus (match_dup 0) (pc))
13035                                   (const_int -126))
13036                               (lt (minus (match_dup 0) (pc))
13037                                   (const_int 128)))
13038              (const_int 2)
13039              (const_int 6)))])
13041 ;; In general it is not safe to assume too much about CCmode registers,
13042 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13043 ;; conditions this is safe on x86, so help combine not create
13045 ;;      seta    %al
13046 ;;      testb   %al, %al
13047 ;;      je      Lfoo
13049 (define_split 
13050   [(set (pc)
13051         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13052                                       [(reg FLAGS_REG) (const_int 0)])
13053                           (const_int 0))
13054                       (label_ref (match_operand 1 "" ""))
13055                       (pc)))]
13056   ""
13057   [(set (pc)
13058         (if_then_else (match_dup 0)
13059                       (label_ref (match_dup 1))
13060                       (pc)))]
13062   PUT_MODE (operands[0], VOIDmode);
13064   
13065 (define_split 
13066   [(set (pc)
13067         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13068                                       [(reg FLAGS_REG) (const_int 0)])
13069                           (const_int 0))
13070                       (label_ref (match_operand 1 "" ""))
13071                       (pc)))]
13072   ""
13073   [(set (pc)
13074         (if_then_else (match_dup 0)
13075                       (label_ref (match_dup 1))
13076                       (pc)))]
13078   rtx new_op0 = copy_rtx (operands[0]);
13079   operands[0] = new_op0;
13080   PUT_MODE (new_op0, VOIDmode);
13081   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13082                                              GET_MODE (XEXP (new_op0, 0))));
13084   /* Make sure that (a) the CCmode we have for the flags is strong
13085      enough for the reversed compare or (b) we have a valid FP compare.  */
13086   if (! ix86_comparison_operator (new_op0, VOIDmode))
13087     FAIL;
13090 ;; Define combination compare-and-branch fp compare instructions to use
13091 ;; during early optimization.  Splitting the operation apart early makes
13092 ;; for bad code when we want to reverse the operation.
13094 (define_insn "*fp_jcc_1"
13095   [(set (pc)
13096         (if_then_else (match_operator 0 "comparison_operator"
13097                         [(match_operand 1 "register_operand" "f")
13098                          (match_operand 2 "register_operand" "f")])
13099           (label_ref (match_operand 3 "" ""))
13100           (pc)))
13101    (clobber (reg:CCFP FPSR_REG))
13102    (clobber (reg:CCFP FLAGS_REG))]
13103   "TARGET_CMOVE && TARGET_80387
13104    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13105    && FLOAT_MODE_P (GET_MODE (operands[1]))
13106    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13107    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13108   "#")
13110 (define_insn "*fp_jcc_1_sse"
13111   [(set (pc)
13112         (if_then_else (match_operator 0 "comparison_operator"
13113                         [(match_operand 1 "register_operand" "f#x,x#f")
13114                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13115           (label_ref (match_operand 3 "" ""))
13116           (pc)))
13117    (clobber (reg:CCFP FPSR_REG))
13118    (clobber (reg:CCFP FLAGS_REG))]
13119   "TARGET_80387
13120    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13121    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13122    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13123   "#")
13125 (define_insn "*fp_jcc_1_sse_only"
13126   [(set (pc)
13127         (if_then_else (match_operator 0 "comparison_operator"
13128                         [(match_operand 1 "register_operand" "x")
13129                          (match_operand 2 "nonimmediate_operand" "xm")])
13130           (label_ref (match_operand 3 "" ""))
13131           (pc)))
13132    (clobber (reg:CCFP FPSR_REG))
13133    (clobber (reg:CCFP FLAGS_REG))]
13134   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13135    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13136    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13137   "#")
13139 (define_insn "*fp_jcc_2"
13140   [(set (pc)
13141         (if_then_else (match_operator 0 "comparison_operator"
13142                         [(match_operand 1 "register_operand" "f")
13143                          (match_operand 2 "register_operand" "f")])
13144           (pc)
13145           (label_ref (match_operand 3 "" ""))))
13146    (clobber (reg:CCFP FPSR_REG))
13147    (clobber (reg:CCFP FLAGS_REG))]
13148   "TARGET_CMOVE && TARGET_80387
13149    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13150    && FLOAT_MODE_P (GET_MODE (operands[1]))
13151    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13152    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13153   "#")
13155 (define_insn "*fp_jcc_2_sse"
13156   [(set (pc)
13157         (if_then_else (match_operator 0 "comparison_operator"
13158                         [(match_operand 1 "register_operand" "f#x,x#f")
13159                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13160           (pc)
13161           (label_ref (match_operand 3 "" ""))))
13162    (clobber (reg:CCFP FPSR_REG))
13163    (clobber (reg:CCFP FLAGS_REG))]
13164   "TARGET_80387
13165    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13166    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13167    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13168   "#")
13170 (define_insn "*fp_jcc_2_sse_only"
13171   [(set (pc)
13172         (if_then_else (match_operator 0 "comparison_operator"
13173                         [(match_operand 1 "register_operand" "x")
13174                          (match_operand 2 "nonimmediate_operand" "xm")])
13175           (pc)
13176           (label_ref (match_operand 3 "" ""))))
13177    (clobber (reg:CCFP FPSR_REG))
13178    (clobber (reg:CCFP FLAGS_REG))]
13179   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13180    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13181    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13182   "#")
13184 (define_insn "*fp_jcc_3"
13185   [(set (pc)
13186         (if_then_else (match_operator 0 "comparison_operator"
13187                         [(match_operand 1 "register_operand" "f")
13188                          (match_operand 2 "nonimmediate_operand" "fm")])
13189           (label_ref (match_operand 3 "" ""))
13190           (pc)))
13191    (clobber (reg:CCFP FPSR_REG))
13192    (clobber (reg:CCFP FLAGS_REG))
13193    (clobber (match_scratch:HI 4 "=a"))]
13194   "TARGET_80387
13195    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13196    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13197    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13198    && SELECT_CC_MODE (GET_CODE (operands[0]),
13199                       operands[1], operands[2]) == CCFPmode
13200    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13201   "#")
13203 (define_insn "*fp_jcc_4"
13204   [(set (pc)
13205         (if_then_else (match_operator 0 "comparison_operator"
13206                         [(match_operand 1 "register_operand" "f")
13207                          (match_operand 2 "nonimmediate_operand" "fm")])
13208           (pc)
13209           (label_ref (match_operand 3 "" ""))))
13210    (clobber (reg:CCFP FPSR_REG))
13211    (clobber (reg:CCFP FLAGS_REG))
13212    (clobber (match_scratch:HI 4 "=a"))]
13213   "TARGET_80387
13214    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13215    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13216    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13217    && SELECT_CC_MODE (GET_CODE (operands[0]),
13218                       operands[1], operands[2]) == CCFPmode
13219    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13220   "#")
13222 (define_insn "*fp_jcc_5"
13223   [(set (pc)
13224         (if_then_else (match_operator 0 "comparison_operator"
13225                         [(match_operand 1 "register_operand" "f")
13226                          (match_operand 2 "register_operand" "f")])
13227           (label_ref (match_operand 3 "" ""))
13228           (pc)))
13229    (clobber (reg:CCFP FPSR_REG))
13230    (clobber (reg:CCFP FLAGS_REG))
13231    (clobber (match_scratch:HI 4 "=a"))]
13232   "TARGET_80387
13233    && FLOAT_MODE_P (GET_MODE (operands[1]))
13234    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13235    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13236   "#")
13238 (define_insn "*fp_jcc_6"
13239   [(set (pc)
13240         (if_then_else (match_operator 0 "comparison_operator"
13241                         [(match_operand 1 "register_operand" "f")
13242                          (match_operand 2 "register_operand" "f")])
13243           (pc)
13244           (label_ref (match_operand 3 "" ""))))
13245    (clobber (reg:CCFP FPSR_REG))
13246    (clobber (reg:CCFP FLAGS_REG))
13247    (clobber (match_scratch:HI 4 "=a"))]
13248   "TARGET_80387
13249    && FLOAT_MODE_P (GET_MODE (operands[1]))
13250    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13251    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13252   "#")
13254 (define_insn "*fp_jcc_7"
13255   [(set (pc)
13256         (if_then_else (match_operator 0 "comparison_operator"
13257                         [(match_operand 1 "register_operand" "f")
13258                          (match_operand 2 "const_double_operand" "C")])
13259           (label_ref (match_operand 3 "" ""))
13260           (pc)))
13261    (clobber (reg:CCFP FPSR_REG))
13262    (clobber (reg:CCFP FLAGS_REG))
13263    (clobber (match_scratch:HI 4 "=a"))]
13264   "TARGET_80387
13265    && FLOAT_MODE_P (GET_MODE (operands[1]))
13266    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13267    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13268    && SELECT_CC_MODE (GET_CODE (operands[0]),
13269                       operands[1], operands[2]) == CCFPmode
13270    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13271   "#")
13273 ;; The order of operands in *fp_jcc_8 is forced by combine in
13274 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13275 ;; with a precedence over other operators and is always put in the first
13276 ;; place. Swap condition and operands to match ficom instruction.
13278 (define_insn "*fp_jcc_8"
13279   [(set (pc)
13280         (if_then_else (match_operator 0 "comparison_operator"
13281                         [(match_operator 1 "float_operator"
13282                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13283                            (match_operand 3 "register_operand" "f,f")])
13284           (label_ref (match_operand 4 "" ""))
13285           (pc)))
13286    (clobber (reg:CCFP FPSR_REG))
13287    (clobber (reg:CCFP FLAGS_REG))
13288    (clobber (match_scratch:HI 5 "=a,a"))]
13289   "TARGET_80387 && TARGET_USE_FIOP
13290    && FLOAT_MODE_P (GET_MODE (operands[3]))
13291    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13292    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13293    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13294    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13295   "#")
13297 (define_split
13298   [(set (pc)
13299         (if_then_else (match_operator 0 "comparison_operator"
13300                         [(match_operand 1 "register_operand" "")
13301                          (match_operand 2 "nonimmediate_operand" "")])
13302           (match_operand 3 "" "")
13303           (match_operand 4 "" "")))
13304    (clobber (reg:CCFP FPSR_REG))
13305    (clobber (reg:CCFP FLAGS_REG))]
13306   "reload_completed"
13307   [(const_int 0)]
13309   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13310                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13311   DONE;
13314 (define_split
13315   [(set (pc)
13316         (if_then_else (match_operator 0 "comparison_operator"
13317                         [(match_operand 1 "register_operand" "")
13318                          (match_operand 2 "general_operand" "")])
13319           (match_operand 3 "" "")
13320           (match_operand 4 "" "")))
13321    (clobber (reg:CCFP FPSR_REG))
13322    (clobber (reg:CCFP FLAGS_REG))
13323    (clobber (match_scratch:HI 5 "=a"))]
13324   "reload_completed"
13325   [(const_int 0)]
13327   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13328                         operands[3], operands[4], operands[5], NULL_RTX);
13329   DONE;
13332 (define_split
13333   [(set (pc)
13334         (if_then_else (match_operator 0 "comparison_operator"
13335                         [(match_operator 1 "float_operator"
13336                            [(match_operand:SI 2 "memory_operand" "")])
13337                            (match_operand 3 "register_operand" "")])
13338           (match_operand 4 "" "")
13339           (match_operand 5 "" "")))
13340    (clobber (reg:CCFP FPSR_REG))
13341    (clobber (reg:CCFP FLAGS_REG))
13342    (clobber (match_scratch:HI 6 "=a"))]
13343   "reload_completed"
13344   [(const_int 0)]
13346   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13347   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13348                         operands[3], operands[7],
13349                         operands[4], operands[5], operands[6], NULL_RTX);
13350   DONE;
13353 ;; %%% Kill this when reload knows how to do it.
13354 (define_split
13355   [(set (pc)
13356         (if_then_else (match_operator 0 "comparison_operator"
13357                         [(match_operator 1 "float_operator"
13358                            [(match_operand:SI 2 "register_operand" "")])
13359                            (match_operand 3 "register_operand" "")])
13360           (match_operand 4 "" "")
13361           (match_operand 5 "" "")))
13362    (clobber (reg:CCFP FPSR_REG))
13363    (clobber (reg:CCFP FLAGS_REG))
13364    (clobber (match_scratch:HI 6 "=a"))]
13365   "reload_completed"
13366   [(const_int 0)]
13368   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13369   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13370   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13371                         operands[3], operands[7],
13372                         operands[4], operands[5], operands[6], operands[2]);
13373   DONE;
13376 ;; Unconditional and other jump instructions
13378 (define_insn "jump"
13379   [(set (pc)
13380         (label_ref (match_operand 0 "" "")))]
13381   ""
13382   "jmp\t%l0"
13383   [(set_attr "type" "ibr")
13384    (set (attr "length")
13385            (if_then_else (and (ge (minus (match_dup 0) (pc))
13386                                   (const_int -126))
13387                               (lt (minus (match_dup 0) (pc))
13388                                   (const_int 128)))
13389              (const_int 2)
13390              (const_int 5)))
13391    (set_attr "modrm" "0")])
13393 (define_expand "indirect_jump"
13394   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13395   ""
13396   "")
13398 (define_insn "*indirect_jump"
13399   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13400   "!TARGET_64BIT"
13401   "jmp\t%A0"
13402   [(set_attr "type" "ibr")
13403    (set_attr "length_immediate" "0")])
13405 (define_insn "*indirect_jump_rtx64"
13406   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13407   "TARGET_64BIT"
13408   "jmp\t%A0"
13409   [(set_attr "type" "ibr")
13410    (set_attr "length_immediate" "0")])
13412 (define_expand "tablejump"
13413   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13414               (use (label_ref (match_operand 1 "" "")))])]
13415   ""
13417   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13418      relative.  Convert the relative address to an absolute address.  */
13419   if (flag_pic)
13420     {
13421       rtx op0, op1;
13422       enum rtx_code code;
13424       if (TARGET_64BIT)
13425         {
13426           code = PLUS;
13427           op0 = operands[0];
13428           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13429         }
13430       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13431         {
13432           code = PLUS;
13433           op0 = operands[0];
13434           op1 = pic_offset_table_rtx;
13435         }
13436       else
13437         {
13438           code = MINUS;
13439           op0 = pic_offset_table_rtx;
13440           op1 = operands[0];
13441         }
13443       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13444                                          OPTAB_DIRECT);
13445     }
13448 (define_insn "*tablejump_1"
13449   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13450    (use (label_ref (match_operand 1 "" "")))]
13451   "!TARGET_64BIT"
13452   "jmp\t%A0"
13453   [(set_attr "type" "ibr")
13454    (set_attr "length_immediate" "0")])
13456 (define_insn "*tablejump_1_rtx64"
13457   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13458    (use (label_ref (match_operand 1 "" "")))]
13459   "TARGET_64BIT"
13460   "jmp\t%A0"
13461   [(set_attr "type" "ibr")
13462    (set_attr "length_immediate" "0")])
13464 ;; Loop instruction
13466 ;; This is all complicated by the fact that since this is a jump insn
13467 ;; we must handle our own reloads.
13469 (define_expand "doloop_end"
13470   [(use (match_operand 0 "" ""))        ; loop pseudo
13471    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13472    (use (match_operand 2 "" ""))        ; max iterations
13473    (use (match_operand 3 "" ""))        ; loop level 
13474    (use (match_operand 4 "" ""))]       ; label
13475   "!TARGET_64BIT && TARGET_USE_LOOP"
13476   "                                 
13478   /* Only use cloop on innermost loops.  */
13479   if (INTVAL (operands[3]) > 1)
13480     FAIL;
13481   if (GET_MODE (operands[0]) != SImode)
13482     FAIL;
13483   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13484                                            operands[0]));
13485   DONE;
13488 (define_insn "doloop_end_internal"
13489   [(set (pc)
13490         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13491                           (const_int 1))
13492                       (label_ref (match_operand 0 "" ""))
13493                       (pc)))
13494    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13495         (plus:SI (match_dup 1)
13496                  (const_int -1)))
13497    (clobber (match_scratch:SI 3 "=X,X,r"))
13498    (clobber (reg:CC FLAGS_REG))]
13499   "!TARGET_64BIT && TARGET_USE_LOOP
13500    && (reload_in_progress || reload_completed
13501        || register_operand (operands[2], VOIDmode))"
13503   if (which_alternative != 0)
13504     return "#";
13505   if (get_attr_length (insn) == 2)
13506     return "%+loop\t%l0";
13507   else
13508     return "dec{l}\t%1\;%+jne\t%l0";
13510   [(set (attr "length")
13511         (if_then_else (and (eq_attr "alternative" "0")
13512                            (and (ge (minus (match_dup 0) (pc))
13513                                     (const_int -126))
13514                                 (lt (minus (match_dup 0) (pc))
13515                                     (const_int 128))))
13516                       (const_int 2)
13517                       (const_int 16)))
13518    ;; We don't know the type before shorten branches.  Optimistically expect
13519    ;; the loop instruction to match.
13520    (set (attr "type") (const_string "ibr"))])
13522 (define_split
13523   [(set (pc)
13524         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13525                           (const_int 1))
13526                       (match_operand 0 "" "")
13527                       (pc)))
13528    (set (match_dup 1)
13529         (plus:SI (match_dup 1)
13530                  (const_int -1)))
13531    (clobber (match_scratch:SI 2 ""))
13532    (clobber (reg:CC FLAGS_REG))]
13533   "!TARGET_64BIT && TARGET_USE_LOOP
13534    && reload_completed
13535    && REGNO (operands[1]) != 2"
13536   [(parallel [(set (reg:CCZ FLAGS_REG)
13537                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13538                                  (const_int 0)))
13539               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13540    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13541                            (match_dup 0)
13542                            (pc)))]
13543   "")
13544   
13545 (define_split
13546   [(set (pc)
13547         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13548                           (const_int 1))
13549                       (match_operand 0 "" "")
13550                       (pc)))
13551    (set (match_operand:SI 2 "nonimmediate_operand" "")
13552         (plus:SI (match_dup 1)
13553                  (const_int -1)))
13554    (clobber (match_scratch:SI 3 ""))
13555    (clobber (reg:CC FLAGS_REG))]
13556   "!TARGET_64BIT && TARGET_USE_LOOP
13557    && reload_completed
13558    && (! REG_P (operands[2])
13559        || ! rtx_equal_p (operands[1], operands[2]))"
13560   [(set (match_dup 3) (match_dup 1))
13561    (parallel [(set (reg:CCZ FLAGS_REG)
13562                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13563                                 (const_int 0)))
13564               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13565    (set (match_dup 2) (match_dup 3))
13566    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13567                            (match_dup 0)
13568                            (pc)))]
13569   "")
13571 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13573 (define_peephole2
13574   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13575    (set (match_operand:QI 1 "register_operand" "")
13576         (match_operator:QI 2 "ix86_comparison_operator"
13577           [(reg FLAGS_REG) (const_int 0)]))
13578    (set (match_operand 3 "q_regs_operand" "")
13579         (zero_extend (match_dup 1)))]
13580   "(peep2_reg_dead_p (3, operands[1])
13581     || operands_match_p (operands[1], operands[3]))
13582    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13583   [(set (match_dup 4) (match_dup 0))
13584    (set (strict_low_part (match_dup 5))
13585         (match_dup 2))]
13587   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13588   operands[5] = gen_lowpart (QImode, operands[3]);
13589   ix86_expand_clear (operands[3]);
13592 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13594 (define_peephole2
13595   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13596    (set (match_operand:QI 1 "register_operand" "")
13597         (match_operator:QI 2 "ix86_comparison_operator"
13598           [(reg FLAGS_REG) (const_int 0)]))
13599    (parallel [(set (match_operand 3 "q_regs_operand" "")
13600                    (zero_extend (match_dup 1)))
13601               (clobber (reg:CC FLAGS_REG))])]
13602   "(peep2_reg_dead_p (3, operands[1])
13603     || operands_match_p (operands[1], operands[3]))
13604    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13605   [(set (match_dup 4) (match_dup 0))
13606    (set (strict_low_part (match_dup 5))
13607         (match_dup 2))]
13609   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13610   operands[5] = gen_lowpart (QImode, operands[3]);
13611   ix86_expand_clear (operands[3]);
13614 ;; Call instructions.
13616 ;; The predicates normally associated with named expanders are not properly
13617 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13618 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13620 ;; Call subroutine returning no value.
13622 (define_expand "call_pop"
13623   [(parallel [(call (match_operand:QI 0 "" "")
13624                     (match_operand:SI 1 "" ""))
13625               (set (reg:SI SP_REG)
13626                    (plus:SI (reg:SI SP_REG)
13627                             (match_operand:SI 3 "" "")))])]
13628   "!TARGET_64BIT"
13630   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13631   DONE;
13634 (define_insn "*call_pop_0"
13635   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13636          (match_operand:SI 1 "" ""))
13637    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13638                             (match_operand:SI 2 "immediate_operand" "")))]
13639   "!TARGET_64BIT"
13641   if (SIBLING_CALL_P (insn))
13642     return "jmp\t%P0";
13643   else
13644     return "call\t%P0";
13646   [(set_attr "type" "call")])
13647   
13648 (define_insn "*call_pop_1"
13649   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13650          (match_operand:SI 1 "" ""))
13651    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13652                             (match_operand:SI 2 "immediate_operand" "i")))]
13653   "!TARGET_64BIT"
13655   if (constant_call_address_operand (operands[0], Pmode))
13656     {
13657       if (SIBLING_CALL_P (insn))
13658         return "jmp\t%P0";
13659       else
13660         return "call\t%P0";
13661     }
13662   if (SIBLING_CALL_P (insn))
13663     return "jmp\t%A0";
13664   else
13665     return "call\t%A0";
13667   [(set_attr "type" "call")])
13669 (define_expand "call"
13670   [(call (match_operand:QI 0 "" "")
13671          (match_operand 1 "" ""))
13672    (use (match_operand 2 "" ""))]
13673   ""
13675   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13676   DONE;
13679 (define_expand "sibcall"
13680   [(call (match_operand:QI 0 "" "")
13681          (match_operand 1 "" ""))
13682    (use (match_operand 2 "" ""))]
13683   ""
13685   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13686   DONE;
13689 (define_insn "*call_0"
13690   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13691          (match_operand 1 "" ""))]
13692   ""
13694   if (SIBLING_CALL_P (insn))
13695     return "jmp\t%P0";
13696   else
13697     return "call\t%P0";
13699   [(set_attr "type" "call")])
13701 (define_insn "*call_1"
13702   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13703          (match_operand 1 "" ""))]
13704   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13706   if (constant_call_address_operand (operands[0], Pmode))
13707     return "call\t%P0";
13708   return "call\t%A0";
13710   [(set_attr "type" "call")])
13712 (define_insn "*sibcall_1"
13713   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13714          (match_operand 1 "" ""))]
13715   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13717   if (constant_call_address_operand (operands[0], Pmode))
13718     return "jmp\t%P0";
13719   return "jmp\t%A0";
13721   [(set_attr "type" "call")])
13723 (define_insn "*call_1_rex64"
13724   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13725          (match_operand 1 "" ""))]
13726   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13728   if (constant_call_address_operand (operands[0], Pmode))
13729     return "call\t%P0";
13730   return "call\t%A0";
13732   [(set_attr "type" "call")])
13734 (define_insn "*sibcall_1_rex64"
13735   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13736          (match_operand 1 "" ""))]
13737   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13738   "jmp\t%P0"
13739   [(set_attr "type" "call")])
13741 (define_insn "*sibcall_1_rex64_v"
13742   [(call (mem:QI (reg:DI 40))
13743          (match_operand 0 "" ""))]
13744   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13745   "jmp\t*%%r11"
13746   [(set_attr "type" "call")])
13749 ;; Call subroutine, returning value in operand 0
13751 (define_expand "call_value_pop"
13752   [(parallel [(set (match_operand 0 "" "")
13753                    (call (match_operand:QI 1 "" "")
13754                          (match_operand:SI 2 "" "")))
13755               (set (reg:SI SP_REG)
13756                    (plus:SI (reg:SI SP_REG)
13757                             (match_operand:SI 4 "" "")))])]
13758   "!TARGET_64BIT"
13760   ix86_expand_call (operands[0], operands[1], operands[2],
13761                     operands[3], operands[4], 0);
13762   DONE;
13765 (define_expand "call_value"
13766   [(set (match_operand 0 "" "")
13767         (call (match_operand:QI 1 "" "")
13768               (match_operand:SI 2 "" "")))
13769    (use (match_operand:SI 3 "" ""))]
13770   ;; Operand 2 not used on the i386.
13771   ""
13773   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13774   DONE;
13777 (define_expand "sibcall_value"
13778   [(set (match_operand 0 "" "")
13779         (call (match_operand:QI 1 "" "")
13780               (match_operand:SI 2 "" "")))
13781    (use (match_operand:SI 3 "" ""))]
13782   ;; Operand 2 not used on the i386.
13783   ""
13785   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13786   DONE;
13789 ;; Call subroutine returning any type.
13791 (define_expand "untyped_call"
13792   [(parallel [(call (match_operand 0 "" "")
13793                     (const_int 0))
13794               (match_operand 1 "" "")
13795               (match_operand 2 "" "")])]
13796   ""
13798   int i;
13800   /* In order to give reg-stack an easier job in validating two
13801      coprocessor registers as containing a possible return value,
13802      simply pretend the untyped call returns a complex long double
13803      value.  */
13805   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13806                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13807                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13808                     NULL, 0);
13810   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13811     {
13812       rtx set = XVECEXP (operands[2], 0, i);
13813       emit_move_insn (SET_DEST (set), SET_SRC (set));
13814     }
13816   /* The optimizer does not know that the call sets the function value
13817      registers we stored in the result block.  We avoid problems by
13818      claiming that all hard registers are used and clobbered at this
13819      point.  */
13820   emit_insn (gen_blockage (const0_rtx));
13822   DONE;
13825 ;; Prologue and epilogue instructions
13827 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13828 ;; all of memory.  This blocks insns from being moved across this point.
13830 (define_insn "blockage"
13831   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13832   ""
13833   ""
13834   [(set_attr "length" "0")])
13836 ;; Insn emitted into the body of a function to return from a function.
13837 ;; This is only done if the function's epilogue is known to be simple.
13838 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13840 (define_expand "return"
13841   [(return)]
13842   "ix86_can_use_return_insn_p ()"
13844   if (current_function_pops_args)
13845     {
13846       rtx popc = GEN_INT (current_function_pops_args);
13847       emit_jump_insn (gen_return_pop_internal (popc));
13848       DONE;
13849     }
13852 (define_insn "return_internal"
13853   [(return)]
13854   "reload_completed"
13855   "ret"
13856   [(set_attr "length" "1")
13857    (set_attr "length_immediate" "0")
13858    (set_attr "modrm" "0")])
13860 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13861 ;; instruction Athlon and K8 have.
13863 (define_insn "return_internal_long"
13864   [(return)
13865    (unspec [(const_int 0)] UNSPEC_REP)]
13866   "reload_completed"
13867   "rep {;} ret"
13868   [(set_attr "length" "1")
13869    (set_attr "length_immediate" "0")
13870    (set_attr "prefix_rep" "1")
13871    (set_attr "modrm" "0")])
13873 (define_insn "return_pop_internal"
13874   [(return)
13875    (use (match_operand:SI 0 "const_int_operand" ""))]
13876   "reload_completed"
13877   "ret\t%0"
13878   [(set_attr "length" "3")
13879    (set_attr "length_immediate" "2")
13880    (set_attr "modrm" "0")])
13882 (define_insn "return_indirect_internal"
13883   [(return)
13884    (use (match_operand:SI 0 "register_operand" "r"))]
13885   "reload_completed"
13886   "jmp\t%A0"
13887   [(set_attr "type" "ibr")
13888    (set_attr "length_immediate" "0")])
13890 (define_insn "nop"
13891   [(const_int 0)]
13892   ""
13893   "nop"
13894   [(set_attr "length" "1")
13895    (set_attr "length_immediate" "0")
13896    (set_attr "modrm" "0")])
13898 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13899 ;; branch prediction penalty for the third jump in a 16-byte
13900 ;; block on K8.
13902 (define_insn "align"
13903   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13904   ""
13906 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13907   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13908 #else
13909   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13910      The align insn is used to avoid 3 jump instructions in the row to improve
13911      branch prediction and the benefits hardly outweight the cost of extra 8
13912      nops on the average inserted by full alignment pseudo operation.  */
13913 #endif
13914   return "";
13916   [(set_attr "length" "16")])
13918 (define_expand "prologue"
13919   [(const_int 1)]
13920   ""
13921   "ix86_expand_prologue (); DONE;")
13923 (define_insn "set_got"
13924   [(set (match_operand:SI 0 "register_operand" "=r")
13925         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13926    (clobber (reg:CC FLAGS_REG))]
13927   "!TARGET_64BIT"
13928   { return output_set_got (operands[0]); }
13929   [(set_attr "type" "multi")
13930    (set_attr "length" "12")])
13932 (define_expand "epilogue"
13933   [(const_int 1)]
13934   ""
13935   "ix86_expand_epilogue (1); DONE;")
13937 (define_expand "sibcall_epilogue"
13938   [(const_int 1)]
13939   ""
13940   "ix86_expand_epilogue (0); DONE;")
13942 (define_expand "eh_return"
13943   [(use (match_operand 0 "register_operand" ""))]
13944   ""
13946   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13948   /* Tricky bit: we write the address of the handler to which we will
13949      be returning into someone else's stack frame, one word below the
13950      stack address we wish to restore.  */
13951   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13952   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13953   tmp = gen_rtx_MEM (Pmode, tmp);
13954   emit_move_insn (tmp, ra);
13956   if (Pmode == SImode)
13957     emit_jump_insn (gen_eh_return_si (sa));
13958   else
13959     emit_jump_insn (gen_eh_return_di (sa));
13960   emit_barrier ();
13961   DONE;
13964 (define_insn_and_split "eh_return_si"
13965   [(set (pc) 
13966         (unspec [(match_operand:SI 0 "register_operand" "c")]
13967                  UNSPEC_EH_RETURN))]
13968   "!TARGET_64BIT"
13969   "#"
13970   "reload_completed"
13971   [(const_int 1)]
13972   "ix86_expand_epilogue (2); DONE;")
13974 (define_insn_and_split "eh_return_di"
13975   [(set (pc) 
13976         (unspec [(match_operand:DI 0 "register_operand" "c")]
13977                  UNSPEC_EH_RETURN))]
13978   "TARGET_64BIT"
13979   "#"
13980   "reload_completed"
13981   [(const_int 1)]
13982   "ix86_expand_epilogue (2); DONE;")
13984 (define_insn "leave"
13985   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13986    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13987    (clobber (mem:BLK (scratch)))]
13988   "!TARGET_64BIT"
13989   "leave"
13990   [(set_attr "type" "leave")])
13992 (define_insn "leave_rex64"
13993   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13994    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13995    (clobber (mem:BLK (scratch)))]
13996   "TARGET_64BIT"
13997   "leave"
13998   [(set_attr "type" "leave")])
14000 (define_expand "ffssi2"
14001   [(parallel
14002      [(set (match_operand:SI 0 "register_operand" "") 
14003            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14004       (clobber (match_scratch:SI 2 ""))
14005       (clobber (reg:CC FLAGS_REG))])]
14006   ""
14007   "")
14009 (define_insn_and_split "*ffs_cmove"
14010   [(set (match_operand:SI 0 "register_operand" "=r") 
14011         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14012    (clobber (match_scratch:SI 2 "=&r"))
14013    (clobber (reg:CC FLAGS_REG))]
14014   "TARGET_CMOVE"
14015   "#"
14016   "&& reload_completed"
14017   [(set (match_dup 2) (const_int -1))
14018    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14019               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14020    (set (match_dup 0) (if_then_else:SI
14021                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14022                         (match_dup 2)
14023                         (match_dup 0)))
14024    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14025               (clobber (reg:CC FLAGS_REG))])]
14026   "")
14028 (define_insn_and_split "*ffs_no_cmove"
14029   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14030         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14031    (clobber (match_scratch:SI 2 "=&q"))
14032    (clobber (reg:CC FLAGS_REG))]
14033   ""
14034   "#"
14035   "reload_completed"
14036   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14037               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14038    (set (strict_low_part (match_dup 3))
14039         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14040    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14041               (clobber (reg:CC FLAGS_REG))])
14042    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14043               (clobber (reg:CC FLAGS_REG))])
14044    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14045               (clobber (reg:CC FLAGS_REG))])]
14047   operands[3] = gen_lowpart (QImode, operands[2]);
14048   ix86_expand_clear (operands[2]);
14051 (define_insn "*ffssi_1"
14052   [(set (reg:CCZ FLAGS_REG)
14053         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14054                      (const_int 0)))
14055    (set (match_operand:SI 0 "register_operand" "=r")
14056         (ctz:SI (match_dup 1)))]
14057   ""
14058   "bsf{l}\t{%1, %0|%0, %1}"
14059   [(set_attr "prefix_0f" "1")])
14061 (define_expand "ffsdi2"
14062   [(parallel
14063      [(set (match_operand:DI 0 "register_operand" "") 
14064            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14065       (clobber (match_scratch:DI 2 ""))
14066       (clobber (reg:CC FLAGS_REG))])]
14067   "TARGET_64BIT && TARGET_CMOVE"
14068   "")
14070 (define_insn_and_split "*ffs_rex64"
14071   [(set (match_operand:DI 0 "register_operand" "=r") 
14072         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14073    (clobber (match_scratch:DI 2 "=&r"))
14074    (clobber (reg:CC FLAGS_REG))]
14075   "TARGET_64BIT && TARGET_CMOVE"
14076   "#"
14077   "&& reload_completed"
14078   [(set (match_dup 2) (const_int -1))
14079    (parallel [(set (reg:CCZ FLAGS_REG)
14080                    (compare:CCZ (match_dup 1) (const_int 0)))
14081               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14082    (set (match_dup 0) (if_then_else:DI
14083                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14084                         (match_dup 2)
14085                         (match_dup 0)))
14086    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14087               (clobber (reg:CC FLAGS_REG))])]
14088   "")
14090 (define_insn "*ffsdi_1"
14091   [(set (reg:CCZ FLAGS_REG)
14092         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14093                      (const_int 0)))
14094    (set (match_operand:DI 0 "register_operand" "=r")
14095         (ctz:DI (match_dup 1)))]
14096   "TARGET_64BIT"
14097   "bsf{q}\t{%1, %0|%0, %1}"
14098   [(set_attr "prefix_0f" "1")])
14100 (define_insn "ctzsi2"
14101   [(set (match_operand:SI 0 "register_operand" "=r")
14102         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14103    (clobber (reg:CC FLAGS_REG))]
14104   ""
14105   "bsf{l}\t{%1, %0|%0, %1}"
14106   [(set_attr "prefix_0f" "1")])
14108 (define_insn "ctzdi2"
14109   [(set (match_operand:DI 0 "register_operand" "=r")
14110         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14111    (clobber (reg:CC FLAGS_REG))]
14112   "TARGET_64BIT"
14113   "bsf{q}\t{%1, %0|%0, %1}"
14114   [(set_attr "prefix_0f" "1")])
14116 (define_expand "clzsi2"
14117   [(parallel
14118      [(set (match_operand:SI 0 "register_operand" "")
14119            (minus:SI (const_int 31)
14120                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14121       (clobber (reg:CC FLAGS_REG))])
14122    (parallel
14123      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14124       (clobber (reg:CC FLAGS_REG))])]
14125   ""
14126   "")
14128 (define_insn "*bsr"
14129   [(set (match_operand:SI 0 "register_operand" "=r")
14130         (minus:SI (const_int 31)
14131                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14132    (clobber (reg:CC FLAGS_REG))]
14133   ""
14134   "bsr{l}\t{%1, %0|%0, %1}"
14135   [(set_attr "prefix_0f" "1")])
14137 (define_expand "clzdi2"
14138   [(parallel
14139      [(set (match_operand:DI 0 "register_operand" "")
14140            (minus:DI (const_int 63)
14141                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14142       (clobber (reg:CC FLAGS_REG))])
14143    (parallel
14144      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14145       (clobber (reg:CC FLAGS_REG))])]
14146   "TARGET_64BIT"
14147   "")
14149 (define_insn "*bsr_rex64"
14150   [(set (match_operand:DI 0 "register_operand" "=r")
14151         (minus:DI (const_int 63)
14152                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14153    (clobber (reg:CC FLAGS_REG))]
14154   "TARGET_64BIT"
14155   "bsr{q}\t{%1, %0|%0, %1}"
14156   [(set_attr "prefix_0f" "1")])
14158 ;; Thread-local storage patterns for ELF.
14160 ;; Note that these code sequences must appear exactly as shown
14161 ;; in order to allow linker relaxation.
14163 (define_insn "*tls_global_dynamic_32_gnu"
14164   [(set (match_operand:SI 0 "register_operand" "=a")
14165         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14166                     (match_operand:SI 2 "tls_symbolic_operand" "")
14167                     (match_operand:SI 3 "call_insn_operand" "")]
14168                     UNSPEC_TLS_GD))
14169    (clobber (match_scratch:SI 4 "=d"))
14170    (clobber (match_scratch:SI 5 "=c"))
14171    (clobber (reg:CC FLAGS_REG))]
14172   "!TARGET_64BIT && TARGET_GNU_TLS"
14173   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14174   [(set_attr "type" "multi")
14175    (set_attr "length" "12")])
14177 (define_insn "*tls_global_dynamic_32_sun"
14178   [(set (match_operand:SI 0 "register_operand" "=a")
14179         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14180                     (match_operand:SI 2 "tls_symbolic_operand" "")
14181                     (match_operand:SI 3 "call_insn_operand" "")]
14182                     UNSPEC_TLS_GD))
14183    (clobber (match_scratch:SI 4 "=d"))
14184    (clobber (match_scratch:SI 5 "=c"))
14185    (clobber (reg:CC FLAGS_REG))]
14186   "!TARGET_64BIT && TARGET_SUN_TLS"
14187   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14188         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14189   [(set_attr "type" "multi")
14190    (set_attr "length" "14")])
14192 (define_expand "tls_global_dynamic_32"
14193   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14194                    (unspec:SI
14195                     [(match_dup 2)
14196                      (match_operand:SI 1 "tls_symbolic_operand" "")
14197                      (match_dup 3)]
14198                     UNSPEC_TLS_GD))
14199               (clobber (match_scratch:SI 4 ""))
14200               (clobber (match_scratch:SI 5 ""))
14201               (clobber (reg:CC FLAGS_REG))])]
14202   ""
14204   if (flag_pic)
14205     operands[2] = pic_offset_table_rtx;
14206   else
14207     {
14208       operands[2] = gen_reg_rtx (Pmode);
14209       emit_insn (gen_set_got (operands[2]));
14210     }
14211   operands[3] = ix86_tls_get_addr ();
14214 (define_insn "*tls_global_dynamic_64"
14215   [(set (match_operand:DI 0 "register_operand" "=a")
14216         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14217                       (match_operand:DI 3 "" "")))
14218    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14219               UNSPEC_TLS_GD)]
14220   "TARGET_64BIT"
14221   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14222   [(set_attr "type" "multi")
14223    (set_attr "length" "16")])
14225 (define_expand "tls_global_dynamic_64"
14226   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14227                    (call (mem:QI (match_dup 2)) (const_int 0)))
14228               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14229                          UNSPEC_TLS_GD)])]
14230   ""
14232   operands[2] = ix86_tls_get_addr ();
14235 (define_insn "*tls_local_dynamic_base_32_gnu"
14236   [(set (match_operand:SI 0 "register_operand" "=a")
14237         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14238                     (match_operand:SI 2 "call_insn_operand" "")]
14239                    UNSPEC_TLS_LD_BASE))
14240    (clobber (match_scratch:SI 3 "=d"))
14241    (clobber (match_scratch:SI 4 "=c"))
14242    (clobber (reg:CC FLAGS_REG))]
14243   "!TARGET_64BIT && TARGET_GNU_TLS"
14244   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14245   [(set_attr "type" "multi")
14246    (set_attr "length" "11")])
14248 (define_insn "*tls_local_dynamic_base_32_sun"
14249   [(set (match_operand:SI 0 "register_operand" "=a")
14250         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14251                     (match_operand:SI 2 "call_insn_operand" "")]
14252                    UNSPEC_TLS_LD_BASE))
14253    (clobber (match_scratch:SI 3 "=d"))
14254    (clobber (match_scratch:SI 4 "=c"))
14255    (clobber (reg:CC FLAGS_REG))]
14256   "!TARGET_64BIT && TARGET_SUN_TLS"
14257   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14258         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14259   [(set_attr "type" "multi")
14260    (set_attr "length" "13")])
14262 (define_expand "tls_local_dynamic_base_32"
14263   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14264                    (unspec:SI [(match_dup 1) (match_dup 2)]
14265                               UNSPEC_TLS_LD_BASE))
14266               (clobber (match_scratch:SI 3 ""))
14267               (clobber (match_scratch:SI 4 ""))
14268               (clobber (reg:CC FLAGS_REG))])]
14269   ""
14271   if (flag_pic)
14272     operands[1] = pic_offset_table_rtx;
14273   else
14274     {
14275       operands[1] = gen_reg_rtx (Pmode);
14276       emit_insn (gen_set_got (operands[1]));
14277     }
14278   operands[2] = ix86_tls_get_addr ();
14281 (define_insn "*tls_local_dynamic_base_64"
14282   [(set (match_operand:DI 0 "register_operand" "=a")
14283         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14284                       (match_operand:DI 2 "" "")))
14285    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14286   "TARGET_64BIT"
14287   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14288   [(set_attr "type" "multi")
14289    (set_attr "length" "12")])
14291 (define_expand "tls_local_dynamic_base_64"
14292   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14293                    (call (mem:QI (match_dup 1)) (const_int 0)))
14294               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14295   ""
14297   operands[1] = ix86_tls_get_addr ();
14300 ;; Local dynamic of a single variable is a lose.  Show combine how
14301 ;; to convert that back to global dynamic.
14303 (define_insn_and_split "*tls_local_dynamic_32_once"
14304   [(set (match_operand:SI 0 "register_operand" "=a")
14305         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14306                              (match_operand:SI 2 "call_insn_operand" "")]
14307                             UNSPEC_TLS_LD_BASE)
14308                  (const:SI (unspec:SI
14309                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14310                             UNSPEC_DTPOFF))))
14311    (clobber (match_scratch:SI 4 "=d"))
14312    (clobber (match_scratch:SI 5 "=c"))
14313    (clobber (reg:CC FLAGS_REG))]
14314   ""
14315   "#"
14316   ""
14317   [(parallel [(set (match_dup 0)
14318                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14319                               UNSPEC_TLS_GD))
14320               (clobber (match_dup 4))
14321               (clobber (match_dup 5))
14322               (clobber (reg:CC FLAGS_REG))])]
14323   "")
14325 ;; Load and add the thread base pointer from %gs:0.
14327 (define_insn "*load_tp_si"
14328   [(set (match_operand:SI 0 "register_operand" "=r")
14329         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14330   "!TARGET_64BIT"
14331   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14332   [(set_attr "type" "imov")
14333    (set_attr "modrm" "0")
14334    (set_attr "length" "7")
14335    (set_attr "memory" "load")
14336    (set_attr "imm_disp" "false")])
14338 (define_insn "*add_tp_si"
14339   [(set (match_operand:SI 0 "register_operand" "=r")
14340         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14341                  (match_operand:SI 1 "register_operand" "0")))
14342    (clobber (reg:CC FLAGS_REG))]
14343   "!TARGET_64BIT"
14344   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14345   [(set_attr "type" "alu")
14346    (set_attr "modrm" "0")
14347    (set_attr "length" "7")
14348    (set_attr "memory" "load")
14349    (set_attr "imm_disp" "false")])
14351 (define_insn "*load_tp_di"
14352   [(set (match_operand:DI 0 "register_operand" "=r")
14353         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14354   "TARGET_64BIT"
14355   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14356   [(set_attr "type" "imov")
14357    (set_attr "modrm" "0")
14358    (set_attr "length" "7")
14359    (set_attr "memory" "load")
14360    (set_attr "imm_disp" "false")])
14362 (define_insn "*add_tp_di"
14363   [(set (match_operand:DI 0 "register_operand" "=r")
14364         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14365                  (match_operand:DI 1 "register_operand" "0")))
14366    (clobber (reg:CC FLAGS_REG))]
14367   "TARGET_64BIT"
14368   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14369   [(set_attr "type" "alu")
14370    (set_attr "modrm" "0")
14371    (set_attr "length" "7")
14372    (set_attr "memory" "load")
14373    (set_attr "imm_disp" "false")])
14375 ;; These patterns match the binary 387 instructions for addM3, subM3,
14376 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14377 ;; SFmode.  The first is the normal insn, the second the same insn but
14378 ;; with one operand a conversion, and the third the same insn but with
14379 ;; the other operand a conversion.  The conversion may be SFmode or
14380 ;; SImode if the target mode DFmode, but only SImode if the target mode
14381 ;; is SFmode.
14383 ;; Gcc is slightly more smart about handling normal two address instructions
14384 ;; so use special patterns for add and mull.
14385 (define_insn "*fop_sf_comm_nosse"
14386   [(set (match_operand:SF 0 "register_operand" "=f")
14387         (match_operator:SF 3 "binary_fp_operator"
14388                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14389                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14390   "TARGET_80387 && !TARGET_SSE_MATH
14391    && COMMUTATIVE_ARITH_P (operands[3])
14392    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14393   "* return output_387_binary_op (insn, operands);"
14394   [(set (attr "type") 
14395         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14396            (const_string "fmul")
14397            (const_string "fop")))
14398    (set_attr "mode" "SF")])
14400 (define_insn "*fop_sf_comm"
14401   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14402         (match_operator:SF 3 "binary_fp_operator"
14403                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14404                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14405   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14406    && COMMUTATIVE_ARITH_P (operands[3])
14407    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14408   "* return output_387_binary_op (insn, operands);"
14409   [(set (attr "type") 
14410         (if_then_else (eq_attr "alternative" "1")
14411            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14412               (const_string "ssemul")
14413               (const_string "sseadd"))
14414            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14415               (const_string "fmul")
14416               (const_string "fop"))))
14417    (set_attr "mode" "SF")])
14419 (define_insn "*fop_sf_comm_sse"
14420   [(set (match_operand:SF 0 "register_operand" "=x")
14421         (match_operator:SF 3 "binary_fp_operator"
14422                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14423                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14424   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14425    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14426   "* return output_387_binary_op (insn, operands);"
14427   [(set (attr "type") 
14428         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14429            (const_string "ssemul")
14430            (const_string "sseadd")))
14431    (set_attr "mode" "SF")])
14433 (define_insn "*fop_df_comm_nosse"
14434   [(set (match_operand:DF 0 "register_operand" "=f")
14435         (match_operator:DF 3 "binary_fp_operator"
14436                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14437                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14438   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14439    && COMMUTATIVE_ARITH_P (operands[3])
14440    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14441   "* return output_387_binary_op (insn, operands);"
14442   [(set (attr "type") 
14443         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14444            (const_string "fmul")
14445            (const_string "fop")))
14446    (set_attr "mode" "DF")])
14448 (define_insn "*fop_df_comm"
14449   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14450         (match_operator:DF 3 "binary_fp_operator"
14451                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14452                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14453   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14454    && COMMUTATIVE_ARITH_P (operands[3])
14455    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14456   "* return output_387_binary_op (insn, operands);"
14457   [(set (attr "type") 
14458         (if_then_else (eq_attr "alternative" "1")
14459            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14460               (const_string "ssemul")
14461               (const_string "sseadd"))
14462            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14463               (const_string "fmul")
14464               (const_string "fop"))))
14465    (set_attr "mode" "DF")])
14467 (define_insn "*fop_df_comm_sse"
14468   [(set (match_operand:DF 0 "register_operand" "=Y")
14469         (match_operator:DF 3 "binary_fp_operator"
14470                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14471                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14472   "TARGET_SSE2 && TARGET_SSE_MATH
14473    && COMMUTATIVE_ARITH_P (operands[3])
14474    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14475   "* return output_387_binary_op (insn, operands);"
14476   [(set (attr "type") 
14477         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14478            (const_string "ssemul")
14479            (const_string "sseadd")))
14480    (set_attr "mode" "DF")])
14482 (define_insn "*fop_xf_comm"
14483   [(set (match_operand:XF 0 "register_operand" "=f")
14484         (match_operator:XF 3 "binary_fp_operator"
14485                         [(match_operand:XF 1 "register_operand" "%0")
14486                          (match_operand:XF 2 "register_operand" "f")]))]
14487   "TARGET_80387
14488    && COMMUTATIVE_ARITH_P (operands[3])"
14489   "* return output_387_binary_op (insn, operands);"
14490   [(set (attr "type") 
14491         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14492            (const_string "fmul")
14493            (const_string "fop")))
14494    (set_attr "mode" "XF")])
14496 (define_insn "*fop_sf_1_nosse"
14497   [(set (match_operand:SF 0 "register_operand" "=f,f")
14498         (match_operator:SF 3 "binary_fp_operator"
14499                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14500                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14501   "TARGET_80387 && !TARGET_SSE_MATH
14502    && !COMMUTATIVE_ARITH_P (operands[3])
14503    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14504   "* return output_387_binary_op (insn, operands);"
14505   [(set (attr "type") 
14506         (cond [(match_operand:SF 3 "mult_operator" "") 
14507                  (const_string "fmul")
14508                (match_operand:SF 3 "div_operator" "") 
14509                  (const_string "fdiv")
14510               ]
14511               (const_string "fop")))
14512    (set_attr "mode" "SF")])
14514 (define_insn "*fop_sf_1"
14515   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14516         (match_operator:SF 3 "binary_fp_operator"
14517                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14518                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14519   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14520    && !COMMUTATIVE_ARITH_P (operands[3])
14521    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14522   "* return output_387_binary_op (insn, operands);"
14523   [(set (attr "type") 
14524         (cond [(and (eq_attr "alternative" "2")
14525                     (match_operand:SF 3 "mult_operator" ""))
14526                  (const_string "ssemul")
14527                (and (eq_attr "alternative" "2")
14528                     (match_operand:SF 3 "div_operator" ""))
14529                  (const_string "ssediv")
14530                (eq_attr "alternative" "2")
14531                  (const_string "sseadd")
14532                (match_operand:SF 3 "mult_operator" "") 
14533                  (const_string "fmul")
14534                (match_operand:SF 3 "div_operator" "") 
14535                  (const_string "fdiv")
14536               ]
14537               (const_string "fop")))
14538    (set_attr "mode" "SF")])
14540 (define_insn "*fop_sf_1_sse"
14541   [(set (match_operand:SF 0 "register_operand" "=x")
14542         (match_operator:SF 3 "binary_fp_operator"
14543                         [(match_operand:SF 1 "register_operand" "0")
14544                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14545   "TARGET_SSE_MATH
14546    && !COMMUTATIVE_ARITH_P (operands[3])"
14547   "* return output_387_binary_op (insn, operands);"
14548   [(set (attr "type") 
14549         (cond [(match_operand:SF 3 "mult_operator" "")
14550                  (const_string "ssemul")
14551                (match_operand:SF 3 "div_operator" "")
14552                  (const_string "ssediv")
14553               ]
14554               (const_string "sseadd")))
14555    (set_attr "mode" "SF")])
14557 ;; ??? Add SSE splitters for these!
14558 (define_insn "*fop_sf_2"
14559   [(set (match_operand:SF 0 "register_operand" "=f,f")
14560         (match_operator:SF 3 "binary_fp_operator"
14561           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14562            (match_operand:SF 2 "register_operand" "0,0")]))]
14563   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14564   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14565   [(set (attr "type") 
14566         (cond [(match_operand:SF 3 "mult_operator" "") 
14567                  (const_string "fmul")
14568                (match_operand:SF 3 "div_operator" "") 
14569                  (const_string "fdiv")
14570               ]
14571               (const_string "fop")))
14572    (set_attr "fp_int_src" "true")
14573    (set_attr "mode" "SI")])
14575 (define_insn "*fop_sf_3"
14576   [(set (match_operand:SF 0 "register_operand" "=f,f")
14577         (match_operator:SF 3 "binary_fp_operator"
14578           [(match_operand:SF 1 "register_operand" "0,0")
14579            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14580   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14581   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14582   [(set (attr "type") 
14583         (cond [(match_operand:SF 3 "mult_operator" "") 
14584                  (const_string "fmul")
14585                (match_operand:SF 3 "div_operator" "") 
14586                  (const_string "fdiv")
14587               ]
14588               (const_string "fop")))
14589    (set_attr "fp_int_src" "true")
14590    (set_attr "mode" "SI")])
14592 (define_insn "*fop_df_1_nosse"
14593   [(set (match_operand:DF 0 "register_operand" "=f,f")
14594         (match_operator:DF 3 "binary_fp_operator"
14595                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14596                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14597   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14598    && !COMMUTATIVE_ARITH_P (operands[3])
14599    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14600   "* return output_387_binary_op (insn, operands);"
14601   [(set (attr "type") 
14602         (cond [(match_operand:DF 3 "mult_operator" "") 
14603                  (const_string "fmul")
14604                (match_operand:DF 3 "div_operator" "")
14605                  (const_string "fdiv")
14606               ]
14607               (const_string "fop")))
14608    (set_attr "mode" "DF")])
14611 (define_insn "*fop_df_1"
14612   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14613         (match_operator:DF 3 "binary_fp_operator"
14614                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14615                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14616   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14617    && !COMMUTATIVE_ARITH_P (operands[3])
14618    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14619   "* return output_387_binary_op (insn, operands);"
14620   [(set (attr "type") 
14621         (cond [(and (eq_attr "alternative" "2")
14622                     (match_operand:SF 3 "mult_operator" ""))
14623                  (const_string "ssemul")
14624                (and (eq_attr "alternative" "2")
14625                     (match_operand:SF 3 "div_operator" ""))
14626                  (const_string "ssediv")
14627                (eq_attr "alternative" "2")
14628                  (const_string "sseadd")
14629                (match_operand:DF 3 "mult_operator" "") 
14630                  (const_string "fmul")
14631                (match_operand:DF 3 "div_operator" "") 
14632                  (const_string "fdiv")
14633               ]
14634               (const_string "fop")))
14635    (set_attr "mode" "DF")])
14637 (define_insn "*fop_df_1_sse"
14638   [(set (match_operand:DF 0 "register_operand" "=Y")
14639         (match_operator:DF 3 "binary_fp_operator"
14640                         [(match_operand:DF 1 "register_operand" "0")
14641                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14642   "TARGET_SSE2 && TARGET_SSE_MATH
14643    && !COMMUTATIVE_ARITH_P (operands[3])"
14644   "* return output_387_binary_op (insn, operands);"
14645   [(set_attr "mode" "DF")
14646    (set (attr "type") 
14647         (cond [(match_operand:SF 3 "mult_operator" "")
14648                  (const_string "ssemul")
14649                (match_operand:SF 3 "div_operator" "")
14650                  (const_string "ssediv")
14651               ]
14652               (const_string "sseadd")))])
14654 ;; ??? Add SSE splitters for these!
14655 (define_insn "*fop_df_2"
14656   [(set (match_operand:DF 0 "register_operand" "=f,f")
14657         (match_operator:DF 3 "binary_fp_operator"
14658            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14659             (match_operand:DF 2 "register_operand" "0,0")]))]
14660   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14661   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14662   [(set (attr "type") 
14663         (cond [(match_operand:DF 3 "mult_operator" "") 
14664                  (const_string "fmul")
14665                (match_operand:DF 3 "div_operator" "") 
14666                  (const_string "fdiv")
14667               ]
14668               (const_string "fop")))
14669    (set_attr "fp_int_src" "true")
14670    (set_attr "mode" "SI")])
14672 (define_insn "*fop_df_3"
14673   [(set (match_operand:DF 0 "register_operand" "=f,f")
14674         (match_operator:DF 3 "binary_fp_operator"
14675            [(match_operand:DF 1 "register_operand" "0,0")
14676             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14677   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14678   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14679   [(set (attr "type") 
14680         (cond [(match_operand:DF 3 "mult_operator" "") 
14681                  (const_string "fmul")
14682                (match_operand:DF 3 "div_operator" "") 
14683                  (const_string "fdiv")
14684               ]
14685               (const_string "fop")))
14686    (set_attr "fp_int_src" "true")
14687    (set_attr "mode" "SI")])
14689 (define_insn "*fop_df_4"
14690   [(set (match_operand:DF 0 "register_operand" "=f,f")
14691         (match_operator:DF 3 "binary_fp_operator"
14692            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14693             (match_operand:DF 2 "register_operand" "0,f")]))]
14694   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14695    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14696   "* return output_387_binary_op (insn, operands);"
14697   [(set (attr "type") 
14698         (cond [(match_operand:DF 3 "mult_operator" "") 
14699                  (const_string "fmul")
14700                (match_operand:DF 3 "div_operator" "") 
14701                  (const_string "fdiv")
14702               ]
14703               (const_string "fop")))
14704    (set_attr "mode" "SF")])
14706 (define_insn "*fop_df_5"
14707   [(set (match_operand:DF 0 "register_operand" "=f,f")
14708         (match_operator:DF 3 "binary_fp_operator"
14709           [(match_operand:DF 1 "register_operand" "0,f")
14710            (float_extend:DF
14711             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14712   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14713   "* return output_387_binary_op (insn, operands);"
14714   [(set (attr "type") 
14715         (cond [(match_operand:DF 3 "mult_operator" "") 
14716                  (const_string "fmul")
14717                (match_operand:DF 3 "div_operator" "") 
14718                  (const_string "fdiv")
14719               ]
14720               (const_string "fop")))
14721    (set_attr "mode" "SF")])
14723 (define_insn "*fop_df_6"
14724   [(set (match_operand:DF 0 "register_operand" "=f,f")
14725         (match_operator:DF 3 "binary_fp_operator"
14726           [(float_extend:DF
14727             (match_operand:SF 1 "register_operand" "0,f"))
14728            (float_extend:DF
14729             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14730   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14731   "* return output_387_binary_op (insn, operands);"
14732   [(set (attr "type") 
14733         (cond [(match_operand:DF 3 "mult_operator" "") 
14734                  (const_string "fmul")
14735                (match_operand:DF 3 "div_operator" "") 
14736                  (const_string "fdiv")
14737               ]
14738               (const_string "fop")))
14739    (set_attr "mode" "SF")])
14741 (define_insn "*fop_xf_1"
14742   [(set (match_operand:XF 0 "register_operand" "=f,f")
14743         (match_operator:XF 3 "binary_fp_operator"
14744                         [(match_operand:XF 1 "register_operand" "0,f")
14745                          (match_operand:XF 2 "register_operand" "f,0")]))]
14746   "TARGET_80387
14747    && !COMMUTATIVE_ARITH_P (operands[3])"
14748   "* return output_387_binary_op (insn, operands);"
14749   [(set (attr "type") 
14750         (cond [(match_operand:XF 3 "mult_operator" "") 
14751                  (const_string "fmul")
14752                (match_operand:XF 3 "div_operator" "") 
14753                  (const_string "fdiv")
14754               ]
14755               (const_string "fop")))
14756    (set_attr "mode" "XF")])
14758 (define_insn "*fop_xf_2"
14759   [(set (match_operand:XF 0 "register_operand" "=f,f")
14760         (match_operator:XF 3 "binary_fp_operator"
14761            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14762             (match_operand:XF 2 "register_operand" "0,0")]))]
14763   "TARGET_80387 && TARGET_USE_FIOP"
14764   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14765   [(set (attr "type") 
14766         (cond [(match_operand:XF 3 "mult_operator" "") 
14767                  (const_string "fmul")
14768                (match_operand:XF 3 "div_operator" "") 
14769                  (const_string "fdiv")
14770               ]
14771               (const_string "fop")))
14772    (set_attr "fp_int_src" "true")
14773    (set_attr "mode" "SI")])
14775 (define_insn "*fop_xf_3"
14776   [(set (match_operand:XF 0 "register_operand" "=f,f")
14777         (match_operator:XF 3 "binary_fp_operator"
14778           [(match_operand:XF 1 "register_operand" "0,0")
14779            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14780   "TARGET_80387 && TARGET_USE_FIOP"
14781   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14782   [(set (attr "type") 
14783         (cond [(match_operand:XF 3 "mult_operator" "") 
14784                  (const_string "fmul")
14785                (match_operand:XF 3 "div_operator" "") 
14786                  (const_string "fdiv")
14787               ]
14788               (const_string "fop")))
14789    (set_attr "fp_int_src" "true")
14790    (set_attr "mode" "SI")])
14792 (define_insn "*fop_xf_4"
14793   [(set (match_operand:XF 0 "register_operand" "=f,f")
14794         (match_operator:XF 3 "binary_fp_operator"
14795            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14796             (match_operand:XF 2 "register_operand" "0,f")]))]
14797   "TARGET_80387"
14798   "* return output_387_binary_op (insn, operands);"
14799   [(set (attr "type") 
14800         (cond [(match_operand:XF 3 "mult_operator" "") 
14801                  (const_string "fmul")
14802                (match_operand:XF 3 "div_operator" "") 
14803                  (const_string "fdiv")
14804               ]
14805               (const_string "fop")))
14806    (set_attr "mode" "SF")])
14808 (define_insn "*fop_xf_5"
14809   [(set (match_operand:XF 0 "register_operand" "=f,f")
14810         (match_operator:XF 3 "binary_fp_operator"
14811           [(match_operand:XF 1 "register_operand" "0,f")
14812            (float_extend:XF
14813             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14814   "TARGET_80387"
14815   "* return output_387_binary_op (insn, operands);"
14816   [(set (attr "type") 
14817         (cond [(match_operand:XF 3 "mult_operator" "") 
14818                  (const_string "fmul")
14819                (match_operand:XF 3 "div_operator" "") 
14820                  (const_string "fdiv")
14821               ]
14822               (const_string "fop")))
14823    (set_attr "mode" "SF")])
14825 (define_insn "*fop_xf_6"
14826   [(set (match_operand:XF 0 "register_operand" "=f,f")
14827         (match_operator:XF 3 "binary_fp_operator"
14828           [(float_extend:XF
14829             (match_operand 1 "register_operand" "0,f"))
14830            (float_extend:XF
14831             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14832   "TARGET_80387"
14833   "* return output_387_binary_op (insn, operands);"
14834   [(set (attr "type") 
14835         (cond [(match_operand:XF 3 "mult_operator" "") 
14836                  (const_string "fmul")
14837                (match_operand:XF 3 "div_operator" "") 
14838                  (const_string "fdiv")
14839               ]
14840               (const_string "fop")))
14841    (set_attr "mode" "SF")])
14843 (define_split
14844   [(set (match_operand 0 "register_operand" "")
14845         (match_operator 3 "binary_fp_operator"
14846            [(float (match_operand:SI 1 "register_operand" ""))
14847             (match_operand 2 "register_operand" "")]))]
14848   "TARGET_80387 && reload_completed
14849    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14850   [(const_int 0)]
14852   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14853   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14854   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14855                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14856                                           GET_MODE (operands[3]),
14857                                           operands[4],
14858                                           operands[2])));
14859   ix86_free_from_memory (GET_MODE (operands[1]));
14860   DONE;
14863 (define_split
14864   [(set (match_operand 0 "register_operand" "")
14865         (match_operator 3 "binary_fp_operator"
14866            [(match_operand 1 "register_operand" "")
14867             (float (match_operand:SI 2 "register_operand" ""))]))]
14868   "TARGET_80387 && reload_completed
14869    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14870   [(const_int 0)]
14872   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14873   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14874   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14875                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14876                                           GET_MODE (operands[3]),
14877                                           operands[1],
14878                                           operands[4])));
14879   ix86_free_from_memory (GET_MODE (operands[2]));
14880   DONE;
14883 ;; FPU special functions.
14885 (define_expand "sqrtsf2"
14886   [(set (match_operand:SF 0 "register_operand" "")
14887         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14888   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14890   if (!TARGET_SSE_MATH)
14891     operands[1] = force_reg (SFmode, operands[1]);
14894 (define_insn "sqrtsf2_1"
14895   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14896         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14897   "TARGET_USE_FANCY_MATH_387
14898    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14899   "@
14900    fsqrt
14901    sqrtss\t{%1, %0|%0, %1}"
14902   [(set_attr "type" "fpspc,sse")
14903    (set_attr "mode" "SF,SF")
14904    (set_attr "athlon_decode" "direct,*")])
14906 (define_insn "sqrtsf2_1_sse_only"
14907   [(set (match_operand:SF 0 "register_operand" "=x")
14908         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14909   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14910   "sqrtss\t{%1, %0|%0, %1}"
14911   [(set_attr "type" "sse")
14912    (set_attr "mode" "SF")
14913    (set_attr "athlon_decode" "*")])
14915 (define_insn "sqrtsf2_i387"
14916   [(set (match_operand:SF 0 "register_operand" "=f")
14917         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14918   "TARGET_USE_FANCY_MATH_387
14919    && !TARGET_SSE_MATH"
14920   "fsqrt"
14921   [(set_attr "type" "fpspc")
14922    (set_attr "mode" "SF")
14923    (set_attr "athlon_decode" "direct")])
14925 (define_expand "sqrtdf2"
14926   [(set (match_operand:DF 0 "register_operand" "")
14927         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14928   "TARGET_USE_FANCY_MATH_387
14929    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14931   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14932     operands[1] = force_reg (DFmode, operands[1]);
14935 (define_insn "sqrtdf2_1"
14936   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14937         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14938   "TARGET_USE_FANCY_MATH_387
14939    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14940   "@
14941    fsqrt
14942    sqrtsd\t{%1, %0|%0, %1}"
14943   [(set_attr "type" "fpspc,sse")
14944    (set_attr "mode" "DF,DF")
14945    (set_attr "athlon_decode" "direct,*")])
14947 (define_insn "sqrtdf2_1_sse_only"
14948   [(set (match_operand:DF 0 "register_operand" "=Y")
14949         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14950   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14951   "sqrtsd\t{%1, %0|%0, %1}"
14952   [(set_attr "type" "sse")
14953    (set_attr "mode" "DF")
14954    (set_attr "athlon_decode" "*")])
14956 (define_insn "sqrtdf2_i387"
14957   [(set (match_operand:DF 0 "register_operand" "=f")
14958         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14959   "TARGET_USE_FANCY_MATH_387
14960    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14961   "fsqrt"
14962   [(set_attr "type" "fpspc")
14963    (set_attr "mode" "DF")
14964    (set_attr "athlon_decode" "direct")])
14966 (define_insn "*sqrtextendsfdf2"
14967   [(set (match_operand:DF 0 "register_operand" "=f")
14968         (sqrt:DF (float_extend:DF
14969                   (match_operand:SF 1 "register_operand" "0"))))]
14970   "TARGET_USE_FANCY_MATH_387
14971    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14972   "fsqrt"
14973   [(set_attr "type" "fpspc")
14974    (set_attr "mode" "DF")
14975    (set_attr "athlon_decode" "direct")])
14977 (define_insn "sqrtxf2"
14978   [(set (match_operand:XF 0 "register_operand" "=f")
14979         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14980   "TARGET_USE_FANCY_MATH_387 
14981    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14982   "fsqrt"
14983   [(set_attr "type" "fpspc")
14984    (set_attr "mode" "XF")
14985    (set_attr "athlon_decode" "direct")])
14987 (define_insn "*sqrtextenddfxf2"
14988   [(set (match_operand:XF 0 "register_operand" "=f")
14989         (sqrt:XF (float_extend:XF
14990                   (match_operand:DF 1 "register_operand" "0"))))]
14991   "TARGET_USE_FANCY_MATH_387"
14992   "fsqrt"
14993   [(set_attr "type" "fpspc")
14994    (set_attr "mode" "XF")
14995    (set_attr "athlon_decode" "direct")])
14997 (define_insn "*sqrtextendsfxf2"
14998   [(set (match_operand:XF 0 "register_operand" "=f")
14999         (sqrt:XF (float_extend:XF
15000                   (match_operand:SF 1 "register_operand" "0"))))]
15001   "TARGET_USE_FANCY_MATH_387"
15002   "fsqrt"
15003   [(set_attr "type" "fpspc")
15004    (set_attr "mode" "XF")
15005    (set_attr "athlon_decode" "direct")])
15007 (define_insn "fpremxf4"
15008   [(set (match_operand:XF 0 "register_operand" "=f")
15009         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15010                     (match_operand:XF 3 "register_operand" "1")]
15011                    UNSPEC_FPREM_F))
15012    (set (match_operand:XF 1 "register_operand" "=u")
15013         (unspec:XF [(match_dup 2) (match_dup 3)]
15014                    UNSPEC_FPREM_U))
15015    (set (reg:CCFP FPSR_REG)
15016         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15017   "TARGET_USE_FANCY_MATH_387
15018    && flag_unsafe_math_optimizations"
15019   "fprem"
15020   [(set_attr "type" "fpspc")
15021    (set_attr "mode" "XF")])
15023 (define_expand "fmodsf3"
15024   [(use (match_operand:SF 0 "register_operand" ""))
15025    (use (match_operand:SF 1 "register_operand" ""))
15026    (use (match_operand:SF 2 "register_operand" ""))]
15027   "TARGET_USE_FANCY_MATH_387
15028    && flag_unsafe_math_optimizations"
15030   rtx label = gen_label_rtx ();
15032   rtx op1 = gen_reg_rtx (XFmode);
15033   rtx op2 = gen_reg_rtx (XFmode);
15035   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15036   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15038   emit_label (label);
15040   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15041   ix86_emit_fp_unordered_jump (label);
15043   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15044   DONE;
15047 (define_expand "fmoddf3"
15048   [(use (match_operand:DF 0 "register_operand" ""))
15049    (use (match_operand:DF 1 "register_operand" ""))
15050    (use (match_operand:DF 2 "register_operand" ""))]
15051   "TARGET_USE_FANCY_MATH_387
15052    && flag_unsafe_math_optimizations"
15054   rtx label = gen_label_rtx ();
15056   rtx op1 = gen_reg_rtx (XFmode);
15057   rtx op2 = gen_reg_rtx (XFmode);
15059   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15060   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15062   emit_label (label);
15064   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15065   ix86_emit_fp_unordered_jump (label);
15067   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15068   DONE;
15071 (define_expand "fmodxf3"
15072   [(use (match_operand:XF 0 "register_operand" ""))
15073    (use (match_operand:XF 1 "register_operand" ""))
15074    (use (match_operand:XF 2 "register_operand" ""))]
15075   "TARGET_USE_FANCY_MATH_387
15076    && flag_unsafe_math_optimizations"
15078   rtx label = gen_label_rtx ();
15080   emit_label (label);
15082   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15083                            operands[1], operands[2]));
15084   ix86_emit_fp_unordered_jump (label);
15086   emit_move_insn (operands[0], operands[1]);
15087   DONE;
15090 (define_insn "fprem1xf4"
15091   [(set (match_operand:XF 0 "register_operand" "=f")
15092         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15093                     (match_operand:XF 3 "register_operand" "1")]
15094                    UNSPEC_FPREM1_F))
15095    (set (match_operand:XF 1 "register_operand" "=u")
15096         (unspec:XF [(match_dup 2) (match_dup 3)]
15097                    UNSPEC_FPREM1_U))
15098    (set (reg:CCFP FPSR_REG)
15099         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15100   "TARGET_USE_FANCY_MATH_387
15101    && flag_unsafe_math_optimizations"
15102   "fprem1"
15103   [(set_attr "type" "fpspc")
15104    (set_attr "mode" "XF")])
15106 (define_expand "dremsf3"
15107   [(use (match_operand:SF 0 "register_operand" ""))
15108    (use (match_operand:SF 1 "register_operand" ""))
15109    (use (match_operand:SF 2 "register_operand" ""))]
15110   "TARGET_USE_FANCY_MATH_387
15111    && flag_unsafe_math_optimizations"
15113   rtx label = gen_label_rtx ();
15115   rtx op1 = gen_reg_rtx (XFmode);
15116   rtx op2 = gen_reg_rtx (XFmode);
15118   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15119   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15121   emit_label (label);
15123   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15124   ix86_emit_fp_unordered_jump (label);
15126   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15127   DONE;
15130 (define_expand "dremdf3"
15131   [(use (match_operand:DF 0 "register_operand" ""))
15132    (use (match_operand:DF 1 "register_operand" ""))
15133    (use (match_operand:DF 2 "register_operand" ""))]
15134   "TARGET_USE_FANCY_MATH_387
15135    && flag_unsafe_math_optimizations"
15137   rtx label = gen_label_rtx ();
15139   rtx op1 = gen_reg_rtx (XFmode);
15140   rtx op2 = gen_reg_rtx (XFmode);
15142   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15143   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15145   emit_label (label);
15147   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15148   ix86_emit_fp_unordered_jump (label);
15150   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15151   DONE;
15154 (define_expand "dremxf3"
15155   [(use (match_operand:XF 0 "register_operand" ""))
15156    (use (match_operand:XF 1 "register_operand" ""))
15157    (use (match_operand:XF 2 "register_operand" ""))]
15158   "TARGET_USE_FANCY_MATH_387
15159    && flag_unsafe_math_optimizations"
15161   rtx label = gen_label_rtx ();
15163   emit_label (label);
15165   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15166                             operands[1], operands[2]));
15167   ix86_emit_fp_unordered_jump (label);
15169   emit_move_insn (operands[0], operands[1]);
15170   DONE;
15173 (define_insn "*sindf2"
15174   [(set (match_operand:DF 0 "register_operand" "=f")
15175         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15176   "TARGET_USE_FANCY_MATH_387
15177    && flag_unsafe_math_optimizations"
15178   "fsin"
15179   [(set_attr "type" "fpspc")
15180    (set_attr "mode" "DF")])
15182 (define_insn "*sinsf2"
15183   [(set (match_operand:SF 0 "register_operand" "=f")
15184         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15185   "TARGET_USE_FANCY_MATH_387
15186    && flag_unsafe_math_optimizations"
15187   "fsin"
15188   [(set_attr "type" "fpspc")
15189    (set_attr "mode" "SF")])
15191 (define_insn "*sinextendsfdf2"
15192   [(set (match_operand:DF 0 "register_operand" "=f")
15193         (unspec:DF [(float_extend:DF
15194                      (match_operand:SF 1 "register_operand" "0"))]
15195                    UNSPEC_SIN))]
15196   "TARGET_USE_FANCY_MATH_387
15197    && flag_unsafe_math_optimizations"
15198   "fsin"
15199   [(set_attr "type" "fpspc")
15200    (set_attr "mode" "DF")])
15202 (define_insn "*sinxf2"
15203   [(set (match_operand:XF 0 "register_operand" "=f")
15204         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15205   "TARGET_USE_FANCY_MATH_387
15206    && flag_unsafe_math_optimizations"
15207   "fsin"
15208   [(set_attr "type" "fpspc")
15209    (set_attr "mode" "XF")])
15211 (define_insn "*cosdf2"
15212   [(set (match_operand:DF 0 "register_operand" "=f")
15213         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15214   "TARGET_USE_FANCY_MATH_387
15215    && flag_unsafe_math_optimizations"
15216   "fcos"
15217   [(set_attr "type" "fpspc")
15218    (set_attr "mode" "DF")])
15220 (define_insn "*cossf2"
15221   [(set (match_operand:SF 0 "register_operand" "=f")
15222         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15223   "TARGET_USE_FANCY_MATH_387
15224    && flag_unsafe_math_optimizations"
15225   "fcos"
15226   [(set_attr "type" "fpspc")
15227    (set_attr "mode" "SF")])
15229 (define_insn "*cosextendsfdf2"
15230   [(set (match_operand:DF 0 "register_operand" "=f")
15231         (unspec:DF [(float_extend:DF
15232                      (match_operand:SF 1 "register_operand" "0"))]
15233                    UNSPEC_COS))]
15234   "TARGET_USE_FANCY_MATH_387
15235    && flag_unsafe_math_optimizations"
15236   "fcos"
15237   [(set_attr "type" "fpspc")
15238    (set_attr "mode" "DF")])
15240 (define_insn "*cosxf2"
15241   [(set (match_operand:XF 0 "register_operand" "=f")
15242         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15243   "TARGET_USE_FANCY_MATH_387
15244    && flag_unsafe_math_optimizations"
15245   "fcos"
15246   [(set_attr "type" "fpspc")
15247    (set_attr "mode" "XF")])
15249 ;; With sincos pattern defined, sin and cos builtin function will be
15250 ;; expanded to sincos pattern with one of its outputs left unused. 
15251 ;; Cse pass  will detected, if two sincos patterns can be combined,
15252 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15253 ;; depending on the unused output.
15255 (define_insn "sincosdf3"
15256   [(set (match_operand:DF 0 "register_operand" "=f")
15257         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15258                    UNSPEC_SINCOS_COS))
15259    (set (match_operand:DF 1 "register_operand" "=u")
15260         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15261   "TARGET_USE_FANCY_MATH_387
15262    && flag_unsafe_math_optimizations"
15263   "fsincos"
15264   [(set_attr "type" "fpspc")
15265    (set_attr "mode" "DF")])
15267 (define_split
15268   [(set (match_operand:DF 0 "register_operand" "")
15269         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15270                    UNSPEC_SINCOS_COS))
15271    (set (match_operand:DF 1 "register_operand" "")
15272         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15273   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15274    && !reload_completed && !reload_in_progress"
15275   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15276   "")
15278 (define_split
15279   [(set (match_operand:DF 0 "register_operand" "")
15280         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15281                    UNSPEC_SINCOS_COS))
15282    (set (match_operand:DF 1 "register_operand" "")
15283         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15284   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15285    && !reload_completed && !reload_in_progress"
15286   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15287   "")
15289 (define_insn "sincossf3"
15290   [(set (match_operand:SF 0 "register_operand" "=f")
15291         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15292                    UNSPEC_SINCOS_COS))
15293    (set (match_operand:SF 1 "register_operand" "=u")
15294         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15295   "TARGET_USE_FANCY_MATH_387
15296    && flag_unsafe_math_optimizations"
15297   "fsincos"
15298   [(set_attr "type" "fpspc")
15299    (set_attr "mode" "SF")])
15301 (define_split
15302   [(set (match_operand:SF 0 "register_operand" "")
15303         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15304                    UNSPEC_SINCOS_COS))
15305    (set (match_operand:SF 1 "register_operand" "")
15306         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15307   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15308    && !reload_completed && !reload_in_progress"
15309   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15310   "")
15312 (define_split
15313   [(set (match_operand:SF 0 "register_operand" "")
15314         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15315                    UNSPEC_SINCOS_COS))
15316    (set (match_operand:SF 1 "register_operand" "")
15317         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15318   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15319    && !reload_completed && !reload_in_progress"
15320   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15321   "")
15323 (define_insn "*sincosextendsfdf3"
15324   [(set (match_operand:DF 0 "register_operand" "=f")
15325         (unspec:DF [(float_extend:DF
15326                      (match_operand:SF 2 "register_operand" "0"))]
15327                    UNSPEC_SINCOS_COS))
15328    (set (match_operand:DF 1 "register_operand" "=u")
15329         (unspec:DF [(float_extend:DF
15330                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15331   "TARGET_USE_FANCY_MATH_387
15332    && flag_unsafe_math_optimizations"
15333   "fsincos"
15334   [(set_attr "type" "fpspc")
15335    (set_attr "mode" "DF")])
15337 (define_split
15338   [(set (match_operand:DF 0 "register_operand" "")
15339         (unspec:DF [(float_extend:DF
15340                      (match_operand:SF 2 "register_operand" ""))]
15341                    UNSPEC_SINCOS_COS))
15342    (set (match_operand:DF 1 "register_operand" "")
15343         (unspec:DF [(float_extend:DF
15344                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15345   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15346    && !reload_completed && !reload_in_progress"
15347   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15348                                    (match_dup 2))] UNSPEC_SIN))]
15349   "")
15351 (define_split
15352   [(set (match_operand:DF 0 "register_operand" "")
15353         (unspec:DF [(float_extend:DF
15354                      (match_operand:SF 2 "register_operand" ""))]
15355                    UNSPEC_SINCOS_COS))
15356    (set (match_operand:DF 1 "register_operand" "")
15357         (unspec:DF [(float_extend:DF
15358                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15359   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15360    && !reload_completed && !reload_in_progress"
15361   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15362                                    (match_dup 2))] UNSPEC_COS))]
15363   "")
15365 (define_insn "sincosxf3"
15366   [(set (match_operand:XF 0 "register_operand" "=f")
15367         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15368                    UNSPEC_SINCOS_COS))
15369    (set (match_operand:XF 1 "register_operand" "=u")
15370         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15371   "TARGET_USE_FANCY_MATH_387
15372    && flag_unsafe_math_optimizations"
15373   "fsincos"
15374   [(set_attr "type" "fpspc")
15375    (set_attr "mode" "XF")])
15377 (define_split
15378   [(set (match_operand:XF 0 "register_operand" "")
15379         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15380                    UNSPEC_SINCOS_COS))
15381    (set (match_operand:XF 1 "register_operand" "")
15382         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15383   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15384    && !reload_completed && !reload_in_progress"
15385   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15386   "")
15388 (define_split
15389   [(set (match_operand:XF 0 "register_operand" "")
15390         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15391                    UNSPEC_SINCOS_COS))
15392    (set (match_operand:XF 1 "register_operand" "")
15393         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15394   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15395    && !reload_completed && !reload_in_progress"
15396   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15397   "")
15399 (define_insn "*tandf3_1"
15400   [(set (match_operand:DF 0 "register_operand" "=f")
15401         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15402                    UNSPEC_TAN_ONE))
15403    (set (match_operand:DF 1 "register_operand" "=u")
15404         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15405   "TARGET_USE_FANCY_MATH_387
15406    && flag_unsafe_math_optimizations"
15407   "fptan"
15408   [(set_attr "type" "fpspc")
15409    (set_attr "mode" "DF")])
15411 ;; optimize sequence: fptan
15412 ;;                    fstp    %st(0)
15413 ;;                    fld1
15414 ;; into fptan insn.
15416 (define_peephole2
15417   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15418                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15419                              UNSPEC_TAN_ONE))
15420              (set (match_operand:DF 1 "register_operand" "")
15421                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15422    (set (match_dup 0)
15423         (match_operand:DF 3 "immediate_operand" ""))]
15424   "standard_80387_constant_p (operands[3]) == 2"
15425   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15426              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15427   "")
15429 (define_expand "tandf2"
15430   [(parallel [(set (match_dup 2)
15431                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15432                               UNSPEC_TAN_ONE))
15433               (set (match_operand:DF 0 "register_operand" "")
15434                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15435   "TARGET_USE_FANCY_MATH_387
15436    && flag_unsafe_math_optimizations"
15438   operands[2] = gen_reg_rtx (DFmode);
15441 (define_insn "*tansf3_1"
15442   [(set (match_operand:SF 0 "register_operand" "=f")
15443         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15444                    UNSPEC_TAN_ONE))
15445    (set (match_operand:SF 1 "register_operand" "=u")
15446         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15447   "TARGET_USE_FANCY_MATH_387
15448    && flag_unsafe_math_optimizations"
15449   "fptan"
15450   [(set_attr "type" "fpspc")
15451    (set_attr "mode" "SF")])
15453 ;; optimize sequence: fptan
15454 ;;                    fstp    %st(0)
15455 ;;                    fld1
15456 ;; into fptan insn.
15458 (define_peephole2
15459   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15460                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15461                              UNSPEC_TAN_ONE))
15462              (set (match_operand:SF 1 "register_operand" "")
15463                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15464    (set (match_dup 0)
15465         (match_operand:SF 3 "immediate_operand" ""))]
15466   "standard_80387_constant_p (operands[3]) == 2"
15467   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15468              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15469   "")
15471 (define_expand "tansf2"
15472   [(parallel [(set (match_dup 2)
15473                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15474                               UNSPEC_TAN_ONE))
15475               (set (match_operand:SF 0 "register_operand" "")
15476                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15477   "TARGET_USE_FANCY_MATH_387
15478    && flag_unsafe_math_optimizations"
15480   operands[2] = gen_reg_rtx (SFmode);
15483 (define_insn "*tanxf3_1"
15484   [(set (match_operand:XF 0 "register_operand" "=f")
15485         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15486                    UNSPEC_TAN_ONE))
15487    (set (match_operand:XF 1 "register_operand" "=u")
15488         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15489   "TARGET_USE_FANCY_MATH_387
15490    && flag_unsafe_math_optimizations"
15491   "fptan"
15492   [(set_attr "type" "fpspc")
15493    (set_attr "mode" "XF")])
15495 ;; optimize sequence: fptan
15496 ;;                    fstp    %st(0)
15497 ;;                    fld1
15498 ;; into fptan insn.
15500 (define_peephole2
15501   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15502                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15503                              UNSPEC_TAN_ONE))
15504              (set (match_operand:XF 1 "register_operand" "")
15505                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15506    (set (match_dup 0)
15507         (match_operand:XF 3 "immediate_operand" ""))]
15508   "standard_80387_constant_p (operands[3]) == 2"
15509   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15510              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15511   "")
15513 (define_expand "tanxf2"
15514   [(parallel [(set (match_dup 2)
15515                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15516                               UNSPEC_TAN_ONE))
15517               (set (match_operand:XF 0 "register_operand" "")
15518                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15519   "TARGET_USE_FANCY_MATH_387
15520    && flag_unsafe_math_optimizations"
15522   operands[2] = gen_reg_rtx (XFmode);
15525 (define_insn "atan2df3_1"
15526   [(set (match_operand:DF 0 "register_operand" "=f")
15527         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15528                     (match_operand:DF 1 "register_operand" "u")]
15529                    UNSPEC_FPATAN))
15530    (clobber (match_scratch:DF 3 "=1"))]
15531   "TARGET_USE_FANCY_MATH_387
15532    && flag_unsafe_math_optimizations"
15533   "fpatan"
15534   [(set_attr "type" "fpspc")
15535    (set_attr "mode" "DF")])
15537 (define_expand "atan2df3"
15538   [(use (match_operand:DF 0 "register_operand" "=f"))
15539    (use (match_operand:DF 2 "register_operand" "0"))
15540    (use (match_operand:DF 1 "register_operand" "u"))]
15541   "TARGET_USE_FANCY_MATH_387
15542    && flag_unsafe_math_optimizations"
15544   rtx copy = gen_reg_rtx (DFmode);
15545   emit_move_insn (copy, operands[1]);
15546   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15547   DONE;
15550 (define_expand "atandf2"
15551   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15552                    (unspec:DF [(match_dup 2)
15553                                (match_operand:DF 1 "register_operand" "")]
15554                     UNSPEC_FPATAN))
15555               (clobber (match_scratch:DF 3 ""))])]
15556   "TARGET_USE_FANCY_MATH_387
15557    && flag_unsafe_math_optimizations"
15559   operands[2] = gen_reg_rtx (DFmode);
15560   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15563 (define_insn "atan2sf3_1"
15564   [(set (match_operand:SF 0 "register_operand" "=f")
15565         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15566                     (match_operand:SF 1 "register_operand" "u")]
15567                    UNSPEC_FPATAN))
15568    (clobber (match_scratch:SF 3 "=1"))]
15569   "TARGET_USE_FANCY_MATH_387
15570    && flag_unsafe_math_optimizations"
15571   "fpatan"
15572   [(set_attr "type" "fpspc")
15573    (set_attr "mode" "SF")])
15575 (define_expand "atan2sf3"
15576   [(use (match_operand:SF 0 "register_operand" "=f"))
15577    (use (match_operand:SF 2 "register_operand" "0"))
15578    (use (match_operand:SF 1 "register_operand" "u"))]
15579   "TARGET_USE_FANCY_MATH_387
15580    && flag_unsafe_math_optimizations"
15582   rtx copy = gen_reg_rtx (SFmode);
15583   emit_move_insn (copy, operands[1]);
15584   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15585   DONE;
15588 (define_expand "atansf2"
15589   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15590                    (unspec:SF [(match_dup 2)
15591                                (match_operand:SF 1 "register_operand" "")]
15592                     UNSPEC_FPATAN))
15593               (clobber (match_scratch:SF 3 ""))])]
15594   "TARGET_USE_FANCY_MATH_387
15595    && flag_unsafe_math_optimizations"
15597   operands[2] = gen_reg_rtx (SFmode);
15598   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15601 (define_insn "atan2xf3_1"
15602   [(set (match_operand:XF 0 "register_operand" "=f")
15603         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15604                     (match_operand:XF 1 "register_operand" "u")]
15605                    UNSPEC_FPATAN))
15606    (clobber (match_scratch:XF 3 "=1"))]
15607   "TARGET_USE_FANCY_MATH_387
15608    && flag_unsafe_math_optimizations"
15609   "fpatan"
15610   [(set_attr "type" "fpspc")
15611    (set_attr "mode" "XF")])
15613 (define_expand "atan2xf3"
15614   [(use (match_operand:XF 0 "register_operand" "=f"))
15615    (use (match_operand:XF 2 "register_operand" "0"))
15616    (use (match_operand:XF 1 "register_operand" "u"))]
15617   "TARGET_USE_FANCY_MATH_387
15618    && flag_unsafe_math_optimizations"
15620   rtx copy = gen_reg_rtx (XFmode);
15621   emit_move_insn (copy, operands[1]);
15622   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15623   DONE;
15626 (define_expand "atanxf2"
15627   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15628                    (unspec:XF [(match_dup 2)
15629                                (match_operand:XF 1 "register_operand" "")]
15630                     UNSPEC_FPATAN))
15631               (clobber (match_scratch:XF 3 ""))])]
15632   "TARGET_USE_FANCY_MATH_387
15633    && flag_unsafe_math_optimizations"
15635   operands[2] = gen_reg_rtx (XFmode);
15636   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15639 (define_expand "asindf2"
15640   [(set (match_dup 2)
15641         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15642    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15643    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15644    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15645    (parallel [(set (match_dup 7)
15646                    (unspec:XF [(match_dup 6) (match_dup 2)]
15647                               UNSPEC_FPATAN))
15648               (clobber (match_scratch:XF 8 ""))])
15649    (set (match_operand:DF 0 "register_operand" "")
15650         (float_truncate:DF (match_dup 7)))]
15651   "TARGET_USE_FANCY_MATH_387
15652    && flag_unsafe_math_optimizations"
15654   int i;
15656   for (i=2; i<8; i++)
15657     operands[i] = gen_reg_rtx (XFmode);
15659   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15662 (define_expand "asinsf2"
15663   [(set (match_dup 2)
15664         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15665    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15666    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15667    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15668    (parallel [(set (match_dup 7)
15669                    (unspec:XF [(match_dup 6) (match_dup 2)]
15670                               UNSPEC_FPATAN))
15671               (clobber (match_scratch:XF 8 ""))])
15672    (set (match_operand:SF 0 "register_operand" "")
15673         (float_truncate:SF (match_dup 7)))]
15674   "TARGET_USE_FANCY_MATH_387
15675    && flag_unsafe_math_optimizations"
15677   int i;
15679   for (i=2; i<8; i++)
15680     operands[i] = gen_reg_rtx (XFmode);
15682   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15685 (define_expand "asinxf2"
15686   [(set (match_dup 2)
15687         (mult:XF (match_operand:XF 1 "register_operand" "")
15688                  (match_dup 1)))
15689    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15690    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15691    (parallel [(set (match_operand:XF 0 "register_operand" "")
15692                    (unspec:XF [(match_dup 5) (match_dup 1)]
15693                               UNSPEC_FPATAN))
15694               (clobber (match_scratch:XF 6 ""))])]
15695   "TARGET_USE_FANCY_MATH_387
15696    && flag_unsafe_math_optimizations"
15698   int i;
15700   for (i=2; i<6; i++)
15701     operands[i] = gen_reg_rtx (XFmode);
15703   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15706 (define_expand "acosdf2"
15707   [(set (match_dup 2)
15708         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15709    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15710    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15711    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15712    (parallel [(set (match_dup 7)
15713                    (unspec:XF [(match_dup 2) (match_dup 6)]
15714                               UNSPEC_FPATAN))
15715               (clobber (match_scratch:XF 8 ""))])
15716    (set (match_operand:DF 0 "register_operand" "")
15717         (float_truncate:DF (match_dup 7)))]
15718   "TARGET_USE_FANCY_MATH_387
15719    && flag_unsafe_math_optimizations"
15721   int i;
15723   for (i=2; i<8; i++)
15724     operands[i] = gen_reg_rtx (XFmode);
15726   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15729 (define_expand "acossf2"
15730   [(set (match_dup 2)
15731         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15732    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15733    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15734    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15735    (parallel [(set (match_dup 7)
15736                    (unspec:XF [(match_dup 2) (match_dup 6)]
15737                               UNSPEC_FPATAN))
15738               (clobber (match_scratch:XF 8 ""))])
15739    (set (match_operand:SF 0 "register_operand" "")
15740         (float_truncate:SF (match_dup 7)))]
15741   "TARGET_USE_FANCY_MATH_387
15742    && flag_unsafe_math_optimizations"
15744   int i;
15746   for (i=2; i<8; i++)
15747     operands[i] = gen_reg_rtx (XFmode);
15749   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15752 (define_expand "acosxf2"
15753   [(set (match_dup 2)
15754         (mult:XF (match_operand:XF 1 "register_operand" "")
15755                  (match_dup 1)))
15756    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15757    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15758    (parallel [(set (match_operand:XF 0 "register_operand" "")
15759                    (unspec:XF [(match_dup 1) (match_dup 5)]
15760                               UNSPEC_FPATAN))
15761               (clobber (match_scratch:XF 6 ""))])]
15762   "TARGET_USE_FANCY_MATH_387
15763    && flag_unsafe_math_optimizations"
15765   int i;
15767   for (i=2; i<6; i++)
15768     operands[i] = gen_reg_rtx (XFmode);
15770   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15773 (define_insn "fyl2x_xf3"
15774   [(set (match_operand:XF 0 "register_operand" "=f")
15775         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15776                     (match_operand:XF 1 "register_operand" "u")]
15777                    UNSPEC_FYL2X))
15778    (clobber (match_scratch:XF 3 "=1"))]
15779   "TARGET_USE_FANCY_MATH_387
15780    && flag_unsafe_math_optimizations"
15781   "fyl2x"
15782   [(set_attr "type" "fpspc")
15783    (set_attr "mode" "XF")])
15785 (define_expand "logsf2"
15786   [(set (match_dup 2)
15787         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15788    (parallel [(set (match_dup 4)
15789                    (unspec:XF [(match_dup 2)
15790                                (match_dup 3)] UNSPEC_FYL2X))
15791               (clobber (match_scratch:XF 5 ""))])
15792    (set (match_operand:SF 0 "register_operand" "")
15793         (float_truncate:SF (match_dup 4)))]
15794   "TARGET_USE_FANCY_MATH_387
15795    && flag_unsafe_math_optimizations"
15797   rtx temp;
15799   operands[2] = gen_reg_rtx (XFmode);
15800   operands[3] = gen_reg_rtx (XFmode);
15801   operands[4] = gen_reg_rtx (XFmode);
15803   temp = standard_80387_constant_rtx (4); /* fldln2 */
15804   emit_move_insn (operands[3], temp);
15807 (define_expand "logdf2"
15808   [(set (match_dup 2)
15809         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15810    (parallel [(set (match_dup 4)
15811                    (unspec:XF [(match_dup 2)
15812                                (match_dup 3)] UNSPEC_FYL2X))
15813               (clobber (match_scratch:XF 5 ""))])
15814    (set (match_operand:DF 0 "register_operand" "")
15815         (float_truncate:DF (match_dup 4)))]
15816   "TARGET_USE_FANCY_MATH_387
15817    && flag_unsafe_math_optimizations"
15819   rtx temp;
15821   operands[2] = gen_reg_rtx (XFmode);
15822   operands[3] = gen_reg_rtx (XFmode);
15823   operands[4] = gen_reg_rtx (XFmode);
15825   temp = standard_80387_constant_rtx (4); /* fldln2 */
15826   emit_move_insn (operands[3], temp);
15829 (define_expand "logxf2"
15830   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15831                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15832                                (match_dup 2)] UNSPEC_FYL2X))
15833               (clobber (match_scratch:XF 3 ""))])]
15834   "TARGET_USE_FANCY_MATH_387
15835    && flag_unsafe_math_optimizations"
15837   rtx temp;
15839   operands[2] = gen_reg_rtx (XFmode);
15840   temp = standard_80387_constant_rtx (4); /* fldln2 */
15841   emit_move_insn (operands[2], temp);
15844 (define_expand "log10sf2"
15845   [(set (match_dup 2)
15846         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15847    (parallel [(set (match_dup 4)
15848                    (unspec:XF [(match_dup 2)
15849                                (match_dup 3)] UNSPEC_FYL2X))
15850               (clobber (match_scratch:XF 5 ""))])
15851    (set (match_operand:SF 0 "register_operand" "")
15852         (float_truncate:SF (match_dup 4)))]
15853   "TARGET_USE_FANCY_MATH_387
15854    && flag_unsafe_math_optimizations"
15856   rtx temp;
15858   operands[2] = gen_reg_rtx (XFmode);
15859   operands[3] = gen_reg_rtx (XFmode);
15860   operands[4] = gen_reg_rtx (XFmode);
15862   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15863   emit_move_insn (operands[3], temp);
15866 (define_expand "log10df2"
15867   [(set (match_dup 2)
15868         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15869    (parallel [(set (match_dup 4)
15870                    (unspec:XF [(match_dup 2)
15871                                (match_dup 3)] UNSPEC_FYL2X))
15872               (clobber (match_scratch:XF 5 ""))])
15873    (set (match_operand:DF 0 "register_operand" "")
15874         (float_truncate:DF (match_dup 4)))]
15875   "TARGET_USE_FANCY_MATH_387
15876    && flag_unsafe_math_optimizations"
15878   rtx temp;
15880   operands[2] = gen_reg_rtx (XFmode);
15881   operands[3] = gen_reg_rtx (XFmode);
15882   operands[4] = gen_reg_rtx (XFmode);
15884   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15885   emit_move_insn (operands[3], temp);
15888 (define_expand "log10xf2"
15889   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15890                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15891                                (match_dup 2)] UNSPEC_FYL2X))
15892               (clobber (match_scratch:XF 3 ""))])]
15893   "TARGET_USE_FANCY_MATH_387
15894    && flag_unsafe_math_optimizations"
15896   rtx temp;
15898   operands[2] = gen_reg_rtx (XFmode);
15899   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15900   emit_move_insn (operands[2], temp);
15903 (define_expand "log2sf2"
15904   [(set (match_dup 2)
15905         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15906    (parallel [(set (match_dup 4)
15907                    (unspec:XF [(match_dup 2)
15908                                (match_dup 3)] UNSPEC_FYL2X))
15909               (clobber (match_scratch:XF 5 ""))])
15910    (set (match_operand:SF 0 "register_operand" "")
15911         (float_truncate:SF (match_dup 4)))]
15912   "TARGET_USE_FANCY_MATH_387
15913    && flag_unsafe_math_optimizations"
15915   operands[2] = gen_reg_rtx (XFmode);
15916   operands[3] = gen_reg_rtx (XFmode);
15917   operands[4] = gen_reg_rtx (XFmode);
15919   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15922 (define_expand "log2df2"
15923   [(set (match_dup 2)
15924         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15925    (parallel [(set (match_dup 4)
15926                    (unspec:XF [(match_dup 2)
15927                                (match_dup 3)] UNSPEC_FYL2X))
15928               (clobber (match_scratch:XF 5 ""))])
15929    (set (match_operand:DF 0 "register_operand" "")
15930         (float_truncate:DF (match_dup 4)))]
15931   "TARGET_USE_FANCY_MATH_387
15932    && flag_unsafe_math_optimizations"
15934   operands[2] = gen_reg_rtx (XFmode);
15935   operands[3] = gen_reg_rtx (XFmode);
15936   operands[4] = gen_reg_rtx (XFmode);
15938   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15941 (define_expand "log2xf2"
15942   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15943                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15944                                (match_dup 2)] UNSPEC_FYL2X))
15945               (clobber (match_scratch:XF 3 ""))])]
15946   "TARGET_USE_FANCY_MATH_387
15947    && flag_unsafe_math_optimizations"
15949   operands[2] = gen_reg_rtx (XFmode);
15950   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15953 (define_insn "fyl2xp1_xf3"
15954   [(set (match_operand:XF 0 "register_operand" "=f")
15955         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15956                     (match_operand:XF 1 "register_operand" "u")]
15957                    UNSPEC_FYL2XP1))
15958    (clobber (match_scratch:XF 3 "=1"))]
15959   "TARGET_USE_FANCY_MATH_387
15960    && flag_unsafe_math_optimizations"
15961   "fyl2xp1"
15962   [(set_attr "type" "fpspc")
15963    (set_attr "mode" "XF")])
15965 (define_expand "log1psf2"
15966   [(use (match_operand:XF 0 "register_operand" ""))
15967    (use (match_operand:XF 1 "register_operand" ""))]
15968   "TARGET_USE_FANCY_MATH_387
15969    && flag_unsafe_math_optimizations"
15971   rtx op0 = gen_reg_rtx (XFmode);
15972   rtx op1 = gen_reg_rtx (XFmode);
15974   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15975   ix86_emit_i387_log1p (op0, op1);
15976   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15977   DONE;
15980 (define_expand "log1pdf2"
15981   [(use (match_operand:XF 0 "register_operand" ""))
15982    (use (match_operand:XF 1 "register_operand" ""))]
15983   "TARGET_USE_FANCY_MATH_387
15984    && flag_unsafe_math_optimizations"
15986   rtx op0 = gen_reg_rtx (XFmode);
15987   rtx op1 = gen_reg_rtx (XFmode);
15989   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15990   ix86_emit_i387_log1p (op0, op1);
15991   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15992   DONE;
15995 (define_expand "log1pxf2"
15996   [(use (match_operand:XF 0 "register_operand" ""))
15997    (use (match_operand:XF 1 "register_operand" ""))]
15998   "TARGET_USE_FANCY_MATH_387
15999    && flag_unsafe_math_optimizations"
16001   ix86_emit_i387_log1p (operands[0], operands[1]);
16002   DONE;
16005 (define_insn "*fxtractxf3"
16006   [(set (match_operand:XF 0 "register_operand" "=f")
16007         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16008                    UNSPEC_XTRACT_FRACT))
16009    (set (match_operand:XF 1 "register_operand" "=u")
16010         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16011   "TARGET_USE_FANCY_MATH_387
16012    && flag_unsafe_math_optimizations"
16013   "fxtract"
16014   [(set_attr "type" "fpspc")
16015    (set_attr "mode" "XF")])
16017 (define_expand "logbsf2"
16018   [(set (match_dup 2)
16019         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16020    (parallel [(set (match_dup 3)
16021                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16022               (set (match_dup 4)
16023                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16024    (set (match_operand:SF 0 "register_operand" "")
16025         (float_truncate:SF (match_dup 4)))]
16026   "TARGET_USE_FANCY_MATH_387
16027    && flag_unsafe_math_optimizations"
16029   operands[2] = gen_reg_rtx (XFmode);
16030   operands[3] = gen_reg_rtx (XFmode);
16031   operands[4] = gen_reg_rtx (XFmode);
16034 (define_expand "logbdf2"
16035   [(set (match_dup 2)
16036         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16037    (parallel [(set (match_dup 3)
16038                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16039               (set (match_dup 4)
16040                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16041    (set (match_operand:DF 0 "register_operand" "")
16042         (float_truncate:DF (match_dup 4)))]
16043   "TARGET_USE_FANCY_MATH_387
16044    && flag_unsafe_math_optimizations"
16046   operands[2] = gen_reg_rtx (XFmode);
16047   operands[3] = gen_reg_rtx (XFmode);
16048   operands[4] = gen_reg_rtx (XFmode);
16051 (define_expand "logbxf2"
16052   [(parallel [(set (match_dup 2)
16053                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16054                               UNSPEC_XTRACT_FRACT))
16055               (set (match_operand:XF 0 "register_operand" "")
16056                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16057   "TARGET_USE_FANCY_MATH_387
16058    && flag_unsafe_math_optimizations"
16060   operands[2] = gen_reg_rtx (XFmode);
16063 (define_expand "ilogbsi2"
16064   [(parallel [(set (match_dup 2)
16065                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16066                               UNSPEC_XTRACT_FRACT))
16067               (set (match_operand:XF 3 "register_operand" "")
16068                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16069    (parallel [(set (match_operand:SI 0 "register_operand" "")
16070                    (fix:SI (match_dup 3)))
16071               (clobber (reg:CC FLAGS_REG))])]
16072   "TARGET_USE_FANCY_MATH_387
16073    && flag_unsafe_math_optimizations"
16075   operands[2] = gen_reg_rtx (XFmode);
16076   operands[3] = gen_reg_rtx (XFmode);
16079 (define_insn "*f2xm1xf2"
16080   [(set (match_operand:XF 0 "register_operand" "=f")
16081         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16082          UNSPEC_F2XM1))]
16083   "TARGET_USE_FANCY_MATH_387
16084    && flag_unsafe_math_optimizations"
16085   "f2xm1"
16086   [(set_attr "type" "fpspc")
16087    (set_attr "mode" "XF")])
16089 (define_insn "*fscalexf4"
16090   [(set (match_operand:XF 0 "register_operand" "=f")
16091         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16092                     (match_operand:XF 3 "register_operand" "1")]
16093                    UNSPEC_FSCALE_FRACT))
16094    (set (match_operand:XF 1 "register_operand" "=u")
16095         (unspec:XF [(match_dup 2) (match_dup 3)]
16096                    UNSPEC_FSCALE_EXP))]
16097   "TARGET_USE_FANCY_MATH_387
16098    && flag_unsafe_math_optimizations"
16099   "fscale"
16100   [(set_attr "type" "fpspc")
16101    (set_attr "mode" "XF")])
16103 (define_expand "expsf2"
16104   [(set (match_dup 2)
16105         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16106    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16107    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16108    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16109    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16110    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16111    (parallel [(set (match_dup 10)
16112                    (unspec:XF [(match_dup 9) (match_dup 5)]
16113                               UNSPEC_FSCALE_FRACT))
16114               (set (match_dup 11)
16115                    (unspec:XF [(match_dup 9) (match_dup 5)]
16116                               UNSPEC_FSCALE_EXP))])
16117    (set (match_operand:SF 0 "register_operand" "")
16118         (float_truncate:SF (match_dup 10)))]
16119   "TARGET_USE_FANCY_MATH_387
16120    && flag_unsafe_math_optimizations"
16122   rtx temp;
16123   int i;
16125   for (i=2; i<12; i++)
16126     operands[i] = gen_reg_rtx (XFmode);
16127   temp = standard_80387_constant_rtx (5); /* fldl2e */
16128   emit_move_insn (operands[3], temp);
16129   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16132 (define_expand "expdf2"
16133   [(set (match_dup 2)
16134         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16135    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16136    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16137    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16138    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16139    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16140    (parallel [(set (match_dup 10)
16141                    (unspec:XF [(match_dup 9) (match_dup 5)]
16142                               UNSPEC_FSCALE_FRACT))
16143               (set (match_dup 11)
16144                    (unspec:XF [(match_dup 9) (match_dup 5)]
16145                               UNSPEC_FSCALE_EXP))])
16146    (set (match_operand:DF 0 "register_operand" "")
16147         (float_truncate:DF (match_dup 10)))]
16148   "TARGET_USE_FANCY_MATH_387
16149    && flag_unsafe_math_optimizations"
16151   rtx temp;
16152   int i;
16154   for (i=2; i<12; i++)
16155     operands[i] = gen_reg_rtx (XFmode);
16156   temp = standard_80387_constant_rtx (5); /* fldl2e */
16157   emit_move_insn (operands[3], temp);
16158   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16161 (define_expand "expxf2"
16162   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16163                                (match_dup 2)))
16164    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16165    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16166    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16167    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16168    (parallel [(set (match_operand:XF 0 "register_operand" "")
16169                    (unspec:XF [(match_dup 8) (match_dup 4)]
16170                               UNSPEC_FSCALE_FRACT))
16171               (set (match_dup 9)
16172                    (unspec:XF [(match_dup 8) (match_dup 4)]
16173                               UNSPEC_FSCALE_EXP))])]
16174   "TARGET_USE_FANCY_MATH_387
16175    && flag_unsafe_math_optimizations"
16177   rtx temp;
16178   int i;
16180   for (i=2; i<10; i++)
16181     operands[i] = gen_reg_rtx (XFmode);
16182   temp = standard_80387_constant_rtx (5); /* fldl2e */
16183   emit_move_insn (operands[2], temp);
16184   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16187 (define_expand "exp10sf2"
16188   [(set (match_dup 2)
16189         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16190    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16191    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16192    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16193    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16194    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16195    (parallel [(set (match_dup 10)
16196                    (unspec:XF [(match_dup 9) (match_dup 5)]
16197                               UNSPEC_FSCALE_FRACT))
16198               (set (match_dup 11)
16199                    (unspec:XF [(match_dup 9) (match_dup 5)]
16200                               UNSPEC_FSCALE_EXP))])
16201    (set (match_operand:SF 0 "register_operand" "")
16202         (float_truncate:SF (match_dup 10)))]
16203   "TARGET_USE_FANCY_MATH_387
16204    && flag_unsafe_math_optimizations"
16206   rtx temp;
16207   int i;
16209   for (i=2; i<12; i++)
16210     operands[i] = gen_reg_rtx (XFmode);
16211   temp = standard_80387_constant_rtx (6); /* fldl2t */
16212   emit_move_insn (operands[3], temp);
16213   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16216 (define_expand "exp10df2"
16217   [(set (match_dup 2)
16218         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16219    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16220    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16221    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16222    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16223    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16224    (parallel [(set (match_dup 10)
16225                    (unspec:XF [(match_dup 9) (match_dup 5)]
16226                               UNSPEC_FSCALE_FRACT))
16227               (set (match_dup 11)
16228                    (unspec:XF [(match_dup 9) (match_dup 5)]
16229                               UNSPEC_FSCALE_EXP))])
16230    (set (match_operand:DF 0 "register_operand" "")
16231         (float_truncate:DF (match_dup 10)))]
16232   "TARGET_USE_FANCY_MATH_387
16233    && flag_unsafe_math_optimizations"
16235   rtx temp;
16236   int i;
16238   for (i=2; i<12; i++)
16239     operands[i] = gen_reg_rtx (XFmode);
16240   temp = standard_80387_constant_rtx (6); /* fldl2t */
16241   emit_move_insn (operands[3], temp);
16242   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16245 (define_expand "exp10xf2"
16246   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16247                                (match_dup 2)))
16248    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16249    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16250    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16251    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16252    (parallel [(set (match_operand:XF 0 "register_operand" "")
16253                    (unspec:XF [(match_dup 8) (match_dup 4)]
16254                               UNSPEC_FSCALE_FRACT))
16255               (set (match_dup 9)
16256                    (unspec:XF [(match_dup 8) (match_dup 4)]
16257                               UNSPEC_FSCALE_EXP))])]
16258   "TARGET_USE_FANCY_MATH_387
16259    && flag_unsafe_math_optimizations"
16261   rtx temp;
16262   int i;
16264   for (i=2; i<10; i++)
16265     operands[i] = gen_reg_rtx (XFmode);
16266   temp = standard_80387_constant_rtx (6); /* fldl2t */
16267   emit_move_insn (operands[2], temp);
16268   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16271 (define_expand "exp2sf2"
16272   [(set (match_dup 2)
16273         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16274    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16275    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16276    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16277    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16278    (parallel [(set (match_dup 8)
16279                    (unspec:XF [(match_dup 7) (match_dup 3)]
16280                               UNSPEC_FSCALE_FRACT))
16281               (set (match_dup 9)
16282                    (unspec:XF [(match_dup 7) (match_dup 3)]
16283                               UNSPEC_FSCALE_EXP))])
16284    (set (match_operand:SF 0 "register_operand" "")
16285         (float_truncate:SF (match_dup 8)))]
16286   "TARGET_USE_FANCY_MATH_387
16287    && flag_unsafe_math_optimizations"
16289   int i;
16291   for (i=2; i<10; i++)
16292     operands[i] = gen_reg_rtx (XFmode);
16293   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16296 (define_expand "exp2df2"
16297   [(set (match_dup 2)
16298         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16299    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16300    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16301    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16302    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16303    (parallel [(set (match_dup 8)
16304                    (unspec:XF [(match_dup 7) (match_dup 3)]
16305                               UNSPEC_FSCALE_FRACT))
16306               (set (match_dup 9)
16307                    (unspec:XF [(match_dup 7) (match_dup 3)]
16308                               UNSPEC_FSCALE_EXP))])
16309    (set (match_operand:DF 0 "register_operand" "")
16310         (float_truncate:DF (match_dup 8)))]
16311   "TARGET_USE_FANCY_MATH_387
16312    && flag_unsafe_math_optimizations"
16314   int i;
16316   for (i=2; i<10; i++)
16317     operands[i] = gen_reg_rtx (XFmode);
16318   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16321 (define_expand "exp2xf2"
16322   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16323    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16324    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16325    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16326    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16327    (parallel [(set (match_operand:XF 0 "register_operand" "")
16328                    (unspec:XF [(match_dup 7) (match_dup 3)]
16329                               UNSPEC_FSCALE_FRACT))
16330               (set (match_dup 8)
16331                    (unspec:XF [(match_dup 7) (match_dup 3)]
16332                               UNSPEC_FSCALE_EXP))])]
16333   "TARGET_USE_FANCY_MATH_387
16334    && flag_unsafe_math_optimizations"
16336   int i;
16338   for (i=2; i<9; i++)
16339     operands[i] = gen_reg_rtx (XFmode);
16340   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16343 (define_expand "expm1df2"
16344   [(set (match_dup 2)
16345         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16346    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16347    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16348    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16349    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16350    (parallel [(set (match_dup 8)
16351                    (unspec:XF [(match_dup 7) (match_dup 5)]
16352                               UNSPEC_FSCALE_FRACT))
16353                    (set (match_dup 9)
16354                    (unspec:XF [(match_dup 7) (match_dup 5)]
16355                               UNSPEC_FSCALE_EXP))])
16356    (parallel [(set (match_dup 11)
16357                    (unspec:XF [(match_dup 10) (match_dup 9)]
16358                               UNSPEC_FSCALE_FRACT))
16359               (set (match_dup 12)
16360                    (unspec:XF [(match_dup 10) (match_dup 9)]
16361                               UNSPEC_FSCALE_EXP))])
16362    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16363    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16364    (set (match_operand:DF 0 "register_operand" "")
16365         (float_truncate:DF (match_dup 14)))]
16366   "TARGET_USE_FANCY_MATH_387
16367    && flag_unsafe_math_optimizations"
16369   rtx temp;
16370   int i;
16372   for (i=2; i<15; i++)
16373     operands[i] = gen_reg_rtx (XFmode);
16374   temp = standard_80387_constant_rtx (5); /* fldl2e */
16375   emit_move_insn (operands[3], temp);
16376   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16379 (define_expand "expm1sf2"
16380   [(set (match_dup 2)
16381         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16382    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16383    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16384    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16385    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16386    (parallel [(set (match_dup 8)
16387                    (unspec:XF [(match_dup 7) (match_dup 5)]
16388                               UNSPEC_FSCALE_FRACT))
16389                    (set (match_dup 9)
16390                    (unspec:XF [(match_dup 7) (match_dup 5)]
16391                               UNSPEC_FSCALE_EXP))])
16392    (parallel [(set (match_dup 11)
16393                    (unspec:XF [(match_dup 10) (match_dup 9)]
16394                               UNSPEC_FSCALE_FRACT))
16395               (set (match_dup 12)
16396                    (unspec:XF [(match_dup 10) (match_dup 9)]
16397                               UNSPEC_FSCALE_EXP))])
16398    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16399    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16400    (set (match_operand:SF 0 "register_operand" "")
16401         (float_truncate:SF (match_dup 14)))]
16402   "TARGET_USE_FANCY_MATH_387
16403    && flag_unsafe_math_optimizations"
16405   rtx temp;
16406   int i;
16408   for (i=2; i<15; i++)
16409     operands[i] = gen_reg_rtx (XFmode);
16410   temp = standard_80387_constant_rtx (5); /* fldl2e */
16411   emit_move_insn (operands[3], temp);
16412   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16415 (define_expand "expm1xf2"
16416   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16417                                (match_dup 2)))
16418    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16419    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16420    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16421    (parallel [(set (match_dup 7)
16422                    (unspec:XF [(match_dup 6) (match_dup 4)]
16423                               UNSPEC_FSCALE_FRACT))
16424                    (set (match_dup 8)
16425                    (unspec:XF [(match_dup 6) (match_dup 4)]
16426                               UNSPEC_FSCALE_EXP))])
16427    (parallel [(set (match_dup 10)
16428                    (unspec:XF [(match_dup 9) (match_dup 8)]
16429                               UNSPEC_FSCALE_FRACT))
16430               (set (match_dup 11)
16431                    (unspec:XF [(match_dup 9) (match_dup 8)]
16432                               UNSPEC_FSCALE_EXP))])
16433    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16434    (set (match_operand:XF 0 "register_operand" "")
16435         (plus:XF (match_dup 12) (match_dup 7)))]
16436   "TARGET_USE_FANCY_MATH_387
16437    && flag_unsafe_math_optimizations"
16439   rtx temp;
16440   int i;
16442   for (i=2; i<13; i++)
16443     operands[i] = gen_reg_rtx (XFmode);
16444   temp = standard_80387_constant_rtx (5); /* fldl2e */
16445   emit_move_insn (operands[2], temp);
16446   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16450 (define_insn "frndintxf2"
16451   [(set (match_operand:XF 0 "register_operand" "=f")
16452         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16453          UNSPEC_FRNDINT))]
16454   "TARGET_USE_FANCY_MATH_387
16455    && flag_unsafe_math_optimizations"
16456   "frndint"
16457   [(set_attr "type" "fpspc")
16458    (set_attr "mode" "XF")])
16460 (define_expand "rintdf2"
16461   [(use (match_operand:DF 0 "register_operand" ""))
16462    (use (match_operand:DF 1 "register_operand" ""))]
16463   "TARGET_USE_FANCY_MATH_387
16464    && flag_unsafe_math_optimizations"
16466   rtx op0 = gen_reg_rtx (XFmode);
16467   rtx op1 = gen_reg_rtx (XFmode);
16469   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16470   emit_insn (gen_frndintxf2 (op0, op1));
16472   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16473   DONE;
16476 (define_expand "rintsf2"
16477   [(use (match_operand:SF 0 "register_operand" ""))
16478    (use (match_operand:SF 1 "register_operand" ""))]
16479   "TARGET_USE_FANCY_MATH_387
16480    && flag_unsafe_math_optimizations"
16482   rtx op0 = gen_reg_rtx (XFmode);
16483   rtx op1 = gen_reg_rtx (XFmode);
16485   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16486   emit_insn (gen_frndintxf2 (op0, op1));
16488   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16489   DONE;
16492 (define_expand "rintxf2"
16493   [(use (match_operand:XF 0 "register_operand" ""))
16494    (use (match_operand:XF 1 "register_operand" ""))]
16495   "TARGET_USE_FANCY_MATH_387
16496    && flag_unsafe_math_optimizations"
16498   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16499   DONE;
16502 (define_insn "frndintxf2_floor"
16503   [(set (match_operand:XF 0 "register_operand" "=f")
16504         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16505          UNSPEC_FRNDINT_FLOOR))
16506    (use (match_operand:HI 2 "memory_operand" "m"))
16507    (use (match_operand:HI 3 "memory_operand" "m"))]
16508   "TARGET_USE_FANCY_MATH_387
16509    && flag_unsafe_math_optimizations"
16510   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16511   [(set_attr "type" "frndint")
16512    (set_attr "i387_cw" "floor")
16513    (set_attr "mode" "XF")])
16515 (define_expand "floordf2"
16516   [(use (match_operand:DF 0 "register_operand" ""))
16517    (use (match_operand:DF 1 "register_operand" ""))]
16518   "TARGET_USE_FANCY_MATH_387
16519    && flag_unsafe_math_optimizations"
16521   rtx op0 = gen_reg_rtx (XFmode);
16522   rtx op1 = gen_reg_rtx (XFmode);
16523   rtx op2 = assign_386_stack_local (HImode, 1);
16524   rtx op3 = assign_386_stack_local (HImode, 2);
16525         
16526   ix86_optimize_mode_switching = 1;
16528   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16529   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16531   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16532   DONE;
16535 (define_expand "floorsf2"
16536   [(use (match_operand:SF 0 "register_operand" ""))
16537    (use (match_operand:SF 1 "register_operand" ""))]
16538   "TARGET_USE_FANCY_MATH_387
16539    && flag_unsafe_math_optimizations"
16541   rtx op0 = gen_reg_rtx (XFmode);
16542   rtx op1 = gen_reg_rtx (XFmode);
16543   rtx op2 = assign_386_stack_local (HImode, 1);
16544   rtx op3 = assign_386_stack_local (HImode, 2);
16545         
16546   ix86_optimize_mode_switching = 1;
16548   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16549   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16551   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16552   DONE;
16555 (define_expand "floorxf2"
16556   [(use (match_operand:XF 0 "register_operand" ""))
16557    (use (match_operand:XF 1 "register_operand" ""))]
16558   "TARGET_USE_FANCY_MATH_387
16559    && flag_unsafe_math_optimizations"
16561   rtx op2 = assign_386_stack_local (HImode, 1);
16562   rtx op3 = assign_386_stack_local (HImode, 2);
16563         
16564   ix86_optimize_mode_switching = 1;
16566   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16567   DONE;
16570 (define_insn "frndintxf2_ceil"
16571   [(set (match_operand:XF 0 "register_operand" "=f")
16572         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16573          UNSPEC_FRNDINT_CEIL))
16574    (use (match_operand:HI 2 "memory_operand" "m"))
16575    (use (match_operand:HI 3 "memory_operand" "m"))]
16576   "TARGET_USE_FANCY_MATH_387
16577    && flag_unsafe_math_optimizations"
16578   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16579   [(set_attr "type" "frndint")
16580    (set_attr "i387_cw" "ceil")
16581    (set_attr "mode" "XF")])
16583 (define_expand "ceildf2"
16584   [(use (match_operand:DF 0 "register_operand" ""))
16585    (use (match_operand:DF 1 "register_operand" ""))]
16586   "TARGET_USE_FANCY_MATH_387
16587    && flag_unsafe_math_optimizations"
16589   rtx op0 = gen_reg_rtx (XFmode);
16590   rtx op1 = gen_reg_rtx (XFmode);
16591   rtx op2 = assign_386_stack_local (HImode, 1);
16592   rtx op3 = assign_386_stack_local (HImode, 2);
16593         
16594   ix86_optimize_mode_switching = 1;
16596   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16597   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16599   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16600   DONE;
16603 (define_expand "ceilsf2"
16604   [(use (match_operand:SF 0 "register_operand" ""))
16605    (use (match_operand:SF 1 "register_operand" ""))]
16606   "TARGET_USE_FANCY_MATH_387
16607    && flag_unsafe_math_optimizations"
16609   rtx op0 = gen_reg_rtx (XFmode);
16610   rtx op1 = gen_reg_rtx (XFmode);
16611   rtx op2 = assign_386_stack_local (HImode, 1);
16612   rtx op3 = assign_386_stack_local (HImode, 2);
16613         
16614   ix86_optimize_mode_switching = 1;
16616   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16617   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16619   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16620   DONE;
16623 (define_expand "ceilxf2"
16624   [(use (match_operand:XF 0 "register_operand" ""))
16625    (use (match_operand:XF 1 "register_operand" ""))]
16626   "TARGET_USE_FANCY_MATH_387
16627    && flag_unsafe_math_optimizations"
16629   rtx op2 = assign_386_stack_local (HImode, 1);
16630   rtx op3 = assign_386_stack_local (HImode, 2);
16631         
16632   ix86_optimize_mode_switching = 1;
16634   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16635   DONE;
16638 (define_insn "frndintxf2_trunc"
16639   [(set (match_operand:XF 0 "register_operand" "=f")
16640         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16641          UNSPEC_FRNDINT_TRUNC))
16642    (use (match_operand:HI 2 "memory_operand" "m"))
16643    (use (match_operand:HI 3 "memory_operand" "m"))]
16644   "TARGET_USE_FANCY_MATH_387
16645    && flag_unsafe_math_optimizations"
16646   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16647   [(set_attr "type" "frndint")
16648    (set_attr "i387_cw" "trunc")
16649    (set_attr "mode" "XF")])
16651 (define_expand "btruncdf2"
16652   [(use (match_operand:DF 0 "register_operand" ""))
16653    (use (match_operand:DF 1 "register_operand" ""))]
16654   "TARGET_USE_FANCY_MATH_387
16655    && flag_unsafe_math_optimizations"
16657   rtx op0 = gen_reg_rtx (XFmode);
16658   rtx op1 = gen_reg_rtx (XFmode);
16659   rtx op2 = assign_386_stack_local (HImode, 1);
16660   rtx op3 = assign_386_stack_local (HImode, 2);
16661         
16662   ix86_optimize_mode_switching = 1;
16664   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16665   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16667   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16668   DONE;
16671 (define_expand "btruncsf2"
16672   [(use (match_operand:SF 0 "register_operand" ""))
16673    (use (match_operand:SF 1 "register_operand" ""))]
16674   "TARGET_USE_FANCY_MATH_387
16675    && flag_unsafe_math_optimizations"
16677   rtx op0 = gen_reg_rtx (XFmode);
16678   rtx op1 = gen_reg_rtx (XFmode);
16679   rtx op2 = assign_386_stack_local (HImode, 1);
16680   rtx op3 = assign_386_stack_local (HImode, 2);
16681         
16682   ix86_optimize_mode_switching = 1;
16684   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16685   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16687   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16688   DONE;
16691 (define_expand "btruncxf2"
16692   [(use (match_operand:XF 0 "register_operand" ""))
16693    (use (match_operand:XF 1 "register_operand" ""))]
16694   "TARGET_USE_FANCY_MATH_387
16695    && flag_unsafe_math_optimizations"
16697   rtx op2 = assign_386_stack_local (HImode, 1);
16698   rtx op3 = assign_386_stack_local (HImode, 2);
16699         
16700   ix86_optimize_mode_switching = 1;
16702   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16703   DONE;
16706 (define_insn "frndintxf2_mask_pm"
16707   [(set (match_operand:XF 0 "register_operand" "=f")
16708         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16709          UNSPEC_FRNDINT_MASK_PM))
16710    (use (match_operand:HI 2 "memory_operand" "m"))
16711    (use (match_operand:HI 3 "memory_operand" "m"))]
16712   "TARGET_USE_FANCY_MATH_387
16713    && flag_unsafe_math_optimizations"
16714   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16715   [(set_attr "type" "frndint")
16716    (set_attr "i387_cw" "mask_pm")
16717    (set_attr "mode" "XF")])
16719 (define_expand "nearbyintdf2"
16720   [(use (match_operand:DF 0 "register_operand" ""))
16721    (use (match_operand:DF 1 "register_operand" ""))]
16722   "TARGET_USE_FANCY_MATH_387
16723    && flag_unsafe_math_optimizations"
16725   rtx op0 = gen_reg_rtx (XFmode);
16726   rtx op1 = gen_reg_rtx (XFmode);
16727   rtx op2 = assign_386_stack_local (HImode, 1);
16728   rtx op3 = assign_386_stack_local (HImode, 2);
16729         
16730   ix86_optimize_mode_switching = 1;
16732   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16733   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16735   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16736   DONE;
16739 (define_expand "nearbyintsf2"
16740   [(use (match_operand:SF 0 "register_operand" ""))
16741    (use (match_operand:SF 1 "register_operand" ""))]
16742   "TARGET_USE_FANCY_MATH_387
16743    && flag_unsafe_math_optimizations"
16745   rtx op0 = gen_reg_rtx (XFmode);
16746   rtx op1 = gen_reg_rtx (XFmode);
16747   rtx op2 = assign_386_stack_local (HImode, 1);
16748   rtx op3 = assign_386_stack_local (HImode, 2);
16749         
16750   ix86_optimize_mode_switching = 1;
16752   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16753   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16755   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16756   DONE;
16759 (define_expand "nearbyintxf2"
16760   [(use (match_operand:XF 0 "register_operand" ""))
16761    (use (match_operand:XF 1 "register_operand" ""))]
16762   "TARGET_USE_FANCY_MATH_387
16763    && flag_unsafe_math_optimizations"
16765   rtx op2 = assign_386_stack_local (HImode, 1);
16766   rtx op3 = assign_386_stack_local (HImode, 2);
16767         
16768   ix86_optimize_mode_switching = 1;
16770   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16771                                      op2, op3));
16772   DONE;
16776 ;; Block operation instructions
16778 (define_insn "cld"
16779  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16780  ""
16781  "cld"
16782   [(set_attr "type" "cld")])
16784 (define_expand "movmemsi"
16785   [(use (match_operand:BLK 0 "memory_operand" ""))
16786    (use (match_operand:BLK 1 "memory_operand" ""))
16787    (use (match_operand:SI 2 "nonmemory_operand" ""))
16788    (use (match_operand:SI 3 "const_int_operand" ""))]
16789   "! optimize_size"
16791  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16792    DONE;
16793  else
16794    FAIL;
16797 (define_expand "movmemdi"
16798   [(use (match_operand:BLK 0 "memory_operand" ""))
16799    (use (match_operand:BLK 1 "memory_operand" ""))
16800    (use (match_operand:DI 2 "nonmemory_operand" ""))
16801    (use (match_operand:DI 3 "const_int_operand" ""))]
16802   "TARGET_64BIT"
16804  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16805    DONE;
16806  else
16807    FAIL;
16810 ;; Most CPUs don't like single string operations
16811 ;; Handle this case here to simplify previous expander.
16813 (define_expand "strmov"
16814   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16815    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16816    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16817               (clobber (reg:CC FLAGS_REG))])
16818    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16819               (clobber (reg:CC FLAGS_REG))])]
16820   ""
16822   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16824   /* If .md ever supports :P for Pmode, these can be directly
16825      in the pattern above.  */
16826   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16827   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16829   if (TARGET_SINGLE_STRINGOP || optimize_size)
16830     {
16831       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16832                                       operands[2], operands[3],
16833                                       operands[5], operands[6]));
16834       DONE;
16835     }
16837   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16840 (define_expand "strmov_singleop"
16841   [(parallel [(set (match_operand 1 "memory_operand" "")
16842                    (match_operand 3 "memory_operand" ""))
16843               (set (match_operand 0 "register_operand" "")
16844                    (match_operand 4 "" ""))
16845               (set (match_operand 2 "register_operand" "")
16846                    (match_operand 5 "" ""))
16847               (use (reg:SI DIRFLAG_REG))])]
16848   "TARGET_SINGLE_STRINGOP || optimize_size"
16849   "")
16851 (define_insn "*strmovdi_rex_1"
16852   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16853         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16854    (set (match_operand:DI 0 "register_operand" "=D")
16855         (plus:DI (match_dup 2)
16856                  (const_int 8)))
16857    (set (match_operand:DI 1 "register_operand" "=S")
16858         (plus:DI (match_dup 3)
16859                  (const_int 8)))
16860    (use (reg:SI DIRFLAG_REG))]
16861   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16862   "movsq"
16863   [(set_attr "type" "str")
16864    (set_attr "mode" "DI")
16865    (set_attr "memory" "both")])
16867 (define_insn "*strmovsi_1"
16868   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16869         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16870    (set (match_operand:SI 0 "register_operand" "=D")
16871         (plus:SI (match_dup 2)
16872                  (const_int 4)))
16873    (set (match_operand:SI 1 "register_operand" "=S")
16874         (plus:SI (match_dup 3)
16875                  (const_int 4)))
16876    (use (reg:SI DIRFLAG_REG))]
16877   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16878   "{movsl|movsd}"
16879   [(set_attr "type" "str")
16880    (set_attr "mode" "SI")
16881    (set_attr "memory" "both")])
16883 (define_insn "*strmovsi_rex_1"
16884   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16885         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16886    (set (match_operand:DI 0 "register_operand" "=D")
16887         (plus:DI (match_dup 2)
16888                  (const_int 4)))
16889    (set (match_operand:DI 1 "register_operand" "=S")
16890         (plus:DI (match_dup 3)
16891                  (const_int 4)))
16892    (use (reg:SI DIRFLAG_REG))]
16893   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16894   "{movsl|movsd}"
16895   [(set_attr "type" "str")
16896    (set_attr "mode" "SI")
16897    (set_attr "memory" "both")])
16899 (define_insn "*strmovhi_1"
16900   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16901         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16902    (set (match_operand:SI 0 "register_operand" "=D")
16903         (plus:SI (match_dup 2)
16904                  (const_int 2)))
16905    (set (match_operand:SI 1 "register_operand" "=S")
16906         (plus:SI (match_dup 3)
16907                  (const_int 2)))
16908    (use (reg:SI DIRFLAG_REG))]
16909   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16910   "movsw"
16911   [(set_attr "type" "str")
16912    (set_attr "memory" "both")
16913    (set_attr "mode" "HI")])
16915 (define_insn "*strmovhi_rex_1"
16916   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16917         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16918    (set (match_operand:DI 0 "register_operand" "=D")
16919         (plus:DI (match_dup 2)
16920                  (const_int 2)))
16921    (set (match_operand:DI 1 "register_operand" "=S")
16922         (plus:DI (match_dup 3)
16923                  (const_int 2)))
16924    (use (reg:SI DIRFLAG_REG))]
16925   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16926   "movsw"
16927   [(set_attr "type" "str")
16928    (set_attr "memory" "both")
16929    (set_attr "mode" "HI")])
16931 (define_insn "*strmovqi_1"
16932   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16933         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16934    (set (match_operand:SI 0 "register_operand" "=D")
16935         (plus:SI (match_dup 2)
16936                  (const_int 1)))
16937    (set (match_operand:SI 1 "register_operand" "=S")
16938         (plus:SI (match_dup 3)
16939                  (const_int 1)))
16940    (use (reg:SI DIRFLAG_REG))]
16941   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16942   "movsb"
16943   [(set_attr "type" "str")
16944    (set_attr "memory" "both")
16945    (set_attr "mode" "QI")])
16947 (define_insn "*strmovqi_rex_1"
16948   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16949         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16950    (set (match_operand:DI 0 "register_operand" "=D")
16951         (plus:DI (match_dup 2)
16952                  (const_int 1)))
16953    (set (match_operand:DI 1 "register_operand" "=S")
16954         (plus:DI (match_dup 3)
16955                  (const_int 1)))
16956    (use (reg:SI DIRFLAG_REG))]
16957   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16958   "movsb"
16959   [(set_attr "type" "str")
16960    (set_attr "memory" "both")
16961    (set_attr "mode" "QI")])
16963 (define_expand "rep_mov"
16964   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16965               (set (match_operand 0 "register_operand" "")
16966                    (match_operand 5 "" ""))
16967               (set (match_operand 2 "register_operand" "")
16968                    (match_operand 6 "" ""))
16969               (set (match_operand 1 "memory_operand" "")
16970                    (match_operand 3 "memory_operand" ""))
16971               (use (match_dup 4))
16972               (use (reg:SI DIRFLAG_REG))])]
16973   ""
16974   "")
16976 (define_insn "*rep_movdi_rex64"
16977   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16978    (set (match_operand:DI 0 "register_operand" "=D") 
16979         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16980                             (const_int 3))
16981                  (match_operand:DI 3 "register_operand" "0")))
16982    (set (match_operand:DI 1 "register_operand" "=S") 
16983         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16984                  (match_operand:DI 4 "register_operand" "1")))
16985    (set (mem:BLK (match_dup 3))
16986         (mem:BLK (match_dup 4)))
16987    (use (match_dup 5))
16988    (use (reg:SI DIRFLAG_REG))]
16989   "TARGET_64BIT"
16990   "{rep\;movsq|rep movsq}"
16991   [(set_attr "type" "str")
16992    (set_attr "prefix_rep" "1")
16993    (set_attr "memory" "both")
16994    (set_attr "mode" "DI")])
16996 (define_insn "*rep_movsi"
16997   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16998    (set (match_operand:SI 0 "register_operand" "=D") 
16999         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17000                             (const_int 2))
17001                  (match_operand:SI 3 "register_operand" "0")))
17002    (set (match_operand:SI 1 "register_operand" "=S") 
17003         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17004                  (match_operand:SI 4 "register_operand" "1")))
17005    (set (mem:BLK (match_dup 3))
17006         (mem:BLK (match_dup 4)))
17007    (use (match_dup 5))
17008    (use (reg:SI DIRFLAG_REG))]
17009   "!TARGET_64BIT"
17010   "{rep\;movsl|rep movsd}"
17011   [(set_attr "type" "str")
17012    (set_attr "prefix_rep" "1")
17013    (set_attr "memory" "both")
17014    (set_attr "mode" "SI")])
17016 (define_insn "*rep_movsi_rex64"
17017   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17018    (set (match_operand:DI 0 "register_operand" "=D") 
17019         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17020                             (const_int 2))
17021                  (match_operand:DI 3 "register_operand" "0")))
17022    (set (match_operand:DI 1 "register_operand" "=S") 
17023         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17024                  (match_operand:DI 4 "register_operand" "1")))
17025    (set (mem:BLK (match_dup 3))
17026         (mem:BLK (match_dup 4)))
17027    (use (match_dup 5))
17028    (use (reg:SI DIRFLAG_REG))]
17029   "TARGET_64BIT"
17030   "{rep\;movsl|rep movsd}"
17031   [(set_attr "type" "str")
17032    (set_attr "prefix_rep" "1")
17033    (set_attr "memory" "both")
17034    (set_attr "mode" "SI")])
17036 (define_insn "*rep_movqi"
17037   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17038    (set (match_operand:SI 0 "register_operand" "=D") 
17039         (plus:SI (match_operand:SI 3 "register_operand" "0")
17040                  (match_operand:SI 5 "register_operand" "2")))
17041    (set (match_operand:SI 1 "register_operand" "=S") 
17042         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17043    (set (mem:BLK (match_dup 3))
17044         (mem:BLK (match_dup 4)))
17045    (use (match_dup 5))
17046    (use (reg:SI DIRFLAG_REG))]
17047   "!TARGET_64BIT"
17048   "{rep\;movsb|rep movsb}"
17049   [(set_attr "type" "str")
17050    (set_attr "prefix_rep" "1")
17051    (set_attr "memory" "both")
17052    (set_attr "mode" "SI")])
17054 (define_insn "*rep_movqi_rex64"
17055   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17056    (set (match_operand:DI 0 "register_operand" "=D") 
17057         (plus:DI (match_operand:DI 3 "register_operand" "0")
17058                  (match_operand:DI 5 "register_operand" "2")))
17059    (set (match_operand:DI 1 "register_operand" "=S") 
17060         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17061    (set (mem:BLK (match_dup 3))
17062         (mem:BLK (match_dup 4)))
17063    (use (match_dup 5))
17064    (use (reg:SI DIRFLAG_REG))]
17065   "TARGET_64BIT"
17066   "{rep\;movsb|rep movsb}"
17067   [(set_attr "type" "str")
17068    (set_attr "prefix_rep" "1")
17069    (set_attr "memory" "both")
17070    (set_attr "mode" "SI")])
17072 (define_expand "clrmemsi"
17073    [(use (match_operand:BLK 0 "memory_operand" ""))
17074     (use (match_operand:SI 1 "nonmemory_operand" ""))
17075     (use (match_operand 2 "const_int_operand" ""))]
17076   ""
17078  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17079    DONE;
17080  else
17081    FAIL;
17084 (define_expand "clrmemdi"
17085    [(use (match_operand:BLK 0 "memory_operand" ""))
17086     (use (match_operand:DI 1 "nonmemory_operand" ""))
17087     (use (match_operand 2 "const_int_operand" ""))]
17088   "TARGET_64BIT"
17090  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17091    DONE;
17092  else
17093    FAIL;
17096 ;; Most CPUs don't like single string operations
17097 ;; Handle this case here to simplify previous expander.
17099 (define_expand "strset"
17100   [(set (match_operand 1 "memory_operand" "")
17101         (match_operand 2 "register_operand" ""))
17102    (parallel [(set (match_operand 0 "register_operand" "")
17103                    (match_dup 3))
17104               (clobber (reg:CC FLAGS_REG))])]
17105   ""
17107   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17108     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17110   /* If .md ever supports :P for Pmode, this can be directly
17111      in the pattern above.  */
17112   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17113                               GEN_INT (GET_MODE_SIZE (GET_MODE
17114                                                       (operands[2]))));
17115   if (TARGET_SINGLE_STRINGOP || optimize_size)
17116     {
17117       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17118                                       operands[3]));
17119       DONE;
17120     }
17123 (define_expand "strset_singleop"
17124   [(parallel [(set (match_operand 1 "memory_operand" "")
17125                    (match_operand 2 "register_operand" ""))
17126               (set (match_operand 0 "register_operand" "")
17127                    (match_operand 3 "" ""))
17128               (use (reg:SI DIRFLAG_REG))])]
17129   "TARGET_SINGLE_STRINGOP || optimize_size"
17130   "")
17132 (define_insn "*strsetdi_rex_1"
17133   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17134         (match_operand:DI 2 "register_operand" "a"))
17135    (set (match_operand:DI 0 "register_operand" "=D")
17136         (plus:DI (match_dup 1)
17137                  (const_int 8)))
17138    (use (reg:SI DIRFLAG_REG))]
17139   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17140   "stosq"
17141   [(set_attr "type" "str")
17142    (set_attr "memory" "store")
17143    (set_attr "mode" "DI")])
17145 (define_insn "*strsetsi_1"
17146   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17147         (match_operand:SI 2 "register_operand" "a"))
17148    (set (match_operand:SI 0 "register_operand" "=D")
17149         (plus:SI (match_dup 1)
17150                  (const_int 4)))
17151    (use (reg:SI DIRFLAG_REG))]
17152   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17153   "{stosl|stosd}"
17154   [(set_attr "type" "str")
17155    (set_attr "memory" "store")
17156    (set_attr "mode" "SI")])
17158 (define_insn "*strsetsi_rex_1"
17159   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17160         (match_operand:SI 2 "register_operand" "a"))
17161    (set (match_operand:DI 0 "register_operand" "=D")
17162         (plus:DI (match_dup 1)
17163                  (const_int 4)))
17164    (use (reg:SI DIRFLAG_REG))]
17165   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17166   "{stosl|stosd}"
17167   [(set_attr "type" "str")
17168    (set_attr "memory" "store")
17169    (set_attr "mode" "SI")])
17171 (define_insn "*strsethi_1"
17172   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17173         (match_operand:HI 2 "register_operand" "a"))
17174    (set (match_operand:SI 0 "register_operand" "=D")
17175         (plus:SI (match_dup 1)
17176                  (const_int 2)))
17177    (use (reg:SI DIRFLAG_REG))]
17178   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17179   "stosw"
17180   [(set_attr "type" "str")
17181    (set_attr "memory" "store")
17182    (set_attr "mode" "HI")])
17184 (define_insn "*strsethi_rex_1"
17185   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17186         (match_operand:HI 2 "register_operand" "a"))
17187    (set (match_operand:DI 0 "register_operand" "=D")
17188         (plus:DI (match_dup 1)
17189                  (const_int 2)))
17190    (use (reg:SI DIRFLAG_REG))]
17191   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17192   "stosw"
17193   [(set_attr "type" "str")
17194    (set_attr "memory" "store")
17195    (set_attr "mode" "HI")])
17197 (define_insn "*strsetqi_1"
17198   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17199         (match_operand:QI 2 "register_operand" "a"))
17200    (set (match_operand:SI 0 "register_operand" "=D")
17201         (plus:SI (match_dup 1)
17202                  (const_int 1)))
17203    (use (reg:SI DIRFLAG_REG))]
17204   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17205   "stosb"
17206   [(set_attr "type" "str")
17207    (set_attr "memory" "store")
17208    (set_attr "mode" "QI")])
17210 (define_insn "*strsetqi_rex_1"
17211   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17212         (match_operand:QI 2 "register_operand" "a"))
17213    (set (match_operand:DI 0 "register_operand" "=D")
17214         (plus:DI (match_dup 1)
17215                  (const_int 1)))
17216    (use (reg:SI DIRFLAG_REG))]
17217   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17218   "stosb"
17219   [(set_attr "type" "str")
17220    (set_attr "memory" "store")
17221    (set_attr "mode" "QI")])
17223 (define_expand "rep_stos"
17224   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17225               (set (match_operand 0 "register_operand" "")
17226                    (match_operand 4 "" ""))
17227               (set (match_operand 2 "memory_operand" "") (const_int 0))
17228               (use (match_operand 3 "register_operand" ""))
17229               (use (match_dup 1))
17230               (use (reg:SI DIRFLAG_REG))])]
17231   ""
17232   "")
17234 (define_insn "*rep_stosdi_rex64"
17235   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17236    (set (match_operand:DI 0 "register_operand" "=D") 
17237         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17238                             (const_int 3))
17239                  (match_operand:DI 3 "register_operand" "0")))
17240    (set (mem:BLK (match_dup 3))
17241         (const_int 0))
17242    (use (match_operand:DI 2 "register_operand" "a"))
17243    (use (match_dup 4))
17244    (use (reg:SI DIRFLAG_REG))]
17245   "TARGET_64BIT"
17246   "{rep\;stosq|rep stosq}"
17247   [(set_attr "type" "str")
17248    (set_attr "prefix_rep" "1")
17249    (set_attr "memory" "store")
17250    (set_attr "mode" "DI")])
17252 (define_insn "*rep_stossi"
17253   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17254    (set (match_operand:SI 0 "register_operand" "=D") 
17255         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17256                             (const_int 2))
17257                  (match_operand:SI 3 "register_operand" "0")))
17258    (set (mem:BLK (match_dup 3))
17259         (const_int 0))
17260    (use (match_operand:SI 2 "register_operand" "a"))
17261    (use (match_dup 4))
17262    (use (reg:SI DIRFLAG_REG))]
17263   "!TARGET_64BIT"
17264   "{rep\;stosl|rep stosd}"
17265   [(set_attr "type" "str")
17266    (set_attr "prefix_rep" "1")
17267    (set_attr "memory" "store")
17268    (set_attr "mode" "SI")])
17270 (define_insn "*rep_stossi_rex64"
17271   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17272    (set (match_operand:DI 0 "register_operand" "=D") 
17273         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17274                             (const_int 2))
17275                  (match_operand:DI 3 "register_operand" "0")))
17276    (set (mem:BLK (match_dup 3))
17277         (const_int 0))
17278    (use (match_operand:SI 2 "register_operand" "a"))
17279    (use (match_dup 4))
17280    (use (reg:SI DIRFLAG_REG))]
17281   "TARGET_64BIT"
17282   "{rep\;stosl|rep stosd}"
17283   [(set_attr "type" "str")
17284    (set_attr "prefix_rep" "1")
17285    (set_attr "memory" "store")
17286    (set_attr "mode" "SI")])
17288 (define_insn "*rep_stosqi"
17289   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17290    (set (match_operand:SI 0 "register_operand" "=D") 
17291         (plus:SI (match_operand:SI 3 "register_operand" "0")
17292                  (match_operand:SI 4 "register_operand" "1")))
17293    (set (mem:BLK (match_dup 3))
17294         (const_int 0))
17295    (use (match_operand:QI 2 "register_operand" "a"))
17296    (use (match_dup 4))
17297    (use (reg:SI DIRFLAG_REG))]
17298   "!TARGET_64BIT"
17299   "{rep\;stosb|rep stosb}"
17300   [(set_attr "type" "str")
17301    (set_attr "prefix_rep" "1")
17302    (set_attr "memory" "store")
17303    (set_attr "mode" "QI")])
17305 (define_insn "*rep_stosqi_rex64"
17306   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17307    (set (match_operand:DI 0 "register_operand" "=D") 
17308         (plus:DI (match_operand:DI 3 "register_operand" "0")
17309                  (match_operand:DI 4 "register_operand" "1")))
17310    (set (mem:BLK (match_dup 3))
17311         (const_int 0))
17312    (use (match_operand:QI 2 "register_operand" "a"))
17313    (use (match_dup 4))
17314    (use (reg:SI DIRFLAG_REG))]
17315   "TARGET_64BIT"
17316   "{rep\;stosb|rep stosb}"
17317   [(set_attr "type" "str")
17318    (set_attr "prefix_rep" "1")
17319    (set_attr "memory" "store")
17320    (set_attr "mode" "QI")])
17322 (define_expand "cmpstrsi"
17323   [(set (match_operand:SI 0 "register_operand" "")
17324         (compare:SI (match_operand:BLK 1 "general_operand" "")
17325                     (match_operand:BLK 2 "general_operand" "")))
17326    (use (match_operand 3 "general_operand" ""))
17327    (use (match_operand 4 "immediate_operand" ""))]
17328   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17330   rtx addr1, addr2, out, outlow, count, countreg, align;
17332   /* Can't use this if the user has appropriated esi or edi.  */
17333   if (global_regs[4] || global_regs[5])
17334     FAIL;
17336   out = operands[0];
17337   if (GET_CODE (out) != REG)
17338     out = gen_reg_rtx (SImode);
17340   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17341   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17342   if (addr1 != XEXP (operands[1], 0))
17343     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17344   if (addr2 != XEXP (operands[2], 0))
17345     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17347   count = operands[3];
17348   countreg = ix86_zero_extend_to_Pmode (count);
17350   /* %%% Iff we are testing strict equality, we can use known alignment
17351      to good advantage.  This may be possible with combine, particularly
17352      once cc0 is dead.  */
17353   align = operands[4];
17355   emit_insn (gen_cld ());
17356   if (GET_CODE (count) == CONST_INT)
17357     {
17358       if (INTVAL (count) == 0)
17359         {
17360           emit_move_insn (operands[0], const0_rtx);
17361           DONE;
17362         }
17363       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17364                                     operands[1], operands[2]));
17365     }
17366   else
17367     {
17368       if (TARGET_64BIT)
17369         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17370       else
17371         emit_insn (gen_cmpsi_1 (countreg, countreg));
17372       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17373                                  operands[1], operands[2]));
17374     }
17376   outlow = gen_lowpart (QImode, out);
17377   emit_insn (gen_cmpintqi (outlow));
17378   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17380   if (operands[0] != out)
17381     emit_move_insn (operands[0], out);
17383   DONE;
17386 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17388 (define_expand "cmpintqi"
17389   [(set (match_dup 1)
17390         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17391    (set (match_dup 2)
17392         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17393    (parallel [(set (match_operand:QI 0 "register_operand" "")
17394                    (minus:QI (match_dup 1)
17395                              (match_dup 2)))
17396               (clobber (reg:CC FLAGS_REG))])]
17397   ""
17398   "operands[1] = gen_reg_rtx (QImode);
17399    operands[2] = gen_reg_rtx (QImode);")
17401 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17402 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17404 (define_expand "cmpstrqi_nz_1"
17405   [(parallel [(set (reg:CC FLAGS_REG)
17406                    (compare:CC (match_operand 4 "memory_operand" "")
17407                                (match_operand 5 "memory_operand" "")))
17408               (use (match_operand 2 "register_operand" ""))
17409               (use (match_operand:SI 3 "immediate_operand" ""))
17410               (use (reg:SI DIRFLAG_REG))
17411               (clobber (match_operand 0 "register_operand" ""))
17412               (clobber (match_operand 1 "register_operand" ""))
17413               (clobber (match_dup 2))])]
17414   ""
17415   "")
17417 (define_insn "*cmpstrqi_nz_1"
17418   [(set (reg:CC FLAGS_REG)
17419         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17420                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17421    (use (match_operand:SI 6 "register_operand" "2"))
17422    (use (match_operand:SI 3 "immediate_operand" "i"))
17423    (use (reg:SI DIRFLAG_REG))
17424    (clobber (match_operand:SI 0 "register_operand" "=S"))
17425    (clobber (match_operand:SI 1 "register_operand" "=D"))
17426    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17427   "!TARGET_64BIT"
17428   "repz{\;| }cmpsb"
17429   [(set_attr "type" "str")
17430    (set_attr "mode" "QI")
17431    (set_attr "prefix_rep" "1")])
17433 (define_insn "*cmpstrqi_nz_rex_1"
17434   [(set (reg:CC FLAGS_REG)
17435         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17436                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17437    (use (match_operand:DI 6 "register_operand" "2"))
17438    (use (match_operand:SI 3 "immediate_operand" "i"))
17439    (use (reg:SI DIRFLAG_REG))
17440    (clobber (match_operand:DI 0 "register_operand" "=S"))
17441    (clobber (match_operand:DI 1 "register_operand" "=D"))
17442    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17443   "TARGET_64BIT"
17444   "repz{\;| }cmpsb"
17445   [(set_attr "type" "str")
17446    (set_attr "mode" "QI")
17447    (set_attr "prefix_rep" "1")])
17449 ;; The same, but the count is not known to not be zero.
17451 (define_expand "cmpstrqi_1"
17452   [(parallel [(set (reg:CC FLAGS_REG)
17453                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17454                                      (const_int 0))
17455                   (compare:CC (match_operand 4 "memory_operand" "")
17456                               (match_operand 5 "memory_operand" ""))
17457                   (const_int 0)))
17458               (use (match_operand:SI 3 "immediate_operand" ""))
17459               (use (reg:CC FLAGS_REG))
17460               (use (reg:SI DIRFLAG_REG))
17461               (clobber (match_operand 0 "register_operand" ""))
17462               (clobber (match_operand 1 "register_operand" ""))
17463               (clobber (match_dup 2))])]
17464   ""
17465   "")
17467 (define_insn "*cmpstrqi_1"
17468   [(set (reg:CC FLAGS_REG)
17469         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17470                              (const_int 0))
17471           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17472                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17473           (const_int 0)))
17474    (use (match_operand:SI 3 "immediate_operand" "i"))
17475    (use (reg:CC FLAGS_REG))
17476    (use (reg:SI DIRFLAG_REG))
17477    (clobber (match_operand:SI 0 "register_operand" "=S"))
17478    (clobber (match_operand:SI 1 "register_operand" "=D"))
17479    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17480   "!TARGET_64BIT"
17481   "repz{\;| }cmpsb"
17482   [(set_attr "type" "str")
17483    (set_attr "mode" "QI")
17484    (set_attr "prefix_rep" "1")])
17486 (define_insn "*cmpstrqi_rex_1"
17487   [(set (reg:CC FLAGS_REG)
17488         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17489                              (const_int 0))
17490           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17491                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17492           (const_int 0)))
17493    (use (match_operand:SI 3 "immediate_operand" "i"))
17494    (use (reg:CC FLAGS_REG))
17495    (use (reg:SI DIRFLAG_REG))
17496    (clobber (match_operand:DI 0 "register_operand" "=S"))
17497    (clobber (match_operand:DI 1 "register_operand" "=D"))
17498    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17499   "TARGET_64BIT"
17500   "repz{\;| }cmpsb"
17501   [(set_attr "type" "str")
17502    (set_attr "mode" "QI")
17503    (set_attr "prefix_rep" "1")])
17505 (define_expand "strlensi"
17506   [(set (match_operand:SI 0 "register_operand" "")
17507         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17508                     (match_operand:QI 2 "immediate_operand" "")
17509                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17510   ""
17512  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17513    DONE;
17514  else
17515    FAIL;
17518 (define_expand "strlendi"
17519   [(set (match_operand:DI 0 "register_operand" "")
17520         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17521                     (match_operand:QI 2 "immediate_operand" "")
17522                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17523   ""
17525  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17526    DONE;
17527  else
17528    FAIL;
17531 (define_expand "strlenqi_1"
17532   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17533               (use (reg:SI DIRFLAG_REG))
17534               (clobber (match_operand 1 "register_operand" ""))
17535               (clobber (reg:CC FLAGS_REG))])]
17536   ""
17537   "")
17539 (define_insn "*strlenqi_1"
17540   [(set (match_operand:SI 0 "register_operand" "=&c")
17541         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17542                     (match_operand:QI 2 "register_operand" "a")
17543                     (match_operand:SI 3 "immediate_operand" "i")
17544                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17545    (use (reg:SI DIRFLAG_REG))
17546    (clobber (match_operand:SI 1 "register_operand" "=D"))
17547    (clobber (reg:CC FLAGS_REG))]
17548   "!TARGET_64BIT"
17549   "repnz{\;| }scasb"
17550   [(set_attr "type" "str")
17551    (set_attr "mode" "QI")
17552    (set_attr "prefix_rep" "1")])
17554 (define_insn "*strlenqi_rex_1"
17555   [(set (match_operand:DI 0 "register_operand" "=&c")
17556         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17557                     (match_operand:QI 2 "register_operand" "a")
17558                     (match_operand:DI 3 "immediate_operand" "i")
17559                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17560    (use (reg:SI DIRFLAG_REG))
17561    (clobber (match_operand:DI 1 "register_operand" "=D"))
17562    (clobber (reg:CC FLAGS_REG))]
17563   "TARGET_64BIT"
17564   "repnz{\;| }scasb"
17565   [(set_attr "type" "str")
17566    (set_attr "mode" "QI")
17567    (set_attr "prefix_rep" "1")])
17569 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17570 ;; handled in combine, but it is not currently up to the task.
17571 ;; When used for their truth value, the cmpstr* expanders generate
17572 ;; code like this:
17574 ;;   repz cmpsb
17575 ;;   seta       %al
17576 ;;   setb       %dl
17577 ;;   cmpb       %al, %dl
17578 ;;   jcc        label
17580 ;; The intermediate three instructions are unnecessary.
17582 ;; This one handles cmpstr*_nz_1...
17583 (define_peephole2
17584   [(parallel[
17585      (set (reg:CC FLAGS_REG)
17586           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17587                       (mem:BLK (match_operand 5 "register_operand" ""))))
17588      (use (match_operand 6 "register_operand" ""))
17589      (use (match_operand:SI 3 "immediate_operand" ""))
17590      (use (reg:SI DIRFLAG_REG))
17591      (clobber (match_operand 0 "register_operand" ""))
17592      (clobber (match_operand 1 "register_operand" ""))
17593      (clobber (match_operand 2 "register_operand" ""))])
17594    (set (match_operand:QI 7 "register_operand" "")
17595         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17596    (set (match_operand:QI 8 "register_operand" "")
17597         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17598    (set (reg FLAGS_REG)
17599         (compare (match_dup 7) (match_dup 8)))
17600   ]
17601   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17602   [(parallel[
17603      (set (reg:CC FLAGS_REG)
17604           (compare:CC (mem:BLK (match_dup 4))
17605                       (mem:BLK (match_dup 5))))
17606      (use (match_dup 6))
17607      (use (match_dup 3))
17608      (use (reg:SI DIRFLAG_REG))
17609      (clobber (match_dup 0))
17610      (clobber (match_dup 1))
17611      (clobber (match_dup 2))])]
17612   "")
17614 ;; ...and this one handles cmpstr*_1.
17615 (define_peephole2
17616   [(parallel[
17617      (set (reg:CC FLAGS_REG)
17618           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17619                                (const_int 0))
17620             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17621                         (mem:BLK (match_operand 5 "register_operand" "")))
17622             (const_int 0)))
17623      (use (match_operand:SI 3 "immediate_operand" ""))
17624      (use (reg:CC FLAGS_REG))
17625      (use (reg:SI DIRFLAG_REG))
17626      (clobber (match_operand 0 "register_operand" ""))
17627      (clobber (match_operand 1 "register_operand" ""))
17628      (clobber (match_operand 2 "register_operand" ""))])
17629    (set (match_operand:QI 7 "register_operand" "")
17630         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17631    (set (match_operand:QI 8 "register_operand" "")
17632         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17633    (set (reg FLAGS_REG)
17634         (compare (match_dup 7) (match_dup 8)))
17635   ]
17636   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17637   [(parallel[
17638      (set (reg:CC FLAGS_REG)
17639           (if_then_else:CC (ne (match_dup 6)
17640                                (const_int 0))
17641             (compare:CC (mem:BLK (match_dup 4))
17642                         (mem:BLK (match_dup 5)))
17643             (const_int 0)))
17644      (use (match_dup 3))
17645      (use (reg:CC FLAGS_REG))
17646      (use (reg:SI DIRFLAG_REG))
17647      (clobber (match_dup 0))
17648      (clobber (match_dup 1))
17649      (clobber (match_dup 2))])]
17650   "")
17654 ;; Conditional move instructions.
17656 (define_expand "movdicc"
17657   [(set (match_operand:DI 0 "register_operand" "")
17658         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17659                          (match_operand:DI 2 "general_operand" "")
17660                          (match_operand:DI 3 "general_operand" "")))]
17661   "TARGET_64BIT"
17662   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17664 (define_insn "x86_movdicc_0_m1_rex64"
17665   [(set (match_operand:DI 0 "register_operand" "=r")
17666         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17667           (const_int -1)
17668           (const_int 0)))
17669    (clobber (reg:CC FLAGS_REG))]
17670   "TARGET_64BIT"
17671   "sbb{q}\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" "DI")
17679    (set_attr "length_immediate" "0")])
17681 (define_insn "movdicc_c_rex64"
17682   [(set (match_operand:DI 0 "register_operand" "=r,r")
17683         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17684                                 [(reg FLAGS_REG) (const_int 0)])
17685                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17686                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17687   "TARGET_64BIT && 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" "DI")])
17695 (define_expand "movsicc"
17696   [(set (match_operand:SI 0 "register_operand" "")
17697         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17698                          (match_operand:SI 2 "general_operand" "")
17699                          (match_operand:SI 3 "general_operand" "")))]
17700   ""
17701   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17703 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17704 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17705 ;; So just document what we're doing explicitly.
17707 (define_insn "x86_movsicc_0_m1"
17708   [(set (match_operand:SI 0 "register_operand" "=r")
17709         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17710           (const_int -1)
17711           (const_int 0)))
17712    (clobber (reg:CC FLAGS_REG))]
17713   ""
17714   "sbb{l}\t%0, %0"
17715   ; Since we don't have the proper number of operands for an alu insn,
17716   ; fill in all the blanks.
17717   [(set_attr "type" "alu")
17718    (set_attr "pent_pair" "pu")
17719    (set_attr "memory" "none")
17720    (set_attr "imm_disp" "false")
17721    (set_attr "mode" "SI")
17722    (set_attr "length_immediate" "0")])
17724 (define_insn "*movsicc_noc"
17725   [(set (match_operand:SI 0 "register_operand" "=r,r")
17726         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17727                                 [(reg FLAGS_REG) (const_int 0)])
17728                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17729                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17730   "TARGET_CMOVE
17731    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17732   "@
17733    cmov%O2%C1\t{%2, %0|%0, %2}
17734    cmov%O2%c1\t{%3, %0|%0, %3}"
17735   [(set_attr "type" "icmov")
17736    (set_attr "mode" "SI")])
17738 (define_expand "movhicc"
17739   [(set (match_operand:HI 0 "register_operand" "")
17740         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17741                          (match_operand:HI 2 "general_operand" "")
17742                          (match_operand:HI 3 "general_operand" "")))]
17743   "TARGET_HIMODE_MATH"
17744   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17746 (define_insn "*movhicc_noc"
17747   [(set (match_operand:HI 0 "register_operand" "=r,r")
17748         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17749                                 [(reg FLAGS_REG) (const_int 0)])
17750                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17751                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17752   "TARGET_CMOVE
17753    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17754   "@
17755    cmov%O2%C1\t{%2, %0|%0, %2}
17756    cmov%O2%c1\t{%3, %0|%0, %3}"
17757   [(set_attr "type" "icmov")
17758    (set_attr "mode" "HI")])
17760 (define_expand "movqicc"
17761   [(set (match_operand:QI 0 "register_operand" "")
17762         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17763                          (match_operand:QI 2 "general_operand" "")
17764                          (match_operand:QI 3 "general_operand" "")))]
17765   "TARGET_QIMODE_MATH"
17766   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17768 (define_insn_and_split "*movqicc_noc"
17769   [(set (match_operand:QI 0 "register_operand" "=r,r")
17770         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17771                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17772                       (match_operand:QI 2 "register_operand" "r,0")
17773                       (match_operand:QI 3 "register_operand" "0,r")))]
17774   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17775   "#"
17776   "&& reload_completed"
17777   [(set (match_dup 0)
17778         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17779                       (match_dup 2)
17780                       (match_dup 3)))]
17781   "operands[0] = gen_lowpart (SImode, operands[0]);
17782    operands[2] = gen_lowpart (SImode, operands[2]);
17783    operands[3] = gen_lowpart (SImode, operands[3]);"
17784   [(set_attr "type" "icmov")
17785    (set_attr "mode" "SI")])
17787 (define_expand "movsfcc"
17788   [(set (match_operand:SF 0 "register_operand" "")
17789         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17790                          (match_operand:SF 2 "register_operand" "")
17791                          (match_operand:SF 3 "register_operand" "")))]
17792   "TARGET_CMOVE"
17793   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17795 (define_insn "*movsfcc_1"
17796   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17797         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17798                                 [(reg FLAGS_REG) (const_int 0)])
17799                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17800                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17801   "TARGET_CMOVE
17802    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17803   "@
17804    fcmov%F1\t{%2, %0|%0, %2}
17805    fcmov%f1\t{%3, %0|%0, %3}
17806    cmov%O2%C1\t{%2, %0|%0, %2}
17807    cmov%O2%c1\t{%3, %0|%0, %3}"
17808   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17809    (set_attr "mode" "SF,SF,SI,SI")])
17811 (define_expand "movdfcc"
17812   [(set (match_operand:DF 0 "register_operand" "")
17813         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17814                          (match_operand:DF 2 "register_operand" "")
17815                          (match_operand:DF 3 "register_operand" "")))]
17816   "TARGET_CMOVE"
17817   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17819 (define_insn "*movdfcc_1"
17820   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17821         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17822                                 [(reg FLAGS_REG) (const_int 0)])
17823                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17824                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17825   "!TARGET_64BIT && TARGET_CMOVE
17826    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17827   "@
17828    fcmov%F1\t{%2, %0|%0, %2}
17829    fcmov%f1\t{%3, %0|%0, %3}
17830    #
17831    #"
17832   [(set_attr "type" "fcmov,fcmov,multi,multi")
17833    (set_attr "mode" "DF")])
17835 (define_insn "*movdfcc_1_rex64"
17836   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17837         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17838                                 [(reg FLAGS_REG) (const_int 0)])
17839                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17840                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17841   "TARGET_64BIT && TARGET_CMOVE
17842    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17843   "@
17844    fcmov%F1\t{%2, %0|%0, %2}
17845    fcmov%f1\t{%3, %0|%0, %3}
17846    cmov%O2%C1\t{%2, %0|%0, %2}
17847    cmov%O2%c1\t{%3, %0|%0, %3}"
17848   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17849    (set_attr "mode" "DF")])
17851 (define_split
17852   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17853         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17854                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17855                       (match_operand:DF 2 "nonimmediate_operand" "")
17856                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17857   "!TARGET_64BIT && reload_completed"
17858   [(set (match_dup 2)
17859         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17860                       (match_dup 5)
17861                       (match_dup 7)))
17862    (set (match_dup 3)
17863         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17864                       (match_dup 6)
17865                       (match_dup 8)))]
17866   "split_di (operands+2, 1, operands+5, operands+6);
17867    split_di (operands+3, 1, operands+7, operands+8);
17868    split_di (operands, 1, operands+2, operands+3);")
17870 (define_expand "movxfcc"
17871   [(set (match_operand:XF 0 "register_operand" "")
17872         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17873                          (match_operand:XF 2 "register_operand" "")
17874                          (match_operand:XF 3 "register_operand" "")))]
17875   "TARGET_CMOVE"
17876   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17878 (define_insn "*movxfcc_1"
17879   [(set (match_operand:XF 0 "register_operand" "=f,f")
17880         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17881                                 [(reg FLAGS_REG) (const_int 0)])
17882                       (match_operand:XF 2 "register_operand" "f,0")
17883                       (match_operand:XF 3 "register_operand" "0,f")))]
17884   "TARGET_CMOVE"
17885   "@
17886    fcmov%F1\t{%2, %0|%0, %2}
17887    fcmov%f1\t{%3, %0|%0, %3}"
17888   [(set_attr "type" "fcmov")
17889    (set_attr "mode" "XF")])
17891 (define_expand "minsf3"
17892   [(parallel [
17893      (set (match_operand:SF 0 "register_operand" "")
17894           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17895                                (match_operand:SF 2 "nonimmediate_operand" ""))
17896                            (match_dup 1)
17897                            (match_dup 2)))
17898      (clobber (reg:CC FLAGS_REG))])]
17899   "TARGET_SSE"
17900   "")
17902 (define_insn "*minsf"
17903   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17904         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17905                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17906                          (match_dup 1)
17907                          (match_dup 2)))
17908    (clobber (reg:CC FLAGS_REG))]
17909   "TARGET_SSE && TARGET_IEEE_FP"
17910   "#")
17912 (define_insn "*minsf_nonieee"
17913   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17914         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17915                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17916                          (match_dup 1)
17917                          (match_dup 2)))
17918    (clobber (reg:CC FLAGS_REG))]
17919   "TARGET_SSE && !TARGET_IEEE_FP
17920    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17921   "#")
17923 (define_split
17924   [(set (match_operand:SF 0 "register_operand" "")
17925         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17926                              (match_operand:SF 2 "nonimmediate_operand" ""))
17927                          (match_operand:SF 3 "register_operand" "")
17928                          (match_operand:SF 4 "nonimmediate_operand" "")))
17929    (clobber (reg:CC FLAGS_REG))]
17930   "SSE_REG_P (operands[0]) && reload_completed
17931    && ((operands_match_p (operands[1], operands[3])
17932         && operands_match_p (operands[2], operands[4]))
17933        || (operands_match_p (operands[1], operands[4])
17934            && operands_match_p (operands[2], operands[3])))"
17935   [(set (match_dup 0)
17936         (if_then_else:SF (lt (match_dup 1)
17937                              (match_dup 2))
17938                          (match_dup 1)
17939                          (match_dup 2)))])
17941 ;; Conditional addition patterns
17942 (define_expand "addqicc"
17943   [(match_operand:QI 0 "register_operand" "")
17944    (match_operand 1 "comparison_operator" "")
17945    (match_operand:QI 2 "register_operand" "")
17946    (match_operand:QI 3 "const_int_operand" "")]
17947   ""
17948   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17950 (define_expand "addhicc"
17951   [(match_operand:HI 0 "register_operand" "")
17952    (match_operand 1 "comparison_operator" "")
17953    (match_operand:HI 2 "register_operand" "")
17954    (match_operand:HI 3 "const_int_operand" "")]
17955   ""
17956   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17958 (define_expand "addsicc"
17959   [(match_operand:SI 0 "register_operand" "")
17960    (match_operand 1 "comparison_operator" "")
17961    (match_operand:SI 2 "register_operand" "")
17962    (match_operand:SI 3 "const_int_operand" "")]
17963   ""
17964   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17966 (define_expand "adddicc"
17967   [(match_operand:DI 0 "register_operand" "")
17968    (match_operand 1 "comparison_operator" "")
17969    (match_operand:DI 2 "register_operand" "")
17970    (match_operand:DI 3 "const_int_operand" "")]
17971   "TARGET_64BIT"
17972   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17974 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17976 (define_split
17977   [(set (match_operand:SF 0 "fp_register_operand" "")
17978         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17979                              (match_operand:SF 2 "register_operand" ""))
17980                          (match_operand:SF 3 "register_operand" "")
17981                          (match_operand:SF 4 "register_operand" "")))
17982    (clobber (reg:CC FLAGS_REG))]
17983   "reload_completed
17984    && ((operands_match_p (operands[1], operands[3])
17985         && operands_match_p (operands[2], operands[4]))
17986        || (operands_match_p (operands[1], operands[4])
17987            && operands_match_p (operands[2], operands[3])))"
17988   [(set (reg:CCFP FLAGS_REG)
17989         (compare:CCFP (match_dup 2)
17990                       (match_dup 1)))
17991    (set (match_dup 0)
17992         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17993                          (match_dup 1)
17994                          (match_dup 2)))])
17996 (define_insn "*minsf_sse"
17997   [(set (match_operand:SF 0 "register_operand" "=x")
17998         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17999                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18000                          (match_dup 1)
18001                          (match_dup 2)))]
18002   "TARGET_SSE && reload_completed"
18003   "minss\t{%2, %0|%0, %2}"
18004   [(set_attr "type" "sse")
18005    (set_attr "mode" "SF")])
18007 (define_expand "mindf3"
18008   [(parallel [
18009      (set (match_operand:DF 0 "register_operand" "")
18010           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18011                                (match_operand:DF 2 "nonimmediate_operand" ""))
18012                            (match_dup 1)
18013                            (match_dup 2)))
18014      (clobber (reg:CC FLAGS_REG))])]
18015   "TARGET_SSE2 && TARGET_SSE_MATH"
18016   "#")
18018 (define_insn "*mindf"
18019   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18020         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18021                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18022                          (match_dup 1)
18023                          (match_dup 2)))
18024    (clobber (reg:CC FLAGS_REG))]
18025   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
18026   "#")
18028 (define_insn "*mindf_nonieee"
18029   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18030         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18031                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18032                          (match_dup 1)
18033                          (match_dup 2)))
18034    (clobber (reg:CC FLAGS_REG))]
18035   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18036    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18037   "#")
18039 (define_split
18040   [(set (match_operand:DF 0 "register_operand" "")
18041         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18042                              (match_operand:DF 2 "nonimmediate_operand" ""))
18043                          (match_operand:DF 3 "register_operand" "")
18044                          (match_operand:DF 4 "nonimmediate_operand" "")))
18045    (clobber (reg:CC FLAGS_REG))]
18046   "SSE_REG_P (operands[0]) && reload_completed
18047    && ((operands_match_p (operands[1], operands[3])
18048         && operands_match_p (operands[2], operands[4]))
18049        || (operands_match_p (operands[1], operands[4])
18050            && operands_match_p (operands[2], operands[3])))"
18051   [(set (match_dup 0)
18052         (if_then_else:DF (lt (match_dup 1)
18053                              (match_dup 2))
18054                          (match_dup 1)
18055                          (match_dup 2)))])
18057 ;; We can't represent the LT test directly.  Do this by swapping the operands.
18058 (define_split
18059   [(set (match_operand:DF 0 "fp_register_operand" "")
18060         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18061                              (match_operand:DF 2 "register_operand" ""))
18062                          (match_operand:DF 3 "register_operand" "")
18063                          (match_operand:DF 4 "register_operand" "")))
18064    (clobber (reg:CC FLAGS_REG))]
18065   "reload_completed
18066    && ((operands_match_p (operands[1], operands[3])
18067         && operands_match_p (operands[2], operands[4]))
18068        || (operands_match_p (operands[1], operands[4])
18069            && operands_match_p (operands[2], operands[3])))"
18070   [(set (reg:CCFP FLAGS_REG)
18071         (compare:CCFP (match_dup 2)
18072                       (match_dup 1)))
18073    (set (match_dup 0)
18074         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18075                          (match_dup 1)
18076                          (match_dup 2)))])
18078 (define_insn "*mindf_sse"
18079   [(set (match_operand:DF 0 "register_operand" "=Y")
18080         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
18081                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18082                          (match_dup 1)
18083                          (match_dup 2)))]
18084   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18085   "minsd\t{%2, %0|%0, %2}"
18086   [(set_attr "type" "sse")
18087    (set_attr "mode" "DF")])
18089 (define_expand "maxsf3"
18090   [(parallel [
18091      (set (match_operand:SF 0 "register_operand" "")
18092           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18093                                (match_operand:SF 2 "nonimmediate_operand" ""))
18094                            (match_dup 1)
18095                            (match_dup 2)))
18096      (clobber (reg:CC FLAGS_REG))])]
18097   "TARGET_SSE"
18098   "#")
18100 (define_insn "*maxsf"
18101   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
18102         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
18103                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
18104                          (match_dup 1)
18105                          (match_dup 2)))
18106    (clobber (reg:CC FLAGS_REG))]
18107   "TARGET_SSE && TARGET_IEEE_FP"
18108   "#")
18110 (define_insn "*maxsf_nonieee"
18111   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
18112         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
18113                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
18114                          (match_dup 1)
18115                          (match_dup 2)))
18116    (clobber (reg:CC FLAGS_REG))]
18117   "TARGET_SSE && !TARGET_IEEE_FP
18118    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18119   "#")
18121 (define_split
18122   [(set (match_operand:SF 0 "register_operand" "")
18123         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18124                              (match_operand:SF 2 "nonimmediate_operand" ""))
18125                          (match_operand:SF 3 "register_operand" "")
18126                          (match_operand:SF 4 "nonimmediate_operand" "")))
18127    (clobber (reg:CC FLAGS_REG))]
18128   "SSE_REG_P (operands[0]) && reload_completed
18129    && ((operands_match_p (operands[1], operands[3])
18130         && operands_match_p (operands[2], operands[4]))
18131        || (operands_match_p (operands[1], operands[4])
18132            && operands_match_p (operands[2], operands[3])))"
18133   [(set (match_dup 0)
18134         (if_then_else:SF (gt (match_dup 1)
18135                              (match_dup 2))
18136                          (match_dup 1)
18137                          (match_dup 2)))])
18139 (define_split
18140   [(set (match_operand:SF 0 "fp_register_operand" "")
18141         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18142                              (match_operand:SF 2 "register_operand" ""))
18143                          (match_operand:SF 3 "register_operand" "")
18144                          (match_operand:SF 4 "register_operand" "")))
18145    (clobber (reg:CC FLAGS_REG))]
18146   "reload_completed
18147    && ((operands_match_p (operands[1], operands[3])
18148         && operands_match_p (operands[2], operands[4]))
18149        || (operands_match_p (operands[1], operands[4])
18150            && operands_match_p (operands[2], operands[3])))"
18151   [(set (reg:CCFP FLAGS_REG)
18152         (compare:CCFP (match_dup 1)
18153                       (match_dup 2)))
18154    (set (match_dup 0)
18155         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18156                          (match_dup 1)
18157                          (match_dup 2)))])
18159 (define_insn "*maxsf_sse"
18160   [(set (match_operand:SF 0 "register_operand" "=x")
18161         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
18162                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
18163                          (match_dup 1)
18164                          (match_dup 2)))]
18165   "TARGET_SSE && reload_completed"
18166   "maxss\t{%2, %0|%0, %2}"
18167   [(set_attr "type" "sse")
18168    (set_attr "mode" "SF")])
18170 (define_expand "maxdf3"
18171   [(parallel [
18172      (set (match_operand:DF 0 "register_operand" "")
18173           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18174                                (match_operand:DF 2 "nonimmediate_operand" ""))
18175                            (match_dup 1)
18176                            (match_dup 2)))
18177      (clobber (reg:CC FLAGS_REG))])]
18178   "TARGET_SSE2 && TARGET_SSE_MATH"
18179   "#")
18181 (define_insn "*maxdf"
18182   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18183         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18184                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18185                          (match_dup 1)
18186                          (match_dup 2)))
18187    (clobber (reg:CC FLAGS_REG))]
18188   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
18189   "#")
18191 (define_insn "*maxdf_nonieee"
18192   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18193         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18194                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18195                          (match_dup 1)
18196                          (match_dup 2)))
18197    (clobber (reg:CC FLAGS_REG))]
18198   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18199    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18200   "#")
18202 (define_split
18203   [(set (match_operand:DF 0 "register_operand" "")
18204         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18205                              (match_operand:DF 2 "nonimmediate_operand" ""))
18206                          (match_operand:DF 3 "register_operand" "")
18207                          (match_operand:DF 4 "nonimmediate_operand" "")))
18208    (clobber (reg:CC FLAGS_REG))]
18209   "SSE_REG_P (operands[0]) && reload_completed
18210    && ((operands_match_p (operands[1], operands[3])
18211         && operands_match_p (operands[2], operands[4]))
18212        || (operands_match_p (operands[1], operands[4])
18213            && operands_match_p (operands[2], operands[3])))"
18214   [(set (match_dup 0)
18215         (if_then_else:DF (gt (match_dup 1)
18216                              (match_dup 2))
18217                          (match_dup 1)
18218                          (match_dup 2)))])
18220 (define_split
18221   [(set (match_operand:DF 0 "fp_register_operand" "")
18222         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18223                              (match_operand:DF 2 "register_operand" ""))
18224                          (match_operand:DF 3 "register_operand" "")
18225                          (match_operand:DF 4 "register_operand" "")))
18226    (clobber (reg:CC FLAGS_REG))]
18227   "reload_completed
18228    && ((operands_match_p (operands[1], operands[3])
18229         && operands_match_p (operands[2], operands[4]))
18230        || (operands_match_p (operands[1], operands[4])
18231            && operands_match_p (operands[2], operands[3])))"
18232   [(set (reg:CCFP FLAGS_REG)
18233         (compare:CCFP (match_dup 1)
18234                       (match_dup 2)))
18235    (set (match_dup 0)
18236         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18237                          (match_dup 1)
18238                          (match_dup 2)))])
18240 (define_insn "*maxdf_sse"
18241   [(set (match_operand:DF 0 "register_operand" "=Y")
18242         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
18243                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18244                          (match_dup 1)
18245                          (match_dup 2)))]
18246   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18247   "maxsd\t{%2, %0|%0, %2}"
18248   [(set_attr "type" "sse")
18249    (set_attr "mode" "DF")])
18251 ;; Misc patterns (?)
18253 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18254 ;; Otherwise there will be nothing to keep
18255 ;; 
18256 ;; [(set (reg ebp) (reg esp))]
18257 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18258 ;;  (clobber (eflags)]
18259 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18261 ;; in proper program order.
18262 (define_insn "pro_epilogue_adjust_stack_1"
18263   [(set (match_operand:SI 0 "register_operand" "=r,r")
18264         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18265                  (match_operand:SI 2 "immediate_operand" "i,i")))
18266    (clobber (reg:CC FLAGS_REG))
18267    (clobber (mem:BLK (scratch)))]
18268   "!TARGET_64BIT"
18270   switch (get_attr_type (insn))
18271     {
18272     case TYPE_IMOV:
18273       return "mov{l}\t{%1, %0|%0, %1}";
18275     case TYPE_ALU:
18276       if (GET_CODE (operands[2]) == CONST_INT
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{l}\t{%2, %0|%0, %2}";
18283         }
18284       return "add{l}\t{%2, %0|%0, %2}";
18286     case TYPE_LEA:
18287       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18288       return "lea{l}\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:SI 2 "const0_operand" "")
18298                  (const_string "imov")
18299               ]
18300               (const_string "lea")))
18301    (set_attr "mode" "SI")])
18303 (define_insn "pro_epilogue_adjust_stack_rex64"
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 2 "x86_64_immediate_operand" "e,e")))
18307    (clobber (reg:CC FLAGS_REG))
18308    (clobber (mem:BLK (scratch)))]
18309   "TARGET_64BIT"
18311   switch (get_attr_type (insn))
18312     {
18313     case TYPE_IMOV:
18314       return "mov{q}\t{%1, %0|%0, %1}";
18316     case TYPE_ALU:
18317       if (GET_CODE (operands[2]) == CONST_INT
18318           /* Avoid overflows.  */
18319           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18320           && (INTVAL (operands[2]) == 128
18321               || (INTVAL (operands[2]) < 0
18322                   && INTVAL (operands[2]) != -128)))
18323         {
18324           operands[2] = GEN_INT (-INTVAL (operands[2]));
18325           return "sub{q}\t{%2, %0|%0, %2}";
18326         }
18327       return "add{q}\t{%2, %0|%0, %2}";
18329     case TYPE_LEA:
18330       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18331       return "lea{q}\t{%a2, %0|%0, %a2}";
18333     default:
18334       abort ();
18335     }
18337   [(set (attr "type")
18338         (cond [(eq_attr "alternative" "0")
18339                  (const_string "alu")
18340                (match_operand:DI 2 "const0_operand" "")
18341                  (const_string "imov")
18342               ]
18343               (const_string "lea")))
18344    (set_attr "mode" "DI")])
18346 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18347   [(set (match_operand:DI 0 "register_operand" "=r,r")
18348         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18349                  (match_operand:DI 3 "immediate_operand" "i,i")))
18350    (use (match_operand:DI 2 "register_operand" "r,r"))
18351    (clobber (reg:CC FLAGS_REG))
18352    (clobber (mem:BLK (scratch)))]
18353   "TARGET_64BIT"
18355   switch (get_attr_type (insn))
18356     {
18357     case TYPE_ALU:
18358       return "add{q}\t{%2, %0|%0, %2}";
18360     case TYPE_LEA:
18361       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18362       return "lea{q}\t{%a2, %0|%0, %a2}";
18364     default:
18365       abort ();
18366     }
18368   [(set_attr "type" "alu,lea")
18369    (set_attr "mode" "DI")])
18371 ;; Placeholder for the conditional moves.  This one is split either to SSE
18372 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18373 ;; fact is that compares supported by the cmp??ss instructions are exactly
18374 ;; swapped of those supported by cmove sequence.
18375 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18376 ;; supported by i387 comparisons and we do need to emit two conditional moves
18377 ;; in tandem.
18379 (define_insn "sse_movsfcc"
18380   [(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")
18381         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18382                         [(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")
18383                          (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")])
18384                       (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")
18385                       (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")))
18386    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18387    (clobber (reg:CC FLAGS_REG))]
18388   "TARGET_SSE
18389    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18390    /* Avoid combine from being smart and converting min/max
18391       instruction patterns into conditional moves.  */
18392    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18393         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18394        || !rtx_equal_p (operands[4], operands[2])
18395        || !rtx_equal_p (operands[5], operands[3]))
18396    && (!TARGET_IEEE_FP
18397        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18398   "#")
18400 (define_insn "sse_movsfcc_eq"
18401   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18402         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18403                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18404                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18405                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18406    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18407    (clobber (reg:CC FLAGS_REG))]
18408   "TARGET_SSE
18409    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18410   "#")
18412 (define_insn "sse_movdfcc"
18413   [(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")
18414         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18415                         [(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")
18416                          (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")])
18417                       (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")
18418                       (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")))
18419    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18420    (clobber (reg:CC FLAGS_REG))]
18421   "TARGET_SSE2
18422    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18423    /* Avoid combine from being smart and converting min/max
18424       instruction patterns into conditional moves.  */
18425    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18426         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18427        || !rtx_equal_p (operands[4], operands[2])
18428        || !rtx_equal_p (operands[5], operands[3]))
18429    && (!TARGET_IEEE_FP
18430        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18431   "#")
18433 (define_insn "sse_movdfcc_eq"
18434   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18435         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18436                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18437                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18438                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18439    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18440    (clobber (reg:CC FLAGS_REG))]
18441   "TARGET_SSE
18442    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18443   "#")
18445 ;; For non-sse moves just expand the usual cmove sequence.
18446 (define_split
18447   [(set (match_operand 0 "register_operand" "")
18448         (if_then_else (match_operator 1 "comparison_operator"
18449                         [(match_operand 4 "nonimmediate_operand" "")
18450                          (match_operand 5 "register_operand" "")])
18451                       (match_operand 2 "nonimmediate_operand" "")
18452                       (match_operand 3 "nonimmediate_operand" "")))
18453    (clobber (match_operand 6 "" ""))
18454    (clobber (reg:CC FLAGS_REG))]
18455   "!SSE_REG_P (operands[0]) && reload_completed
18456    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18457   [(const_int 0)]
18459    ix86_compare_op0 = operands[5];
18460    ix86_compare_op1 = operands[4];
18461    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18462                                  VOIDmode, operands[5], operands[4]);
18463    ix86_expand_fp_movcc (operands);
18464    DONE;
18467 ;; Split SSE based conditional move into sequence:
18468 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18469 ;; and   op2, op0   -  zero op2 if comparison was false
18470 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18471 ;; or    op2, op0   -  get the nonzero one into the result.
18472 (define_split
18473   [(set (match_operand:SF 0 "register_operand" "")
18474         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18475                         [(match_operand:SF 4 "register_operand" "")
18476                          (match_operand:SF 5 "nonimmediate_operand" "")])
18477                       (match_operand:SF 2 "register_operand" "")
18478                       (match_operand:SF 3 "register_operand" "")))
18479    (clobber (match_operand 6 "" ""))
18480    (clobber (reg:CC FLAGS_REG))]
18481   "SSE_REG_P (operands[0]) && reload_completed"
18482   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18483    (set (match_dup 2) (and:V4SF (match_dup 2)
18484                                 (match_dup 8)))
18485    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18486                                           (match_dup 3)))
18487    (set (match_dup 0) (ior:V4SF (match_dup 6)
18488                                 (match_dup 7)))]
18490   /* If op2 == op3, op3 would be clobbered before it is used.  */
18491   if (operands_match_p (operands[2], operands[3]))
18492     {
18493       emit_move_insn (operands[0], operands[2]);
18494       DONE;
18495     }
18497   PUT_MODE (operands[1], GET_MODE (operands[0]));
18498   if (operands_match_p (operands[0], operands[4]))
18499     operands[6] = operands[4], operands[7] = operands[2];
18500   else
18501     operands[6] = operands[2], operands[7] = operands[4];
18502   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18503   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18504   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18505   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18506   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18507   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18510 (define_split
18511   [(set (match_operand:DF 0 "register_operand" "")
18512         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18513                         [(match_operand:DF 4 "register_operand" "")
18514                          (match_operand:DF 5 "nonimmediate_operand" "")])
18515                       (match_operand:DF 2 "register_operand" "")
18516                       (match_operand:DF 3 "register_operand" "")))
18517    (clobber (match_operand 6 "" ""))
18518    (clobber (reg:CC FLAGS_REG))]
18519   "SSE_REG_P (operands[0]) && reload_completed"
18520   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18521    (set (match_dup 2) (and:V2DF (match_dup 2)
18522                                 (match_dup 8)))
18523    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18524                                           (match_dup 3)))
18525    (set (match_dup 0) (ior:V2DF (match_dup 6)
18526                                 (match_dup 7)))]
18528   if (GET_MODE (operands[2]) == DFmode
18529       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18530     {
18531       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18532       emit_insn (gen_sse2_unpcklpd (op, op, op));
18533       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18534       emit_insn (gen_sse2_unpcklpd (op, op, op));
18535     }
18537   /* If op2 == op3, op3 would be clobbered before it is used.  */
18538   if (operands_match_p (operands[2], operands[3]))
18539     {
18540       emit_move_insn (operands[0], operands[2]);
18541       DONE;
18542     }
18544   PUT_MODE (operands[1], GET_MODE (operands[0]));
18545   if (operands_match_p (operands[0], operands[4]))
18546     operands[6] = operands[4], operands[7] = operands[2];
18547   else
18548     operands[6] = operands[2], operands[7] = operands[4];
18549   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18550   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18551   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18552   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18553   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18554   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18557 ;; Special case of conditional move we can handle effectively.
18558 ;; Do not brother with the integer/floating point case, since these are
18559 ;; bot considerably slower, unlike in the generic case.
18560 (define_insn "*sse_movsfcc_const0_1"
18561   [(set (match_operand:SF 0 "register_operand" "=&x")
18562         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18563                         [(match_operand:SF 4 "register_operand" "0")
18564                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18565                       (match_operand:SF 2 "register_operand" "x")
18566                       (match_operand:SF 3 "const0_operand" "X")))]
18567   "TARGET_SSE"
18568   "#")
18570 (define_insn "*sse_movsfcc_const0_2"
18571   [(set (match_operand:SF 0 "register_operand" "=&x")
18572         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18573                         [(match_operand:SF 4 "register_operand" "0")
18574                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18575                       (match_operand:SF 2 "const0_operand" "X")
18576                       (match_operand:SF 3 "register_operand" "x")))]
18577   "TARGET_SSE"
18578   "#")
18580 (define_insn "*sse_movsfcc_const0_3"
18581   [(set (match_operand:SF 0 "register_operand" "=&x")
18582         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18583                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18584                          (match_operand:SF 5 "register_operand" "0")])
18585                       (match_operand:SF 2 "register_operand" "x")
18586                       (match_operand:SF 3 "const0_operand" "X")))]
18587   "TARGET_SSE"
18588   "#")
18590 (define_insn "*sse_movsfcc_const0_4"
18591   [(set (match_operand:SF 0 "register_operand" "=&x")
18592         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18593                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18594                          (match_operand:SF 5 "register_operand" "0")])
18595                       (match_operand:SF 2 "const0_operand" "X")
18596                       (match_operand:SF 3 "register_operand" "x")))]
18597   "TARGET_SSE"
18598   "#")
18600 (define_insn "*sse_movdfcc_const0_1"
18601   [(set (match_operand:DF 0 "register_operand" "=&Y")
18602         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18603                         [(match_operand:DF 4 "register_operand" "0")
18604                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18605                       (match_operand:DF 2 "register_operand" "Y")
18606                       (match_operand:DF 3 "const0_operand" "X")))]
18607   "TARGET_SSE2"
18608   "#")
18610 (define_insn "*sse_movdfcc_const0_2"
18611   [(set (match_operand:DF 0 "register_operand" "=&Y")
18612         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18613                         [(match_operand:DF 4 "register_operand" "0")
18614                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18615                       (match_operand:DF 2 "const0_operand" "X")
18616                       (match_operand:DF 3 "register_operand" "Y")))]
18617   "TARGET_SSE2"
18618   "#")
18620 (define_insn "*sse_movdfcc_const0_3"
18621   [(set (match_operand:DF 0 "register_operand" "=&Y")
18622         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18623                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18624                          (match_operand:DF 5 "register_operand" "0")])
18625                       (match_operand:DF 2 "register_operand" "Y")
18626                       (match_operand:DF 3 "const0_operand" "X")))]
18627   "TARGET_SSE2"
18628   "#")
18630 (define_insn "*sse_movdfcc_const0_4"
18631   [(set (match_operand:DF 0 "register_operand" "=&Y")
18632         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18633                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18634                          (match_operand:DF 5 "register_operand" "0")])
18635                       (match_operand:DF 2 "const0_operand" "X")
18636                       (match_operand:DF 3 "register_operand" "Y")))]
18637   "TARGET_SSE2"
18638   "#")
18640 (define_split
18641   [(set (match_operand:SF 0 "register_operand" "")
18642         (if_then_else (match_operator 1 "comparison_operator"
18643                         [(match_operand:SF 4 "nonimmediate_operand" "")
18644                          (match_operand:SF 5 "nonimmediate_operand" "")])
18645                       (match_operand:SF 2 "nonmemory_operand" "")
18646                       (match_operand:SF 3 "nonmemory_operand" "")))]
18647   "SSE_REG_P (operands[0]) && reload_completed
18648    && (const0_operand (operands[2], GET_MODE (operands[0]))
18649        || const0_operand (operands[3], GET_MODE (operands[0])))"
18650   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18651    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18653   PUT_MODE (operands[1], GET_MODE (operands[0]));
18654   if (!sse_comparison_operator (operands[1], VOIDmode)
18655       || !rtx_equal_p (operands[0], operands[4]))
18656     {
18657       rtx tmp = operands[5];
18658       operands[5] = operands[4];
18659       operands[4] = tmp;
18660       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18661     }
18662   if (!rtx_equal_p (operands[0], operands[4]))
18663     abort ();
18664   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18665   if (const0_operand (operands[2], GET_MODE (operands[2])))
18666     {
18667       operands[7] = operands[3];
18668       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18669     }
18670   else
18671     {
18672       operands[7] = operands[2];
18673       operands[6] = operands[8];
18674     }
18675   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18678 (define_split
18679   [(set (match_operand:DF 0 "register_operand" "")
18680         (if_then_else (match_operator 1 "comparison_operator"
18681                         [(match_operand:DF 4 "nonimmediate_operand" "")
18682                          (match_operand:DF 5 "nonimmediate_operand" "")])
18683                       (match_operand:DF 2 "nonmemory_operand" "")
18684                       (match_operand:DF 3 "nonmemory_operand" "")))]
18685   "SSE_REG_P (operands[0]) && reload_completed
18686    && (const0_operand (operands[2], GET_MODE (operands[0]))
18687        || const0_operand (operands[3], GET_MODE (operands[0])))"
18688   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18689    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18691   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18692       && GET_MODE (operands[2]) == DFmode)
18693     {
18694       if (REG_P (operands[2]))
18695         {
18696           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18697           emit_insn (gen_sse2_unpcklpd (op, op, op));
18698         }
18699       if (REG_P (operands[3]))
18700         {
18701           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18702           emit_insn (gen_sse2_unpcklpd (op, op, op));
18703         }
18704     }
18705   PUT_MODE (operands[1], GET_MODE (operands[0]));
18706   if (!sse_comparison_operator (operands[1], VOIDmode)
18707       || !rtx_equal_p (operands[0], operands[4]))
18708     {
18709       rtx tmp = operands[5];
18710       operands[5] = operands[4];
18711       operands[4] = tmp;
18712       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18713     }
18714   if (!rtx_equal_p (operands[0], operands[4]))
18715     abort ();
18716   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18717   if (const0_operand (operands[2], GET_MODE (operands[2])))
18718     {
18719       operands[7] = operands[3];
18720       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18721     }
18722   else
18723     {
18724       operands[7] = operands[2];
18725       operands[6] = operands[8];
18726     }
18727   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18730 (define_expand "allocate_stack_worker"
18731   [(match_operand:SI 0 "register_operand" "")]
18732   "TARGET_STACK_PROBE"
18734   if (reload_completed)
18735     {
18736       if (TARGET_64BIT)
18737         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18738       else
18739         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18740     }
18741   else
18742     {
18743       if (TARGET_64BIT)
18744         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18745       else
18746         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18747     }
18748   DONE;
18751 (define_insn "allocate_stack_worker_1"
18752   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18753     UNSPECV_STACK_PROBE)
18754    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18755    (clobber (match_scratch:SI 1 "=0"))
18756    (clobber (reg:CC FLAGS_REG))]
18757   "!TARGET_64BIT && TARGET_STACK_PROBE"
18758   "call\t__alloca"
18759   [(set_attr "type" "multi")
18760    (set_attr "length" "5")])
18762 (define_expand "allocate_stack_worker_postreload"
18763   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18764                                     UNSPECV_STACK_PROBE)
18765               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18766               (clobber (match_dup 0))
18767               (clobber (reg:CC FLAGS_REG))])]
18768   ""
18769   "")
18771 (define_insn "allocate_stack_worker_rex64"
18772   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18773     UNSPECV_STACK_PROBE)
18774    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18775    (clobber (match_scratch:DI 1 "=0"))
18776    (clobber (reg:CC FLAGS_REG))]
18777   "TARGET_64BIT && TARGET_STACK_PROBE"
18778   "call\t__alloca"
18779   [(set_attr "type" "multi")
18780    (set_attr "length" "5")])
18782 (define_expand "allocate_stack_worker_rex64_postreload"
18783   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18784                                     UNSPECV_STACK_PROBE)
18785               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18786               (clobber (match_dup 0))
18787               (clobber (reg:CC FLAGS_REG))])]
18788   ""
18789   "")
18791 (define_expand "allocate_stack"
18792   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18793                    (minus:SI (reg:SI SP_REG)
18794                              (match_operand:SI 1 "general_operand" "")))
18795               (clobber (reg:CC FLAGS_REG))])
18796    (parallel [(set (reg:SI SP_REG)
18797                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18798               (clobber (reg:CC FLAGS_REG))])]
18799   "TARGET_STACK_PROBE"
18801 #ifdef CHECK_STACK_LIMIT
18802   if (GET_CODE (operands[1]) == CONST_INT
18803       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18804     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18805                            operands[1]));
18806   else 
18807 #endif
18808     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18809                                                             operands[1])));
18811   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18812   DONE;
18815 (define_expand "builtin_setjmp_receiver"
18816   [(label_ref (match_operand 0 "" ""))]
18817   "!TARGET_64BIT && flag_pic"
18819   emit_insn (gen_set_got (pic_offset_table_rtx));
18820   DONE;
18823 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18825 (define_split
18826   [(set (match_operand 0 "register_operand" "")
18827         (match_operator 3 "promotable_binary_operator"
18828            [(match_operand 1 "register_operand" "")
18829             (match_operand 2 "aligned_operand" "")]))
18830    (clobber (reg:CC FLAGS_REG))]
18831   "! TARGET_PARTIAL_REG_STALL && reload_completed
18832    && ((GET_MODE (operands[0]) == HImode 
18833         && ((!optimize_size && !TARGET_FAST_PREFIX)
18834             || GET_CODE (operands[2]) != CONST_INT
18835             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18836        || (GET_MODE (operands[0]) == QImode 
18837            && (TARGET_PROMOTE_QImode || optimize_size)))"
18838   [(parallel [(set (match_dup 0)
18839                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18840               (clobber (reg:CC FLAGS_REG))])]
18841   "operands[0] = gen_lowpart (SImode, operands[0]);
18842    operands[1] = gen_lowpart (SImode, operands[1]);
18843    if (GET_CODE (operands[3]) != ASHIFT)
18844      operands[2] = gen_lowpart (SImode, operands[2]);
18845    PUT_MODE (operands[3], SImode);")
18847 ; Promote the QImode tests, as i386 has encoding of the AND
18848 ; instruction with 32-bit sign-extended immediate and thus the
18849 ; instruction size is unchanged, except in the %eax case for
18850 ; which it is increased by one byte, hence the ! optimize_size.
18851 (define_split
18852   [(set (match_operand 0 "flags_reg_operand" "")
18853         (match_operator 2 "compare_operator"
18854           [(and (match_operand 3 "aligned_operand" "")
18855                 (match_operand 4 "const_int_operand" ""))
18856            (const_int 0)]))
18857    (set (match_operand 1 "register_operand" "")
18858         (and (match_dup 3) (match_dup 4)))]
18859   "! TARGET_PARTIAL_REG_STALL && reload_completed
18860    /* Ensure that the operand will remain sign-extended immediate.  */
18861    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18862    && ! optimize_size
18863    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18864        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18865   [(parallel [(set (match_dup 0)
18866                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18867                                     (const_int 0)]))
18868               (set (match_dup 1)
18869                    (and:SI (match_dup 3) (match_dup 4)))])]
18871   operands[4]
18872     = gen_int_mode (INTVAL (operands[4])
18873                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18874   operands[1] = gen_lowpart (SImode, operands[1]);
18875   operands[3] = gen_lowpart (SImode, operands[3]);
18878 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18879 ; the TEST instruction with 32-bit sign-extended immediate and thus
18880 ; the instruction size would at least double, which is not what we
18881 ; want even with ! optimize_size.
18882 (define_split
18883   [(set (match_operand 0 "flags_reg_operand" "")
18884         (match_operator 1 "compare_operator"
18885           [(and (match_operand:HI 2 "aligned_operand" "")
18886                 (match_operand:HI 3 "const_int_operand" ""))
18887            (const_int 0)]))]
18888   "! TARGET_PARTIAL_REG_STALL && reload_completed
18889    /* Ensure that the operand will remain sign-extended immediate.  */
18890    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18891    && ! TARGET_FAST_PREFIX
18892    && ! optimize_size"
18893   [(set (match_dup 0)
18894         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18895                          (const_int 0)]))]
18897   operands[3]
18898     = gen_int_mode (INTVAL (operands[3])
18899                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18900   operands[2] = gen_lowpart (SImode, operands[2]);
18903 (define_split
18904   [(set (match_operand 0 "register_operand" "")
18905         (neg (match_operand 1 "register_operand" "")))
18906    (clobber (reg:CC FLAGS_REG))]
18907   "! TARGET_PARTIAL_REG_STALL && reload_completed
18908    && (GET_MODE (operands[0]) == HImode
18909        || (GET_MODE (operands[0]) == QImode 
18910            && (TARGET_PROMOTE_QImode || optimize_size)))"
18911   [(parallel [(set (match_dup 0)
18912                    (neg:SI (match_dup 1)))
18913               (clobber (reg:CC FLAGS_REG))])]
18914   "operands[0] = gen_lowpart (SImode, operands[0]);
18915    operands[1] = gen_lowpart (SImode, operands[1]);")
18917 (define_split
18918   [(set (match_operand 0 "register_operand" "")
18919         (not (match_operand 1 "register_operand" "")))]
18920   "! TARGET_PARTIAL_REG_STALL && reload_completed
18921    && (GET_MODE (operands[0]) == HImode
18922        || (GET_MODE (operands[0]) == QImode 
18923            && (TARGET_PROMOTE_QImode || optimize_size)))"
18924   [(set (match_dup 0)
18925         (not:SI (match_dup 1)))]
18926   "operands[0] = gen_lowpart (SImode, operands[0]);
18927    operands[1] = gen_lowpart (SImode, operands[1]);")
18929 (define_split 
18930   [(set (match_operand 0 "register_operand" "")
18931         (if_then_else (match_operator 1 "comparison_operator" 
18932                                 [(reg FLAGS_REG) (const_int 0)])
18933                       (match_operand 2 "register_operand" "")
18934                       (match_operand 3 "register_operand" "")))]
18935   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18936    && (GET_MODE (operands[0]) == HImode
18937        || (GET_MODE (operands[0]) == QImode 
18938            && (TARGET_PROMOTE_QImode || optimize_size)))"
18939   [(set (match_dup 0)
18940         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18941   "operands[0] = gen_lowpart (SImode, operands[0]);
18942    operands[2] = gen_lowpart (SImode, operands[2]);
18943    operands[3] = gen_lowpart (SImode, operands[3]);")
18944                         
18946 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18947 ;; transform a complex memory operation into two memory to register operations.
18949 ;; Don't push memory operands
18950 (define_peephole2
18951   [(set (match_operand:SI 0 "push_operand" "")
18952         (match_operand:SI 1 "memory_operand" ""))
18953    (match_scratch:SI 2 "r")]
18954   "! optimize_size && ! TARGET_PUSH_MEMORY"
18955   [(set (match_dup 2) (match_dup 1))
18956    (set (match_dup 0) (match_dup 2))]
18957   "")
18959 (define_peephole2
18960   [(set (match_operand:DI 0 "push_operand" "")
18961         (match_operand:DI 1 "memory_operand" ""))
18962    (match_scratch:DI 2 "r")]
18963   "! optimize_size && ! TARGET_PUSH_MEMORY"
18964   [(set (match_dup 2) (match_dup 1))
18965    (set (match_dup 0) (match_dup 2))]
18966   "")
18968 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18969 ;; SImode pushes.
18970 (define_peephole2
18971   [(set (match_operand:SF 0 "push_operand" "")
18972         (match_operand:SF 1 "memory_operand" ""))
18973    (match_scratch:SF 2 "r")]
18974   "! optimize_size && ! TARGET_PUSH_MEMORY"
18975   [(set (match_dup 2) (match_dup 1))
18976    (set (match_dup 0) (match_dup 2))]
18977   "")
18979 (define_peephole2
18980   [(set (match_operand:HI 0 "push_operand" "")
18981         (match_operand:HI 1 "memory_operand" ""))
18982    (match_scratch:HI 2 "r")]
18983   "! optimize_size && ! TARGET_PUSH_MEMORY"
18984   [(set (match_dup 2) (match_dup 1))
18985    (set (match_dup 0) (match_dup 2))]
18986   "")
18988 (define_peephole2
18989   [(set (match_operand:QI 0 "push_operand" "")
18990         (match_operand:QI 1 "memory_operand" ""))
18991    (match_scratch:QI 2 "q")]
18992   "! optimize_size && ! TARGET_PUSH_MEMORY"
18993   [(set (match_dup 2) (match_dup 1))
18994    (set (match_dup 0) (match_dup 2))]
18995   "")
18997 ;; Don't move an immediate directly to memory when the instruction
18998 ;; gets too big.
18999 (define_peephole2
19000   [(match_scratch:SI 1 "r")
19001    (set (match_operand:SI 0 "memory_operand" "")
19002         (const_int 0))]
19003   "! optimize_size
19004    && ! TARGET_USE_MOV0
19005    && TARGET_SPLIT_LONG_MOVES
19006    && get_attr_length (insn) >= ix86_cost->large_insn
19007    && peep2_regno_dead_p (0, FLAGS_REG)"
19008   [(parallel [(set (match_dup 1) (const_int 0))
19009               (clobber (reg:CC FLAGS_REG))])
19010    (set (match_dup 0) (match_dup 1))]
19011   "")
19013 (define_peephole2
19014   [(match_scratch:HI 1 "r")
19015    (set (match_operand:HI 0 "memory_operand" "")
19016         (const_int 0))]
19017   "! optimize_size
19018    && ! TARGET_USE_MOV0
19019    && TARGET_SPLIT_LONG_MOVES
19020    && get_attr_length (insn) >= ix86_cost->large_insn
19021    && peep2_regno_dead_p (0, FLAGS_REG)"
19022   [(parallel [(set (match_dup 2) (const_int 0))
19023               (clobber (reg:CC FLAGS_REG))])
19024    (set (match_dup 0) (match_dup 1))]
19025   "operands[2] = gen_lowpart (SImode, operands[1]);")
19027 (define_peephole2
19028   [(match_scratch:QI 1 "q")
19029    (set (match_operand:QI 0 "memory_operand" "")
19030         (const_int 0))]
19031   "! optimize_size
19032    && ! TARGET_USE_MOV0
19033    && TARGET_SPLIT_LONG_MOVES
19034    && get_attr_length (insn) >= ix86_cost->large_insn
19035    && peep2_regno_dead_p (0, FLAGS_REG)"
19036   [(parallel [(set (match_dup 2) (const_int 0))
19037               (clobber (reg:CC FLAGS_REG))])
19038    (set (match_dup 0) (match_dup 1))]
19039   "operands[2] = gen_lowpart (SImode, operands[1]);")
19041 (define_peephole2
19042   [(match_scratch:SI 2 "r")
19043    (set (match_operand:SI 0 "memory_operand" "")
19044         (match_operand:SI 1 "immediate_operand" ""))]
19045   "! optimize_size
19046    && get_attr_length (insn) >= ix86_cost->large_insn
19047    && TARGET_SPLIT_LONG_MOVES"
19048   [(set (match_dup 2) (match_dup 1))
19049    (set (match_dup 0) (match_dup 2))]
19050   "")
19052 (define_peephole2
19053   [(match_scratch:HI 2 "r")
19054    (set (match_operand:HI 0 "memory_operand" "")
19055         (match_operand:HI 1 "immediate_operand" ""))]
19056   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19057   && TARGET_SPLIT_LONG_MOVES"
19058   [(set (match_dup 2) (match_dup 1))
19059    (set (match_dup 0) (match_dup 2))]
19060   "")
19062 (define_peephole2
19063   [(match_scratch:QI 2 "q")
19064    (set (match_operand:QI 0 "memory_operand" "")
19065         (match_operand:QI 1 "immediate_operand" ""))]
19066   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19067   && TARGET_SPLIT_LONG_MOVES"
19068   [(set (match_dup 2) (match_dup 1))
19069    (set (match_dup 0) (match_dup 2))]
19070   "")
19072 ;; Don't compare memory with zero, load and use a test instead.
19073 (define_peephole2
19074   [(set (match_operand 0 "flags_reg_operand" "")
19075         (match_operator 1 "compare_operator"
19076           [(match_operand:SI 2 "memory_operand" "")
19077            (const_int 0)]))
19078    (match_scratch:SI 3 "r")]
19079   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19080   [(set (match_dup 3) (match_dup 2))
19081    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19082   "")
19084 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19085 ;; Don't split NOTs with a displacement operand, because resulting XOR
19086 ;; will not be pairable anyway.
19088 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19089 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19090 ;; so this split helps here as well.
19092 ;; Note: Can't do this as a regular split because we can't get proper
19093 ;; lifetime information then.
19095 (define_peephole2
19096   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19097         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19098   "!optimize_size
19099    && peep2_regno_dead_p (0, FLAGS_REG)
19100    && ((TARGET_PENTIUM 
19101         && (GET_CODE (operands[0]) != MEM
19102             || !memory_displacement_operand (operands[0], SImode)))
19103        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19104   [(parallel [(set (match_dup 0)
19105                    (xor:SI (match_dup 1) (const_int -1)))
19106               (clobber (reg:CC FLAGS_REG))])]
19107   "")
19109 (define_peephole2
19110   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19111         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19112   "!optimize_size
19113    && peep2_regno_dead_p (0, FLAGS_REG)
19114    && ((TARGET_PENTIUM 
19115         && (GET_CODE (operands[0]) != MEM
19116             || !memory_displacement_operand (operands[0], HImode)))
19117        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19118   [(parallel [(set (match_dup 0)
19119                    (xor:HI (match_dup 1) (const_int -1)))
19120               (clobber (reg:CC FLAGS_REG))])]
19121   "")
19123 (define_peephole2
19124   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19125         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19126   "!optimize_size
19127    && peep2_regno_dead_p (0, FLAGS_REG)
19128    && ((TARGET_PENTIUM 
19129         && (GET_CODE (operands[0]) != MEM
19130             || !memory_displacement_operand (operands[0], QImode)))
19131        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19132   [(parallel [(set (match_dup 0)
19133                    (xor:QI (match_dup 1) (const_int -1)))
19134               (clobber (reg:CC FLAGS_REG))])]
19135   "")
19137 ;; Non pairable "test imm, reg" instructions can be translated to
19138 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19139 ;; byte opcode instead of two, have a short form for byte operands),
19140 ;; so do it for other CPUs as well.  Given that the value was dead,
19141 ;; this should not create any new dependencies.  Pass on the sub-word
19142 ;; versions if we're concerned about partial register stalls.
19144 (define_peephole2
19145   [(set (match_operand 0 "flags_reg_operand" "")
19146         (match_operator 1 "compare_operator"
19147           [(and:SI (match_operand:SI 2 "register_operand" "")
19148                    (match_operand:SI 3 "immediate_operand" ""))
19149            (const_int 0)]))]
19150   "ix86_match_ccmode (insn, CCNOmode)
19151    && (true_regnum (operands[2]) != 0
19152        || (GET_CODE (operands[3]) == CONST_INT
19153            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19154    && peep2_reg_dead_p (1, operands[2])"
19155   [(parallel
19156      [(set (match_dup 0)
19157            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19158                             (const_int 0)]))
19159       (set (match_dup 2)
19160            (and:SI (match_dup 2) (match_dup 3)))])]
19161   "")
19163 ;; We don't need to handle HImode case, because it will be promoted to SImode
19164 ;; on ! TARGET_PARTIAL_REG_STALL
19166 (define_peephole2
19167   [(set (match_operand 0 "flags_reg_operand" "")
19168         (match_operator 1 "compare_operator"
19169           [(and:QI (match_operand:QI 2 "register_operand" "")
19170                    (match_operand:QI 3 "immediate_operand" ""))
19171            (const_int 0)]))]
19172   "! TARGET_PARTIAL_REG_STALL
19173    && ix86_match_ccmode (insn, CCNOmode)
19174    && true_regnum (operands[2]) != 0
19175    && peep2_reg_dead_p (1, operands[2])"
19176   [(parallel
19177      [(set (match_dup 0)
19178            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19179                             (const_int 0)]))
19180       (set (match_dup 2)
19181            (and:QI (match_dup 2) (match_dup 3)))])]
19182   "")
19184 (define_peephole2
19185   [(set (match_operand 0 "flags_reg_operand" "")
19186         (match_operator 1 "compare_operator"
19187           [(and:SI
19188              (zero_extract:SI
19189                (match_operand 2 "ext_register_operand" "")
19190                (const_int 8)
19191                (const_int 8))
19192              (match_operand 3 "const_int_operand" ""))
19193            (const_int 0)]))]
19194   "! TARGET_PARTIAL_REG_STALL
19195    && ix86_match_ccmode (insn, CCNOmode)
19196    && true_regnum (operands[2]) != 0
19197    && peep2_reg_dead_p (1, operands[2])"
19198   [(parallel [(set (match_dup 0)
19199                    (match_op_dup 1
19200                      [(and:SI
19201                         (zero_extract:SI
19202                           (match_dup 2)
19203                           (const_int 8)
19204                           (const_int 8))
19205                         (match_dup 3))
19206                       (const_int 0)]))
19207               (set (zero_extract:SI (match_dup 2)
19208                                     (const_int 8)
19209                                     (const_int 8))
19210                    (and:SI 
19211                      (zero_extract:SI
19212                        (match_dup 2)
19213                        (const_int 8)
19214                        (const_int 8))
19215                      (match_dup 3)))])]
19216   "")
19218 ;; Don't do logical operations with memory inputs.
19219 (define_peephole2
19220   [(match_scratch:SI 2 "r")
19221    (parallel [(set (match_operand:SI 0 "register_operand" "")
19222                    (match_operator:SI 3 "arith_or_logical_operator"
19223                      [(match_dup 0)
19224                       (match_operand:SI 1 "memory_operand" "")]))
19225               (clobber (reg:CC FLAGS_REG))])]
19226   "! optimize_size && ! TARGET_READ_MODIFY"
19227   [(set (match_dup 2) (match_dup 1))
19228    (parallel [(set (match_dup 0)
19229                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19230               (clobber (reg:CC FLAGS_REG))])]
19231   "")
19233 (define_peephole2
19234   [(match_scratch:SI 2 "r")
19235    (parallel [(set (match_operand:SI 0 "register_operand" "")
19236                    (match_operator:SI 3 "arith_or_logical_operator"
19237                      [(match_operand:SI 1 "memory_operand" "")
19238                       (match_dup 0)]))
19239               (clobber (reg:CC FLAGS_REG))])]
19240   "! optimize_size && ! TARGET_READ_MODIFY"
19241   [(set (match_dup 2) (match_dup 1))
19242    (parallel [(set (match_dup 0)
19243                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19244               (clobber (reg:CC FLAGS_REG))])]
19245   "")
19247 ; Don't do logical operations with memory outputs
19249 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19250 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19251 ; the same decoder scheduling characteristics as the original.
19253 (define_peephole2
19254   [(match_scratch:SI 2 "r")
19255    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19256                    (match_operator:SI 3 "arith_or_logical_operator"
19257                      [(match_dup 0)
19258                       (match_operand:SI 1 "nonmemory_operand" "")]))
19259               (clobber (reg:CC FLAGS_REG))])]
19260   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19261   [(set (match_dup 2) (match_dup 0))
19262    (parallel [(set (match_dup 2)
19263                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19264               (clobber (reg:CC FLAGS_REG))])
19265    (set (match_dup 0) (match_dup 2))]
19266   "")
19268 (define_peephole2
19269   [(match_scratch:SI 2 "r")
19270    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19271                    (match_operator:SI 3 "arith_or_logical_operator"
19272                      [(match_operand:SI 1 "nonmemory_operand" "")
19273                       (match_dup 0)]))
19274               (clobber (reg:CC FLAGS_REG))])]
19275   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19276   [(set (match_dup 2) (match_dup 0))
19277    (parallel [(set (match_dup 2)
19278                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19279               (clobber (reg:CC FLAGS_REG))])
19280    (set (match_dup 0) (match_dup 2))]
19281   "")
19283 ;; Attempt to always use XOR for zeroing registers.
19284 (define_peephole2
19285   [(set (match_operand 0 "register_operand" "")
19286         (const_int 0))]
19287   "(GET_MODE (operands[0]) == QImode
19288     || GET_MODE (operands[0]) == HImode
19289     || GET_MODE (operands[0]) == SImode
19290     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19291    && (! TARGET_USE_MOV0 || optimize_size)
19292    && peep2_regno_dead_p (0, FLAGS_REG)"
19293   [(parallel [(set (match_dup 0) (const_int 0))
19294               (clobber (reg:CC FLAGS_REG))])]
19295   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19296                               operands[0]);")
19298 (define_peephole2
19299   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19300         (const_int 0))]
19301   "(GET_MODE (operands[0]) == QImode
19302     || GET_MODE (operands[0]) == HImode)
19303    && (! TARGET_USE_MOV0 || optimize_size)
19304    && peep2_regno_dead_p (0, FLAGS_REG)"
19305   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19306               (clobber (reg:CC FLAGS_REG))])])
19308 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19309 (define_peephole2
19310   [(set (match_operand 0 "register_operand" "")
19311         (const_int -1))]
19312   "(GET_MODE (operands[0]) == HImode
19313     || GET_MODE (operands[0]) == SImode 
19314     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19315    && (optimize_size || TARGET_PENTIUM)
19316    && peep2_regno_dead_p (0, FLAGS_REG)"
19317   [(parallel [(set (match_dup 0) (const_int -1))
19318               (clobber (reg:CC FLAGS_REG))])]
19319   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19320                               operands[0]);")
19322 ;; Attempt to convert simple leas to adds. These can be created by
19323 ;; move expanders.
19324 (define_peephole2
19325   [(set (match_operand:SI 0 "register_operand" "")
19326         (plus:SI (match_dup 0)
19327                  (match_operand:SI 1 "nonmemory_operand" "")))]
19328   "peep2_regno_dead_p (0, FLAGS_REG)"
19329   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19330               (clobber (reg:CC FLAGS_REG))])]
19331   "")
19333 (define_peephole2
19334   [(set (match_operand:SI 0 "register_operand" "")
19335         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19336                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19337   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19338   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19339               (clobber (reg:CC FLAGS_REG))])]
19340   "operands[2] = gen_lowpart (SImode, operands[2]);")
19342 (define_peephole2
19343   [(set (match_operand:DI 0 "register_operand" "")
19344         (plus:DI (match_dup 0)
19345                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19346   "peep2_regno_dead_p (0, FLAGS_REG)"
19347   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19348               (clobber (reg:CC FLAGS_REG))])]
19349   "")
19351 (define_peephole2
19352   [(set (match_operand:SI 0 "register_operand" "")
19353         (mult:SI (match_dup 0)
19354                  (match_operand:SI 1 "const_int_operand" "")))]
19355   "exact_log2 (INTVAL (operands[1])) >= 0
19356    && peep2_regno_dead_p (0, FLAGS_REG)"
19357   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19358               (clobber (reg:CC FLAGS_REG))])]
19359   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19361 (define_peephole2
19362   [(set (match_operand:DI 0 "register_operand" "")
19363         (mult:DI (match_dup 0)
19364                  (match_operand:DI 1 "const_int_operand" "")))]
19365   "exact_log2 (INTVAL (operands[1])) >= 0
19366    && peep2_regno_dead_p (0, FLAGS_REG)"
19367   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19368               (clobber (reg:CC FLAGS_REG))])]
19369   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19371 (define_peephole2
19372   [(set (match_operand:SI 0 "register_operand" "")
19373         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19374                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19375   "exact_log2 (INTVAL (operands[2])) >= 0
19376    && REGNO (operands[0]) == REGNO (operands[1])
19377    && peep2_regno_dead_p (0, FLAGS_REG)"
19378   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19379               (clobber (reg:CC FLAGS_REG))])]
19380   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19382 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19383 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19384 ;; many CPUs it is also faster, since special hardware to avoid esp
19385 ;; dependencies is present.
19387 ;; While some of these conversions may be done using splitters, we use peepholes
19388 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19390 ;; Convert prologue esp subtractions to push.
19391 ;; We need register to push.  In order to keep verify_flow_info happy we have
19392 ;; two choices
19393 ;; - use scratch and clobber it in order to avoid dependencies
19394 ;; - use already live register
19395 ;; We can't use the second way right now, since there is no reliable way how to
19396 ;; verify that given register is live.  First choice will also most likely in
19397 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19398 ;; call clobbered registers are dead.  We may want to use base pointer as an
19399 ;; alternative when no register is available later.
19401 (define_peephole2
19402   [(match_scratch:SI 0 "r")
19403    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19404               (clobber (reg:CC FLAGS_REG))
19405               (clobber (mem:BLK (scratch)))])]
19406   "optimize_size || !TARGET_SUB_ESP_4"
19407   [(clobber (match_dup 0))
19408    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19409               (clobber (mem:BLK (scratch)))])])
19411 (define_peephole2
19412   [(match_scratch:SI 0 "r")
19413    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19414               (clobber (reg:CC FLAGS_REG))
19415               (clobber (mem:BLK (scratch)))])]
19416   "optimize_size || !TARGET_SUB_ESP_8"
19417   [(clobber (match_dup 0))
19418    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19419    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19420               (clobber (mem:BLK (scratch)))])])
19422 ;; Convert esp subtractions to push.
19423 (define_peephole2
19424   [(match_scratch:SI 0 "r")
19425    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19426               (clobber (reg:CC FLAGS_REG))])]
19427   "optimize_size || !TARGET_SUB_ESP_4"
19428   [(clobber (match_dup 0))
19429    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19431 (define_peephole2
19432   [(match_scratch:SI 0 "r")
19433    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19434               (clobber (reg:CC FLAGS_REG))])]
19435   "optimize_size || !TARGET_SUB_ESP_8"
19436   [(clobber (match_dup 0))
19437    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19438    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19440 ;; Convert epilogue deallocator to pop.
19441 (define_peephole2
19442   [(match_scratch:SI 0 "r")
19443    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19444               (clobber (reg:CC FLAGS_REG))
19445               (clobber (mem:BLK (scratch)))])]
19446   "optimize_size || !TARGET_ADD_ESP_4"
19447   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19448               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19449               (clobber (mem:BLK (scratch)))])]
19450   "")
19452 ;; Two pops case is tricky, since pop causes dependency on destination register.
19453 ;; We use two registers if available.
19454 (define_peephole2
19455   [(match_scratch:SI 0 "r")
19456    (match_scratch:SI 1 "r")
19457    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19458               (clobber (reg:CC FLAGS_REG))
19459               (clobber (mem:BLK (scratch)))])]
19460   "optimize_size || !TARGET_ADD_ESP_8"
19461   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19462               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19463               (clobber (mem:BLK (scratch)))])
19464    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19465               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19466   "")
19468 (define_peephole2
19469   [(match_scratch:SI 0 "r")
19470    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19471               (clobber (reg:CC FLAGS_REG))
19472               (clobber (mem:BLK (scratch)))])]
19473   "optimize_size"
19474   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19475               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19476               (clobber (mem:BLK (scratch)))])
19477    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19478               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19479   "")
19481 ;; Convert esp additions to pop.
19482 (define_peephole2
19483   [(match_scratch:SI 0 "r")
19484    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19485               (clobber (reg:CC FLAGS_REG))])]
19486   ""
19487   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19488               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19489   "")
19491 ;; Two pops case is tricky, since pop causes dependency on destination register.
19492 ;; We use two registers if available.
19493 (define_peephole2
19494   [(match_scratch:SI 0 "r")
19495    (match_scratch:SI 1 "r")
19496    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19497               (clobber (reg:CC FLAGS_REG))])]
19498   ""
19499   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19500               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19501    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19502               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19503   "")
19505 (define_peephole2
19506   [(match_scratch:SI 0 "r")
19507    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19508               (clobber (reg:CC FLAGS_REG))])]
19509   "optimize_size"
19510   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19511               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19512    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19513               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19514   "")
19516 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19517 ;; required and register dies.  Similarly for 128 to plus -128.
19518 (define_peephole2
19519   [(set (match_operand 0 "flags_reg_operand" "")
19520         (match_operator 1 "compare_operator"
19521           [(match_operand 2 "register_operand" "")
19522            (match_operand 3 "const_int_operand" "")]))]
19523   "(INTVAL (operands[3]) == -1
19524     || INTVAL (operands[3]) == 1
19525     || INTVAL (operands[3]) == 128)
19526    && ix86_match_ccmode (insn, CCGCmode)
19527    && peep2_reg_dead_p (1, operands[2])"
19528   [(parallel [(set (match_dup 0)
19529                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19530               (clobber (match_dup 2))])]
19531   "")
19533 (define_peephole2
19534   [(match_scratch:DI 0 "r")
19535    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19536               (clobber (reg:CC FLAGS_REG))
19537               (clobber (mem:BLK (scratch)))])]
19538   "optimize_size || !TARGET_SUB_ESP_4"
19539   [(clobber (match_dup 0))
19540    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19541               (clobber (mem:BLK (scratch)))])])
19543 (define_peephole2
19544   [(match_scratch:DI 0 "r")
19545    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19546               (clobber (reg:CC FLAGS_REG))
19547               (clobber (mem:BLK (scratch)))])]
19548   "optimize_size || !TARGET_SUB_ESP_8"
19549   [(clobber (match_dup 0))
19550    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19551    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19552               (clobber (mem:BLK (scratch)))])])
19554 ;; Convert esp subtractions to push.
19555 (define_peephole2
19556   [(match_scratch:DI 0 "r")
19557    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19558               (clobber (reg:CC FLAGS_REG))])]
19559   "optimize_size || !TARGET_SUB_ESP_4"
19560   [(clobber (match_dup 0))
19561    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19563 (define_peephole2
19564   [(match_scratch:DI 0 "r")
19565    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19566               (clobber (reg:CC FLAGS_REG))])]
19567   "optimize_size || !TARGET_SUB_ESP_8"
19568   [(clobber (match_dup 0))
19569    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19570    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19572 ;; Convert epilogue deallocator to pop.
19573 (define_peephole2
19574   [(match_scratch:DI 0 "r")
19575    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19576               (clobber (reg:CC FLAGS_REG))
19577               (clobber (mem:BLK (scratch)))])]
19578   "optimize_size || !TARGET_ADD_ESP_4"
19579   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19580               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19581               (clobber (mem:BLK (scratch)))])]
19582   "")
19584 ;; Two pops case is tricky, since pop causes dependency on destination register.
19585 ;; We use two registers if available.
19586 (define_peephole2
19587   [(match_scratch:DI 0 "r")
19588    (match_scratch:DI 1 "r")
19589    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19590               (clobber (reg:CC FLAGS_REG))
19591               (clobber (mem:BLK (scratch)))])]
19592   "optimize_size || !TARGET_ADD_ESP_8"
19593   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19594               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19595               (clobber (mem:BLK (scratch)))])
19596    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19597               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19598   "")
19600 (define_peephole2
19601   [(match_scratch:DI 0 "r")
19602    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19603               (clobber (reg:CC FLAGS_REG))
19604               (clobber (mem:BLK (scratch)))])]
19605   "optimize_size"
19606   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19607               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19608               (clobber (mem:BLK (scratch)))])
19609    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19610               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19611   "")
19613 ;; Convert esp additions to pop.
19614 (define_peephole2
19615   [(match_scratch:DI 0 "r")
19616    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19617               (clobber (reg:CC FLAGS_REG))])]
19618   ""
19619   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19620               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19621   "")
19623 ;; Two pops case is tricky, since pop causes dependency on destination register.
19624 ;; We use two registers if available.
19625 (define_peephole2
19626   [(match_scratch:DI 0 "r")
19627    (match_scratch:DI 1 "r")
19628    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19629               (clobber (reg:CC FLAGS_REG))])]
19630   ""
19631   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19632               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19633    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19634               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19635   "")
19637 (define_peephole2
19638   [(match_scratch:DI 0 "r")
19639    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19640               (clobber (reg:CC FLAGS_REG))])]
19641   "optimize_size"
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    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19645               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19646   "")
19648 ;; Convert imul by three, five and nine into lea
19649 (define_peephole2
19650   [(parallel
19651     [(set (match_operand:SI 0 "register_operand" "")
19652           (mult:SI (match_operand:SI 1 "register_operand" "")
19653                    (match_operand:SI 2 "const_int_operand" "")))
19654      (clobber (reg:CC FLAGS_REG))])]
19655   "INTVAL (operands[2]) == 3
19656    || INTVAL (operands[2]) == 5
19657    || INTVAL (operands[2]) == 9"
19658   [(set (match_dup 0)
19659         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19660                  (match_dup 1)))]
19661   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19663 (define_peephole2
19664   [(parallel
19665     [(set (match_operand:SI 0 "register_operand" "")
19666           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19667                    (match_operand:SI 2 "const_int_operand" "")))
19668      (clobber (reg:CC FLAGS_REG))])]
19669   "!optimize_size 
19670    && (INTVAL (operands[2]) == 3
19671        || INTVAL (operands[2]) == 5
19672        || INTVAL (operands[2]) == 9)"
19673   [(set (match_dup 0) (match_dup 1))
19674    (set (match_dup 0)
19675         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19676                  (match_dup 0)))]
19677   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19679 (define_peephole2
19680   [(parallel
19681     [(set (match_operand:DI 0 "register_operand" "")
19682           (mult:DI (match_operand:DI 1 "register_operand" "")
19683                    (match_operand:DI 2 "const_int_operand" "")))
19684      (clobber (reg:CC FLAGS_REG))])]
19685   "TARGET_64BIT
19686    && (INTVAL (operands[2]) == 3
19687        || INTVAL (operands[2]) == 5
19688        || INTVAL (operands[2]) == 9)"
19689   [(set (match_dup 0)
19690         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19691                  (match_dup 1)))]
19692   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19694 (define_peephole2
19695   [(parallel
19696     [(set (match_operand:DI 0 "register_operand" "")
19697           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19698                    (match_operand:DI 2 "const_int_operand" "")))
19699      (clobber (reg:CC FLAGS_REG))])]
19700   "TARGET_64BIT
19701    && !optimize_size 
19702    && (INTVAL (operands[2]) == 3
19703        || INTVAL (operands[2]) == 5
19704        || INTVAL (operands[2]) == 9)"
19705   [(set (match_dup 0) (match_dup 1))
19706    (set (match_dup 0)
19707         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19708                  (match_dup 0)))]
19709   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19711 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19712 ;; imul $32bit_imm, reg, reg is direct decoded.
19713 (define_peephole2
19714   [(match_scratch:DI 3 "r")
19715    (parallel [(set (match_operand:DI 0 "register_operand" "")
19716                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19717                             (match_operand:DI 2 "immediate_operand" "")))
19718               (clobber (reg:CC FLAGS_REG))])]
19719   "TARGET_K8 && !optimize_size
19720    && (GET_CODE (operands[2]) != CONST_INT
19721        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19722   [(set (match_dup 3) (match_dup 1))
19723    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19724               (clobber (reg:CC FLAGS_REG))])]
19727 (define_peephole2
19728   [(match_scratch:SI 3 "r")
19729    (parallel [(set (match_operand:SI 0 "register_operand" "")
19730                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19731                             (match_operand:SI 2 "immediate_operand" "")))
19732               (clobber (reg:CC FLAGS_REG))])]
19733   "TARGET_K8 && !optimize_size
19734    && (GET_CODE (operands[2]) != CONST_INT
19735        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19736   [(set (match_dup 3) (match_dup 1))
19737    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19738               (clobber (reg:CC FLAGS_REG))])]
19741 (define_peephole2
19742   [(match_scratch:SI 3 "r")
19743    (parallel [(set (match_operand:DI 0 "register_operand" "")
19744                    (zero_extend:DI
19745                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19746                               (match_operand:SI 2 "immediate_operand" ""))))
19747               (clobber (reg:CC FLAGS_REG))])]
19748   "TARGET_K8 && !optimize_size
19749    && (GET_CODE (operands[2]) != CONST_INT
19750        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19751   [(set (match_dup 3) (match_dup 1))
19752    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19753               (clobber (reg:CC FLAGS_REG))])]
19756 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19757 ;; Convert it into imul reg, reg
19758 ;; It would be better to force assembler to encode instruction using long
19759 ;; immediate, but there is apparently no way to do so.
19760 (define_peephole2
19761   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19762                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19763                             (match_operand:DI 2 "const_int_operand" "")))
19764               (clobber (reg:CC FLAGS_REG))])
19765    (match_scratch:DI 3 "r")]
19766   "TARGET_K8 && !optimize_size
19767    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19768   [(set (match_dup 3) (match_dup 2))
19769    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19770               (clobber (reg:CC FLAGS_REG))])]
19772   if (!rtx_equal_p (operands[0], operands[1]))
19773     emit_move_insn (operands[0], operands[1]);
19776 (define_peephole2
19777   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19778                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19779                             (match_operand:SI 2 "const_int_operand" "")))
19780               (clobber (reg:CC FLAGS_REG))])
19781    (match_scratch:SI 3 "r")]
19782   "TARGET_K8 && !optimize_size
19783    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19784   [(set (match_dup 3) (match_dup 2))
19785    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19786               (clobber (reg:CC FLAGS_REG))])]
19788   if (!rtx_equal_p (operands[0], operands[1]))
19789     emit_move_insn (operands[0], operands[1]);
19792 (define_peephole2
19793   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19794                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19795                             (match_operand:HI 2 "immediate_operand" "")))
19796               (clobber (reg:CC FLAGS_REG))])
19797    (match_scratch:HI 3 "r")]
19798   "TARGET_K8 && !optimize_size"
19799   [(set (match_dup 3) (match_dup 2))
19800    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19801               (clobber (reg:CC FLAGS_REG))])]
19803   if (!rtx_equal_p (operands[0], operands[1]))
19804     emit_move_insn (operands[0], operands[1]);
19807 ;; Call-value patterns last so that the wildcard operand does not
19808 ;; disrupt insn-recog's switch tables.
19810 (define_insn "*call_value_pop_0"
19811   [(set (match_operand 0 "" "")
19812         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19813               (match_operand:SI 2 "" "")))
19814    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19815                             (match_operand:SI 3 "immediate_operand" "")))]
19816   "!TARGET_64BIT"
19818   if (SIBLING_CALL_P (insn))
19819     return "jmp\t%P1";
19820   else
19821     return "call\t%P1";
19823   [(set_attr "type" "callv")])
19825 (define_insn "*call_value_pop_1"
19826   [(set (match_operand 0 "" "")
19827         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19828               (match_operand:SI 2 "" "")))
19829    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19830                             (match_operand:SI 3 "immediate_operand" "i")))]
19831   "!TARGET_64BIT"
19833   if (constant_call_address_operand (operands[1], Pmode))
19834     {
19835       if (SIBLING_CALL_P (insn))
19836         return "jmp\t%P1";
19837       else
19838         return "call\t%P1";
19839     }
19840   if (SIBLING_CALL_P (insn))
19841     return "jmp\t%A1";
19842   else
19843     return "call\t%A1";
19845   [(set_attr "type" "callv")])
19847 (define_insn "*call_value_0"
19848   [(set (match_operand 0 "" "")
19849         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19850               (match_operand:SI 2 "" "")))]
19851   "!TARGET_64BIT"
19853   if (SIBLING_CALL_P (insn))
19854     return "jmp\t%P1";
19855   else
19856     return "call\t%P1";
19858   [(set_attr "type" "callv")])
19860 (define_insn "*call_value_0_rex64"
19861   [(set (match_operand 0 "" "")
19862         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19863               (match_operand:DI 2 "const_int_operand" "")))]
19864   "TARGET_64BIT"
19866   if (SIBLING_CALL_P (insn))
19867     return "jmp\t%P1";
19868   else
19869     return "call\t%P1";
19871   [(set_attr "type" "callv")])
19873 (define_insn "*call_value_1"
19874   [(set (match_operand 0 "" "")
19875         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19876               (match_operand:SI 2 "" "")))]
19877   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19879   if (constant_call_address_operand (operands[1], Pmode))
19880     return "call\t%P1";
19881   return "call\t%A1";
19883   [(set_attr "type" "callv")])
19885 (define_insn "*sibcall_value_1"
19886   [(set (match_operand 0 "" "")
19887         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19888               (match_operand:SI 2 "" "")))]
19889   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19891   if (constant_call_address_operand (operands[1], Pmode))
19892     return "jmp\t%P1";
19893   return "jmp\t%A1";
19895   [(set_attr "type" "callv")])
19897 (define_insn "*call_value_1_rex64"
19898   [(set (match_operand 0 "" "")
19899         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19900               (match_operand:DI 2 "" "")))]
19901   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19903   if (constant_call_address_operand (operands[1], Pmode))
19904     return "call\t%P1";
19905   return "call\t%A1";
19907   [(set_attr "type" "callv")])
19909 (define_insn "*sibcall_value_1_rex64"
19910   [(set (match_operand 0 "" "")
19911         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19912               (match_operand:DI 2 "" "")))]
19913   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19914   "jmp\t%P1"
19915   [(set_attr "type" "callv")])
19917 (define_insn "*sibcall_value_1_rex64_v"
19918   [(set (match_operand 0 "" "")
19919         (call (mem:QI (reg:DI 40))
19920               (match_operand:DI 1 "" "")))]
19921   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19922   "jmp\t*%%r11"
19923   [(set_attr "type" "callv")])
19925 (define_insn "trap"
19926   [(trap_if (const_int 1) (const_int 5))]
19927   ""
19928   "int\t$5")
19930 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19931 ;;; for the sake of bounds checking.  By emitting bounds checks as
19932 ;;; conditional traps rather than as conditional jumps around
19933 ;;; unconditional traps we avoid introducing spurious basic-block
19934 ;;; boundaries and facilitate elimination of redundant checks.  In
19935 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19936 ;;; interrupt 5.
19937 ;;; 
19938 ;;; FIXME: Static branch prediction rules for ix86 are such that
19939 ;;; forward conditional branches predict as untaken.  As implemented
19940 ;;; below, pseudo conditional traps violate that rule.  We should use
19941 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19942 ;;; section loaded at the end of the text segment and branch forward
19943 ;;; there on bounds-failure, and then jump back immediately (in case
19944 ;;; the system chooses to ignore bounds violations, or to report
19945 ;;; violations and continue execution).
19947 (define_expand "conditional_trap"
19948   [(trap_if (match_operator 0 "comparison_operator"
19949              [(match_dup 2) (const_int 0)])
19950             (match_operand 1 "const_int_operand" ""))]
19951   ""
19953   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19954                               ix86_expand_compare (GET_CODE (operands[0]),
19955                                                    NULL, NULL),
19956                               operands[1]));
19957   DONE;
19960 (define_insn "*conditional_trap_1"
19961   [(trap_if (match_operator 0 "comparison_operator"
19962              [(reg FLAGS_REG) (const_int 0)])
19963             (match_operand 1 "const_int_operand" ""))]
19964   ""
19966   operands[2] = gen_label_rtx ();
19967   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19968   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19969                              CODE_LABEL_NUMBER (operands[2]));
19970   RET;
19973         ;; Pentium III SIMD instructions.
19975 ;; Moves for SSE/MMX regs.
19977 (define_insn "movv4sf_internal"
19978   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19979         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19980   "TARGET_SSE"
19981   "@
19982     xorps\t%0, %0
19983     movaps\t{%1, %0|%0, %1}
19984     movaps\t{%1, %0|%0, %1}"
19985   [(set_attr "type" "ssemov")
19986    (set_attr "mode" "V4SF")])
19988 (define_split
19989   [(set (match_operand:V4SF 0 "register_operand" "")
19990         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19991   "TARGET_SSE"
19992   [(set (match_dup 0)
19993         (vec_merge:V4SF
19994          (vec_duplicate:V4SF (match_dup 1))
19995          (match_dup 2)
19996          (const_int 1)))]
19998   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19999   operands[2] = CONST0_RTX (V4SFmode);
20002 (define_insn "movv4si_internal"
20003   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
20004         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
20005   "TARGET_SSE"
20007   switch (which_alternative)
20008     {
20009     case 0:
20010       if (get_attr_mode (insn) == MODE_V4SF)
20011         return "xorps\t%0, %0";
20012       else
20013         return "pxor\t%0, %0";
20014     case 1:
20015     case 2:
20016       if (get_attr_mode (insn) == MODE_V4SF)
20017         return "movaps\t{%1, %0|%0, %1}";
20018       else
20019         return "movdqa\t{%1, %0|%0, %1}";
20020     default:
20021       abort ();
20022     }
20024   [(set_attr "type" "ssemov")
20025    (set (attr "mode")
20026         (cond [(eq_attr "alternative" "0,1")
20027                  (if_then_else
20028                    (ne (symbol_ref "optimize_size")
20029                        (const_int 0))
20030                    (const_string "V4SF")
20031                    (const_string "TI"))
20032                (eq_attr "alternative" "2")
20033                  (if_then_else
20034                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20035                             (const_int 0))
20036                         (ne (symbol_ref "optimize_size")
20037                             (const_int 0)))
20038                    (const_string "V4SF")
20039                    (const_string "TI"))]
20040                (const_string "TI")))])
20042 (define_insn "movv2di_internal"
20043   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
20044         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
20045   "TARGET_SSE"
20047   switch (which_alternative)
20048     {
20049     case 0:
20050       if (get_attr_mode (insn) == MODE_V4SF)
20051         return "xorps\t%0, %0";
20052       else
20053         return "pxor\t%0, %0";
20054     case 1:
20055     case 2:
20056       if (get_attr_mode (insn) == MODE_V4SF)
20057         return "movaps\t{%1, %0|%0, %1}";
20058       else
20059         return "movdqa\t{%1, %0|%0, %1}";
20060     default:
20061       abort ();
20062     }
20064   [(set_attr "type" "ssemov")
20065    (set (attr "mode")
20066         (cond [(eq_attr "alternative" "0,1")
20067                  (if_then_else
20068                    (ne (symbol_ref "optimize_size")
20069                        (const_int 0))
20070                    (const_string "V4SF")
20071                    (const_string "TI"))
20072                (eq_attr "alternative" "2")
20073                  (if_then_else
20074                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20075                             (const_int 0))
20076                         (ne (symbol_ref "optimize_size")
20077                             (const_int 0)))
20078                    (const_string "V4SF")
20079                    (const_string "TI"))]
20080                (const_string "TI")))])
20082 (define_split
20083   [(set (match_operand:V2DF 0 "register_operand" "")
20084         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
20085   "TARGET_SSE2"
20086   [(set (match_dup 0)
20087         (vec_merge:V2DF
20088          (vec_duplicate:V2DF (match_dup 1))
20089          (match_dup 2)
20090          (const_int 1)))]
20092   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
20093   operands[2] = CONST0_RTX (V2DFmode);
20096 (define_insn "movv8qi_internal"
20097   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20098         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20099   "TARGET_MMX
20100    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20101   "@
20102     pxor\t%0, %0
20103     movq\t{%1, %0|%0, %1}
20104     movq\t{%1, %0|%0, %1}
20105     movdq2q\t{%1, %0|%0, %1}
20106     movq2dq\t{%1, %0|%0, %1}
20107     movq\t{%1, %0|%0, %1}
20108     movq\t{%1, %0|%0, %1}"
20109   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20110    (set_attr "mode" "DI")])
20112 (define_insn "movv4hi_internal"
20113   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20114         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20115   "TARGET_MMX
20116    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20117   "@
20118     pxor\t%0, %0
20119     movq\t{%1, %0|%0, %1}
20120     movq\t{%1, %0|%0, %1}
20121     movdq2q\t{%1, %0|%0, %1}
20122     movq2dq\t{%1, %0|%0, %1}
20123     movq\t{%1, %0|%0, %1}
20124     movq\t{%1, %0|%0, %1}"
20125   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20126    (set_attr "mode" "DI")])
20128 (define_insn "*movv2si_internal"
20129   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20130         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20131   "TARGET_MMX
20132    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20133   "@
20134     pxor\t%0, %0
20135     movq\t{%1, %0|%0, %1}
20136     movq\t{%1, %0|%0, %1}
20137     movdq2q\t{%1, %0|%0, %1}
20138     movq2dq\t{%1, %0|%0, %1}
20139     movq\t{%1, %0|%0, %1}
20140     movq\t{%1, %0|%0, %1}"
20141   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20142    (set_attr "mode" "DI")])
20144 (define_insn "movv2sf_internal"
20145   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
20146         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
20147   "TARGET_3DNOW
20148    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20149   "@
20150     pxor\t%0, %0
20151     movq\t{%1, %0|%0, %1}
20152     movq\t{%1, %0|%0, %1}
20153     movdq2q\t{%1, %0|%0, %1}
20154     movq2dq\t{%1, %0|%0, %1}
20155     movlps\t{%1, %0|%0, %1}
20156     movlps\t{%1, %0|%0, %1}"
20157   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20158    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
20160 (define_expand "movti"
20161   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20162         (match_operand:TI 1 "nonimmediate_operand" ""))]
20163   "TARGET_SSE || TARGET_64BIT"
20165   if (TARGET_64BIT)
20166     ix86_expand_move (TImode, operands);
20167   else
20168     ix86_expand_vector_move (TImode, operands);
20169   DONE;
20172 (define_expand "movtf"
20173   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20174         (match_operand:TF 1 "nonimmediate_operand" ""))]
20175   "TARGET_64BIT"
20177   if (TARGET_64BIT)
20178     ix86_expand_move (TFmode, operands);
20179   else
20180     ix86_expand_vector_move (TFmode, operands);
20181   DONE;
20184 (define_insn "movv2df_internal"
20185   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
20186         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
20187   "TARGET_SSE2
20188    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20190   switch (which_alternative)
20191     {
20192     case 0:
20193       if (get_attr_mode (insn) == MODE_V4SF)
20194         return "xorps\t%0, %0";
20195       else
20196         return "xorpd\t%0, %0";
20197     case 1:
20198     case 2:
20199       if (get_attr_mode (insn) == MODE_V4SF)
20200         return "movaps\t{%1, %0|%0, %1}";
20201       else
20202         return "movapd\t{%1, %0|%0, %1}";
20203     default:
20204       abort ();
20205     }
20207   [(set_attr "type" "ssemov")
20208    (set (attr "mode")
20209         (cond [(eq_attr "alternative" "0,1")
20210                  (if_then_else
20211                    (ne (symbol_ref "optimize_size")
20212                        (const_int 0))
20213                    (const_string "V4SF")
20214                    (const_string "V2DF"))
20215                (eq_attr "alternative" "2")
20216                  (if_then_else
20217                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20218                             (const_int 0))
20219                         (ne (symbol_ref "optimize_size")
20220                             (const_int 0)))
20221                    (const_string "V4SF")
20222                    (const_string "V2DF"))]
20223                (const_string "V2DF")))])
20225 (define_insn "movv8hi_internal"
20226   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
20227         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
20228   "TARGET_SSE2
20229    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20231   switch (which_alternative)
20232     {
20233     case 0:
20234       if (get_attr_mode (insn) == MODE_V4SF)
20235         return "xorps\t%0, %0";
20236       else
20237         return "pxor\t%0, %0";
20238     case 1:
20239     case 2:
20240       if (get_attr_mode (insn) == MODE_V4SF)
20241         return "movaps\t{%1, %0|%0, %1}";
20242       else
20243         return "movdqa\t{%1, %0|%0, %1}";
20244     default:
20245       abort ();
20246     }
20248   [(set_attr "type" "ssemov")
20249    (set (attr "mode")
20250         (cond [(eq_attr "alternative" "0,1")
20251                  (if_then_else
20252                    (ne (symbol_ref "optimize_size")
20253                        (const_int 0))
20254                    (const_string "V4SF")
20255                    (const_string "TI"))
20256                (eq_attr "alternative" "2")
20257                  (if_then_else
20258                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20259                             (const_int 0))
20260                         (ne (symbol_ref "optimize_size")
20261                             (const_int 0)))
20262                    (const_string "V4SF")
20263                    (const_string "TI"))]
20264                (const_string "TI")))])
20266 (define_insn "movv16qi_internal"
20267   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20268         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20269   "TARGET_SSE2
20270    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20272   switch (which_alternative)
20273     {
20274     case 0:
20275       if (get_attr_mode (insn) == MODE_V4SF)
20276         return "xorps\t%0, %0";
20277       else
20278         return "pxor\t%0, %0";
20279     case 1:
20280     case 2:
20281       if (get_attr_mode (insn) == MODE_V4SF)
20282         return "movaps\t{%1, %0|%0, %1}";
20283       else
20284         return "movdqa\t{%1, %0|%0, %1}";
20285     default:
20286       abort ();
20287     }
20289   [(set_attr "type" "ssemov")
20290    (set (attr "mode")
20291         (cond [(eq_attr "alternative" "0,1")
20292                  (if_then_else
20293                    (ne (symbol_ref "optimize_size")
20294                        (const_int 0))
20295                    (const_string "V4SF")
20296                    (const_string "TI"))
20297                (eq_attr "alternative" "2")
20298                  (if_then_else
20299                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20300                             (const_int 0))
20301                         (ne (symbol_ref "optimize_size")
20302                             (const_int 0)))
20303                    (const_string "V4SF")
20304                    (const_string "TI"))]
20305                (const_string "TI")))])
20307 (define_expand "movv2df"
20308   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20309         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20310   "TARGET_SSE2"
20312   ix86_expand_vector_move (V2DFmode, operands);
20313   DONE;
20316 (define_expand "movv8hi"
20317   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20318         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20319   "TARGET_SSE2"
20321   ix86_expand_vector_move (V8HImode, operands);
20322   DONE;
20325 (define_expand "movv16qi"
20326   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20327         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20328   "TARGET_SSE2"
20330   ix86_expand_vector_move (V16QImode, operands);
20331   DONE;
20334 (define_expand "movv4sf"
20335   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20336         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20337   "TARGET_SSE"
20339   ix86_expand_vector_move (V4SFmode, operands);
20340   DONE;
20343 (define_expand "movv4si"
20344   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20345         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20346   "TARGET_SSE"
20348   ix86_expand_vector_move (V4SImode, operands);
20349   DONE;
20352 (define_expand "movv2di"
20353   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20354         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20355   "TARGET_SSE"
20357   ix86_expand_vector_move (V2DImode, operands);
20358   DONE;
20361 (define_expand "movv2si"
20362   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20363         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20364   "TARGET_MMX"
20366   ix86_expand_vector_move (V2SImode, operands);
20367   DONE;
20370 (define_expand "movv4hi"
20371   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20372         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20373   "TARGET_MMX"
20375   ix86_expand_vector_move (V4HImode, operands);
20376   DONE;
20379 (define_expand "movv8qi"
20380   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20381         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20382   "TARGET_MMX"
20384   ix86_expand_vector_move (V8QImode, operands);
20385   DONE;
20388 (define_expand "movv2sf"
20389   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20390         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20391    "TARGET_3DNOW"
20393   ix86_expand_vector_move (V2SFmode, operands);
20394   DONE;
20397 (define_insn "*pushti"
20398   [(set (match_operand:TI 0 "push_operand" "=<")
20399         (match_operand:TI 1 "register_operand" "x"))]
20400   "TARGET_SSE"
20401   "#")
20403 (define_insn "*pushv2df"
20404   [(set (match_operand:V2DF 0 "push_operand" "=<")
20405         (match_operand:V2DF 1 "register_operand" "x"))]
20406   "TARGET_SSE"
20407   "#")
20409 (define_insn "*pushv2di"
20410   [(set (match_operand:V2DI 0 "push_operand" "=<")
20411         (match_operand:V2DI 1 "register_operand" "x"))]
20412   "TARGET_SSE2"
20413   "#")
20415 (define_insn "*pushv8hi"
20416   [(set (match_operand:V8HI 0 "push_operand" "=<")
20417         (match_operand:V8HI 1 "register_operand" "x"))]
20418   "TARGET_SSE2"
20419   "#")
20421 (define_insn "*pushv16qi"
20422   [(set (match_operand:V16QI 0 "push_operand" "=<")
20423         (match_operand:V16QI 1 "register_operand" "x"))]
20424   "TARGET_SSE2"
20425   "#")
20427 (define_insn "*pushv4sf"
20428   [(set (match_operand:V4SF 0 "push_operand" "=<")
20429         (match_operand:V4SF 1 "register_operand" "x"))]
20430   "TARGET_SSE"
20431   "#")
20433 (define_insn "*pushv4si"
20434   [(set (match_operand:V4SI 0 "push_operand" "=<")
20435         (match_operand:V4SI 1 "register_operand" "x"))]
20436   "TARGET_SSE2"
20437   "#")
20439 (define_insn "*pushv2si"
20440   [(set (match_operand:V2SI 0 "push_operand" "=<")
20441         (match_operand:V2SI 1 "register_operand" "y"))]
20442   "TARGET_MMX"
20443   "#")
20445 (define_insn "*pushv4hi"
20446   [(set (match_operand:V4HI 0 "push_operand" "=<")
20447         (match_operand:V4HI 1 "register_operand" "y"))]
20448   "TARGET_MMX"
20449   "#")
20451 (define_insn "*pushv8qi"
20452   [(set (match_operand:V8QI 0 "push_operand" "=<")
20453         (match_operand:V8QI 1 "register_operand" "y"))]
20454   "TARGET_MMX"
20455   "#")
20457 (define_insn "*pushv2sf"
20458   [(set (match_operand:V2SF 0 "push_operand" "=<")
20459         (match_operand:V2SF 1 "register_operand" "y"))]
20460   "TARGET_3DNOW"
20461   "#")
20463 (define_split
20464   [(set (match_operand 0 "push_operand" "")
20465         (match_operand 1 "register_operand" ""))]
20466   "!TARGET_64BIT && reload_completed
20467    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20468   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20469    (set (match_dup 2) (match_dup 1))]
20470   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20471                                  stack_pointer_rtx);
20472    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20474 (define_split
20475   [(set (match_operand 0 "push_operand" "")
20476         (match_operand 1 "register_operand" ""))]
20477   "TARGET_64BIT && reload_completed
20478    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20479   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20480    (set (match_dup 2) (match_dup 1))]
20481   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20482                                  stack_pointer_rtx);
20483    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20486 (define_insn "movti_internal"
20487   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20488         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20489   "TARGET_SSE && !TARGET_64BIT
20490    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20492   switch (which_alternative)
20493     {
20494     case 0:
20495       if (get_attr_mode (insn) == MODE_V4SF)
20496         return "xorps\t%0, %0";
20497       else
20498         return "pxor\t%0, %0";
20499     case 1:
20500     case 2:
20501       if (get_attr_mode (insn) == MODE_V4SF)
20502         return "movaps\t{%1, %0|%0, %1}";
20503       else
20504         return "movdqa\t{%1, %0|%0, %1}";
20505     default:
20506       abort ();
20507     }
20509   [(set_attr "type" "ssemov,ssemov,ssemov")
20510    (set (attr "mode")
20511         (cond [(eq_attr "alternative" "0,1")
20512                  (if_then_else
20513                    (ne (symbol_ref "optimize_size")
20514                        (const_int 0))
20515                    (const_string "V4SF")
20516                    (const_string "TI"))
20517                (eq_attr "alternative" "2")
20518                  (if_then_else
20519                    (ne (symbol_ref "optimize_size")
20520                        (const_int 0))
20521                    (const_string "V4SF")
20522                    (const_string "TI"))]
20523                (const_string "TI")))])
20525 (define_insn "*movti_rex64"
20526   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20527         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20528   "TARGET_64BIT
20529    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20531   switch (which_alternative)
20532     {
20533     case 0:
20534     case 1:
20535       return "#";
20536     case 2:
20537       if (get_attr_mode (insn) == MODE_V4SF)
20538         return "xorps\t%0, %0";
20539       else
20540         return "pxor\t%0, %0";
20541     case 3:
20542     case 4:
20543       if (get_attr_mode (insn) == MODE_V4SF)
20544         return "movaps\t{%1, %0|%0, %1}";
20545       else
20546         return "movdqa\t{%1, %0|%0, %1}";
20547     default:
20548       abort ();
20549     }
20551   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20552    (set (attr "mode")
20553         (cond [(eq_attr "alternative" "2,3")
20554                  (if_then_else
20555                    (ne (symbol_ref "optimize_size")
20556                        (const_int 0))
20557                    (const_string "V4SF")
20558                    (const_string "TI"))
20559                (eq_attr "alternative" "4")
20560                  (if_then_else
20561                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20562                             (const_int 0))
20563                         (ne (symbol_ref "optimize_size")
20564                             (const_int 0)))
20565                    (const_string "V4SF")
20566                    (const_string "TI"))]
20567                (const_string "DI")))])
20569 (define_insn "*movtf_rex64"
20570   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20571         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20572   "TARGET_64BIT
20573    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20575   switch (which_alternative)
20576     {
20577     case 0:
20578     case 1:
20579       return "#";
20580     case 2:
20581       if (get_attr_mode (insn) == MODE_V4SF)
20582         return "xorps\t%0, %0";
20583       else
20584         return "pxor\t%0, %0";
20585     case 3:
20586     case 4:
20587       if (get_attr_mode (insn) == MODE_V4SF)
20588         return "movaps\t{%1, %0|%0, %1}";
20589       else
20590         return "movdqa\t{%1, %0|%0, %1}";
20591     default:
20592       abort ();
20593     }
20595   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20596    (set (attr "mode")
20597         (cond [(eq_attr "alternative" "2,3")
20598                  (if_then_else
20599                    (ne (symbol_ref "optimize_size")
20600                        (const_int 0))
20601                    (const_string "V4SF")
20602                    (const_string "TI"))
20603                (eq_attr "alternative" "4")
20604                  (if_then_else
20605                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20606                             (const_int 0))
20607                         (ne (symbol_ref "optimize_size")
20608                             (const_int 0)))
20609                    (const_string "V4SF")
20610                    (const_string "TI"))]
20611                (const_string "DI")))])
20613 (define_split
20614   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20615         (match_operand:TI 1 "general_operand" ""))]
20616   "reload_completed && !SSE_REG_P (operands[0])
20617    && !SSE_REG_P (operands[1])"
20618   [(const_int 0)]
20619   "ix86_split_long_move (operands); DONE;")
20621 (define_split
20622   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20623         (match_operand:TF 1 "general_operand" ""))]
20624   "reload_completed && !SSE_REG_P (operands[0])
20625    && !SSE_REG_P (operands[1])"
20626   [(const_int 0)]
20627   "ix86_split_long_move (operands); DONE;")
20629 ;; These two patterns are useful for specifying exactly whether to use
20630 ;; movaps or movups
20631 (define_expand "sse_movaps"
20632   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20633         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20634                      UNSPEC_MOVA))]
20635   "TARGET_SSE"
20637   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20638     {
20639       rtx tmp = gen_reg_rtx (V4SFmode);
20640       emit_insn (gen_sse_movaps (tmp, operands[1]));
20641       emit_move_insn (operands[0], tmp);
20642       DONE;
20643     }
20646 (define_insn "*sse_movaps_1"
20647   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20648         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20649                      UNSPEC_MOVA))]
20650   "TARGET_SSE
20651    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20652   "movaps\t{%1, %0|%0, %1}"
20653   [(set_attr "type" "ssemov,ssemov")
20654    (set_attr "mode" "V4SF")])
20656 (define_expand "sse_movups"
20657   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20658         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20659                      UNSPEC_MOVU))]
20660   "TARGET_SSE"
20662   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20663     {
20664       rtx tmp = gen_reg_rtx (V4SFmode);
20665       emit_insn (gen_sse_movups (tmp, operands[1]));
20666       emit_move_insn (operands[0], tmp);
20667       DONE;
20668     }
20671 (define_insn "*sse_movups_1"
20672   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20673         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20674                      UNSPEC_MOVU))]
20675   "TARGET_SSE
20676    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20677   "movups\t{%1, %0|%0, %1}"
20678   [(set_attr "type" "ssecvt,ssecvt")
20679    (set_attr "mode" "V4SF")])
20681 ;; SSE Strange Moves.
20683 (define_insn "sse_movmskps"
20684   [(set (match_operand:SI 0 "register_operand" "=r")
20685         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20686                    UNSPEC_MOVMSK))]
20687   "TARGET_SSE"
20688   "movmskps\t{%1, %0|%0, %1}"
20689   [(set_attr "type" "ssecvt")
20690    (set_attr "mode" "V4SF")])
20692 (define_insn "mmx_pmovmskb"
20693   [(set (match_operand:SI 0 "register_operand" "=r")
20694         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20695                    UNSPEC_MOVMSK))]
20696   "TARGET_SSE || TARGET_3DNOW_A"
20697   "pmovmskb\t{%1, %0|%0, %1}"
20698   [(set_attr "type" "ssecvt")
20699    (set_attr "mode" "V4SF")])
20702 (define_insn "mmx_maskmovq"
20703   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20704         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20705                       (match_operand:V8QI 2 "register_operand" "y")]
20706                      UNSPEC_MASKMOV))]
20707   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20708   ;; @@@ check ordering of operands in intel/nonintel syntax
20709   "maskmovq\t{%2, %1|%1, %2}"
20710   [(set_attr "type" "mmxcvt")
20711    (set_attr "mode" "DI")])
20713 (define_insn "mmx_maskmovq_rex"
20714   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20715         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20716                       (match_operand:V8QI 2 "register_operand" "y")]
20717                      UNSPEC_MASKMOV))]
20718   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20719   ;; @@@ check ordering of operands in intel/nonintel syntax
20720   "maskmovq\t{%2, %1|%1, %2}"
20721   [(set_attr "type" "mmxcvt")
20722    (set_attr "mode" "DI")])
20724 (define_insn "sse_movntv4sf"
20725   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20726         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20727                      UNSPEC_MOVNT))]
20728   "TARGET_SSE"
20729   "movntps\t{%1, %0|%0, %1}"
20730   [(set_attr "type" "ssemov")
20731    (set_attr "mode" "V4SF")])
20733 (define_insn "sse_movntdi"
20734   [(set (match_operand:DI 0 "memory_operand" "=m")
20735         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20736                    UNSPEC_MOVNT))]
20737   "TARGET_SSE || TARGET_3DNOW_A"
20738   "movntq\t{%1, %0|%0, %1}"
20739   [(set_attr "type" "mmxmov")
20740    (set_attr "mode" "DI")])
20742 (define_insn "sse_movhlps"
20743   [(set (match_operand:V4SF 0 "register_operand" "=x")
20744         (vec_merge:V4SF
20745          (match_operand:V4SF 1 "register_operand" "0")
20746          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20747                           (parallel [(const_int 2)
20748                                      (const_int 3)
20749                                      (const_int 0)
20750                                      (const_int 1)]))
20751          (const_int 3)))]
20752   "TARGET_SSE"
20753   "movhlps\t{%2, %0|%0, %2}"
20754   [(set_attr "type" "ssecvt")
20755    (set_attr "mode" "V4SF")])
20757 (define_insn "sse_movlhps"
20758   [(set (match_operand:V4SF 0 "register_operand" "=x")
20759         (vec_merge:V4SF
20760          (match_operand:V4SF 1 "register_operand" "0")
20761          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20762                           (parallel [(const_int 2)
20763                                      (const_int 3)
20764                                      (const_int 0)
20765                                      (const_int 1)]))
20766          (const_int 12)))]
20767   "TARGET_SSE"
20768   "movlhps\t{%2, %0|%0, %2}"
20769   [(set_attr "type" "ssecvt")
20770    (set_attr "mode" "V4SF")])
20772 (define_insn "sse_movhps"
20773   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20774         (vec_merge:V4SF
20775          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20776          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20777          (const_int 12)))]
20778   "TARGET_SSE
20779    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20780   "movhps\t{%2, %0|%0, %2}"
20781   [(set_attr "type" "ssecvt")
20782    (set_attr "mode" "V4SF")])
20784 (define_insn "sse_movlps"
20785   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20786         (vec_merge:V4SF
20787          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20788          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20789          (const_int 3)))]
20790   "TARGET_SSE
20791    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20792   "movlps\t{%2, %0|%0, %2}"
20793   [(set_attr "type" "ssecvt")
20794    (set_attr "mode" "V4SF")])
20796 (define_expand "sse_loadss"
20797   [(match_operand:V4SF 0 "register_operand" "")
20798    (match_operand:SF 1 "memory_operand" "")]
20799   "TARGET_SSE"
20801   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20802                                CONST0_RTX (V4SFmode)));
20803   DONE;
20806 (define_insn "sse_loadss_1"
20807   [(set (match_operand:V4SF 0 "register_operand" "=x")
20808         (vec_merge:V4SF
20809          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20810          (match_operand:V4SF 2 "const0_operand" "X")
20811          (const_int 1)))]
20812   "TARGET_SSE"
20813   "movss\t{%1, %0|%0, %1}"
20814   [(set_attr "type" "ssemov")
20815    (set_attr "mode" "SF")])
20817 (define_insn "sse_movss"
20818   [(set (match_operand:V4SF 0 "register_operand" "=x")
20819         (vec_merge:V4SF
20820          (match_operand:V4SF 1 "register_operand" "0")
20821          (match_operand:V4SF 2 "register_operand" "x")
20822          (const_int 14)))]
20823   "TARGET_SSE"
20824   "movss\t{%2, %0|%0, %2}"
20825   [(set_attr "type" "ssemov")
20826    (set_attr "mode" "SF")])
20828 (define_insn "sse_storess"
20829   [(set (match_operand:SF 0 "memory_operand" "=m")
20830         (vec_select:SF
20831          (match_operand:V4SF 1 "register_operand" "x")
20832          (parallel [(const_int 0)])))]
20833   "TARGET_SSE"
20834   "movss\t{%1, %0|%0, %1}"
20835   [(set_attr "type" "ssemov")
20836    (set_attr "mode" "SF")])
20838 (define_insn "sse_shufps"
20839   [(set (match_operand:V4SF 0 "register_operand" "=x")
20840         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20841                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20842                       (match_operand:SI 3 "immediate_operand" "i")]
20843                      UNSPEC_SHUFFLE))]
20844   "TARGET_SSE"
20845   ;; @@@ check operand order for intel/nonintel syntax
20846   "shufps\t{%3, %2, %0|%0, %2, %3}"
20847   [(set_attr "type" "ssecvt")
20848    (set_attr "mode" "V4SF")])
20851 ;; SSE arithmetic
20853 (define_insn "addv4sf3"
20854   [(set (match_operand:V4SF 0 "register_operand" "=x")
20855         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20856                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20857   "TARGET_SSE"
20858   "addps\t{%2, %0|%0, %2}"
20859   [(set_attr "type" "sseadd")
20860    (set_attr "mode" "V4SF")])
20862 (define_insn "vmaddv4sf3"
20863   [(set (match_operand:V4SF 0 "register_operand" "=x")
20864         (vec_merge:V4SF
20865          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20866                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20867          (match_dup 1)
20868          (const_int 1)))]
20869   "TARGET_SSE"
20870   "addss\t{%2, %0|%0, %2}"
20871   [(set_attr "type" "sseadd")
20872    (set_attr "mode" "SF")])
20874 (define_insn "subv4sf3"
20875   [(set (match_operand:V4SF 0 "register_operand" "=x")
20876         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20877                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20878   "TARGET_SSE"
20879   "subps\t{%2, %0|%0, %2}"
20880   [(set_attr "type" "sseadd")
20881    (set_attr "mode" "V4SF")])
20883 (define_insn "vmsubv4sf3"
20884   [(set (match_operand:V4SF 0 "register_operand" "=x")
20885         (vec_merge:V4SF
20886          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20887                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20888          (match_dup 1)
20889          (const_int 1)))]
20890   "TARGET_SSE"
20891   "subss\t{%2, %0|%0, %2}"
20892   [(set_attr "type" "sseadd")
20893    (set_attr "mode" "SF")])
20895 ;; ??? Should probably be done by generic code instead.
20896 (define_expand "negv4sf2"
20897   [(set (match_operand:V4SF 0 "register_operand" "")
20898         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20899                   (match_dup 2)))]
20900   "TARGET_SSE"
20902   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20903   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20904   operands[2] = force_reg (V4SFmode, vm0);
20907 (define_insn "mulv4sf3"
20908   [(set (match_operand:V4SF 0 "register_operand" "=x")
20909         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20910                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20911   "TARGET_SSE"
20912   "mulps\t{%2, %0|%0, %2}"
20913   [(set_attr "type" "ssemul")
20914    (set_attr "mode" "V4SF")])
20916 (define_insn "vmmulv4sf3"
20917   [(set (match_operand:V4SF 0 "register_operand" "=x")
20918         (vec_merge:V4SF
20919          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20920                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20921          (match_dup 1)
20922          (const_int 1)))]
20923   "TARGET_SSE"
20924   "mulss\t{%2, %0|%0, %2}"
20925   [(set_attr "type" "ssemul")
20926    (set_attr "mode" "SF")])
20928 (define_insn "divv4sf3"
20929   [(set (match_operand:V4SF 0 "register_operand" "=x")
20930         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20931                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20932   "TARGET_SSE"
20933   "divps\t{%2, %0|%0, %2}"
20934   [(set_attr "type" "ssediv")
20935    (set_attr "mode" "V4SF")])
20937 (define_insn "vmdivv4sf3"
20938   [(set (match_operand:V4SF 0 "register_operand" "=x")
20939         (vec_merge:V4SF
20940          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20941                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20942          (match_dup 1)
20943          (const_int 1)))]
20944   "TARGET_SSE"
20945   "divss\t{%2, %0|%0, %2}"
20946   [(set_attr "type" "ssediv")
20947    (set_attr "mode" "SF")])
20950 ;; SSE square root/reciprocal
20952 (define_insn "rcpv4sf2"
20953   [(set (match_operand:V4SF 0 "register_operand" "=x")
20954         (unspec:V4SF
20955          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20956   "TARGET_SSE"
20957   "rcpps\t{%1, %0|%0, %1}"
20958   [(set_attr "type" "sse")
20959    (set_attr "mode" "V4SF")])
20961 (define_insn "vmrcpv4sf2"
20962   [(set (match_operand:V4SF 0 "register_operand" "=x")
20963         (vec_merge:V4SF
20964          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20965                       UNSPEC_RCP)
20966          (match_operand:V4SF 2 "register_operand" "0")
20967          (const_int 1)))]
20968   "TARGET_SSE"
20969   "rcpss\t{%1, %0|%0, %1}"
20970   [(set_attr "type" "sse")
20971    (set_attr "mode" "SF")])
20973 (define_insn "rsqrtv4sf2"
20974   [(set (match_operand:V4SF 0 "register_operand" "=x")
20975         (unspec:V4SF
20976          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20977   "TARGET_SSE"
20978   "rsqrtps\t{%1, %0|%0, %1}"
20979   [(set_attr "type" "sse")
20980    (set_attr "mode" "V4SF")])
20982 (define_insn "vmrsqrtv4sf2"
20983   [(set (match_operand:V4SF 0 "register_operand" "=x")
20984         (vec_merge:V4SF
20985          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20986                       UNSPEC_RSQRT)
20987          (match_operand:V4SF 2 "register_operand" "0")
20988          (const_int 1)))]
20989   "TARGET_SSE"
20990   "rsqrtss\t{%1, %0|%0, %1}"
20991   [(set_attr "type" "sse")
20992    (set_attr "mode" "SF")])
20994 (define_insn "sqrtv4sf2"
20995   [(set (match_operand:V4SF 0 "register_operand" "=x")
20996         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20997   "TARGET_SSE"
20998   "sqrtps\t{%1, %0|%0, %1}"
20999   [(set_attr "type" "sse")
21000    (set_attr "mode" "V4SF")])
21002 (define_insn "vmsqrtv4sf2"
21003   [(set (match_operand:V4SF 0 "register_operand" "=x")
21004         (vec_merge:V4SF
21005          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21006          (match_operand:V4SF 2 "register_operand" "0")
21007          (const_int 1)))]
21008   "TARGET_SSE"
21009   "sqrtss\t{%1, %0|%0, %1}"
21010   [(set_attr "type" "sse")
21011    (set_attr "mode" "SF")])
21013 ;; SSE logical operations.
21015 ;; SSE defines logical operations on floating point values.  This brings
21016 ;; interesting challenge to RTL representation where logicals are only valid
21017 ;; on integral types.  We deal with this by representing the floating point
21018 ;; logical as logical on arguments casted to TImode as this is what hardware
21019 ;; really does.  Unfortunately hardware requires the type information to be
21020 ;; present and thus we must avoid subregs from being simplified and eliminated
21021 ;; in later compilation phases.
21023 ;; We have following variants from each instruction:
21024 ;; sse_andsf3 - the operation taking V4SF vector operands
21025 ;;              and doing TImode cast on them
21026 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
21027 ;;                      TImode, since backend insist on eliminating casts
21028 ;;                      on memory operands
21029 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
21030 ;;                   We cannot accept memory operand here as instruction reads
21031 ;;                   whole scalar.  This is generated only post reload by GCC
21032 ;;                   scalar float operations that expands to logicals (fabs)
21033 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
21034 ;;                   memory operand.  Eventually combine can be able
21035 ;;                   to synthesize these using splitter.
21036 ;; sse2_anddf3, *sse2_anddf3_memory
21037 ;;              
21038 ;; 
21039 ;; These are not called andti3 etc. because we really really don't want
21040 ;; the compiler to widen DImode ands to TImode ands and then try to move
21041 ;; into DImode subregs of SSE registers, and them together, and move out
21042 ;; of DImode subregs again!
21043 ;; SSE1 single precision floating point logical operation
21044 (define_expand "sse_andv4sf3"
21045   [(set (match_operand:V4SF 0 "register_operand" "")
21046         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
21047                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21048   "TARGET_SSE"
21049   "")
21051 (define_insn "*sse_andv4sf3"
21052   [(set (match_operand:V4SF 0 "register_operand" "=x")
21053         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21054                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21055   "TARGET_SSE
21056    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21057   "andps\t{%2, %0|%0, %2}"
21058   [(set_attr "type" "sselog")
21059    (set_attr "mode" "V4SF")])
21061 (define_expand "sse_nandv4sf3"
21062   [(set (match_operand:V4SF 0 "register_operand" "")
21063         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
21064                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21065   "TARGET_SSE"
21066   "")
21068 (define_insn "*sse_nandv4sf3"
21069   [(set (match_operand:V4SF 0 "register_operand" "=x")
21070         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
21071                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21072   "TARGET_SSE"
21073   "andnps\t{%2, %0|%0, %2}"
21074   [(set_attr "type" "sselog")
21075    (set_attr "mode" "V4SF")])
21077 (define_expand "sse_iorv4sf3"
21078   [(set (match_operand:V4SF 0 "register_operand" "")
21079         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
21080                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21081   "TARGET_SSE"
21082   "")
21084 (define_insn "*sse_iorv4sf3"
21085   [(set (match_operand:V4SF 0 "register_operand" "=x")
21086         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21087                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21088   "TARGET_SSE
21089    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21090   "orps\t{%2, %0|%0, %2}"
21091   [(set_attr "type" "sselog")
21092    (set_attr "mode" "V4SF")])
21094 (define_expand "sse_xorv4sf3"
21095   [(set (match_operand:V4SF 0 "register_operand" "")
21096         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
21097                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21098   "TARGET_SSE"
21099   "")
21101 (define_insn "*sse_xorv4sf3"
21102   [(set (match_operand:V4SF 0 "register_operand" "=x")
21103         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21104                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21105   "TARGET_SSE
21106    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21107   "xorps\t{%2, %0|%0, %2}"
21108   [(set_attr "type" "sselog")
21109    (set_attr "mode" "V4SF")])
21111 ;; SSE2 double precision floating point logical operation
21113 (define_expand "sse2_andv2df3"
21114   [(set (match_operand:V2DF 0 "register_operand" "")
21115         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
21116                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21117   "TARGET_SSE2"
21118   "")
21120 (define_insn "*sse2_andv2df3"
21121   [(set (match_operand:V2DF 0 "register_operand" "=x")
21122         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21123                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21124   "TARGET_SSE2
21125    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21126   "andpd\t{%2, %0|%0, %2}"
21127   [(set_attr "type" "sselog")
21128    (set_attr "mode" "V2DF")])
21130 (define_expand "sse2_nandv2df3"
21131   [(set (match_operand:V2DF 0 "register_operand" "")
21132         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
21133                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21134   "TARGET_SSE2"
21135   "")
21137 (define_insn "*sse2_nandv2df3"
21138   [(set (match_operand:V2DF 0 "register_operand" "=x")
21139         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
21140                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21141   "TARGET_SSE2"
21142   "andnpd\t{%2, %0|%0, %2}"
21143   [(set_attr "type" "sselog")
21144    (set_attr "mode" "V2DF")])
21146 (define_expand "sse2_iorv2df3"
21147   [(set (match_operand:V2DF 0 "register_operand" "")
21148         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
21149                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21150   "TARGET_SSE2"
21151   "")
21153 (define_insn "*sse2_iorv2df3"
21154   [(set (match_operand:V2DF 0 "register_operand" "=x")
21155         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21156                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21157   "TARGET_SSE2
21158    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21159   "orpd\t{%2, %0|%0, %2}"
21160   [(set_attr "type" "sselog")
21161    (set_attr "mode" "V2DF")])
21163 (define_expand "sse2_xorv2df3"
21164   [(set (match_operand:V2DF 0 "register_operand" "")
21165         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
21166                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21167   "TARGET_SSE2"
21168   "")
21170 (define_insn "*sse2_xorv2df3"
21171   [(set (match_operand:V2DF 0 "register_operand" "=x")
21172         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21173                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21174   "TARGET_SSE2
21175    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21176   "xorpd\t{%2, %0|%0, %2}"
21177   [(set_attr "type" "sselog")
21178    (set_attr "mode" "V2DF")])
21180 ;; SSE2 integral logicals.  These patterns must always come after floating
21181 ;; point ones since we don't want compiler to use integer opcodes on floating
21182 ;; point SSE values to avoid matching of subregs in the match_operand.
21183 (define_insn "*sse2_andti3"
21184   [(set (match_operand:TI 0 "register_operand" "=x")
21185         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21186                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21187   "TARGET_SSE2
21188    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21189   "pand\t{%2, %0|%0, %2}"
21190   [(set_attr "type" "sselog")
21191    (set_attr "mode" "TI")])
21193 (define_insn "sse2_andv2di3"
21194   [(set (match_operand:V2DI 0 "register_operand" "=x")
21195         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21196                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21197   "TARGET_SSE2
21198    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21199   "pand\t{%2, %0|%0, %2}"
21200   [(set_attr "type" "sselog")
21201    (set_attr "mode" "TI")])
21203 (define_insn "*sse2_nandti3"
21204   [(set (match_operand:TI 0 "register_operand" "=x")
21205         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
21206                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21207   "TARGET_SSE2"
21208   "pandn\t{%2, %0|%0, %2}"
21209   [(set_attr "type" "sselog")
21210    (set_attr "mode" "TI")])
21212 (define_insn "sse2_nandv2di3"
21213   [(set (match_operand:V2DI 0 "register_operand" "=x")
21214         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
21215                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21216   "TARGET_SSE2
21217    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21218   "pandn\t{%2, %0|%0, %2}"
21219   [(set_attr "type" "sselog")
21220    (set_attr "mode" "TI")])
21222 (define_insn "*sse2_iorti3"
21223   [(set (match_operand:TI 0 "register_operand" "=x")
21224         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21225                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21226   "TARGET_SSE2
21227    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21228   "por\t{%2, %0|%0, %2}"
21229   [(set_attr "type" "sselog")
21230    (set_attr "mode" "TI")])
21232 (define_insn "sse2_iorv2di3"
21233   [(set (match_operand:V2DI 0 "register_operand" "=x")
21234         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21235                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21236   "TARGET_SSE2
21237    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21238   "por\t{%2, %0|%0, %2}"
21239   [(set_attr "type" "sselog")
21240    (set_attr "mode" "TI")])
21242 (define_insn "*sse2_xorti3"
21243   [(set (match_operand:TI 0 "register_operand" "=x")
21244         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21245                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21246   "TARGET_SSE2
21247    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21248   "pxor\t{%2, %0|%0, %2}"
21249   [(set_attr "type" "sselog")
21250    (set_attr "mode" "TI")])
21252 (define_insn "sse2_xorv2di3"
21253   [(set (match_operand:V2DI 0 "register_operand" "=x")
21254         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21255                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21256   "TARGET_SSE2
21257    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21258   "pxor\t{%2, %0|%0, %2}"
21259   [(set_attr "type" "sselog")
21260    (set_attr "mode" "TI")])
21262 ;; Use xor, but don't show input operands so they aren't live before
21263 ;; this insn.
21264 (define_insn "sse_clrv4sf"
21265   [(set (match_operand:V4SF 0 "register_operand" "=x")
21266         (match_operand:V4SF 1 "const0_operand" "X"))]
21267   "TARGET_SSE"
21269   if (get_attr_mode (insn) == MODE_TI)
21270     return "pxor\t{%0, %0|%0, %0}";
21271   else
21272     return "xorps\t{%0, %0|%0, %0}";
21274   [(set_attr "type" "sselog")
21275    (set_attr "memory" "none")
21276    (set (attr "mode")
21277         (if_then_else
21278            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21279                          (const_int 0))
21280                      (ne (symbol_ref "TARGET_SSE2")
21281                          (const_int 0)))
21282                 (eq (symbol_ref "optimize_size")
21283                     (const_int 0)))
21284          (const_string "TI")
21285          (const_string "V4SF")))])
21287 ;; Use xor, but don't show input operands so they aren't live before
21288 ;; this insn.
21289 (define_insn "sse_clrv2df"
21290   [(set (match_operand:V2DF 0 "register_operand" "=x")
21291         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21292   "TARGET_SSE2"
21293   "xorpd\t{%0, %0|%0, %0}"
21294   [(set_attr "type" "sselog")
21295    (set_attr "memory" "none")
21296    (set_attr "mode" "V4SF")])
21298 ;; SSE mask-generating compares
21300 (define_insn "maskcmpv4sf3"
21301   [(set (match_operand:V4SI 0 "register_operand" "=x")
21302         (match_operator:V4SI 3 "sse_comparison_operator"
21303                 [(match_operand:V4SF 1 "register_operand" "0")
21304                  (match_operand:V4SF 2 "register_operand" "x")]))]
21305   "TARGET_SSE"
21306   "cmp%D3ps\t{%2, %0|%0, %2}"
21307   [(set_attr "type" "ssecmp")
21308    (set_attr "mode" "V4SF")])
21310 (define_insn "maskncmpv4sf3"
21311   [(set (match_operand:V4SI 0 "register_operand" "=x")
21312         (not:V4SI
21313          (match_operator:V4SI 3 "sse_comparison_operator"
21314                 [(match_operand:V4SF 1 "register_operand" "0")
21315                  (match_operand:V4SF 2 "register_operand" "x")])))]
21316   "TARGET_SSE"
21318   if (GET_CODE (operands[3]) == UNORDERED)
21319     return "cmpordps\t{%2, %0|%0, %2}";
21320   else
21321     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21323   [(set_attr "type" "ssecmp")
21324    (set_attr "mode" "V4SF")])
21326 (define_insn "vmmaskcmpv4sf3"
21327   [(set (match_operand:V4SI 0 "register_operand" "=x")
21328         (vec_merge:V4SI
21329          (match_operator:V4SI 3 "sse_comparison_operator"
21330                 [(match_operand:V4SF 1 "register_operand" "0")
21331                  (match_operand:V4SF 2 "register_operand" "x")])
21332          (subreg:V4SI (match_dup 1) 0)
21333          (const_int 1)))]
21334   "TARGET_SSE"
21335   "cmp%D3ss\t{%2, %0|%0, %2}"
21336   [(set_attr "type" "ssecmp")
21337    (set_attr "mode" "SF")])
21339 (define_insn "vmmaskncmpv4sf3"
21340   [(set (match_operand:V4SI 0 "register_operand" "=x")
21341         (vec_merge:V4SI
21342          (not:V4SI
21343           (match_operator:V4SI 3 "sse_comparison_operator"
21344                 [(match_operand:V4SF 1 "register_operand" "0")
21345                  (match_operand:V4SF 2 "register_operand" "x")]))
21346          (subreg:V4SI (match_dup 1) 0)
21347          (const_int 1)))]
21348   "TARGET_SSE"
21350   if (GET_CODE (operands[3]) == UNORDERED)
21351     return "cmpordss\t{%2, %0|%0, %2}";
21352   else
21353     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21355   [(set_attr "type" "ssecmp")
21356    (set_attr "mode" "SF")])
21358 (define_insn "sse_comi"
21359   [(set (reg:CCFP FLAGS_REG)
21360         (compare:CCFP (vec_select:SF
21361                        (match_operand:V4SF 0 "register_operand" "x")
21362                        (parallel [(const_int 0)]))
21363                       (vec_select:SF
21364                        (match_operand:V4SF 1 "register_operand" "x")
21365                        (parallel [(const_int 0)]))))]
21366   "TARGET_SSE"
21367   "comiss\t{%1, %0|%0, %1}"
21368   [(set_attr "type" "ssecomi")
21369    (set_attr "mode" "SF")])
21371 (define_insn "sse_ucomi"
21372   [(set (reg:CCFPU FLAGS_REG)
21373         (compare:CCFPU (vec_select:SF
21374                         (match_operand:V4SF 0 "register_operand" "x")
21375                         (parallel [(const_int 0)]))
21376                        (vec_select:SF
21377                         (match_operand:V4SF 1 "register_operand" "x")
21378                         (parallel [(const_int 0)]))))]
21379   "TARGET_SSE"
21380   "ucomiss\t{%1, %0|%0, %1}"
21381   [(set_attr "type" "ssecomi")
21382    (set_attr "mode" "SF")])
21385 ;; SSE unpack
21387 (define_insn "sse_unpckhps"
21388   [(set (match_operand:V4SF 0 "register_operand" "=x")
21389         (vec_merge:V4SF
21390          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21391                           (parallel [(const_int 2)
21392                                      (const_int 0)
21393                                      (const_int 3)
21394                                      (const_int 1)]))
21395          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21396                           (parallel [(const_int 0)
21397                                      (const_int 2)
21398                                      (const_int 1)
21399                                      (const_int 3)]))
21400          (const_int 5)))]
21401   "TARGET_SSE"
21402   "unpckhps\t{%2, %0|%0, %2}"
21403   [(set_attr "type" "ssecvt")
21404    (set_attr "mode" "V4SF")])
21406 (define_insn "sse_unpcklps"
21407   [(set (match_operand:V4SF 0 "register_operand" "=x")
21408         (vec_merge:V4SF
21409          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21410                           (parallel [(const_int 0)
21411                                      (const_int 2)
21412                                      (const_int 1)
21413                                      (const_int 3)]))
21414          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21415                           (parallel [(const_int 2)
21416                                      (const_int 0)
21417                                      (const_int 3)
21418                                      (const_int 1)]))
21419          (const_int 5)))]
21420   "TARGET_SSE"
21421   "unpcklps\t{%2, %0|%0, %2}"
21422   [(set_attr "type" "ssecvt")
21423    (set_attr "mode" "V4SF")])
21426 ;; SSE min/max
21428 (define_insn "smaxv4sf3"
21429   [(set (match_operand:V4SF 0 "register_operand" "=x")
21430         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21431                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21432   "TARGET_SSE"
21433   "maxps\t{%2, %0|%0, %2}"
21434   [(set_attr "type" "sse")
21435    (set_attr "mode" "V4SF")])
21437 (define_insn "vmsmaxv4sf3"
21438   [(set (match_operand:V4SF 0 "register_operand" "=x")
21439         (vec_merge:V4SF
21440          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21441                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21442          (match_dup 1)
21443          (const_int 1)))]
21444   "TARGET_SSE"
21445   "maxss\t{%2, %0|%0, %2}"
21446   [(set_attr "type" "sse")
21447    (set_attr "mode" "SF")])
21449 (define_insn "sminv4sf3"
21450   [(set (match_operand:V4SF 0 "register_operand" "=x")
21451         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21452                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21453   "TARGET_SSE"
21454   "minps\t{%2, %0|%0, %2}"
21455   [(set_attr "type" "sse")
21456    (set_attr "mode" "V4SF")])
21458 (define_insn "vmsminv4sf3"
21459   [(set (match_operand:V4SF 0 "register_operand" "=x")
21460         (vec_merge:V4SF
21461          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21462                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21463          (match_dup 1)
21464          (const_int 1)))]
21465   "TARGET_SSE"
21466   "minss\t{%2, %0|%0, %2}"
21467   [(set_attr "type" "sse")
21468    (set_attr "mode" "SF")])
21470 ;; SSE <-> integer/MMX conversions
21472 (define_insn "cvtpi2ps"
21473   [(set (match_operand:V4SF 0 "register_operand" "=x")
21474         (vec_merge:V4SF
21475          (match_operand:V4SF 1 "register_operand" "0")
21476          (vec_duplicate:V4SF
21477           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21478          (const_int 12)))]
21479   "TARGET_SSE"
21480   "cvtpi2ps\t{%2, %0|%0, %2}"
21481   [(set_attr "type" "ssecvt")
21482    (set_attr "mode" "V4SF")])
21484 (define_insn "cvtps2pi"
21485   [(set (match_operand:V2SI 0 "register_operand" "=y")
21486         (vec_select:V2SI
21487          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21488          (parallel [(const_int 0) (const_int 1)])))]
21489   "TARGET_SSE"
21490   "cvtps2pi\t{%1, %0|%0, %1}"
21491   [(set_attr "type" "ssecvt")
21492    (set_attr "mode" "V4SF")])
21494 (define_insn "cvttps2pi"
21495   [(set (match_operand:V2SI 0 "register_operand" "=y")
21496         (vec_select:V2SI
21497          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21498                       UNSPEC_FIX)
21499          (parallel [(const_int 0) (const_int 1)])))]
21500   "TARGET_SSE"
21501   "cvttps2pi\t{%1, %0|%0, %1}"
21502   [(set_attr "type" "ssecvt")
21503    (set_attr "mode" "SF")])
21505 (define_insn "cvtsi2ss"
21506   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21507         (vec_merge:V4SF
21508          (match_operand:V4SF 1 "register_operand" "0,0")
21509          (vec_duplicate:V4SF
21510           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21511          (const_int 14)))]
21512   "TARGET_SSE"
21513   "cvtsi2ss\t{%2, %0|%0, %2}"
21514   [(set_attr "type" "sseicvt")
21515    (set_attr "athlon_decode" "vector,double")
21516    (set_attr "mode" "SF")])
21518 (define_insn "cvtsi2ssq"
21519   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21520         (vec_merge:V4SF
21521          (match_operand:V4SF 1 "register_operand" "0,0")
21522          (vec_duplicate:V4SF
21523           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21524          (const_int 14)))]
21525   "TARGET_SSE && TARGET_64BIT"
21526   "cvtsi2ssq\t{%2, %0|%0, %2}"
21527   [(set_attr "type" "sseicvt")
21528    (set_attr "athlon_decode" "vector,double")
21529    (set_attr "mode" "SF")])
21531 (define_insn "cvtss2si"
21532   [(set (match_operand:SI 0 "register_operand" "=r,r")
21533         (vec_select:SI
21534          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21535          (parallel [(const_int 0)])))]
21536   "TARGET_SSE"
21537   "cvtss2si\t{%1, %0|%0, %1}"
21538   [(set_attr "type" "sseicvt")
21539    (set_attr "athlon_decode" "double,vector")
21540    (set_attr "mode" "SI")])
21542 (define_insn "cvtss2siq"
21543   [(set (match_operand:DI 0 "register_operand" "=r,r")
21544         (vec_select:DI
21545          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21546          (parallel [(const_int 0)])))]
21547   "TARGET_SSE"
21548   "cvtss2siq\t{%1, %0|%0, %1}"
21549   [(set_attr "type" "sseicvt")
21550    (set_attr "athlon_decode" "double,vector")
21551    (set_attr "mode" "DI")])
21553 (define_insn "cvttss2si"
21554   [(set (match_operand:SI 0 "register_operand" "=r,r")
21555         (vec_select:SI
21556          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21557                       UNSPEC_FIX)
21558          (parallel [(const_int 0)])))]
21559   "TARGET_SSE"
21560   "cvttss2si\t{%1, %0|%0, %1}"
21561   [(set_attr "type" "sseicvt")
21562    (set_attr "mode" "SF")
21563    (set_attr "athlon_decode" "double,vector")])
21565 (define_insn "cvttss2siq"
21566   [(set (match_operand:DI 0 "register_operand" "=r,r")
21567         (vec_select:DI
21568          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21569                       UNSPEC_FIX)
21570          (parallel [(const_int 0)])))]
21571   "TARGET_SSE && TARGET_64BIT"
21572   "cvttss2siq\t{%1, %0|%0, %1}"
21573   [(set_attr "type" "sseicvt")
21574    (set_attr "mode" "SF")
21575    (set_attr "athlon_decode" "double,vector")])
21578 ;; MMX insns
21580 ;; MMX arithmetic
21582 (define_insn "addv8qi3"
21583   [(set (match_operand:V8QI 0 "register_operand" "=y")
21584         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21585                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21586   "TARGET_MMX"
21587   "paddb\t{%2, %0|%0, %2}"
21588   [(set_attr "type" "mmxadd")
21589    (set_attr "mode" "DI")])
21591 (define_insn "addv4hi3"
21592   [(set (match_operand:V4HI 0 "register_operand" "=y")
21593         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21594                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21595   "TARGET_MMX"
21596   "paddw\t{%2, %0|%0, %2}"
21597   [(set_attr "type" "mmxadd")
21598    (set_attr "mode" "DI")])
21600 (define_insn "addv2si3"
21601   [(set (match_operand:V2SI 0 "register_operand" "=y")
21602         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21603                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21604   "TARGET_MMX"
21605   "paddd\t{%2, %0|%0, %2}"
21606   [(set_attr "type" "mmxadd")
21607    (set_attr "mode" "DI")])
21609 (define_insn "mmx_adddi3"
21610   [(set (match_operand:DI 0 "register_operand" "=y")
21611         (unspec:DI
21612          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21613                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21614          UNSPEC_NOP))]
21615   "TARGET_MMX"
21616   "paddq\t{%2, %0|%0, %2}"
21617   [(set_attr "type" "mmxadd")
21618    (set_attr "mode" "DI")])
21620 (define_insn "ssaddv8qi3"
21621   [(set (match_operand:V8QI 0 "register_operand" "=y")
21622         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21623                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21624   "TARGET_MMX"
21625   "paddsb\t{%2, %0|%0, %2}"
21626   [(set_attr "type" "mmxadd")
21627    (set_attr "mode" "DI")])
21629 (define_insn "ssaddv4hi3"
21630   [(set (match_operand:V4HI 0 "register_operand" "=y")
21631         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21632                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21633   "TARGET_MMX"
21634   "paddsw\t{%2, %0|%0, %2}"
21635   [(set_attr "type" "mmxadd")
21636    (set_attr "mode" "DI")])
21638 (define_insn "usaddv8qi3"
21639   [(set (match_operand:V8QI 0 "register_operand" "=y")
21640         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21641                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21642   "TARGET_MMX"
21643   "paddusb\t{%2, %0|%0, %2}"
21644   [(set_attr "type" "mmxadd")
21645    (set_attr "mode" "DI")])
21647 (define_insn "usaddv4hi3"
21648   [(set (match_operand:V4HI 0 "register_operand" "=y")
21649         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21650                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21651   "TARGET_MMX"
21652   "paddusw\t{%2, %0|%0, %2}"
21653   [(set_attr "type" "mmxadd")
21654    (set_attr "mode" "DI")])
21656 (define_insn "subv8qi3"
21657   [(set (match_operand:V8QI 0 "register_operand" "=y")
21658         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21659                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21660   "TARGET_MMX"
21661   "psubb\t{%2, %0|%0, %2}"
21662   [(set_attr "type" "mmxadd")
21663    (set_attr "mode" "DI")])
21665 (define_insn "subv4hi3"
21666   [(set (match_operand:V4HI 0 "register_operand" "=y")
21667         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21668                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21669   "TARGET_MMX"
21670   "psubw\t{%2, %0|%0, %2}"
21671   [(set_attr "type" "mmxadd")
21672    (set_attr "mode" "DI")])
21674 (define_insn "subv2si3"
21675   [(set (match_operand:V2SI 0 "register_operand" "=y")
21676         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21677                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21678   "TARGET_MMX"
21679   "psubd\t{%2, %0|%0, %2}"
21680   [(set_attr "type" "mmxadd")
21681    (set_attr "mode" "DI")])
21683 (define_insn "mmx_subdi3"
21684   [(set (match_operand:DI 0 "register_operand" "=y")
21685         (unspec:DI
21686          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21687                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21688          UNSPEC_NOP))]
21689   "TARGET_MMX"
21690   "psubq\t{%2, %0|%0, %2}"
21691   [(set_attr "type" "mmxadd")
21692    (set_attr "mode" "DI")])
21694 (define_insn "sssubv8qi3"
21695   [(set (match_operand:V8QI 0 "register_operand" "=y")
21696         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21697                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21698   "TARGET_MMX"
21699   "psubsb\t{%2, %0|%0, %2}"
21700   [(set_attr "type" "mmxadd")
21701    (set_attr "mode" "DI")])
21703 (define_insn "sssubv4hi3"
21704   [(set (match_operand:V4HI 0 "register_operand" "=y")
21705         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21706                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21707   "TARGET_MMX"
21708   "psubsw\t{%2, %0|%0, %2}"
21709   [(set_attr "type" "mmxadd")
21710    (set_attr "mode" "DI")])
21712 (define_insn "ussubv8qi3"
21713   [(set (match_operand:V8QI 0 "register_operand" "=y")
21714         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21715                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21716   "TARGET_MMX"
21717   "psubusb\t{%2, %0|%0, %2}"
21718   [(set_attr "type" "mmxadd")
21719    (set_attr "mode" "DI")])
21721 (define_insn "ussubv4hi3"
21722   [(set (match_operand:V4HI 0 "register_operand" "=y")
21723         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21724                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21725   "TARGET_MMX"
21726   "psubusw\t{%2, %0|%0, %2}"
21727   [(set_attr "type" "mmxadd")
21728    (set_attr "mode" "DI")])
21730 (define_insn "mulv4hi3"
21731   [(set (match_operand:V4HI 0 "register_operand" "=y")
21732         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21733                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21734   "TARGET_MMX"
21735   "pmullw\t{%2, %0|%0, %2}"
21736   [(set_attr "type" "mmxmul")
21737    (set_attr "mode" "DI")])
21739 (define_insn "smulv4hi3_highpart"
21740   [(set (match_operand:V4HI 0 "register_operand" "=y")
21741         (truncate:V4HI
21742          (lshiftrt:V4SI
21743           (mult:V4SI (sign_extend:V4SI
21744                       (match_operand:V4HI 1 "register_operand" "0"))
21745                      (sign_extend:V4SI
21746                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21747           (const_int 16))))]
21748   "TARGET_MMX"
21749   "pmulhw\t{%2, %0|%0, %2}"
21750   [(set_attr "type" "mmxmul")
21751    (set_attr "mode" "DI")])
21753 (define_insn "umulv4hi3_highpart"
21754   [(set (match_operand:V4HI 0 "register_operand" "=y")
21755         (truncate:V4HI
21756          (lshiftrt:V4SI
21757           (mult:V4SI (zero_extend:V4SI
21758                       (match_operand:V4HI 1 "register_operand" "0"))
21759                      (zero_extend:V4SI
21760                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21761           (const_int 16))))]
21762   "TARGET_SSE || TARGET_3DNOW_A"
21763   "pmulhuw\t{%2, %0|%0, %2}"
21764   [(set_attr "type" "mmxmul")
21765    (set_attr "mode" "DI")])
21767 (define_insn "mmx_pmaddwd"
21768   [(set (match_operand:V2SI 0 "register_operand" "=y")
21769         (plus:V2SI
21770          (mult:V2SI
21771           (sign_extend:V2SI
21772            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21773                             (parallel [(const_int 0) (const_int 2)])))
21774           (sign_extend:V2SI
21775            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21776                             (parallel [(const_int 0) (const_int 2)]))))
21777          (mult:V2SI
21778           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21779                                              (parallel [(const_int 1)
21780                                                         (const_int 3)])))
21781           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21782                                              (parallel [(const_int 1)
21783                                                         (const_int 3)]))))))]
21784   "TARGET_MMX"
21785   "pmaddwd\t{%2, %0|%0, %2}"
21786   [(set_attr "type" "mmxmul")
21787    (set_attr "mode" "DI")])
21790 ;; MMX logical operations
21791 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21792 ;; normal code that also wants to use the FPU from getting broken.
21793 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21794 (define_insn "mmx_iordi3"
21795   [(set (match_operand:DI 0 "register_operand" "=y")
21796         (unspec:DI
21797          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21798                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21799          UNSPEC_NOP))]
21800   "TARGET_MMX"
21801   "por\t{%2, %0|%0, %2}"
21802   [(set_attr "type" "mmxadd")
21803    (set_attr "mode" "DI")])
21805 (define_insn "mmx_xordi3"
21806   [(set (match_operand:DI 0 "register_operand" "=y")
21807         (unspec:DI
21808          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21809                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21810          UNSPEC_NOP))]
21811   "TARGET_MMX"
21812   "pxor\t{%2, %0|%0, %2}"
21813   [(set_attr "type" "mmxadd")
21814    (set_attr "mode" "DI")
21815    (set_attr "memory" "none")])
21817 ;; Same as pxor, but don't show input operands so that we don't think
21818 ;; they are live.
21819 (define_insn "mmx_clrdi"
21820   [(set (match_operand:DI 0 "register_operand" "=y")
21821         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21822   "TARGET_MMX"
21823   "pxor\t{%0, %0|%0, %0}"
21824   [(set_attr "type" "mmxadd")
21825    (set_attr "mode" "DI")
21826    (set_attr "memory" "none")])
21828 (define_insn "mmx_anddi3"
21829   [(set (match_operand:DI 0 "register_operand" "=y")
21830         (unspec:DI
21831          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21832                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21833          UNSPEC_NOP))]
21834   "TARGET_MMX"
21835   "pand\t{%2, %0|%0, %2}"
21836   [(set_attr "type" "mmxadd")
21837    (set_attr "mode" "DI")])
21839 (define_insn "mmx_nanddi3"
21840   [(set (match_operand:DI 0 "register_operand" "=y")
21841         (unspec:DI
21842          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21843                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21844          UNSPEC_NOP))]
21845   "TARGET_MMX"
21846   "pandn\t{%2, %0|%0, %2}"
21847   [(set_attr "type" "mmxadd")
21848    (set_attr "mode" "DI")])
21851 ;; MMX unsigned averages/sum of absolute differences
21853 (define_insn "mmx_uavgv8qi3"
21854   [(set (match_operand:V8QI 0 "register_operand" "=y")
21855         (ashiftrt:V8QI
21856          (plus:V8QI (plus:V8QI
21857                      (match_operand:V8QI 1 "register_operand" "0")
21858                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21859                     (const_vector:V8QI [(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                                         (const_int 1)]))
21867          (const_int 1)))]
21868   "TARGET_SSE || TARGET_3DNOW_A"
21869   "pavgb\t{%2, %0|%0, %2}"
21870   [(set_attr "type" "mmxshft")
21871    (set_attr "mode" "DI")])
21873 (define_insn "mmx_uavgv4hi3"
21874   [(set (match_operand:V4HI 0 "register_operand" "=y")
21875         (ashiftrt:V4HI
21876          (plus:V4HI (plus:V4HI
21877                      (match_operand:V4HI 1 "register_operand" "0")
21878                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21879                     (const_vector:V4HI [(const_int 1)
21880                                         (const_int 1)
21881                                         (const_int 1)
21882                                         (const_int 1)]))
21883          (const_int 1)))]
21884   "TARGET_SSE || TARGET_3DNOW_A"
21885   "pavgw\t{%2, %0|%0, %2}"
21886   [(set_attr "type" "mmxshft")
21887    (set_attr "mode" "DI")])
21889 (define_insn "mmx_psadbw"
21890   [(set (match_operand:DI 0 "register_operand" "=y")
21891         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21892                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21893                    UNSPEC_PSADBW))]
21894   "TARGET_SSE || TARGET_3DNOW_A"
21895   "psadbw\t{%2, %0|%0, %2}"
21896   [(set_attr "type" "mmxshft")
21897    (set_attr "mode" "DI")])
21900 ;; MMX insert/extract/shuffle
21902 (define_insn "mmx_pinsrw"
21903   [(set (match_operand:V4HI 0 "register_operand" "=y")
21904         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21905                         (vec_duplicate:V4HI
21906                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21907                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21908   "TARGET_SSE || TARGET_3DNOW_A"
21909   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21910   [(set_attr "type" "mmxcvt")
21911    (set_attr "mode" "DI")])
21913 (define_insn "mmx_pextrw"
21914   [(set (match_operand:SI 0 "register_operand" "=r")
21915         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21916                                        (parallel
21917                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21918   "TARGET_SSE || TARGET_3DNOW_A"
21919   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21920   [(set_attr "type" "mmxcvt")
21921    (set_attr "mode" "DI")])
21923 (define_insn "mmx_pshufw"
21924   [(set (match_operand:V4HI 0 "register_operand" "=y")
21925         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21926                       (match_operand:SI 2 "immediate_operand" "i")]
21927                      UNSPEC_SHUFFLE))]
21928   "TARGET_SSE || TARGET_3DNOW_A"
21929   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21930   [(set_attr "type" "mmxcvt")
21931    (set_attr "mode" "DI")])
21934 ;; MMX mask-generating comparisons
21936 (define_insn "eqv8qi3"
21937   [(set (match_operand:V8QI 0 "register_operand" "=y")
21938         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21939                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21940   "TARGET_MMX"
21941   "pcmpeqb\t{%2, %0|%0, %2}"
21942   [(set_attr "type" "mmxcmp")
21943    (set_attr "mode" "DI")])
21945 (define_insn "eqv4hi3"
21946   [(set (match_operand:V4HI 0 "register_operand" "=y")
21947         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21948                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21949   "TARGET_MMX"
21950   "pcmpeqw\t{%2, %0|%0, %2}"
21951   [(set_attr "type" "mmxcmp")
21952    (set_attr "mode" "DI")])
21954 (define_insn "eqv2si3"
21955   [(set (match_operand:V2SI 0 "register_operand" "=y")
21956         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21957                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21958   "TARGET_MMX"
21959   "pcmpeqd\t{%2, %0|%0, %2}"
21960   [(set_attr "type" "mmxcmp")
21961    (set_attr "mode" "DI")])
21963 (define_insn "gtv8qi3"
21964   [(set (match_operand:V8QI 0 "register_operand" "=y")
21965         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21966                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21967   "TARGET_MMX"
21968   "pcmpgtb\t{%2, %0|%0, %2}"
21969   [(set_attr "type" "mmxcmp")
21970    (set_attr "mode" "DI")])
21972 (define_insn "gtv4hi3"
21973   [(set (match_operand:V4HI 0 "register_operand" "=y")
21974         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21975                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21976   "TARGET_MMX"
21977   "pcmpgtw\t{%2, %0|%0, %2}"
21978   [(set_attr "type" "mmxcmp")
21979    (set_attr "mode" "DI")])
21981 (define_insn "gtv2si3"
21982   [(set (match_operand:V2SI 0 "register_operand" "=y")
21983         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21984                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21985   "TARGET_MMX"
21986   "pcmpgtd\t{%2, %0|%0, %2}"
21987   [(set_attr "type" "mmxcmp")
21988    (set_attr "mode" "DI")])
21991 ;; MMX max/min insns
21993 (define_insn "umaxv8qi3"
21994   [(set (match_operand:V8QI 0 "register_operand" "=y")
21995         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21996                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21997   "TARGET_SSE || TARGET_3DNOW_A"
21998   "pmaxub\t{%2, %0|%0, %2}"
21999   [(set_attr "type" "mmxadd")
22000    (set_attr "mode" "DI")])
22002 (define_insn "smaxv4hi3"
22003   [(set (match_operand:V4HI 0 "register_operand" "=y")
22004         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
22005                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22006   "TARGET_SSE || TARGET_3DNOW_A"
22007   "pmaxsw\t{%2, %0|%0, %2}"
22008   [(set_attr "type" "mmxadd")
22009    (set_attr "mode" "DI")])
22011 (define_insn "uminv8qi3"
22012   [(set (match_operand:V8QI 0 "register_operand" "=y")
22013         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
22014                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22015   "TARGET_SSE || TARGET_3DNOW_A"
22016   "pminub\t{%2, %0|%0, %2}"
22017   [(set_attr "type" "mmxadd")
22018    (set_attr "mode" "DI")])
22020 (define_insn "sminv4hi3"
22021   [(set (match_operand:V4HI 0 "register_operand" "=y")
22022         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
22023                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22024   "TARGET_SSE || TARGET_3DNOW_A"
22025   "pminsw\t{%2, %0|%0, %2}"
22026   [(set_attr "type" "mmxadd")
22027    (set_attr "mode" "DI")])
22030 ;; MMX shifts
22032 (define_insn "ashrv4hi3"
22033   [(set (match_operand:V4HI 0 "register_operand" "=y")
22034         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22035                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22036   "TARGET_MMX"
22037   "psraw\t{%2, %0|%0, %2}"
22038   [(set_attr "type" "mmxshft")
22039    (set_attr "mode" "DI")])
22041 (define_insn "ashrv2si3"
22042   [(set (match_operand:V2SI 0 "register_operand" "=y")
22043         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22044                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22045   "TARGET_MMX"
22046   "psrad\t{%2, %0|%0, %2}"
22047   [(set_attr "type" "mmxshft")
22048    (set_attr "mode" "DI")])
22050 (define_insn "lshrv4hi3"
22051   [(set (match_operand:V4HI 0 "register_operand" "=y")
22052         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22053                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22054   "TARGET_MMX"
22055   "psrlw\t{%2, %0|%0, %2}"
22056   [(set_attr "type" "mmxshft")
22057    (set_attr "mode" "DI")])
22059 (define_insn "lshrv2si3"
22060   [(set (match_operand:V2SI 0 "register_operand" "=y")
22061         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22062                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22063   "TARGET_MMX"
22064   "psrld\t{%2, %0|%0, %2}"
22065   [(set_attr "type" "mmxshft")
22066    (set_attr "mode" "DI")])
22068 ;; See logical MMX insns.
22069 (define_insn "mmx_lshrdi3"
22070   [(set (match_operand:DI 0 "register_operand" "=y")
22071         (unspec:DI
22072           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
22073                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
22074           UNSPEC_NOP))]
22075   "TARGET_MMX"
22076   "psrlq\t{%2, %0|%0, %2}"
22077   [(set_attr "type" "mmxshft")
22078    (set_attr "mode" "DI")])
22080 (define_insn "ashlv4hi3"
22081   [(set (match_operand:V4HI 0 "register_operand" "=y")
22082         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
22083                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22084   "TARGET_MMX"
22085   "psllw\t{%2, %0|%0, %2}"
22086   [(set_attr "type" "mmxshft")
22087    (set_attr "mode" "DI")])
22089 (define_insn "ashlv2si3"
22090   [(set (match_operand:V2SI 0 "register_operand" "=y")
22091         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
22092                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
22093   "TARGET_MMX"
22094   "pslld\t{%2, %0|%0, %2}"
22095   [(set_attr "type" "mmxshft")
22096    (set_attr "mode" "DI")])
22098 ;; See logical MMX insns.
22099 (define_insn "mmx_ashldi3"
22100   [(set (match_operand:DI 0 "register_operand" "=y")
22101         (unspec:DI
22102          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
22103                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
22104          UNSPEC_NOP))]
22105   "TARGET_MMX"
22106   "psllq\t{%2, %0|%0, %2}"
22107   [(set_attr "type" "mmxshft")
22108    (set_attr "mode" "DI")])
22111 ;; MMX pack/unpack insns.
22113 (define_insn "mmx_packsswb"
22114   [(set (match_operand:V8QI 0 "register_operand" "=y")
22115         (vec_concat:V8QI
22116          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22117          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22118   "TARGET_MMX"
22119   "packsswb\t{%2, %0|%0, %2}"
22120   [(set_attr "type" "mmxshft")
22121    (set_attr "mode" "DI")])
22123 (define_insn "mmx_packssdw"
22124   [(set (match_operand:V4HI 0 "register_operand" "=y")
22125         (vec_concat:V4HI
22126          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
22127          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
22128   "TARGET_MMX"
22129   "packssdw\t{%2, %0|%0, %2}"
22130   [(set_attr "type" "mmxshft")
22131    (set_attr "mode" "DI")])
22133 (define_insn "mmx_packuswb"
22134   [(set (match_operand:V8QI 0 "register_operand" "=y")
22135         (vec_concat:V8QI
22136          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22137          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22138   "TARGET_MMX"
22139   "packuswb\t{%2, %0|%0, %2}"
22140   [(set_attr "type" "mmxshft")
22141    (set_attr "mode" "DI")])
22143 (define_insn "mmx_punpckhbw"
22144   [(set (match_operand:V8QI 0 "register_operand" "=y")
22145         (vec_merge:V8QI
22146          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22147                           (parallel [(const_int 4)
22148                                      (const_int 0)
22149                                      (const_int 5)
22150                                      (const_int 1)
22151                                      (const_int 6)
22152                                      (const_int 2)
22153                                      (const_int 7)
22154                                      (const_int 3)]))
22155          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22156                           (parallel [(const_int 0)
22157                                      (const_int 4)
22158                                      (const_int 1)
22159                                      (const_int 5)
22160                                      (const_int 2)
22161                                      (const_int 6)
22162                                      (const_int 3)
22163                                      (const_int 7)]))
22164          (const_int 85)))]
22165   "TARGET_MMX"
22166   "punpckhbw\t{%2, %0|%0, %2}"
22167   [(set_attr "type" "mmxcvt")
22168    (set_attr "mode" "DI")])
22170 (define_insn "mmx_punpckhwd"
22171   [(set (match_operand:V4HI 0 "register_operand" "=y")
22172         (vec_merge:V4HI
22173          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22174                           (parallel [(const_int 0)
22175                                      (const_int 2)
22176                                      (const_int 1)
22177                                      (const_int 3)]))
22178          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22179                           (parallel [(const_int 2)
22180                                      (const_int 0)
22181                                      (const_int 3)
22182                                      (const_int 1)]))
22183          (const_int 5)))]
22184   "TARGET_MMX"
22185   "punpckhwd\t{%2, %0|%0, %2}"
22186   [(set_attr "type" "mmxcvt")
22187    (set_attr "mode" "DI")])
22189 (define_insn "mmx_punpckhdq"
22190   [(set (match_operand:V2SI 0 "register_operand" "=y")
22191         (vec_merge:V2SI
22192          (match_operand:V2SI 1 "register_operand" "0")
22193          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
22194                           (parallel [(const_int 1)
22195                                      (const_int 0)]))
22196          (const_int 1)))]
22197   "TARGET_MMX"
22198   "punpckhdq\t{%2, %0|%0, %2}"
22199   [(set_attr "type" "mmxcvt")
22200    (set_attr "mode" "DI")])
22202 (define_insn "mmx_punpcklbw"
22203   [(set (match_operand:V8QI 0 "register_operand" "=y")
22204         (vec_merge:V8QI
22205          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22206                           (parallel [(const_int 0)
22207                                      (const_int 4)
22208                                      (const_int 1)
22209                                      (const_int 5)
22210                                      (const_int 2)
22211                                      (const_int 6)
22212                                      (const_int 3)
22213                                      (const_int 7)]))
22214          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22215                           (parallel [(const_int 4)
22216                                      (const_int 0)
22217                                      (const_int 5)
22218                                      (const_int 1)
22219                                      (const_int 6)
22220                                      (const_int 2)
22221                                      (const_int 7)
22222                                      (const_int 3)]))
22223          (const_int 85)))]
22224   "TARGET_MMX"
22225   "punpcklbw\t{%2, %0|%0, %2}"
22226   [(set_attr "type" "mmxcvt")
22227    (set_attr "mode" "DI")])
22229 (define_insn "mmx_punpcklwd"
22230   [(set (match_operand:V4HI 0 "register_operand" "=y")
22231         (vec_merge:V4HI
22232          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22233                           (parallel [(const_int 2)
22234                                      (const_int 0)
22235                                      (const_int 3)
22236                                      (const_int 1)]))
22237          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22238                           (parallel [(const_int 0)
22239                                      (const_int 2)
22240                                      (const_int 1)
22241                                      (const_int 3)]))
22242          (const_int 5)))]
22243   "TARGET_MMX"
22244   "punpcklwd\t{%2, %0|%0, %2}"
22245   [(set_attr "type" "mmxcvt")
22246    (set_attr "mode" "DI")])
22248 (define_insn "mmx_punpckldq"
22249   [(set (match_operand:V2SI 0 "register_operand" "=y")
22250         (vec_merge:V2SI
22251          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22252                            (parallel [(const_int 1)
22253                                       (const_int 0)]))
22254          (match_operand:V2SI 2 "register_operand" "y")
22255          (const_int 1)))]
22256   "TARGET_MMX"
22257   "punpckldq\t{%2, %0|%0, %2}"
22258   [(set_attr "type" "mmxcvt")
22259    (set_attr "mode" "DI")])
22262 ;; Miscellaneous stuff
22264 (define_insn "emms"
22265   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22266    (clobber (reg:XF 8))
22267    (clobber (reg:XF 9))
22268    (clobber (reg:XF 10))
22269    (clobber (reg:XF 11))
22270    (clobber (reg:XF 12))
22271    (clobber (reg:XF 13))
22272    (clobber (reg:XF 14))
22273    (clobber (reg:XF 15))
22274    (clobber (reg:DI 29))
22275    (clobber (reg:DI 30))
22276    (clobber (reg:DI 31))
22277    (clobber (reg:DI 32))
22278    (clobber (reg:DI 33))
22279    (clobber (reg:DI 34))
22280    (clobber (reg:DI 35))
22281    (clobber (reg:DI 36))]
22282   "TARGET_MMX"
22283   "emms"
22284   [(set_attr "type" "mmx")
22285    (set_attr "memory" "unknown")])
22287 (define_insn "ldmxcsr"
22288   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22289                     UNSPECV_LDMXCSR)]
22290   "TARGET_SSE"
22291   "ldmxcsr\t%0"
22292   [(set_attr "type" "sse")
22293    (set_attr "memory" "load")])
22295 (define_insn "stmxcsr"
22296   [(set (match_operand:SI 0 "memory_operand" "=m")
22297         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22298   "TARGET_SSE"
22299   "stmxcsr\t%0"
22300   [(set_attr "type" "sse")
22301    (set_attr "memory" "store")])
22303 (define_expand "sfence"
22304   [(set (match_dup 0)
22305         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22306   "TARGET_SSE || TARGET_3DNOW_A"
22308   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22309   MEM_VOLATILE_P (operands[0]) = 1;
22312 (define_insn "*sfence_insn"
22313   [(set (match_operand:BLK 0 "" "")
22314         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22315   "TARGET_SSE || TARGET_3DNOW_A"
22316   "sfence"
22317   [(set_attr "type" "sse")
22318    (set_attr "memory" "unknown")])
22320 (define_expand "sse_prologue_save"
22321   [(parallel [(set (match_operand:BLK 0 "" "")
22322                    (unspec:BLK [(reg:DI 21)
22323                                 (reg:DI 22)
22324                                 (reg:DI 23)
22325                                 (reg:DI 24)
22326                                 (reg:DI 25)
22327                                 (reg:DI 26)
22328                                 (reg:DI 27)
22329                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22330               (use (match_operand:DI 1 "register_operand" ""))
22331               (use (match_operand:DI 2 "immediate_operand" ""))
22332               (use (label_ref:DI (match_operand 3 "" "")))])]
22333   "TARGET_64BIT"
22334   "")
22336 (define_insn "*sse_prologue_save_insn"
22337   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22338                           (match_operand:DI 4 "const_int_operand" "n")))
22339         (unspec:BLK [(reg:DI 21)
22340                      (reg:DI 22)
22341                      (reg:DI 23)
22342                      (reg:DI 24)
22343                      (reg:DI 25)
22344                      (reg:DI 26)
22345                      (reg:DI 27)
22346                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22347    (use (match_operand:DI 1 "register_operand" "r"))
22348    (use (match_operand:DI 2 "const_int_operand" "i"))
22349    (use (label_ref:DI (match_operand 3 "" "X")))]
22350   "TARGET_64BIT
22351    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22352    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22353   "*
22355   int i;
22356   operands[0] = gen_rtx_MEM (Pmode,
22357                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22358   output_asm_insn (\"jmp\\t%A1\", operands);
22359   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22360     {
22361       operands[4] = adjust_address (operands[0], DImode, i*16);
22362       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22363       PUT_MODE (operands[4], TImode);
22364       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22365         output_asm_insn (\"rex\", operands);
22366       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22367     }
22368   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22369                              CODE_LABEL_NUMBER (operands[3]));
22370   RET;
22372   "
22373   [(set_attr "type" "other")
22374    (set_attr "length_immediate" "0")
22375    (set_attr "length_address" "0")
22376    (set_attr "length" "135")
22377    (set_attr "memory" "store")
22378    (set_attr "modrm" "0")
22379    (set_attr "mode" "DI")])
22381 ;; 3Dnow! instructions
22383 (define_insn "addv2sf3"
22384   [(set (match_operand:V2SF 0 "register_operand" "=y")
22385         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22386                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22387   "TARGET_3DNOW"
22388   "pfadd\\t{%2, %0|%0, %2}"
22389   [(set_attr "type" "mmxadd")
22390    (set_attr "mode" "V2SF")])
22392 (define_insn "subv2sf3"
22393   [(set (match_operand:V2SF 0 "register_operand" "=y")
22394         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22395                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22396   "TARGET_3DNOW"
22397   "pfsub\\t{%2, %0|%0, %2}"
22398   [(set_attr "type" "mmxadd")
22399    (set_attr "mode" "V2SF")])
22401 (define_insn "subrv2sf3"
22402   [(set (match_operand:V2SF 0 "register_operand" "=y")
22403         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22404                     (match_operand:V2SF 1 "register_operand" "0")))]
22405   "TARGET_3DNOW"
22406   "pfsubr\\t{%2, %0|%0, %2}"
22407   [(set_attr "type" "mmxadd")
22408    (set_attr "mode" "V2SF")])
22410 (define_insn "gtv2sf3"
22411   [(set (match_operand:V2SI 0 "register_operand" "=y")
22412         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22413                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22414  "TARGET_3DNOW"
22415   "pfcmpgt\\t{%2, %0|%0, %2}"
22416   [(set_attr "type" "mmxcmp")
22417    (set_attr "mode" "V2SF")])
22419 (define_insn "gev2sf3"
22420   [(set (match_operand:V2SI 0 "register_operand" "=y")
22421         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22422                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22423   "TARGET_3DNOW"
22424   "pfcmpge\\t{%2, %0|%0, %2}"
22425   [(set_attr "type" "mmxcmp")
22426    (set_attr "mode" "V2SF")])
22428 (define_insn "eqv2sf3"
22429   [(set (match_operand:V2SI 0 "register_operand" "=y")
22430         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22431                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22432   "TARGET_3DNOW"
22433   "pfcmpeq\\t{%2, %0|%0, %2}"
22434   [(set_attr "type" "mmxcmp")
22435    (set_attr "mode" "V2SF")])
22437 (define_insn "pfmaxv2sf3"
22438   [(set (match_operand:V2SF 0 "register_operand" "=y")
22439         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22440                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22441   "TARGET_3DNOW"
22442   "pfmax\\t{%2, %0|%0, %2}"
22443   [(set_attr "type" "mmxadd")
22444    (set_attr "mode" "V2SF")])
22446 (define_insn "pfminv2sf3"
22447   [(set (match_operand:V2SF 0 "register_operand" "=y")
22448         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22449                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22450   "TARGET_3DNOW"
22451   "pfmin\\t{%2, %0|%0, %2}"
22452   [(set_attr "type" "mmxadd")
22453    (set_attr "mode" "V2SF")])
22455 (define_insn "mulv2sf3"
22456   [(set (match_operand:V2SF 0 "register_operand" "=y")
22457         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22458                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22459   "TARGET_3DNOW"
22460   "pfmul\\t{%2, %0|%0, %2}"
22461   [(set_attr "type" "mmxmul")
22462    (set_attr "mode" "V2SF")])
22464 (define_insn "femms"
22465   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22466    (clobber (reg:XF 8))
22467    (clobber (reg:XF 9))
22468    (clobber (reg:XF 10))
22469    (clobber (reg:XF 11))
22470    (clobber (reg:XF 12))
22471    (clobber (reg:XF 13))
22472    (clobber (reg:XF 14))
22473    (clobber (reg:XF 15))
22474    (clobber (reg:DI 29))
22475    (clobber (reg:DI 30))
22476    (clobber (reg:DI 31))
22477    (clobber (reg:DI 32))
22478    (clobber (reg:DI 33))
22479    (clobber (reg:DI 34))
22480    (clobber (reg:DI 35))
22481    (clobber (reg:DI 36))]
22482   "TARGET_3DNOW"
22483   "femms"
22484   [(set_attr "type" "mmx")
22485    (set_attr "memory" "none")]) 
22487 (define_insn "pf2id"
22488   [(set (match_operand:V2SI 0 "register_operand" "=y")
22489         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22490   "TARGET_3DNOW"
22491   "pf2id\\t{%1, %0|%0, %1}"
22492   [(set_attr "type" "mmxcvt")
22493    (set_attr "mode" "V2SF")])
22495 (define_insn "pf2iw"
22496   [(set (match_operand:V2SI 0 "register_operand" "=y")
22497         (sign_extend:V2SI
22498            (ss_truncate:V2HI
22499               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22500   "TARGET_3DNOW_A"
22501   "pf2iw\\t{%1, %0|%0, %1}"
22502   [(set_attr "type" "mmxcvt")
22503    (set_attr "mode" "V2SF")])
22505 (define_insn "pfacc"
22506   [(set (match_operand:V2SF 0 "register_operand" "=y")
22507         (vec_concat:V2SF
22508            (plus:SF
22509               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22510                              (parallel [(const_int  0)]))
22511               (vec_select:SF (match_dup 1)
22512                              (parallel [(const_int 1)])))
22513            (plus:SF
22514               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22515                              (parallel [(const_int  0)]))
22516               (vec_select:SF (match_dup 2)
22517                              (parallel [(const_int 1)])))))]
22518   "TARGET_3DNOW"
22519   "pfacc\\t{%2, %0|%0, %2}"
22520   [(set_attr "type" "mmxadd")
22521    (set_attr "mode" "V2SF")])
22523 (define_insn "pfnacc"
22524   [(set (match_operand:V2SF 0 "register_operand" "=y")
22525         (vec_concat:V2SF
22526            (minus:SF
22527               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22528                              (parallel [(const_int 0)]))
22529               (vec_select:SF (match_dup 1)
22530                              (parallel [(const_int 1)])))
22531            (minus:SF
22532               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22533                              (parallel [(const_int  0)]))
22534               (vec_select:SF (match_dup 2)
22535                              (parallel [(const_int 1)])))))]
22536   "TARGET_3DNOW_A"
22537   "pfnacc\\t{%2, %0|%0, %2}"
22538   [(set_attr "type" "mmxadd")
22539    (set_attr "mode" "V2SF")])
22541 (define_insn "pfpnacc"
22542   [(set (match_operand:V2SF 0 "register_operand" "=y")
22543         (vec_concat:V2SF
22544            (minus:SF
22545               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22546                              (parallel [(const_int 0)]))
22547               (vec_select:SF (match_dup 1)
22548                              (parallel [(const_int 1)])))
22549            (plus:SF
22550               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22551                              (parallel [(const_int 0)]))
22552               (vec_select:SF (match_dup 2)
22553                              (parallel [(const_int 1)])))))]
22554   "TARGET_3DNOW_A"
22555   "pfpnacc\\t{%2, %0|%0, %2}"
22556   [(set_attr "type" "mmxadd")
22557    (set_attr "mode" "V2SF")])
22559 (define_insn "pi2fw"
22560   [(set (match_operand:V2SF 0 "register_operand" "=y")
22561         (float:V2SF
22562            (vec_concat:V2SI
22563               (sign_extend:SI
22564                  (truncate:HI
22565                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22566                                    (parallel [(const_int 0)]))))
22567               (sign_extend:SI
22568                  (truncate:HI
22569                     (vec_select:SI (match_dup 1)
22570                                    (parallel [(const_int  1)])))))))]
22571   "TARGET_3DNOW_A"
22572   "pi2fw\\t{%1, %0|%0, %1}"
22573   [(set_attr "type" "mmxcvt")
22574    (set_attr "mode" "V2SF")])
22576 (define_insn "floatv2si2"
22577   [(set (match_operand:V2SF 0 "register_operand" "=y")
22578         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22579   "TARGET_3DNOW"
22580   "pi2fd\\t{%1, %0|%0, %1}"
22581   [(set_attr "type" "mmxcvt")
22582    (set_attr "mode" "V2SF")])
22584 ;; This insn is identical to pavgb in operation, but the opcode is
22585 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22587 (define_insn "pavgusb"
22588  [(set (match_operand:V8QI 0 "register_operand" "=y")
22589        (unspec:V8QI
22590           [(match_operand:V8QI 1 "register_operand" "0")
22591            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22592           UNSPEC_PAVGUSB))]
22593   "TARGET_3DNOW"
22594   "pavgusb\\t{%2, %0|%0, %2}"
22595   [(set_attr "type" "mmxshft")
22596    (set_attr "mode" "TI")])
22598 ;; 3DNow reciprocal and sqrt
22600 (define_insn "pfrcpv2sf2"
22601   [(set (match_operand:V2SF 0 "register_operand" "=y")
22602         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22603         UNSPEC_PFRCP))]
22604   "TARGET_3DNOW"
22605   "pfrcp\\t{%1, %0|%0, %1}"
22606   [(set_attr "type" "mmx")
22607    (set_attr "mode" "TI")])
22609 (define_insn "pfrcpit1v2sf3"
22610   [(set (match_operand:V2SF 0 "register_operand" "=y")
22611         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22612                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22613                      UNSPEC_PFRCPIT1))]
22614   "TARGET_3DNOW"
22615   "pfrcpit1\\t{%2, %0|%0, %2}"
22616   [(set_attr "type" "mmx")
22617    (set_attr "mode" "TI")])
22619 (define_insn "pfrcpit2v2sf3"
22620   [(set (match_operand:V2SF 0 "register_operand" "=y")
22621         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22622                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22623                      UNSPEC_PFRCPIT2))]
22624   "TARGET_3DNOW"
22625   "pfrcpit2\\t{%2, %0|%0, %2}"
22626   [(set_attr "type" "mmx")
22627    (set_attr "mode" "TI")])
22629 (define_insn "pfrsqrtv2sf2"
22630   [(set (match_operand:V2SF 0 "register_operand" "=y")
22631         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22632                      UNSPEC_PFRSQRT))]
22633   "TARGET_3DNOW"
22634   "pfrsqrt\\t{%1, %0|%0, %1}"
22635   [(set_attr "type" "mmx")
22636    (set_attr "mode" "TI")])
22637                 
22638 (define_insn "pfrsqit1v2sf3"
22639   [(set (match_operand:V2SF 0 "register_operand" "=y")
22640         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22641                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22642                      UNSPEC_PFRSQIT1))]
22643   "TARGET_3DNOW"
22644   "pfrsqit1\\t{%2, %0|%0, %2}"
22645   [(set_attr "type" "mmx")
22646    (set_attr "mode" "TI")])
22648 (define_insn "pmulhrwv4hi3"
22649   [(set (match_operand:V4HI 0 "register_operand" "=y")
22650         (truncate:V4HI
22651            (lshiftrt:V4SI
22652               (plus:V4SI
22653                  (mult:V4SI
22654                     (sign_extend:V4SI
22655                        (match_operand:V4HI 1 "register_operand" "0"))
22656                     (sign_extend:V4SI
22657                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22658                  (const_vector:V4SI [(const_int 32768)
22659                                      (const_int 32768)
22660                                      (const_int 32768)
22661                                      (const_int 32768)]))
22662               (const_int 16))))]
22663   "TARGET_3DNOW"
22664   "pmulhrw\\t{%2, %0|%0, %2}"
22665   [(set_attr "type" "mmxmul")
22666    (set_attr "mode" "TI")])
22668 (define_insn "pswapdv2si2"
22669   [(set (match_operand:V2SI 0 "register_operand" "=y")
22670         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22671                          (parallel [(const_int 1) (const_int 0)])))]
22672   "TARGET_3DNOW_A"
22673   "pswapd\\t{%1, %0|%0, %1}"
22674   [(set_attr "type" "mmxcvt")
22675    (set_attr "mode" "TI")])
22677 (define_insn "pswapdv2sf2"
22678   [(set (match_operand:V2SF 0 "register_operand" "=y")
22679         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22680                          (parallel [(const_int 1) (const_int 0)])))]
22681   "TARGET_3DNOW_A"
22682   "pswapd\\t{%1, %0|%0, %1}"
22683   [(set_attr "type" "mmxcvt")
22684    (set_attr "mode" "TI")])
22686 (define_expand "prefetch"
22687   [(prefetch (match_operand 0 "address_operand" "")
22688              (match_operand:SI 1 "const_int_operand" "")
22689              (match_operand:SI 2 "const_int_operand" ""))]
22690   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22692   int rw = INTVAL (operands[1]);
22693   int locality = INTVAL (operands[2]);
22695   if (rw != 0 && rw != 1)
22696     abort ();
22697   if (locality < 0 || locality > 3)
22698     abort ();
22699   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22700     abort ();
22702   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22703      suported by SSE counterpart or the SSE prefetch is not available
22704      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22705      of locality.  */
22706   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22707     operands[2] = GEN_INT (3);
22708   else
22709     operands[1] = const0_rtx;
22712 (define_insn "*prefetch_sse"
22713   [(prefetch (match_operand:SI 0 "address_operand" "p")
22714              (const_int 0)
22715              (match_operand:SI 1 "const_int_operand" ""))]
22716   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22718   static const char * const patterns[4] = {
22719    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22720   };
22722   int locality = INTVAL (operands[1]);
22723   if (locality < 0 || locality > 3)
22724     abort ();
22726   return patterns[locality];  
22728   [(set_attr "type" "sse")
22729    (set_attr "memory" "none")])
22731 (define_insn "*prefetch_sse_rex"
22732   [(prefetch (match_operand:DI 0 "address_operand" "p")
22733              (const_int 0)
22734              (match_operand:SI 1 "const_int_operand" ""))]
22735   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22737   static const char * const patterns[4] = {
22738    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22739   };
22741   int locality = INTVAL (operands[1]);
22742   if (locality < 0 || locality > 3)
22743     abort ();
22745   return patterns[locality];  
22747   [(set_attr "type" "sse")
22748    (set_attr "memory" "none")])
22750 (define_insn "*prefetch_3dnow"
22751   [(prefetch (match_operand:SI 0 "address_operand" "p")
22752              (match_operand:SI 1 "const_int_operand" "n")
22753              (const_int 3))]
22754   "TARGET_3DNOW && !TARGET_64BIT"
22756   if (INTVAL (operands[1]) == 0)
22757     return "prefetch\t%a0";
22758   else
22759     return "prefetchw\t%a0";
22761   [(set_attr "type" "mmx")
22762    (set_attr "memory" "none")])
22764 (define_insn "*prefetch_3dnow_rex"
22765   [(prefetch (match_operand:DI 0 "address_operand" "p")
22766              (match_operand:SI 1 "const_int_operand" "n")
22767              (const_int 3))]
22768   "TARGET_3DNOW && TARGET_64BIT"
22770   if (INTVAL (operands[1]) == 0)
22771     return "prefetch\t%a0";
22772   else
22773     return "prefetchw\t%a0";
22775   [(set_attr "type" "mmx")
22776    (set_attr "memory" "none")])
22778 ;; SSE2 support
22780 (define_insn "addv2df3"
22781   [(set (match_operand:V2DF 0 "register_operand" "=x")
22782         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22783                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22784   "TARGET_SSE2"
22785   "addpd\t{%2, %0|%0, %2}"
22786   [(set_attr "type" "sseadd")
22787    (set_attr "mode" "V2DF")])
22789 (define_insn "vmaddv2df3"
22790   [(set (match_operand:V2DF 0 "register_operand" "=x")
22791         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22792                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22793                         (match_dup 1)
22794                         (const_int 1)))]
22795   "TARGET_SSE2"
22796   "addsd\t{%2, %0|%0, %2}"
22797   [(set_attr "type" "sseadd")
22798    (set_attr "mode" "DF")])
22800 (define_insn "subv2df3"
22801   [(set (match_operand:V2DF 0 "register_operand" "=x")
22802         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22803                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22804   "TARGET_SSE2"
22805   "subpd\t{%2, %0|%0, %2}"
22806   [(set_attr "type" "sseadd")
22807    (set_attr "mode" "V2DF")])
22809 (define_insn "vmsubv2df3"
22810   [(set (match_operand:V2DF 0 "register_operand" "=x")
22811         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22812                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22813                         (match_dup 1)
22814                         (const_int 1)))]
22815   "TARGET_SSE2"
22816   "subsd\t{%2, %0|%0, %2}"
22817   [(set_attr "type" "sseadd")
22818    (set_attr "mode" "DF")])
22820 (define_insn "mulv2df3"
22821   [(set (match_operand:V2DF 0 "register_operand" "=x")
22822         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22823                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22824   "TARGET_SSE2"
22825   "mulpd\t{%2, %0|%0, %2}"
22826   [(set_attr "type" "ssemul")
22827    (set_attr "mode" "V2DF")])
22829 (define_insn "vmmulv2df3"
22830   [(set (match_operand:V2DF 0 "register_operand" "=x")
22831         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22832                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22833                         (match_dup 1)
22834                         (const_int 1)))]
22835   "TARGET_SSE2"
22836   "mulsd\t{%2, %0|%0, %2}"
22837   [(set_attr "type" "ssemul")
22838    (set_attr "mode" "DF")])
22840 (define_insn "divv2df3"
22841   [(set (match_operand:V2DF 0 "register_operand" "=x")
22842         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22843                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22844   "TARGET_SSE2"
22845   "divpd\t{%2, %0|%0, %2}"
22846   [(set_attr "type" "ssediv")
22847    (set_attr "mode" "V2DF")])
22849 (define_insn "vmdivv2df3"
22850   [(set (match_operand:V2DF 0 "register_operand" "=x")
22851         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22852                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22853                         (match_dup 1)
22854                         (const_int 1)))]
22855   "TARGET_SSE2"
22856   "divsd\t{%2, %0|%0, %2}"
22857   [(set_attr "type" "ssediv")
22858    (set_attr "mode" "DF")])
22860 ;; SSE min/max
22862 (define_insn "smaxv2df3"
22863   [(set (match_operand:V2DF 0 "register_operand" "=x")
22864         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22865                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22866   "TARGET_SSE2"
22867   "maxpd\t{%2, %0|%0, %2}"
22868   [(set_attr "type" "sseadd")
22869    (set_attr "mode" "V2DF")])
22871 (define_insn "vmsmaxv2df3"
22872   [(set (match_operand:V2DF 0 "register_operand" "=x")
22873         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22874                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22875                         (match_dup 1)
22876                         (const_int 1)))]
22877   "TARGET_SSE2"
22878   "maxsd\t{%2, %0|%0, %2}"
22879   [(set_attr "type" "sseadd")
22880    (set_attr "mode" "DF")])
22882 (define_insn "sminv2df3"
22883   [(set (match_operand:V2DF 0 "register_operand" "=x")
22884         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22885                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22886   "TARGET_SSE2"
22887   "minpd\t{%2, %0|%0, %2}"
22888   [(set_attr "type" "sseadd")
22889    (set_attr "mode" "V2DF")])
22891 (define_insn "vmsminv2df3"
22892   [(set (match_operand:V2DF 0 "register_operand" "=x")
22893         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22894                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22895                         (match_dup 1)
22896                         (const_int 1)))]
22897   "TARGET_SSE2"
22898   "minsd\t{%2, %0|%0, %2}"
22899   [(set_attr "type" "sseadd")
22900    (set_attr "mode" "DF")])
22901 ;; SSE2 square root.  There doesn't appear to be an extension for the
22902 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22904 (define_insn "sqrtv2df2"
22905   [(set (match_operand:V2DF 0 "register_operand" "=x")
22906         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22907   "TARGET_SSE2"
22908   "sqrtpd\t{%1, %0|%0, %1}"
22909   [(set_attr "type" "sse")
22910    (set_attr "mode" "V2DF")])
22912 (define_insn "vmsqrtv2df2"
22913   [(set (match_operand:V2DF 0 "register_operand" "=x")
22914         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22915                         (match_operand:V2DF 2 "register_operand" "0")
22916                         (const_int 1)))]
22917   "TARGET_SSE2"
22918   "sqrtsd\t{%1, %0|%0, %1}"
22919   [(set_attr "type" "sse")
22920    (set_attr "mode" "SF")])
22922 ;; SSE mask-generating compares
22924 (define_insn "maskcmpv2df3"
22925   [(set (match_operand:V2DI 0 "register_operand" "=x")
22926         (match_operator:V2DI 3 "sse_comparison_operator"
22927                              [(match_operand:V2DF 1 "register_operand" "0")
22928                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22929   "TARGET_SSE2"
22930   "cmp%D3pd\t{%2, %0|%0, %2}"
22931   [(set_attr "type" "ssecmp")
22932    (set_attr "mode" "V2DF")])
22934 (define_insn "maskncmpv2df3"
22935   [(set (match_operand:V2DI 0 "register_operand" "=x")
22936         (not:V2DI
22937          (match_operator:V2DI 3 "sse_comparison_operator"
22938                               [(match_operand:V2DF 1 "register_operand" "0")
22939                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22940   "TARGET_SSE2"
22942   if (GET_CODE (operands[3]) == UNORDERED)
22943     return "cmpordps\t{%2, %0|%0, %2}";
22944   else
22945     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22947   [(set_attr "type" "ssecmp")
22948    (set_attr "mode" "V2DF")])
22950 (define_insn "vmmaskcmpv2df3"
22951   [(set (match_operand:V2DI 0 "register_operand" "=x")
22952         (vec_merge:V2DI
22953          (match_operator:V2DI 3 "sse_comparison_operator"
22954                               [(match_operand:V2DF 1 "register_operand" "0")
22955                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22956          (subreg:V2DI (match_dup 1) 0)
22957          (const_int 1)))]
22958   "TARGET_SSE2"
22959   "cmp%D3sd\t{%2, %0|%0, %2}"
22960   [(set_attr "type" "ssecmp")
22961    (set_attr "mode" "DF")])
22963 (define_insn "vmmaskncmpv2df3"
22964   [(set (match_operand:V2DI 0 "register_operand" "=x")
22965         (vec_merge:V2DI
22966          (not:V2DI
22967           (match_operator:V2DI 3 "sse_comparison_operator"
22968                                [(match_operand:V2DF 1 "register_operand" "0")
22969                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22970          (subreg:V2DI (match_dup 1) 0)
22971          (const_int 1)))]
22972   "TARGET_SSE2"
22974   if (GET_CODE (operands[3]) == UNORDERED)
22975     return "cmpordsd\t{%2, %0|%0, %2}";
22976   else
22977     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22979   [(set_attr "type" "ssecmp")
22980    (set_attr "mode" "DF")])
22982 (define_insn "sse2_comi"
22983   [(set (reg:CCFP FLAGS_REG)
22984         (compare:CCFP (vec_select:DF
22985                        (match_operand:V2DF 0 "register_operand" "x")
22986                        (parallel [(const_int 0)]))
22987                       (vec_select:DF
22988                        (match_operand:V2DF 1 "register_operand" "x")
22989                        (parallel [(const_int 0)]))))]
22990   "TARGET_SSE2"
22991   "comisd\t{%1, %0|%0, %1}"
22992   [(set_attr "type" "ssecomi")
22993    (set_attr "mode" "DF")])
22995 (define_insn "sse2_ucomi"
22996   [(set (reg:CCFPU FLAGS_REG)
22997         (compare:CCFPU (vec_select:DF
22998                          (match_operand:V2DF 0 "register_operand" "x")
22999                          (parallel [(const_int 0)]))
23000                         (vec_select:DF
23001                          (match_operand:V2DF 1 "register_operand" "x")
23002                          (parallel [(const_int 0)]))))]
23003   "TARGET_SSE2"
23004   "ucomisd\t{%1, %0|%0, %1}"
23005   [(set_attr "type" "ssecomi")
23006    (set_attr "mode" "DF")])
23008 ;; SSE Strange Moves.
23010 (define_insn "sse2_movmskpd"
23011   [(set (match_operand:SI 0 "register_operand" "=r")
23012         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
23013                    UNSPEC_MOVMSK))]
23014   "TARGET_SSE2"
23015   "movmskpd\t{%1, %0|%0, %1}"
23016   [(set_attr "type" "ssecvt")
23017    (set_attr "mode" "V2DF")])
23019 (define_insn "sse2_pmovmskb"
23020   [(set (match_operand:SI 0 "register_operand" "=r")
23021         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
23022                    UNSPEC_MOVMSK))]
23023   "TARGET_SSE2"
23024   "pmovmskb\t{%1, %0|%0, %1}"
23025   [(set_attr "type" "ssecvt")
23026    (set_attr "mode" "V2DF")])
23028 (define_insn "sse2_maskmovdqu"
23029   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
23030         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23031                        (match_operand:V16QI 2 "register_operand" "x")]
23032                       UNSPEC_MASKMOV))]
23033   "TARGET_SSE2"
23034   ;; @@@ check ordering of operands in intel/nonintel syntax
23035   "maskmovdqu\t{%2, %1|%1, %2}"
23036   [(set_attr "type" "ssecvt")
23037    (set_attr "mode" "TI")])
23039 (define_insn "sse2_maskmovdqu_rex64"
23040   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
23041         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23042                        (match_operand:V16QI 2 "register_operand" "x")]
23043                       UNSPEC_MASKMOV))]
23044   "TARGET_SSE2"
23045   ;; @@@ check ordering of operands in intel/nonintel syntax
23046   "maskmovdqu\t{%2, %1|%1, %2}"
23047   [(set_attr "type" "ssecvt")
23048    (set_attr "mode" "TI")])
23050 (define_insn "sse2_movntv2df"
23051   [(set (match_operand:V2DF 0 "memory_operand" "=m")
23052         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
23053                      UNSPEC_MOVNT))]
23054   "TARGET_SSE2"
23055   "movntpd\t{%1, %0|%0, %1}"
23056   [(set_attr "type" "ssecvt")
23057    (set_attr "mode" "V2DF")])
23059 (define_insn "sse2_movntv2di"
23060   [(set (match_operand:V2DI 0 "memory_operand" "=m")
23061         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
23062                      UNSPEC_MOVNT))]
23063   "TARGET_SSE2"
23064   "movntdq\t{%1, %0|%0, %1}"
23065   [(set_attr "type" "ssecvt")
23066    (set_attr "mode" "TI")])
23068 (define_insn "sse2_movntsi"
23069   [(set (match_operand:SI 0 "memory_operand" "=m")
23070         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
23071                    UNSPEC_MOVNT))]
23072   "TARGET_SSE2"
23073   "movnti\t{%1, %0|%0, %1}"
23074   [(set_attr "type" "ssecvt")
23075    (set_attr "mode" "V2DF")])
23077 ;; SSE <-> integer/MMX conversions
23079 ;; Conversions between SI and SF
23081 (define_insn "cvtdq2ps"
23082   [(set (match_operand:V4SF 0 "register_operand" "=x")
23083         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
23084   "TARGET_SSE2"
23085   "cvtdq2ps\t{%1, %0|%0, %1}"
23086   [(set_attr "type" "ssecvt")
23087    (set_attr "mode" "V2DF")])
23089 (define_insn "cvtps2dq"
23090   [(set (match_operand:V4SI 0 "register_operand" "=x")
23091         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
23092   "TARGET_SSE2"
23093   "cvtps2dq\t{%1, %0|%0, %1}"
23094   [(set_attr "type" "ssecvt")
23095    (set_attr "mode" "TI")])
23097 (define_insn "cvttps2dq"
23098   [(set (match_operand:V4SI 0 "register_operand" "=x")
23099         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
23100                      UNSPEC_FIX))]
23101   "TARGET_SSE2"
23102   "cvttps2dq\t{%1, %0|%0, %1}"
23103   [(set_attr "type" "ssecvt")
23104    (set_attr "mode" "TI")])
23106 ;; Conversions between SI and DF
23108 (define_insn "cvtdq2pd"
23109   [(set (match_operand:V2DF 0 "register_operand" "=x")
23110         (float:V2DF (vec_select:V2SI
23111                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
23112                      (parallel
23113                       [(const_int 0)
23114                        (const_int 1)]))))]
23115   "TARGET_SSE2"
23116   "cvtdq2pd\t{%1, %0|%0, %1}"
23117   [(set_attr "type" "ssecvt")
23118    (set_attr "mode" "V2DF")])
23120 (define_insn "cvtpd2dq"
23121   [(set (match_operand:V4SI 0 "register_operand" "=x")
23122         (vec_concat:V4SI
23123          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
23124          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23125   "TARGET_SSE2"
23126   "cvtpd2dq\t{%1, %0|%0, %1}"
23127   [(set_attr "type" "ssecvt")
23128    (set_attr "mode" "TI")])
23130 (define_insn "cvttpd2dq"
23131   [(set (match_operand:V4SI 0 "register_operand" "=x")
23132         (vec_concat:V4SI
23133          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23134                       UNSPEC_FIX)
23135          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23136   "TARGET_SSE2"
23137   "cvttpd2dq\t{%1, %0|%0, %1}"
23138   [(set_attr "type" "ssecvt")
23139    (set_attr "mode" "TI")])
23141 (define_insn "cvtpd2pi"
23142   [(set (match_operand:V2SI 0 "register_operand" "=y")
23143         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
23144   "TARGET_SSE2"
23145   "cvtpd2pi\t{%1, %0|%0, %1}"
23146   [(set_attr "type" "ssecvt")
23147    (set_attr "mode" "TI")])
23149 (define_insn "cvttpd2pi"
23150   [(set (match_operand:V2SI 0 "register_operand" "=y")
23151         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23152                      UNSPEC_FIX))]
23153   "TARGET_SSE2"
23154   "cvttpd2pi\t{%1, %0|%0, %1}"
23155   [(set_attr "type" "ssecvt")
23156    (set_attr "mode" "TI")])
23158 (define_insn "cvtpi2pd"
23159   [(set (match_operand:V2DF 0 "register_operand" "=x")
23160         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
23161   "TARGET_SSE2"
23162   "cvtpi2pd\t{%1, %0|%0, %1}"
23163   [(set_attr "type" "ssecvt")
23164    (set_attr "mode" "TI")])
23166 ;; Conversions between SI and DF
23168 (define_insn "cvtsd2si"
23169   [(set (match_operand:SI 0 "register_operand" "=r,r")
23170         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23171                                (parallel [(const_int 0)]))))]
23172   "TARGET_SSE2"
23173   "cvtsd2si\t{%1, %0|%0, %1}"
23174   [(set_attr "type" "sseicvt")
23175    (set_attr "athlon_decode" "double,vector")
23176    (set_attr "mode" "SI")])
23178 (define_insn "cvtsd2siq"
23179   [(set (match_operand:DI 0 "register_operand" "=r,r")
23180         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23181                                (parallel [(const_int 0)]))))]
23182   "TARGET_SSE2 && TARGET_64BIT"
23183   "cvtsd2siq\t{%1, %0|%0, %1}"
23184   [(set_attr "type" "sseicvt")
23185    (set_attr "athlon_decode" "double,vector")
23186    (set_attr "mode" "DI")])
23188 (define_insn "cvttsd2si"
23189   [(set (match_operand:SI 0 "register_operand" "=r,r")
23190         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23191                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23192   "TARGET_SSE2"
23193   "cvttsd2si\t{%1, %0|%0, %1}"
23194   [(set_attr "type" "sseicvt")
23195    (set_attr "mode" "SI")
23196    (set_attr "athlon_decode" "double,vector")])
23198 (define_insn "cvttsd2siq"
23199   [(set (match_operand:DI 0 "register_operand" "=r,r")
23200         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23201                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23202   "TARGET_SSE2 && TARGET_64BIT"
23203   "cvttsd2siq\t{%1, %0|%0, %1}"
23204   [(set_attr "type" "sseicvt")
23205    (set_attr "mode" "DI")
23206    (set_attr "athlon_decode" "double,vector")])
23208 (define_insn "cvtsi2sd"
23209   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23210         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23211                         (vec_duplicate:V2DF
23212                           (float:DF
23213                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
23214                         (const_int 2)))]
23215   "TARGET_SSE2"
23216   "cvtsi2sd\t{%2, %0|%0, %2}"
23217   [(set_attr "type" "sseicvt")
23218    (set_attr "mode" "DF")
23219    (set_attr "athlon_decode" "double,direct")])
23221 (define_insn "cvtsi2sdq"
23222   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23223         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23224                         (vec_duplicate:V2DF
23225                           (float:DF
23226                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
23227                         (const_int 2)))]
23228   "TARGET_SSE2 && TARGET_64BIT"
23229   "cvtsi2sdq\t{%2, %0|%0, %2}"
23230   [(set_attr "type" "sseicvt")
23231    (set_attr "mode" "DF")
23232    (set_attr "athlon_decode" "double,direct")])
23234 ;; Conversions between SF and DF
23236 (define_insn "cvtsd2ss"
23237   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
23238         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
23239                         (vec_duplicate:V4SF
23240                           (float_truncate:V2SF
23241                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
23242                         (const_int 14)))]
23243   "TARGET_SSE2"
23244   "cvtsd2ss\t{%2, %0|%0, %2}"
23245   [(set_attr "type" "ssecvt")
23246    (set_attr "athlon_decode" "vector,double")
23247    (set_attr "mode" "SF")])
23249 (define_insn "cvtss2sd"
23250   [(set (match_operand:V2DF 0 "register_operand" "=x")
23251         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23252                         (float_extend:V2DF
23253                           (vec_select:V2SF
23254                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23255                             (parallel [(const_int 0)
23256                                        (const_int 1)])))
23257                         (const_int 2)))]
23258   "TARGET_SSE2"
23259   "cvtss2sd\t{%2, %0|%0, %2}"
23260   [(set_attr "type" "ssecvt")
23261    (set_attr "mode" "DF")])
23263 (define_insn "cvtpd2ps"
23264   [(set (match_operand:V4SF 0 "register_operand" "=x")
23265         (subreg:V4SF
23266           (vec_concat:V4SI
23267             (subreg:V2SI (float_truncate:V2SF
23268                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23269             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23270   "TARGET_SSE2"
23271   "cvtpd2ps\t{%1, %0|%0, %1}"
23272   [(set_attr "type" "ssecvt")
23273    (set_attr "mode" "V4SF")])
23275 (define_insn "cvtps2pd"
23276   [(set (match_operand:V2DF 0 "register_operand" "=x")
23277         (float_extend:V2DF
23278           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23279                            (parallel [(const_int 0)
23280                                       (const_int 1)]))))]
23281   "TARGET_SSE2"
23282   "cvtps2pd\t{%1, %0|%0, %1}"
23283   [(set_attr "type" "ssecvt")
23284    (set_attr "mode" "V2DF")])
23286 ;; SSE2 variants of MMX insns
23288 ;; MMX arithmetic
23290 (define_insn "addv16qi3"
23291   [(set (match_operand:V16QI 0 "register_operand" "=x")
23292         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23293                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23294   "TARGET_SSE2"
23295   "paddb\t{%2, %0|%0, %2}"
23296   [(set_attr "type" "sseiadd")
23297    (set_attr "mode" "TI")])
23299 (define_insn "addv8hi3"
23300   [(set (match_operand:V8HI 0 "register_operand" "=x")
23301         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23302                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23303   "TARGET_SSE2"
23304   "paddw\t{%2, %0|%0, %2}"
23305   [(set_attr "type" "sseiadd")
23306    (set_attr "mode" "TI")])
23308 (define_insn "addv4si3"
23309   [(set (match_operand:V4SI 0 "register_operand" "=x")
23310         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23311                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23312   "TARGET_SSE2"
23313   "paddd\t{%2, %0|%0, %2}"
23314   [(set_attr "type" "sseiadd")
23315    (set_attr "mode" "TI")])
23317 (define_insn "addv2di3"
23318   [(set (match_operand:V2DI 0 "register_operand" "=x")
23319         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23320                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23321   "TARGET_SSE2"
23322   "paddq\t{%2, %0|%0, %2}"
23323   [(set_attr "type" "sseiadd")
23324    (set_attr "mode" "TI")])
23326 (define_insn "ssaddv16qi3"
23327   [(set (match_operand:V16QI 0 "register_operand" "=x")
23328         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23329                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23330   "TARGET_SSE2"
23331   "paddsb\t{%2, %0|%0, %2}"
23332   [(set_attr "type" "sseiadd")
23333    (set_attr "mode" "TI")])
23335 (define_insn "ssaddv8hi3"
23336   [(set (match_operand:V8HI 0 "register_operand" "=x")
23337         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23338                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23339   "TARGET_SSE2"
23340   "paddsw\t{%2, %0|%0, %2}"
23341   [(set_attr "type" "sseiadd")
23342    (set_attr "mode" "TI")])
23344 (define_insn "usaddv16qi3"
23345   [(set (match_operand:V16QI 0 "register_operand" "=x")
23346         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23347                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23348   "TARGET_SSE2"
23349   "paddusb\t{%2, %0|%0, %2}"
23350   [(set_attr "type" "sseiadd")
23351    (set_attr "mode" "TI")])
23353 (define_insn "usaddv8hi3"
23354   [(set (match_operand:V8HI 0 "register_operand" "=x")
23355         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23356                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23357   "TARGET_SSE2"
23358   "paddusw\t{%2, %0|%0, %2}"
23359   [(set_attr "type" "sseiadd")
23360    (set_attr "mode" "TI")])
23362 (define_insn "subv16qi3"
23363   [(set (match_operand:V16QI 0 "register_operand" "=x")
23364         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23365                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23366   "TARGET_SSE2"
23367   "psubb\t{%2, %0|%0, %2}"
23368   [(set_attr "type" "sseiadd")
23369    (set_attr "mode" "TI")])
23371 (define_insn "subv8hi3"
23372   [(set (match_operand:V8HI 0 "register_operand" "=x")
23373         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23374                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23375   "TARGET_SSE2"
23376   "psubw\t{%2, %0|%0, %2}"
23377   [(set_attr "type" "sseiadd")
23378    (set_attr "mode" "TI")])
23380 (define_insn "subv4si3"
23381   [(set (match_operand:V4SI 0 "register_operand" "=x")
23382         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23383                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23384   "TARGET_SSE2"
23385   "psubd\t{%2, %0|%0, %2}"
23386   [(set_attr "type" "sseiadd")
23387    (set_attr "mode" "TI")])
23389 (define_insn "subv2di3"
23390   [(set (match_operand:V2DI 0 "register_operand" "=x")
23391         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23392                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23393   "TARGET_SSE2"
23394   "psubq\t{%2, %0|%0, %2}"
23395   [(set_attr "type" "sseiadd")
23396    (set_attr "mode" "TI")])
23398 (define_insn "sssubv16qi3"
23399   [(set (match_operand:V16QI 0 "register_operand" "=x")
23400         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23401                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23402   "TARGET_SSE2"
23403   "psubsb\t{%2, %0|%0, %2}"
23404   [(set_attr "type" "sseiadd")
23405    (set_attr "mode" "TI")])
23407 (define_insn "sssubv8hi3"
23408   [(set (match_operand:V8HI 0 "register_operand" "=x")
23409         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23410                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23411   "TARGET_SSE2"
23412   "psubsw\t{%2, %0|%0, %2}"
23413   [(set_attr "type" "sseiadd")
23414    (set_attr "mode" "TI")])
23416 (define_insn "ussubv16qi3"
23417   [(set (match_operand:V16QI 0 "register_operand" "=x")
23418         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23419                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23420   "TARGET_SSE2"
23421   "psubusb\t{%2, %0|%0, %2}"
23422   [(set_attr "type" "sseiadd")
23423    (set_attr "mode" "TI")])
23425 (define_insn "ussubv8hi3"
23426   [(set (match_operand:V8HI 0 "register_operand" "=x")
23427         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23428                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23429   "TARGET_SSE2"
23430   "psubusw\t{%2, %0|%0, %2}"
23431   [(set_attr "type" "sseiadd")
23432    (set_attr "mode" "TI")])
23434 (define_insn "mulv8hi3"
23435   [(set (match_operand:V8HI 0 "register_operand" "=x")
23436         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23437                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23438   "TARGET_SSE2"
23439   "pmullw\t{%2, %0|%0, %2}"
23440   [(set_attr "type" "sseimul")
23441    (set_attr "mode" "TI")])
23443 (define_insn "smulv8hi3_highpart"
23444   [(set (match_operand:V8HI 0 "register_operand" "=x")
23445         (truncate:V8HI
23446          (lshiftrt:V8SI
23447           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23448                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23449           (const_int 16))))]
23450   "TARGET_SSE2"
23451   "pmulhw\t{%2, %0|%0, %2}"
23452   [(set_attr "type" "sseimul")
23453    (set_attr "mode" "TI")])
23455 (define_insn "umulv8hi3_highpart"
23456   [(set (match_operand:V8HI 0 "register_operand" "=x")
23457         (truncate:V8HI
23458          (lshiftrt:V8SI
23459           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23460                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23461           (const_int 16))))]
23462   "TARGET_SSE2"
23463   "pmulhuw\t{%2, %0|%0, %2}"
23464   [(set_attr "type" "sseimul")
23465    (set_attr "mode" "TI")])
23467 (define_insn "sse2_umulsidi3"
23468   [(set (match_operand:DI 0 "register_operand" "=y")
23469         (mult:DI (zero_extend:DI (vec_select:SI
23470                                   (match_operand:V2SI 1 "register_operand" "0")
23471                                   (parallel [(const_int 0)])))
23472                  (zero_extend:DI (vec_select:SI
23473                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23474                                   (parallel [(const_int 0)])))))]
23475   "TARGET_SSE2"
23476   "pmuludq\t{%2, %0|%0, %2}"
23477   [(set_attr "type" "mmxmul")
23478    (set_attr "mode" "DI")])
23480 (define_insn "sse2_umulv2siv2di3"
23481   [(set (match_operand:V2DI 0 "register_operand" "=x")
23482         (mult:V2DI (zero_extend:V2DI
23483                      (vec_select:V2SI
23484                        (match_operand:V4SI 1 "register_operand" "0")
23485                        (parallel [(const_int 0) (const_int 2)])))
23486                    (zero_extend:V2DI
23487                      (vec_select:V2SI
23488                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23489                        (parallel [(const_int 0) (const_int 2)])))))]
23490   "TARGET_SSE2"
23491   "pmuludq\t{%2, %0|%0, %2}"
23492   [(set_attr "type" "sseimul")
23493    (set_attr "mode" "TI")])
23495 (define_insn "sse2_pmaddwd"
23496   [(set (match_operand:V4SI 0 "register_operand" "=x")
23497         (plus:V4SI
23498          (mult:V4SI
23499           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23500                                              (parallel [(const_int 0)
23501                                                         (const_int 2)
23502                                                         (const_int 4)
23503                                                         (const_int 6)])))
23504           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23505                                              (parallel [(const_int 0)
23506                                                         (const_int 2)
23507                                                         (const_int 4)
23508                                                         (const_int 6)]))))
23509          (mult:V4SI
23510           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23511                                              (parallel [(const_int 1)
23512                                                         (const_int 3)
23513                                                         (const_int 5)
23514                                                         (const_int 7)])))
23515           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23516                                              (parallel [(const_int 1)
23517                                                         (const_int 3)
23518                                                         (const_int 5)
23519                                                         (const_int 7)]))))))]
23520   "TARGET_SSE2"
23521   "pmaddwd\t{%2, %0|%0, %2}"
23522   [(set_attr "type" "sseiadd")
23523    (set_attr "mode" "TI")])
23525 ;; Same as pxor, but don't show input operands so that we don't think
23526 ;; they are live.
23527 (define_insn "sse2_clrti"
23528   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23529   "TARGET_SSE2"
23531   if (get_attr_mode (insn) == MODE_TI)
23532     return "pxor\t%0, %0";
23533   else
23534     return "xorps\t%0, %0";
23536   [(set_attr "type" "ssemov")
23537    (set_attr "memory" "none")
23538    (set (attr "mode")
23539               (if_then_else
23540                 (ne (symbol_ref "optimize_size")
23541                     (const_int 0))
23542                 (const_string "V4SF")
23543                 (const_string "TI")))])
23545 ;; MMX unsigned averages/sum of absolute differences
23547 (define_insn "sse2_uavgv16qi3"
23548   [(set (match_operand:V16QI 0 "register_operand" "=x")
23549         (ashiftrt:V16QI
23550          (plus:V16QI (plus:V16QI
23551                      (match_operand:V16QI 1 "register_operand" "0")
23552                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23553                      (const_vector:V16QI [(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) (const_int 1)
23560                                           (const_int 1) (const_int 1)]))
23561          (const_int 1)))]
23562   "TARGET_SSE2"
23563   "pavgb\t{%2, %0|%0, %2}"
23564   [(set_attr "type" "sseiadd")
23565    (set_attr "mode" "TI")])
23567 (define_insn "sse2_uavgv8hi3"
23568   [(set (match_operand:V8HI 0 "register_operand" "=x")
23569         (ashiftrt:V8HI
23570          (plus:V8HI (plus:V8HI
23571                      (match_operand:V8HI 1 "register_operand" "0")
23572                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23573                     (const_vector:V8HI [(const_int 1) (const_int 1)
23574                                         (const_int 1) (const_int 1)
23575                                         (const_int 1) (const_int 1)
23576                                         (const_int 1) (const_int 1)]))
23577          (const_int 1)))]
23578   "TARGET_SSE2"
23579   "pavgw\t{%2, %0|%0, %2}"
23580   [(set_attr "type" "sseiadd")
23581    (set_attr "mode" "TI")])
23583 ;; @@@ this isn't the right representation.
23584 (define_insn "sse2_psadbw"
23585   [(set (match_operand:V2DI 0 "register_operand" "=x")
23586         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23587                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23588                      UNSPEC_PSADBW))]
23589   "TARGET_SSE2"
23590   "psadbw\t{%2, %0|%0, %2}"
23591   [(set_attr "type" "sseiadd")
23592    (set_attr "mode" "TI")])
23595 ;; MMX insert/extract/shuffle
23597 (define_insn "sse2_pinsrw"
23598   [(set (match_operand:V8HI 0 "register_operand" "=x")
23599         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23600                         (vec_duplicate:V8HI
23601                          (truncate:HI
23602                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23603                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23604   "TARGET_SSE2"
23605   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23606   [(set_attr "type" "ssecvt")
23607    (set_attr "mode" "TI")])
23609 (define_insn "sse2_pextrw"
23610   [(set (match_operand:SI 0 "register_operand" "=r")
23611         (zero_extend:SI
23612           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23613                          (parallel
23614                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23615   "TARGET_SSE2"
23616   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23617   [(set_attr "type" "ssecvt")
23618    (set_attr "mode" "TI")])
23620 (define_insn "sse2_pshufd"
23621   [(set (match_operand:V4SI 0 "register_operand" "=x")
23622         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23623                       (match_operand:SI 2 "immediate_operand" "i")]
23624                      UNSPEC_SHUFFLE))]
23625   "TARGET_SSE2"
23626   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23627   [(set_attr "type" "ssecvt")
23628    (set_attr "mode" "TI")])
23630 (define_insn "sse2_pshuflw"
23631   [(set (match_operand:V8HI 0 "register_operand" "=x")
23632         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23633                       (match_operand:SI 2 "immediate_operand" "i")]
23634                      UNSPEC_PSHUFLW))]
23635   "TARGET_SSE2"
23636   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23637   [(set_attr "type" "ssecvt")
23638    (set_attr "mode" "TI")])
23640 (define_insn "sse2_pshufhw"
23641   [(set (match_operand:V8HI 0 "register_operand" "=x")
23642         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23643                       (match_operand:SI 2 "immediate_operand" "i")]
23644                      UNSPEC_PSHUFHW))]
23645   "TARGET_SSE2"
23646   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23647   [(set_attr "type" "ssecvt")
23648    (set_attr "mode" "TI")])
23650 ;; MMX mask-generating comparisons
23652 (define_insn "eqv16qi3"
23653   [(set (match_operand:V16QI 0 "register_operand" "=x")
23654         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23655                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23656   "TARGET_SSE2"
23657   "pcmpeqb\t{%2, %0|%0, %2}"
23658   [(set_attr "type" "ssecmp")
23659    (set_attr "mode" "TI")])
23661 (define_insn "eqv8hi3"
23662   [(set (match_operand:V8HI 0 "register_operand" "=x")
23663         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23664                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23665   "TARGET_SSE2"
23666   "pcmpeqw\t{%2, %0|%0, %2}"
23667   [(set_attr "type" "ssecmp")
23668    (set_attr "mode" "TI")])
23670 (define_insn "eqv4si3"
23671   [(set (match_operand:V4SI 0 "register_operand" "=x")
23672         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23673                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23674   "TARGET_SSE2"
23675   "pcmpeqd\t{%2, %0|%0, %2}"
23676   [(set_attr "type" "ssecmp")
23677    (set_attr "mode" "TI")])
23679 (define_insn "gtv16qi3"
23680   [(set (match_operand:V16QI 0 "register_operand" "=x")
23681         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23682                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23683   "TARGET_SSE2"
23684   "pcmpgtb\t{%2, %0|%0, %2}"
23685   [(set_attr "type" "ssecmp")
23686    (set_attr "mode" "TI")])
23688 (define_insn "gtv8hi3"
23689   [(set (match_operand:V8HI 0 "register_operand" "=x")
23690         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23691                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23692   "TARGET_SSE2"
23693   "pcmpgtw\t{%2, %0|%0, %2}"
23694   [(set_attr "type" "ssecmp")
23695    (set_attr "mode" "TI")])
23697 (define_insn "gtv4si3"
23698   [(set (match_operand:V4SI 0 "register_operand" "=x")
23699         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23700                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23701   "TARGET_SSE2"
23702   "pcmpgtd\t{%2, %0|%0, %2}"
23703   [(set_attr "type" "ssecmp")
23704    (set_attr "mode" "TI")])
23707 ;; MMX max/min insns
23709 (define_insn "umaxv16qi3"
23710   [(set (match_operand:V16QI 0 "register_operand" "=x")
23711         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23712                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23713   "TARGET_SSE2"
23714   "pmaxub\t{%2, %0|%0, %2}"
23715   [(set_attr "type" "sseiadd")
23716    (set_attr "mode" "TI")])
23718 (define_insn "smaxv8hi3"
23719   [(set (match_operand:V8HI 0 "register_operand" "=x")
23720         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23721                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23722   "TARGET_SSE2"
23723   "pmaxsw\t{%2, %0|%0, %2}"
23724   [(set_attr "type" "sseiadd")
23725    (set_attr "mode" "TI")])
23727 (define_insn "uminv16qi3"
23728   [(set (match_operand:V16QI 0 "register_operand" "=x")
23729         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23730                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23731   "TARGET_SSE2"
23732   "pminub\t{%2, %0|%0, %2}"
23733   [(set_attr "type" "sseiadd")
23734    (set_attr "mode" "TI")])
23736 (define_insn "sminv8hi3"
23737   [(set (match_operand:V8HI 0 "register_operand" "=x")
23738         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23739                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23740   "TARGET_SSE2"
23741   "pminsw\t{%2, %0|%0, %2}"
23742   [(set_attr "type" "sseiadd")
23743    (set_attr "mode" "TI")])
23746 ;; MMX shifts
23748 (define_insn "ashrv8hi3"
23749   [(set (match_operand:V8HI 0 "register_operand" "=x")
23750         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23751                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23752   "TARGET_SSE2"
23753   "psraw\t{%2, %0|%0, %2}"
23754   [(set_attr "type" "sseishft")
23755    (set_attr "mode" "TI")])
23757 (define_insn "ashrv4si3"
23758   [(set (match_operand:V4SI 0 "register_operand" "=x")
23759         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23760                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23761   "TARGET_SSE2"
23762   "psrad\t{%2, %0|%0, %2}"
23763   [(set_attr "type" "sseishft")
23764    (set_attr "mode" "TI")])
23766 (define_insn "lshrv8hi3"
23767   [(set (match_operand:V8HI 0 "register_operand" "=x")
23768         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23769                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23770   "TARGET_SSE2"
23771   "psrlw\t{%2, %0|%0, %2}"
23772   [(set_attr "type" "sseishft")
23773    (set_attr "mode" "TI")])
23775 (define_insn "lshrv4si3"
23776   [(set (match_operand:V4SI 0 "register_operand" "=x")
23777         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23778                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23779   "TARGET_SSE2"
23780   "psrld\t{%2, %0|%0, %2}"
23781   [(set_attr "type" "sseishft")
23782    (set_attr "mode" "TI")])
23784 (define_insn "lshrv2di3"
23785   [(set (match_operand:V2DI 0 "register_operand" "=x")
23786         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23787                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23788   "TARGET_SSE2"
23789   "psrlq\t{%2, %0|%0, %2}"
23790   [(set_attr "type" "sseishft")
23791    (set_attr "mode" "TI")])
23793 (define_insn "ashlv8hi3"
23794   [(set (match_operand:V8HI 0 "register_operand" "=x")
23795         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23796                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23797   "TARGET_SSE2"
23798   "psllw\t{%2, %0|%0, %2}"
23799   [(set_attr "type" "sseishft")
23800    (set_attr "mode" "TI")])
23802 (define_insn "ashlv4si3"
23803   [(set (match_operand:V4SI 0 "register_operand" "=x")
23804         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23805                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23806   "TARGET_SSE2"
23807   "pslld\t{%2, %0|%0, %2}"
23808   [(set_attr "type" "sseishft")
23809    (set_attr "mode" "TI")])
23811 (define_insn "ashlv2di3"
23812   [(set (match_operand:V2DI 0 "register_operand" "=x")
23813         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23814                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23815   "TARGET_SSE2"
23816   "psllq\t{%2, %0|%0, %2}"
23817   [(set_attr "type" "sseishft")
23818    (set_attr "mode" "TI")])
23820 (define_insn "ashrv8hi3_ti"
23821   [(set (match_operand:V8HI 0 "register_operand" "=x")
23822         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23823                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23824   "TARGET_SSE2"
23825   "psraw\t{%2, %0|%0, %2}"
23826   [(set_attr "type" "sseishft")
23827    (set_attr "mode" "TI")])
23829 (define_insn "ashrv4si3_ti"
23830   [(set (match_operand:V4SI 0 "register_operand" "=x")
23831         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23832                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23833   "TARGET_SSE2"
23834   "psrad\t{%2, %0|%0, %2}"
23835   [(set_attr "type" "sseishft")
23836    (set_attr "mode" "TI")])
23838 (define_insn "lshrv8hi3_ti"
23839   [(set (match_operand:V8HI 0 "register_operand" "=x")
23840         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23841                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23842   "TARGET_SSE2"
23843   "psrlw\t{%2, %0|%0, %2}"
23844   [(set_attr "type" "sseishft")
23845    (set_attr "mode" "TI")])
23847 (define_insn "lshrv4si3_ti"
23848   [(set (match_operand:V4SI 0 "register_operand" "=x")
23849         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23850                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23851   "TARGET_SSE2"
23852   "psrld\t{%2, %0|%0, %2}"
23853   [(set_attr "type" "sseishft")
23854    (set_attr "mode" "TI")])
23856 (define_insn "lshrv2di3_ti"
23857   [(set (match_operand:V2DI 0 "register_operand" "=x")
23858         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23859                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23860   "TARGET_SSE2"
23861   "psrlq\t{%2, %0|%0, %2}"
23862   [(set_attr "type" "sseishft")
23863    (set_attr "mode" "TI")])
23865 (define_insn "ashlv8hi3_ti"
23866   [(set (match_operand:V8HI 0 "register_operand" "=x")
23867         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23868                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23869   "TARGET_SSE2"
23870   "psllw\t{%2, %0|%0, %2}"
23871   [(set_attr "type" "sseishft")
23872    (set_attr "mode" "TI")])
23874 (define_insn "ashlv4si3_ti"
23875   [(set (match_operand:V4SI 0 "register_operand" "=x")
23876         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23877                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23878   "TARGET_SSE2"
23879   "pslld\t{%2, %0|%0, %2}"
23880   [(set_attr "type" "sseishft")
23881    (set_attr "mode" "TI")])
23883 (define_insn "ashlv2di3_ti"
23884   [(set (match_operand:V2DI 0 "register_operand" "=x")
23885         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23886                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23887   "TARGET_SSE2"
23888   "psllq\t{%2, %0|%0, %2}"
23889   [(set_attr "type" "sseishft")
23890    (set_attr "mode" "TI")])
23892 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23893 ;; we wouldn't need here it since we never generate TImode arithmetic.
23895 ;; There has to be some kind of prize for the weirdest new instruction...
23896 (define_insn "sse2_ashlti3"
23897   [(set (match_operand:TI 0 "register_operand" "=x")
23898         (unspec:TI
23899          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23900                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23901                                (const_int 8)))] UNSPEC_NOP))]
23902   "TARGET_SSE2"
23903   "pslldq\t{%2, %0|%0, %2}"
23904   [(set_attr "type" "sseishft")
23905    (set_attr "mode" "TI")])
23907 (define_insn "sse2_lshrti3"
23908   [(set (match_operand:TI 0 "register_operand" "=x")
23909         (unspec:TI
23910          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23911                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23912                                 (const_int 8)))] UNSPEC_NOP))]
23913   "TARGET_SSE2"
23914   "psrldq\t{%2, %0|%0, %2}"
23915   [(set_attr "type" "sseishft")
23916    (set_attr "mode" "TI")])
23918 ;; SSE unpack
23920 (define_insn "sse2_unpckhpd"
23921   [(set (match_operand:V2DF 0 "register_operand" "=x")
23922         (vec_concat:V2DF
23923          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23924                         (parallel [(const_int 1)]))
23925          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23926                         (parallel [(const_int 1)]))))]
23927   "TARGET_SSE2"
23928   "unpckhpd\t{%2, %0|%0, %2}"
23929   [(set_attr "type" "ssecvt")
23930    (set_attr "mode" "V2DF")])
23932 (define_insn "sse2_unpcklpd"
23933   [(set (match_operand:V2DF 0 "register_operand" "=x")
23934         (vec_concat:V2DF
23935          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23936                         (parallel [(const_int 0)]))
23937          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23938                         (parallel [(const_int 0)]))))]
23939   "TARGET_SSE2"
23940   "unpcklpd\t{%2, %0|%0, %2}"
23941   [(set_attr "type" "ssecvt")
23942    (set_attr "mode" "V2DF")])
23944 ;; MMX pack/unpack insns.
23946 (define_insn "sse2_packsswb"
23947   [(set (match_operand:V16QI 0 "register_operand" "=x")
23948         (vec_concat:V16QI
23949          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23950          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23951   "TARGET_SSE2"
23952   "packsswb\t{%2, %0|%0, %2}"
23953   [(set_attr "type" "ssecvt")
23954    (set_attr "mode" "TI")])
23956 (define_insn "sse2_packssdw"
23957   [(set (match_operand:V8HI 0 "register_operand" "=x")
23958         (vec_concat:V8HI
23959          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23960          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23961   "TARGET_SSE2"
23962   "packssdw\t{%2, %0|%0, %2}"
23963   [(set_attr "type" "ssecvt")
23964    (set_attr "mode" "TI")])
23966 (define_insn "sse2_packuswb"
23967   [(set (match_operand:V16QI 0 "register_operand" "=x")
23968         (vec_concat:V16QI
23969          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23970          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23971   "TARGET_SSE2"
23972   "packuswb\t{%2, %0|%0, %2}"
23973   [(set_attr "type" "ssecvt")
23974    (set_attr "mode" "TI")])
23976 (define_insn "sse2_punpckhbw"
23977   [(set (match_operand:V16QI 0 "register_operand" "=x")
23978         (vec_merge:V16QI
23979          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23980                            (parallel [(const_int 8) (const_int 0)
23981                                       (const_int 9) (const_int 1)
23982                                       (const_int 10) (const_int 2)
23983                                       (const_int 11) (const_int 3)
23984                                       (const_int 12) (const_int 4)
23985                                       (const_int 13) (const_int 5)
23986                                       (const_int 14) (const_int 6)
23987                                       (const_int 15) (const_int 7)]))
23988          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23989                            (parallel [(const_int 0) (const_int 8)
23990                                       (const_int 1) (const_int 9)
23991                                       (const_int 2) (const_int 10)
23992                                       (const_int 3) (const_int 11)
23993                                       (const_int 4) (const_int 12)
23994                                       (const_int 5) (const_int 13)
23995                                       (const_int 6) (const_int 14)
23996                                       (const_int 7) (const_int 15)]))
23997          (const_int 21845)))]
23998   "TARGET_SSE2"
23999   "punpckhbw\t{%2, %0|%0, %2}"
24000   [(set_attr "type" "ssecvt")
24001    (set_attr "mode" "TI")])
24003 (define_insn "sse2_punpckhwd"
24004   [(set (match_operand:V8HI 0 "register_operand" "=x")
24005         (vec_merge:V8HI
24006          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24007                           (parallel [(const_int 4) (const_int 0)
24008                                      (const_int 5) (const_int 1)
24009                                      (const_int 6) (const_int 2)
24010                                      (const_int 7) (const_int 3)]))
24011          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24012                           (parallel [(const_int 0) (const_int 4)
24013                                      (const_int 1) (const_int 5)
24014                                      (const_int 2) (const_int 6)
24015                                      (const_int 3) (const_int 7)]))
24016          (const_int 85)))]
24017   "TARGET_SSE2"
24018   "punpckhwd\t{%2, %0|%0, %2}"
24019   [(set_attr "type" "ssecvt")
24020    (set_attr "mode" "TI")])
24022 (define_insn "sse2_punpckhdq"
24023   [(set (match_operand:V4SI 0 "register_operand" "=x")
24024         (vec_merge:V4SI
24025          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24026                           (parallel [(const_int 2) (const_int 0)
24027                                      (const_int 3) (const_int 1)]))
24028          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24029                           (parallel [(const_int 0) (const_int 2)
24030                                      (const_int 1) (const_int 3)]))
24031          (const_int 5)))]
24032   "TARGET_SSE2"
24033   "punpckhdq\t{%2, %0|%0, %2}"
24034   [(set_attr "type" "ssecvt")
24035    (set_attr "mode" "TI")])
24037 (define_insn "sse2_punpcklbw"
24038   [(set (match_operand:V16QI 0 "register_operand" "=x")
24039         (vec_merge:V16QI
24040          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24041                            (parallel [(const_int 0) (const_int 8)
24042                                       (const_int 1) (const_int 9)
24043                                       (const_int 2) (const_int 10)
24044                                       (const_int 3) (const_int 11)
24045                                       (const_int 4) (const_int 12)
24046                                       (const_int 5) (const_int 13)
24047                                       (const_int 6) (const_int 14)
24048                                       (const_int 7) (const_int 15)]))
24049          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24050                            (parallel [(const_int 8) (const_int 0)
24051                                       (const_int 9) (const_int 1)
24052                                       (const_int 10) (const_int 2)
24053                                       (const_int 11) (const_int 3)
24054                                       (const_int 12) (const_int 4)
24055                                       (const_int 13) (const_int 5)
24056                                       (const_int 14) (const_int 6)
24057                                       (const_int 15) (const_int 7)]))
24058          (const_int 21845)))]
24059   "TARGET_SSE2"
24060   "punpcklbw\t{%2, %0|%0, %2}"
24061   [(set_attr "type" "ssecvt")
24062    (set_attr "mode" "TI")])
24064 (define_insn "sse2_punpcklwd"
24065   [(set (match_operand:V8HI 0 "register_operand" "=x")
24066         (vec_merge:V8HI
24067          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24068                           (parallel [(const_int 0) (const_int 4)
24069                                      (const_int 1) (const_int 5)
24070                                      (const_int 2) (const_int 6)
24071                                      (const_int 3) (const_int 7)]))
24072          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24073                           (parallel [(const_int 4) (const_int 0)
24074                                      (const_int 5) (const_int 1)
24075                                      (const_int 6) (const_int 2)
24076                                      (const_int 7) (const_int 3)]))
24077          (const_int 85)))]
24078   "TARGET_SSE2"
24079   "punpcklwd\t{%2, %0|%0, %2}"
24080   [(set_attr "type" "ssecvt")
24081    (set_attr "mode" "TI")])
24083 (define_insn "sse2_punpckldq"
24084   [(set (match_operand:V4SI 0 "register_operand" "=x")
24085         (vec_merge:V4SI
24086          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24087                           (parallel [(const_int 0) (const_int 2)
24088                                      (const_int 1) (const_int 3)]))
24089          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24090                           (parallel [(const_int 2) (const_int 0)
24091                                      (const_int 3) (const_int 1)]))
24092          (const_int 5)))]
24093   "TARGET_SSE2"
24094   "punpckldq\t{%2, %0|%0, %2}"
24095   [(set_attr "type" "ssecvt")
24096    (set_attr "mode" "TI")])
24098 (define_insn "sse2_punpcklqdq"
24099   [(set (match_operand:V2DI 0 "register_operand" "=x")
24100         (vec_merge:V2DI
24101          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24102                           (parallel [(const_int 1)
24103                                      (const_int 0)]))
24104          (match_operand:V2DI 1 "register_operand" "0")
24105          (const_int 1)))]
24106   "TARGET_SSE2"
24107   "punpcklqdq\t{%2, %0|%0, %2}"
24108   [(set_attr "type" "ssecvt")
24109    (set_attr "mode" "TI")])
24111 (define_insn "sse2_punpckhqdq"
24112   [(set (match_operand:V2DI 0 "register_operand" "=x")
24113         (vec_merge:V2DI
24114          (match_operand:V2DI 1 "register_operand" "0")
24115          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24116                           (parallel [(const_int 1)
24117                                      (const_int 0)]))
24118          (const_int 1)))]
24119   "TARGET_SSE2"
24120   "punpckhqdq\t{%2, %0|%0, %2}"
24121   [(set_attr "type" "ssecvt")
24122    (set_attr "mode" "TI")])
24124 ;; SSE2 moves
24126 (define_insn "sse2_movapd"
24127   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24128         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24129                      UNSPEC_MOVA))]
24130   "TARGET_SSE2
24131    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24132   "movapd\t{%1, %0|%0, %1}"
24133   [(set_attr "type" "ssemov")
24134    (set_attr "mode" "V2DF")])
24136 (define_insn "sse2_movupd"
24137   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24138         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24139                      UNSPEC_MOVU))]
24140   "TARGET_SSE2
24141    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24142   "movupd\t{%1, %0|%0, %1}"
24143   [(set_attr "type" "ssecvt")
24144    (set_attr "mode" "V2DF")])
24146 (define_insn "sse2_movdqa"
24147   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24148         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24149                        UNSPEC_MOVA))]
24150   "TARGET_SSE2
24151    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24152   "movdqa\t{%1, %0|%0, %1}"
24153   [(set_attr "type" "ssemov")
24154    (set_attr "mode" "TI")])
24156 (define_insn "sse2_movdqu"
24157   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24158         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24159                        UNSPEC_MOVU))]
24160   "TARGET_SSE2
24161    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24162   "movdqu\t{%1, %0|%0, %1}"
24163   [(set_attr "type" "ssecvt")
24164    (set_attr "mode" "TI")])
24166 (define_insn "sse2_movdq2q"
24167   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
24168         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
24169                        (parallel [(const_int 0)])))]
24170   "TARGET_SSE2 && !TARGET_64BIT"
24171   "@
24172    movq\t{%1, %0|%0, %1}
24173    movdq2q\t{%1, %0|%0, %1}"
24174   [(set_attr "type" "ssecvt")
24175    (set_attr "mode" "TI")])
24177 (define_insn "sse2_movdq2q_rex64"
24178   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
24179         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
24180                        (parallel [(const_int 0)])))]
24181   "TARGET_SSE2 && TARGET_64BIT"
24182   "@
24183    movq\t{%1, %0|%0, %1}
24184    movdq2q\t{%1, %0|%0, %1}
24185    movd\t{%1, %0|%0, %1}"
24186   [(set_attr "type" "ssecvt")
24187    (set_attr "mode" "TI")])
24189 (define_insn "sse2_movq2dq"
24190   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
24191         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
24192                          (const_int 0)))]
24193   "TARGET_SSE2 && !TARGET_64BIT"
24194   "@
24195    movq\t{%1, %0|%0, %1}
24196    movq2dq\t{%1, %0|%0, %1}"
24197   [(set_attr "type" "ssecvt,ssemov")
24198    (set_attr "mode" "TI")])
24200 (define_insn "sse2_movq2dq_rex64"
24201   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
24202         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
24203                          (const_int 0)))]
24204   "TARGET_SSE2 && TARGET_64BIT"
24205   "@
24206    movq\t{%1, %0|%0, %1}
24207    movq2dq\t{%1, %0|%0, %1}
24208    movd\t{%1, %0|%0, %1}"
24209   [(set_attr "type" "ssecvt,ssemov,ssecvt")
24210    (set_attr "mode" "TI")])
24212 (define_insn "sse2_movq"
24213   [(set (match_operand:V2DI 0 "register_operand" "=x")
24214         (vec_concat:V2DI (vec_select:DI
24215                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
24216                           (parallel [(const_int 0)]))
24217                          (const_int 0)))]
24218   "TARGET_SSE2"
24219   "movq\t{%1, %0|%0, %1}"
24220   [(set_attr "type" "ssemov")
24221    (set_attr "mode" "TI")])
24223 (define_insn "sse2_loadd"
24224   [(set (match_operand:V4SI 0 "register_operand" "=x")
24225         (vec_merge:V4SI
24226          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
24227          (const_vector:V4SI [(const_int 0)
24228                              (const_int 0)
24229                              (const_int 0)
24230                              (const_int 0)])
24231          (const_int 1)))]
24232   "TARGET_SSE2"
24233   "movd\t{%1, %0|%0, %1}"
24234   [(set_attr "type" "ssemov")
24235    (set_attr "mode" "TI")])
24237 (define_insn "sse2_stored"
24238   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
24239         (vec_select:SI
24240          (match_operand:V4SI 1 "register_operand" "x")
24241          (parallel [(const_int 0)])))]
24242   "TARGET_SSE2"
24243   "movd\t{%1, %0|%0, %1}"
24244   [(set_attr "type" "ssemov")
24245    (set_attr "mode" "TI")])
24247 (define_insn "sse2_movhpd"
24248   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24249         (vec_merge:V2DF
24250          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24251          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24252          (const_int 1)))]
24253   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24254   "movhpd\t{%2, %0|%0, %2}"
24255   [(set_attr "type" "ssecvt")
24256    (set_attr "mode" "V2DF")])
24258 (define_expand "sse2_loadsd"
24259   [(match_operand:V2DF 0 "register_operand" "")
24260    (match_operand:DF 1 "memory_operand" "")]
24261   "TARGET_SSE2"
24263   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24264                                 CONST0_RTX (V2DFmode)));
24265   DONE;
24268 (define_insn "sse2_loadsd_1"
24269   [(set (match_operand:V2DF 0 "register_operand" "=x")
24270         (vec_merge:V2DF
24271          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24272          (match_operand:V2DF 2 "const0_operand" "X")
24273          (const_int 1)))]
24274   "TARGET_SSE2"
24275   "movsd\t{%1, %0|%0, %1}"
24276   [(set_attr "type" "ssecvt")
24277    (set_attr "mode" "DF")])
24279 (define_insn "sse2_movsd"
24280   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24281         (vec_merge:V2DF
24282          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24283          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24284          (const_int 2)))]
24285   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24286   "@movsd\t{%2, %0|%0, %2}
24287     movlpd\t{%2, %0|%0, %2}
24288     movlpd\t{%2, %0|%0, %2}"
24289   [(set_attr "type" "ssecvt")
24290    (set_attr "mode" "DF,V2DF,V2DF")])
24292 (define_insn "sse2_storesd"
24293   [(set (match_operand:DF 0 "memory_operand" "=m")
24294         (vec_select:DF
24295          (match_operand:V2DF 1 "register_operand" "x")
24296          (parallel [(const_int 0)])))]
24297   "TARGET_SSE2"
24298   "movsd\t{%1, %0|%0, %1}"
24299   [(set_attr "type" "ssecvt")
24300    (set_attr "mode" "DF")])
24302 (define_insn "sse2_shufpd"
24303   [(set (match_operand:V2DF 0 "register_operand" "=x")
24304         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24305                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24306                       (match_operand:SI 3 "immediate_operand" "i")]
24307                      UNSPEC_SHUFFLE))]
24308   "TARGET_SSE2"
24309   ;; @@@ check operand order for intel/nonintel syntax
24310   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24311   [(set_attr "type" "ssecvt")
24312    (set_attr "mode" "V2DF")])
24314 (define_insn "sse2_clflush"
24315   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24316                     UNSPECV_CLFLUSH)]
24317   "TARGET_SSE2"
24318   "clflush\t%a0"
24319   [(set_attr "type" "sse")
24320    (set_attr "memory" "unknown")])
24322 (define_expand "sse2_mfence"
24323   [(set (match_dup 0)
24324         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24325   "TARGET_SSE2"
24327   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24328   MEM_VOLATILE_P (operands[0]) = 1;
24331 (define_insn "*mfence_insn"
24332   [(set (match_operand:BLK 0 "" "")
24333         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24334   "TARGET_SSE2"
24335   "mfence"
24336   [(set_attr "type" "sse")
24337    (set_attr "memory" "unknown")])
24339 (define_expand "sse2_lfence"
24340   [(set (match_dup 0)
24341         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24342   "TARGET_SSE2"
24344   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24345   MEM_VOLATILE_P (operands[0]) = 1;
24348 (define_insn "*lfence_insn"
24349   [(set (match_operand:BLK 0 "" "")
24350         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24351   "TARGET_SSE2"
24352   "lfence"
24353   [(set_attr "type" "sse")
24354    (set_attr "memory" "unknown")])
24356 ;; SSE3
24358 (define_insn "mwait"
24359   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24360                      (match_operand:SI 1 "register_operand" "c")]
24361                     UNSPECV_MWAIT)]
24362   "TARGET_SSE3"
24363   "mwait\t%0, %1"
24364   [(set_attr "length" "3")])
24366 (define_insn "monitor"
24367   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24368                      (match_operand:SI 1 "register_operand" "c")
24369                      (match_operand:SI 2 "register_operand" "d")]
24370                     UNSPECV_MONITOR)]
24371   "TARGET_SSE3"
24372   "monitor\t%0, %1, %2"
24373   [(set_attr "length" "3")])
24375 ;; SSE3 arithmetic
24377 (define_insn "addsubv4sf3"
24378   [(set (match_operand:V4SF 0 "register_operand" "=x")
24379         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24380                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24381                      UNSPEC_ADDSUB))]
24382   "TARGET_SSE3"
24383   "addsubps\t{%2, %0|%0, %2}"
24384   [(set_attr "type" "sseadd")
24385    (set_attr "mode" "V4SF")])
24387 (define_insn "addsubv2df3"
24388   [(set (match_operand:V2DF 0 "register_operand" "=x")
24389         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24390                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24391                      UNSPEC_ADDSUB))]
24392   "TARGET_SSE3"
24393   "addsubpd\t{%2, %0|%0, %2}"
24394   [(set_attr "type" "sseadd")
24395    (set_attr "mode" "V2DF")])
24397 (define_insn "haddv4sf3"
24398   [(set (match_operand:V4SF 0 "register_operand" "=x")
24399         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24400                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24401                      UNSPEC_HADD))]
24402   "TARGET_SSE3"
24403   "haddps\t{%2, %0|%0, %2}"
24404   [(set_attr "type" "sseadd")
24405    (set_attr "mode" "V4SF")])
24407 (define_insn "haddv2df3"
24408   [(set (match_operand:V2DF 0 "register_operand" "=x")
24409         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24410                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24411                      UNSPEC_HADD))]
24412   "TARGET_SSE3"
24413   "haddpd\t{%2, %0|%0, %2}"
24414   [(set_attr "type" "sseadd")
24415    (set_attr "mode" "V2DF")])
24417 (define_insn "hsubv4sf3"
24418   [(set (match_operand:V4SF 0 "register_operand" "=x")
24419         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24420                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24421                      UNSPEC_HSUB))]
24422   "TARGET_SSE3"
24423   "hsubps\t{%2, %0|%0, %2}"
24424   [(set_attr "type" "sseadd")
24425    (set_attr "mode" "V4SF")])
24427 (define_insn "hsubv2df3"
24428   [(set (match_operand:V2DF 0 "register_operand" "=x")
24429         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24430                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24431                      UNSPEC_HSUB))]
24432   "TARGET_SSE3"
24433   "hsubpd\t{%2, %0|%0, %2}"
24434   [(set_attr "type" "sseadd")
24435    (set_attr "mode" "V2DF")])
24437 (define_insn "movshdup"
24438   [(set (match_operand:V4SF 0 "register_operand" "=x")
24439         (unspec:V4SF
24440          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24441   "TARGET_SSE3"
24442   "movshdup\t{%1, %0|%0, %1}"
24443   [(set_attr "type" "sse")
24444    (set_attr "mode" "V4SF")])
24446 (define_insn "movsldup"
24447   [(set (match_operand:V4SF 0 "register_operand" "=x")
24448         (unspec:V4SF
24449          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24450   "TARGET_SSE3"
24451   "movsldup\t{%1, %0|%0, %1}"
24452   [(set_attr "type" "sse")
24453    (set_attr "mode" "V4SF")])
24455 (define_insn "lddqu"
24456   [(set (match_operand:V16QI 0 "register_operand" "=x")
24457         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24458                        UNSPEC_LDQQU))]
24459   "TARGET_SSE3"
24460   "lddqu\t{%1, %0|%0, %1}"
24461   [(set_attr "type" "ssecvt")
24462    (set_attr "mode" "TI")])
24464 (define_insn "loadddup"
24465   [(set (match_operand:V2DF 0 "register_operand" "=x")
24466         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24467   "TARGET_SSE3"
24468   "movddup\t{%1, %0|%0, %1}"
24469   [(set_attr "type" "ssecvt")
24470    (set_attr "mode" "DF")])
24472 (define_insn "movddup"
24473   [(set (match_operand:V2DF 0 "register_operand" "=x")
24474         (vec_duplicate:V2DF
24475          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24476                         (parallel [(const_int 0)]))))]
24477   "TARGET_SSE3"
24478   "movddup\t{%1, %0|%0, %1}"
24479   [(set_attr "type" "ssecvt")
24480    (set_attr "mode" "DF")])