* config/i386/i386.md (sse2_clflush): Use correct operand for clflush.
[official-gcc.git] / gcc / config / i386 / i386.md
blob8b52fbc8ad30ef0a1d63cf82c9083d1d69fe89d7
2 ;; GCC machine description for IA-32 and x86-64.
3 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4 ;; 2001, 2002, 2003, 2004
5 ;; Free Software Foundation, Inc.
6 ;; Mostly by William Schelter.
7 ;; x86_64 support added by Jan Hubicka
8 ;;
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING.  If not, write to
23 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.  */
26 ;; The original PO technology requires these to be ordered by speed,
27 ;; so that assigner will pick the fastest.
29 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
31 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
32 ;; constraint letters.
34 ;; The special asm out single letter directives following a '%' are:
35 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;;     operands[1].
37 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
38 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
39 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
40 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
41 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
42 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
43 ;; 'J' Print the appropriate jump operand.
45 ;; 'b' Print the QImode name of the register for the indicated operand.
46 ;;     %b0 would print %al if operands[0] is reg 0.
47 ;; 'w' Likewise, print the HImode name of the register.
48 ;; 'k' Likewise, print the SImode name of the register.
49 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
50 ;; 'y' Print "st(0)" instead of "st" as a register.
52 ;; UNSPEC usage:
54 (define_constants
55   [; Relocation specifiers
56    (UNSPEC_GOT                  0)
57    (UNSPEC_GOTOFF               1)
58    (UNSPEC_GOTPCREL             2)
59    (UNSPEC_GOTTPOFF             3)
60    (UNSPEC_TPOFF                4)
61    (UNSPEC_NTPOFF               5)
62    (UNSPEC_DTPOFF               6)
63    (UNSPEC_GOTNTPOFF            7)
64    (UNSPEC_INDNTPOFF            8)
66    ; Prologue support
67    (UNSPEC_STACK_ALLOC          11)
68    (UNSPEC_SET_GOT              12)
69    (UNSPEC_SSE_PROLOGUE_SAVE    13)
71    ; TLS support
72    (UNSPEC_TP                   15)
73    (UNSPEC_TLS_GD               16)
74    (UNSPEC_TLS_LD_BASE          17)
76    ; Other random patterns
77    (UNSPEC_SCAS                 20)
78    (UNSPEC_SIN                  21)
79    (UNSPEC_COS                  22)
80    (UNSPEC_FNSTSW               24)
81    (UNSPEC_SAHF                 25)
82    (UNSPEC_FSTCW                26)
83    (UNSPEC_ADD_CARRY            27)
84    (UNSPEC_FLDCW                28)
86    ; For SSE/MMX support:
87    (UNSPEC_FIX                  30)
88    (UNSPEC_MASKMOV              32)
89    (UNSPEC_MOVMSK               33)
90    (UNSPEC_MOVNT                34)
91    (UNSPEC_MOVA                 38)
92    (UNSPEC_MOVU                 39)
93    (UNSPEC_SHUFFLE              41)
94    (UNSPEC_RCP                  42)
95    (UNSPEC_RSQRT                43)
96    (UNSPEC_SFENCE               44)
97    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
98    (UNSPEC_PAVGUSB              49)
99    (UNSPEC_PFRCP                50)
100    (UNSPEC_PFRCPIT1             51)
101    (UNSPEC_PFRCPIT2             52)
102    (UNSPEC_PFRSQRT              53)
103    (UNSPEC_PFRSQIT1             54)
104    (UNSPEC_PSHUFLW              55)
105    (UNSPEC_PSHUFHW              56)
106    (UNSPEC_MFENCE               59)
107    (UNSPEC_LFENCE               60)
108    (UNSPEC_PSADBW               61)
109    (UNSPEC_ADDSUB               71)
110    (UNSPEC_HADD                 72)
111    (UNSPEC_HSUB                 73)
112    (UNSPEC_MOVSHDUP             74)
113    (UNSPEC_MOVSLDUP             75)
114    (UNSPEC_LDQQU                76)
115    (UNSPEC_MOVDDUP              77)
117    ; x87 Floating point
118    (UNSPEC_FPATAN               65)
119    (UNSPEC_FYL2X                66)
120    (UNSPEC_FYL2XP1              67)
121    (UNSPEC_FRNDINT              68)
122    (UNSPEC_F2XM1                69)
124    ; x87 Double output FP
125    (UNSPEC_SINCOS_COS           80)
126    (UNSPEC_SINCOS_SIN           81)
127    (UNSPEC_TAN_ONE              82)
128    (UNSPEC_TAN_TAN              83)
129    (UNSPEC_XTRACT_FRACT         84)
130    (UNSPEC_XTRACT_EXP           85)
131    (UNSPEC_FSCALE_FRACT         86)
132    (UNSPEC_FSCALE_EXP           87)
133    (UNSPEC_FPREM_F              88)
134    (UNSPEC_FPREM_U              89)
135    (UNSPEC_FPREM1_F             90)
136    (UNSPEC_FPREM1_U             91)
138    ; REP instruction
139    (UNSPEC_REP                  75)
141    (UNSPEC_EH_RETURN            76)
142   ])
144 (define_constants
145   [(UNSPECV_BLOCKAGE            0)
146    (UNSPECV_STACK_PROBE         10)
147    (UNSPECV_EMMS                31)
148    (UNSPECV_LDMXCSR             37)
149    (UNSPECV_STMXCSR             40)
150    (UNSPECV_FEMMS               46)
151    (UNSPECV_CLFLUSH             57)
152    (UNSPECV_ALIGN               68)
153    (UNSPECV_MONITOR             69)
154    (UNSPECV_MWAIT               70)
155   ])
157 ;; Registers by name.
158 (define_constants
159   [(BP_REG                       6)
160    (SP_REG                       7)
161    (FLAGS_REG                   17)
162    (FPSR_REG                    18)
163    (DIRFLAG_REG                 19)
164   ])
166 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
167 ;; from i386.c.
169 ;; In C guard expressions, put expressions which may be compile-time
170 ;; constants first.  This allows for better optimization.  For
171 ;; example, write "TARGET_64BIT && reload_completed", not
172 ;; "reload_completed && TARGET_64BIT".
175 ;; Processor type.  This attribute must exactly match the processor_type
176 ;; enumeration in i386.h.
177 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
178   (const (symbol_ref "ix86_tune")))
180 ;; A basic instruction type.  Refinements due to arguments to be
181 ;; provided in other attributes.
182 (define_attr "type"
183   "other,multi,
184    alu,alu1,negnot,imov,imovx,lea,
185    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
186    icmp,test,ibr,setcc,icmov,
187    push,pop,call,callv,leave,
188    str,cld,
189    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
190    sselog,sseiadd,sseishft,sseimul,
191    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
192    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
193   (const_string "other"))
195 ;; Main data type used by the insn
196 (define_attr "mode"
197   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
198   (const_string "unknown"))
200 ;; The CPU unit operations uses.
201 (define_attr "unit" "integer,i387,sse,mmx,unknown"
202   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
203            (const_string "i387")
204          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
205                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
206            (const_string "sse")
207          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
208            (const_string "mmx")
209          (eq_attr "type" "other")
210            (const_string "unknown")]
211          (const_string "integer")))
213 ;; The (bounding maximum) length of an instruction immediate.
214 (define_attr "length_immediate" ""
215   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
216            (const_int 0)
217          (eq_attr "unit" "i387,sse,mmx")
218            (const_int 0)
219          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
220                           imul,icmp,push,pop")
221            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
222          (eq_attr "type" "imov,test")
223            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
224          (eq_attr "type" "call")
225            (if_then_else (match_operand 0 "constant_call_address_operand" "")
226              (const_int 4)
227              (const_int 0))
228          (eq_attr "type" "callv")
229            (if_then_else (match_operand 1 "constant_call_address_operand" "")
230              (const_int 4)
231              (const_int 0))
232          ;; We don't know the size before shorten_branches.  Expect
233          ;; the instruction to fit for better scheduling.
234          (eq_attr "type" "ibr")
235            (const_int 1)
236          ]
237          (symbol_ref "/* Update immediate_length and other attributes! */
238                       abort(),1")))
240 ;; The (bounding maximum) length of an instruction address.
241 (define_attr "length_address" ""
242   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
243            (const_int 0)
244          (and (eq_attr "type" "call")
245               (match_operand 0 "constant_call_address_operand" ""))
246              (const_int 0)
247          (and (eq_attr "type" "callv")
248               (match_operand 1 "constant_call_address_operand" ""))
249              (const_int 0)
250          ]
251          (symbol_ref "ix86_attr_length_address_default (insn)")))
253 ;; Set when length prefix is used.
254 (define_attr "prefix_data16" ""
255   (if_then_else (ior (eq_attr "mode" "HI")
256                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
257     (const_int 1)
258     (const_int 0)))
260 ;; Set when string REP prefix is used.
261 (define_attr "prefix_rep" "" 
262   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
263     (const_int 1)
264     (const_int 0)))
266 ;; Set when 0f opcode prefix is used.
267 (define_attr "prefix_0f" ""
268   (if_then_else 
269     (ior (eq_attr "type" "imovx,setcc,icmov")
270          (eq_attr "unit" "sse,mmx"))
271     (const_int 1)
272     (const_int 0)))
274 ;; Set when REX opcode prefix is used.
275 (define_attr "prefix_rex" ""
276   (cond [(and (eq_attr "mode" "DI")
277               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
278            (const_int 1)
279          (and (eq_attr "mode" "QI")
280               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
281                   (const_int 0)))
282            (const_int 1)
283          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
284              (const_int 0))
285            (const_int 1)
286         ]
287         (const_int 0)))
289 ;; Set when modrm byte is used.
290 (define_attr "modrm" ""
291   (cond [(eq_attr "type" "str,cld,leave")
292            (const_int 0)
293          (eq_attr "unit" "i387")
294            (const_int 0)
295          (and (eq_attr "type" "incdec")
296               (ior (match_operand:SI 1 "register_operand" "")
297                    (match_operand:HI 1 "register_operand" "")))
298            (const_int 0)
299          (and (eq_attr "type" "push")
300               (not (match_operand 1 "memory_operand" "")))
301            (const_int 0)
302          (and (eq_attr "type" "pop")
303               (not (match_operand 0 "memory_operand" "")))
304            (const_int 0)
305          (and (eq_attr "type" "imov")
306               (and (match_operand 0 "register_operand" "")
307                    (match_operand 1 "immediate_operand" "")))
308            (const_int 0)
309          (and (eq_attr "type" "call")
310               (match_operand 0 "constant_call_address_operand" ""))
311              (const_int 0)
312          (and (eq_attr "type" "callv")
313               (match_operand 1 "constant_call_address_operand" ""))
314              (const_int 0)
315          ]
316          (const_int 1)))
318 ;; The (bounding maximum) length of an instruction in bytes.
319 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
320 ;; to split it and compute proper length as for other insns.
321 (define_attr "length" ""
322   (cond [(eq_attr "type" "other,multi,fistp")
323            (const_int 16)
324          (eq_attr "type" "fcmp")
325            (const_int 4)
326          (eq_attr "unit" "i387")
327            (plus (const_int 2)
328                  (plus (attr "prefix_data16")
329                        (attr "length_address")))]
330          (plus (plus (attr "modrm")
331                      (plus (attr "prefix_0f")
332                            (plus (attr "prefix_rex")
333                                  (const_int 1))))
334                (plus (attr "prefix_rep")
335                      (plus (attr "prefix_data16")
336                            (plus (attr "length_immediate")
337                                  (attr "length_address")))))))
339 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
340 ;; `store' if there is a simple memory reference therein, or `unknown'
341 ;; if the instruction is complex.
343 (define_attr "memory" "none,load,store,both,unknown"
344   (cond [(eq_attr "type" "other,multi,str")
345            (const_string "unknown")
346          (eq_attr "type" "lea,fcmov,fpspc,cld")
347            (const_string "none")
348          (eq_attr "type" "fistp,leave")
349            (const_string "both")
350          (eq_attr "type" "push")
351            (if_then_else (match_operand 1 "memory_operand" "")
352              (const_string "both")
353              (const_string "store"))
354          (eq_attr "type" "pop")
355            (if_then_else (match_operand 0 "memory_operand" "")
356              (const_string "both")
357              (const_string "load"))
358          (eq_attr "type" "setcc")
359            (if_then_else (match_operand 0 "memory_operand" "")
360              (const_string "store")
361              (const_string "none"))
362          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
363            (if_then_else (ior (match_operand 0 "memory_operand" "")
364                               (match_operand 1 "memory_operand" ""))
365              (const_string "load")
366              (const_string "none"))
367          (eq_attr "type" "ibr")
368            (if_then_else (match_operand 0 "memory_operand" "")
369              (const_string "load")
370              (const_string "none"))
371          (eq_attr "type" "call")
372            (if_then_else (match_operand 0 "constant_call_address_operand" "")
373              (const_string "none")
374              (const_string "load"))
375          (eq_attr "type" "callv")
376            (if_then_else (match_operand 1 "constant_call_address_operand" "")
377              (const_string "none")
378              (const_string "load"))
379          (and (eq_attr "type" "alu1,negnot,ishift1")
380               (match_operand 1 "memory_operand" ""))
381            (const_string "both")
382          (and (match_operand 0 "memory_operand" "")
383               (match_operand 1 "memory_operand" ""))
384            (const_string "both")
385          (match_operand 0 "memory_operand" "")
386            (const_string "store")
387          (match_operand 1 "memory_operand" "")
388            (const_string "load")
389          (and (eq_attr "type"
390                  "!alu1,negnot,ishift1,
391                    imov,imovx,icmp,test,
392                    fmov,fcmp,fsgn,
393                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
394                    mmx,mmxmov,mmxcmp,mmxcvt")
395               (match_operand 2 "memory_operand" ""))
396            (const_string "load")
397          (and (eq_attr "type" "icmov")
398               (match_operand 3 "memory_operand" ""))
399            (const_string "load")
400         ]
401         (const_string "none")))
403 ;; Indicates if an instruction has both an immediate and a displacement.
405 (define_attr "imm_disp" "false,true,unknown"
406   (cond [(eq_attr "type" "other,multi")
407            (const_string "unknown")
408          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
409               (and (match_operand 0 "memory_displacement_operand" "")
410                    (match_operand 1 "immediate_operand" "")))
411            (const_string "true")
412          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
413               (and (match_operand 0 "memory_displacement_operand" "")
414                    (match_operand 2 "immediate_operand" "")))
415            (const_string "true")
416         ]
417         (const_string "false")))
419 ;; Indicates if an FP operation has an integer source.
421 (define_attr "fp_int_src" "false,true"
422   (const_string "false"))
424 ;; Describe a user's asm statement.
425 (define_asm_attributes
426   [(set_attr "length" "128")
427    (set_attr "type" "multi")])
429 (include "pentium.md")
430 (include "ppro.md")
431 (include "k6.md")
432 (include "athlon.md")
434 ;; Compare instructions.
436 ;; All compare insns have expanders that save the operands away without
437 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
438 ;; after the cmp) will actually emit the cmpM.
440 (define_expand "cmpdi"
441   [(set (reg:CC FLAGS_REG)
442         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
443                     (match_operand:DI 1 "x86_64_general_operand" "")))]
444   ""
446   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
447     operands[0] = force_reg (DImode, operands[0]);
448   ix86_compare_op0 = operands[0];
449   ix86_compare_op1 = operands[1];
450   DONE;
453 (define_expand "cmpsi"
454   [(set (reg:CC FLAGS_REG)
455         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
456                     (match_operand:SI 1 "general_operand" "")))]
457   ""
459   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
460     operands[0] = force_reg (SImode, operands[0]);
461   ix86_compare_op0 = operands[0];
462   ix86_compare_op1 = operands[1];
463   DONE;
466 (define_expand "cmphi"
467   [(set (reg:CC FLAGS_REG)
468         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
469                     (match_operand:HI 1 "general_operand" "")))]
470   ""
472   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
473     operands[0] = force_reg (HImode, operands[0]);
474   ix86_compare_op0 = operands[0];
475   ix86_compare_op1 = operands[1];
476   DONE;
479 (define_expand "cmpqi"
480   [(set (reg:CC FLAGS_REG)
481         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
482                     (match_operand:QI 1 "general_operand" "")))]
483   "TARGET_QIMODE_MATH"
485   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
486     operands[0] = force_reg (QImode, operands[0]);
487   ix86_compare_op0 = operands[0];
488   ix86_compare_op1 = operands[1];
489   DONE;
492 (define_insn "cmpdi_ccno_1_rex64"
493   [(set (reg 17)
494         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
495                  (match_operand:DI 1 "const0_operand" "n,n")))]
496   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
497   "@
498    test{q}\t{%0, %0|%0, %0}
499    cmp{q}\t{%1, %0|%0, %1}"
500   [(set_attr "type" "test,icmp")
501    (set_attr "length_immediate" "0,1")
502    (set_attr "mode" "DI")])
504 (define_insn "*cmpdi_minus_1_rex64"
505   [(set (reg 17)
506         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
507                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
508                  (const_int 0)))]
509   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
510   "cmp{q}\t{%1, %0|%0, %1}"
511   [(set_attr "type" "icmp")
512    (set_attr "mode" "DI")])
514 (define_expand "cmpdi_1_rex64"
515   [(set (reg:CC FLAGS_REG)
516         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
517                     (match_operand:DI 1 "general_operand" "")))]
518   "TARGET_64BIT"
519   "")
521 (define_insn "cmpdi_1_insn_rex64"
522   [(set (reg 17)
523         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
524                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
525   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
526   "cmp{q}\t{%1, %0|%0, %1}"
527   [(set_attr "type" "icmp")
528    (set_attr "mode" "DI")])
531 (define_insn "*cmpsi_ccno_1"
532   [(set (reg 17)
533         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
534                  (match_operand:SI 1 "const0_operand" "n,n")))]
535   "ix86_match_ccmode (insn, CCNOmode)"
536   "@
537    test{l}\t{%0, %0|%0, %0}
538    cmp{l}\t{%1, %0|%0, %1}"
539   [(set_attr "type" "test,icmp")
540    (set_attr "length_immediate" "0,1")
541    (set_attr "mode" "SI")])
543 (define_insn "*cmpsi_minus_1"
544   [(set (reg 17)
545         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
546                            (match_operand:SI 1 "general_operand" "ri,mr"))
547                  (const_int 0)))]
548   "ix86_match_ccmode (insn, CCGOCmode)"
549   "cmp{l}\t{%1, %0|%0, %1}"
550   [(set_attr "type" "icmp")
551    (set_attr "mode" "SI")])
553 (define_expand "cmpsi_1"
554   [(set (reg:CC FLAGS_REG)
555         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
556                     (match_operand:SI 1 "general_operand" "ri,mr")))]
557   ""
558   "")
560 (define_insn "*cmpsi_1_insn"
561   [(set (reg 17)
562         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
563                  (match_operand:SI 1 "general_operand" "ri,mr")))]
564   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
565     && ix86_match_ccmode (insn, CCmode)"
566   "cmp{l}\t{%1, %0|%0, %1}"
567   [(set_attr "type" "icmp")
568    (set_attr "mode" "SI")])
570 (define_insn "*cmphi_ccno_1"
571   [(set (reg 17)
572         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
573                  (match_operand:HI 1 "const0_operand" "n,n")))]
574   "ix86_match_ccmode (insn, CCNOmode)"
575   "@
576    test{w}\t{%0, %0|%0, %0}
577    cmp{w}\t{%1, %0|%0, %1}"
578   [(set_attr "type" "test,icmp")
579    (set_attr "length_immediate" "0,1")
580    (set_attr "mode" "HI")])
582 (define_insn "*cmphi_minus_1"
583   [(set (reg 17)
584         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
585                            (match_operand:HI 1 "general_operand" "ri,mr"))
586                  (const_int 0)))]
587   "ix86_match_ccmode (insn, CCGOCmode)"
588   "cmp{w}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "icmp")
590    (set_attr "mode" "HI")])
592 (define_insn "*cmphi_1"
593   [(set (reg 17)
594         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
595                  (match_operand:HI 1 "general_operand" "ri,mr")))]
596   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
597    && ix86_match_ccmode (insn, CCmode)"
598   "cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "icmp")
600    (set_attr "mode" "HI")])
602 (define_insn "*cmpqi_ccno_1"
603   [(set (reg 17)
604         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
605                  (match_operand:QI 1 "const0_operand" "n,n")))]
606   "ix86_match_ccmode (insn, CCNOmode)"
607   "@
608    test{b}\t{%0, %0|%0, %0}
609    cmp{b}\t{$0, %0|%0, 0}"
610   [(set_attr "type" "test,icmp")
611    (set_attr "length_immediate" "0,1")
612    (set_attr "mode" "QI")])
614 (define_insn "*cmpqi_1"
615   [(set (reg 17)
616         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
617                  (match_operand:QI 1 "general_operand" "qi,mq")))]
618   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619     && ix86_match_ccmode (insn, CCmode)"
620   "cmp{b}\t{%1, %0|%0, %1}"
621   [(set_attr "type" "icmp")
622    (set_attr "mode" "QI")])
624 (define_insn "*cmpqi_minus_1"
625   [(set (reg 17)
626         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
627                            (match_operand:QI 1 "general_operand" "qi,mq"))
628                  (const_int 0)))]
629   "ix86_match_ccmode (insn, CCGOCmode)"
630   "cmp{b}\t{%1, %0|%0, %1}"
631   [(set_attr "type" "icmp")
632    (set_attr "mode" "QI")])
634 (define_insn "*cmpqi_ext_1"
635   [(set (reg 17)
636         (compare
637           (match_operand:QI 0 "general_operand" "Qm")
638           (subreg:QI
639             (zero_extract:SI
640               (match_operand 1 "ext_register_operand" "Q")
641               (const_int 8)
642               (const_int 8)) 0)))]
643   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
644   "cmp{b}\t{%h1, %0|%0, %h1}"
645   [(set_attr "type" "icmp")
646    (set_attr "mode" "QI")])
648 (define_insn "*cmpqi_ext_1_rex64"
649   [(set (reg 17)
650         (compare
651           (match_operand:QI 0 "register_operand" "Q")
652           (subreg:QI
653             (zero_extract:SI
654               (match_operand 1 "ext_register_operand" "Q")
655               (const_int 8)
656               (const_int 8)) 0)))]
657   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
658   "cmp{b}\t{%h1, %0|%0, %h1}"
659   [(set_attr "type" "icmp")
660    (set_attr "mode" "QI")])
662 (define_insn "*cmpqi_ext_2"
663   [(set (reg 17)
664         (compare
665           (subreg:QI
666             (zero_extract:SI
667               (match_operand 0 "ext_register_operand" "Q")
668               (const_int 8)
669               (const_int 8)) 0)
670           (match_operand:QI 1 "const0_operand" "n")))]
671   "ix86_match_ccmode (insn, CCNOmode)"
672   "test{b}\t%h0, %h0"
673   [(set_attr "type" "test")
674    (set_attr "length_immediate" "0")
675    (set_attr "mode" "QI")])
677 (define_expand "cmpqi_ext_3"
678   [(set (reg:CC FLAGS_REG)
679         (compare:CC
680           (subreg:QI
681             (zero_extract:SI
682               (match_operand 0 "ext_register_operand" "")
683               (const_int 8)
684               (const_int 8)) 0)
685           (match_operand:QI 1 "general_operand" "")))]
686   ""
687   "")
689 (define_insn "cmpqi_ext_3_insn"
690   [(set (reg 17)
691         (compare
692           (subreg:QI
693             (zero_extract:SI
694               (match_operand 0 "ext_register_operand" "Q")
695               (const_int 8)
696               (const_int 8)) 0)
697           (match_operand:QI 1 "general_operand" "Qmn")))]
698   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
699   "cmp{b}\t{%1, %h0|%h0, %1}"
700   [(set_attr "type" "icmp")
701    (set_attr "mode" "QI")])
703 (define_insn "cmpqi_ext_3_insn_rex64"
704   [(set (reg 17)
705         (compare
706           (subreg:QI
707             (zero_extract:SI
708               (match_operand 0 "ext_register_operand" "Q")
709               (const_int 8)
710               (const_int 8)) 0)
711           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
712   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
713   "cmp{b}\t{%1, %h0|%h0, %1}"
714   [(set_attr "type" "icmp")
715    (set_attr "mode" "QI")])
717 (define_insn "*cmpqi_ext_4"
718   [(set (reg 17)
719         (compare
720           (subreg:QI
721             (zero_extract:SI
722               (match_operand 0 "ext_register_operand" "Q")
723               (const_int 8)
724               (const_int 8)) 0)
725           (subreg:QI
726             (zero_extract:SI
727               (match_operand 1 "ext_register_operand" "Q")
728               (const_int 8)
729               (const_int 8)) 0)))]
730   "ix86_match_ccmode (insn, CCmode)"
731   "cmp{b}\t{%h1, %h0|%h0, %h1}"
732   [(set_attr "type" "icmp")
733    (set_attr "mode" "QI")])
735 ;; These implement float point compares.
736 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
737 ;; which would allow mix and match FP modes on the compares.  Which is what
738 ;; the old patterns did, but with many more of them.
740 (define_expand "cmpxf"
741   [(set (reg:CC FLAGS_REG)
742         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
743                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
744   "TARGET_80387"
746   ix86_compare_op0 = operands[0];
747   ix86_compare_op1 = operands[1];
748   DONE;
751 (define_expand "cmpdf"
752   [(set (reg:CC FLAGS_REG)
753         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
754                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
755   "TARGET_80387 || TARGET_SSE2"
757   ix86_compare_op0 = operands[0];
758   ix86_compare_op1 = operands[1];
759   DONE;
762 (define_expand "cmpsf"
763   [(set (reg:CC FLAGS_REG)
764         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
765                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
766   "TARGET_80387 || TARGET_SSE"
768   ix86_compare_op0 = operands[0];
769   ix86_compare_op1 = operands[1];
770   DONE;
773 ;; FP compares, step 1:
774 ;; Set the FP condition codes.
776 ;; CCFPmode     compare with exceptions
777 ;; CCFPUmode    compare with no exceptions
779 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
780 ;; and that fp moves clobber the condition codes, and that there is
781 ;; currently no way to describe this fact to reg-stack.  So there are
782 ;; no splitters yet for this.
784 ;; %%% YIKES!  This scheme does not retain a strong connection between 
785 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
786 ;; work!  Only allow tos/mem with tos in op 0.
788 ;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
789 ;; things aren't as bad as they sound...
791 (define_insn "*cmpfp_0"
792   [(set (match_operand:HI 0 "register_operand" "=a")
793         (unspec:HI
794           [(compare:CCFP (match_operand 1 "register_operand" "f")
795                          (match_operand 2 "const0_operand" "X"))]
796           UNSPEC_FNSTSW))]
797   "TARGET_80387
798    && FLOAT_MODE_P (GET_MODE (operands[1]))
799    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
801   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
802     return "ftst\;fnstsw\t%0\;fstp\t%y0";
803   else
804     return "ftst\;fnstsw\t%0";
806   [(set_attr "type" "multi")
807    (set (attr "mode")
808      (cond [(match_operand:SF 1 "" "")
809               (const_string "SF")
810             (match_operand:DF 1 "" "")
811               (const_string "DF")
812            ]
813            (const_string "XF")))])
815 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
816 ;; used to manage the reg stack popping would not be preserved.
818 (define_insn "*cmpfp_2_sf"
819   [(set (reg:CCFP FPSR_REG)
820         (compare:CCFP
821           (match_operand:SF 0 "register_operand" "f")
822           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
823   "TARGET_80387"
824   "* return output_fp_compare (insn, operands, 0, 0);"
825   [(set_attr "type" "fcmp")
826    (set_attr "mode" "SF")])
828 (define_insn "*cmpfp_2_sf_1"
829   [(set (match_operand:HI 0 "register_operand" "=a")
830         (unspec:HI
831           [(compare:CCFP
832              (match_operand:SF 1 "register_operand" "f")
833              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
834           UNSPEC_FNSTSW))]
835   "TARGET_80387"
836   "* return output_fp_compare (insn, operands, 2, 0);"
837   [(set_attr "type" "fcmp")
838    (set_attr "mode" "SF")])
840 (define_insn "*cmpfp_2_df"
841   [(set (reg:CCFP FPSR_REG)
842         (compare:CCFP
843           (match_operand:DF 0 "register_operand" "f")
844           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
845   "TARGET_80387"
846   "* return output_fp_compare (insn, operands, 0, 0);"
847   [(set_attr "type" "fcmp")
848    (set_attr "mode" "DF")])
850 (define_insn "*cmpfp_2_df_1"
851   [(set (match_operand:HI 0 "register_operand" "=a")
852         (unspec:HI
853           [(compare:CCFP
854              (match_operand:DF 1 "register_operand" "f")
855              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
856           UNSPEC_FNSTSW))]
857   "TARGET_80387"
858   "* return output_fp_compare (insn, operands, 2, 0);"
859   [(set_attr "type" "multi")
860    (set_attr "mode" "DF")])
862 (define_insn "*cmpfp_2_xf"
863   [(set (reg:CCFP FPSR_REG)
864         (compare:CCFP
865           (match_operand:XF 0 "register_operand" "f")
866           (match_operand:XF 1 "register_operand" "f")))]
867   "TARGET_80387"
868   "* return output_fp_compare (insn, operands, 0, 0);"
869   [(set_attr "type" "fcmp")
870    (set_attr "mode" "XF")])
872 (define_insn "*cmpfp_2_xf_1"
873   [(set (match_operand:HI 0 "register_operand" "=a")
874         (unspec:HI
875           [(compare:CCFP
876              (match_operand:XF 1 "register_operand" "f")
877              (match_operand:XF 2 "register_operand" "f"))]
878           UNSPEC_FNSTSW))]
879   "TARGET_80387"
880   "* return output_fp_compare (insn, operands, 2, 0);"
881   [(set_attr "type" "multi")
882    (set_attr "mode" "XF")])
884 (define_insn "*cmpfp_2u"
885   [(set (reg:CCFPU FPSR_REG)
886         (compare:CCFPU
887           (match_operand 0 "register_operand" "f")
888           (match_operand 1 "register_operand" "f")))]
889   "TARGET_80387
890    && FLOAT_MODE_P (GET_MODE (operands[0]))
891    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
892   "* return output_fp_compare (insn, operands, 0, 1);"
893   [(set_attr "type" "fcmp")
894    (set (attr "mode")
895      (cond [(match_operand:SF 1 "" "")
896               (const_string "SF")
897             (match_operand:DF 1 "" "")
898               (const_string "DF")
899            ]
900            (const_string "XF")))])
902 (define_insn "*cmpfp_2u_1"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFPU
906              (match_operand 1 "register_operand" "f")
907              (match_operand 2 "register_operand" "f"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387
910    && FLOAT_MODE_P (GET_MODE (operands[1]))
911    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
912   "* return output_fp_compare (insn, operands, 2, 1);"
913   [(set_attr "type" "multi")
914    (set (attr "mode")
915      (cond [(match_operand:SF 1 "" "")
916               (const_string "SF")
917             (match_operand:DF 1 "" "")
918               (const_string "DF")
919            ]
920            (const_string "XF")))])
922 ;; Patterns to match the SImode-in-memory ficom instructions.
924 ;; %%% Play games with accepting gp registers, as otherwise we have to
925 ;; force them to memory during rtl generation, which is no good.  We
926 ;; can get rid of this once we teach reload to do memory input reloads 
927 ;; via pushes.
929 (define_insn "*ficom_1"
930   [(set (reg:CCFP FPSR_REG)
931         (compare:CCFP
932           (match_operand 0 "register_operand" "f,f")
933           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
934   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
935    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
936   "#")
938 ;; Split the not-really-implemented gp register case into a
939 ;; push-op-pop sequence.
941 ;; %%% This is most efficient, but am I gonna get in trouble
942 ;; for separating cc0_setter and cc0_user?
944 (define_split
945   [(set (reg:CCFP FPSR_REG)
946         (compare:CCFP
947           (match_operand:SF 0 "register_operand" "")
948           (float (match_operand:SI 1 "register_operand" ""))))]
949   "0 && TARGET_80387 && reload_completed"
950   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 1))
951    (set (reg:CCFP FPSR_REG) (compare:CCFP (match_dup 0) (match_dup 2)))
952    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
953               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
954   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
955    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
957 ;; FP compares, step 2
958 ;; Move the fpsw to ax.
960 (define_insn "x86_fnstsw_1"
961   [(set (match_operand:HI 0 "register_operand" "=a")
962         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
963   "TARGET_80387"
964   "fnstsw\t%0"
965   [(set_attr "length" "2")
966    (set_attr "mode" "SI")
967    (set_attr "unit" "i387")])
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
972 (define_insn "x86_sahf_1"
973   [(set (reg:CC FLAGS_REG)
974         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
975   "!TARGET_64BIT"
976   "sahf"
977   [(set_attr "length" "1")
978    (set_attr "athlon_decode" "vector")
979    (set_attr "mode" "SI")])
981 ;; Pentium Pro can do steps 1 through 3 in one go.
983 (define_insn "*cmpfp_i"
984   [(set (reg:CCFP FLAGS_REG)
985         (compare:CCFP (match_operand 0 "register_operand" "f")
986                       (match_operand 1 "register_operand" "f")))]
987   "TARGET_80387 && TARGET_CMOVE
988    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989    && FLOAT_MODE_P (GET_MODE (operands[0]))
990    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
991   "* return output_fp_compare (insn, operands, 1, 0);"
992   [(set_attr "type" "fcmp")
993    (set (attr "mode")
994      (cond [(match_operand:SF 1 "" "")
995               (const_string "SF")
996             (match_operand:DF 1 "" "")
997               (const_string "DF")
998            ]
999            (const_string "XF")))
1000    (set_attr "athlon_decode" "vector")])
1002 (define_insn "*cmpfp_i_sse"
1003   [(set (reg:CCFP FLAGS_REG)
1004         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1005                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1006   "TARGET_80387
1007    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1008    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1009   "* return output_fp_compare (insn, operands, 1, 0);"
1010   [(set_attr "type" "fcmp,ssecomi")
1011    (set (attr "mode")
1012      (if_then_else (match_operand:SF 1 "" "")
1013         (const_string "SF")
1014         (const_string "DF")))
1015    (set_attr "athlon_decode" "vector")])
1017 (define_insn "*cmpfp_i_sse_only"
1018   [(set (reg:CCFP FLAGS_REG)
1019         (compare:CCFP (match_operand 0 "register_operand" "x")
1020                       (match_operand 1 "nonimmediate_operand" "xm")))]
1021   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1022    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1023   "* return output_fp_compare (insn, operands, 1, 0);"
1024   [(set_attr "type" "ssecomi")
1025    (set (attr "mode")
1026      (if_then_else (match_operand:SF 1 "" "")
1027         (const_string "SF")
1028         (const_string "DF")))
1029    (set_attr "athlon_decode" "vector")])
1031 (define_insn "*cmpfp_iu"
1032   [(set (reg:CCFPU FLAGS_REG)
1033         (compare:CCFPU (match_operand 0 "register_operand" "f")
1034                        (match_operand 1 "register_operand" "f")))]
1035   "TARGET_80387 && TARGET_CMOVE
1036    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1037    && FLOAT_MODE_P (GET_MODE (operands[0]))
1038    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039   "* return output_fp_compare (insn, operands, 1, 1);"
1040   [(set_attr "type" "fcmp")
1041    (set (attr "mode")
1042      (cond [(match_operand:SF 1 "" "")
1043               (const_string "SF")
1044             (match_operand:DF 1 "" "")
1045               (const_string "DF")
1046            ]
1047            (const_string "XF")))
1048    (set_attr "athlon_decode" "vector")])
1050 (define_insn "*cmpfp_iu_sse"
1051   [(set (reg:CCFPU FLAGS_REG)
1052         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1053                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1054   "TARGET_80387
1055    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1056    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1057   "* return output_fp_compare (insn, operands, 1, 1);"
1058   [(set_attr "type" "fcmp,ssecomi")
1059    (set (attr "mode")
1060      (if_then_else (match_operand:SF 1 "" "")
1061         (const_string "SF")
1062         (const_string "DF")))
1063    (set_attr "athlon_decode" "vector")])
1065 (define_insn "*cmpfp_iu_sse_only"
1066   [(set (reg:CCFPU FLAGS_REG)
1067         (compare:CCFPU (match_operand 0 "register_operand" "x")
1068                        (match_operand 1 "nonimmediate_operand" "xm")))]
1069   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1070    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1071   "* return output_fp_compare (insn, operands, 1, 1);"
1072   [(set_attr "type" "ssecomi")
1073    (set (attr "mode")
1074      (if_then_else (match_operand:SF 1 "" "")
1075         (const_string "SF")
1076         (const_string "DF")))
1077    (set_attr "athlon_decode" "vector")])
1079 ;; Move instructions.
1081 ;; General case of fullword move.
1083 (define_expand "movsi"
1084   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1085         (match_operand:SI 1 "general_operand" ""))]
1086   ""
1087   "ix86_expand_move (SImode, operands); DONE;")
1089 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1090 ;; general_operand.
1092 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1093 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1094 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1095 ;; targets without our curiosities, and it is just as easy to represent
1096 ;; this differently.
1098 (define_insn "*pushsi2"
1099   [(set (match_operand:SI 0 "push_operand" "=<")
1100         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1101   "!TARGET_64BIT"
1102   "push{l}\t%1"
1103   [(set_attr "type" "push")
1104    (set_attr "mode" "SI")])
1106 ;; For 64BIT abi we always round up to 8 bytes.
1107 (define_insn "*pushsi2_rex64"
1108   [(set (match_operand:SI 0 "push_operand" "=X")
1109         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1110   "TARGET_64BIT"
1111   "push{q}\t%q1"
1112   [(set_attr "type" "push")
1113    (set_attr "mode" "SI")])
1115 (define_insn "*pushsi2_prologue"
1116   [(set (match_operand:SI 0 "push_operand" "=<")
1117         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1118    (clobber (mem:BLK (scratch)))]
1119   "!TARGET_64BIT"
1120   "push{l}\t%1"
1121   [(set_attr "type" "push")
1122    (set_attr "mode" "SI")])
1124 (define_insn "*popsi1_epilogue"
1125   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1126         (mem:SI (reg:SI SP_REG)))
1127    (set (reg:SI SP_REG)
1128         (plus:SI (reg:SI SP_REG) (const_int 4)))
1129    (clobber (mem:BLK (scratch)))]
1130   "!TARGET_64BIT"
1131   "pop{l}\t%0"
1132   [(set_attr "type" "pop")
1133    (set_attr "mode" "SI")])
1135 (define_insn "popsi1"
1136   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1137         (mem:SI (reg:SI SP_REG)))
1138    (set (reg:SI SP_REG)
1139         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1140   "!TARGET_64BIT"
1141   "pop{l}\t%0"
1142   [(set_attr "type" "pop")
1143    (set_attr "mode" "SI")])
1145 (define_insn "*movsi_xor"
1146   [(set (match_operand:SI 0 "register_operand" "=r")
1147         (match_operand:SI 1 "const0_operand" "i"))
1148    (clobber (reg:CC FLAGS_REG))]
1149   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1150   "xor{l}\t{%0, %0|%0, %0}"
1151   [(set_attr "type" "alu1")
1152    (set_attr "mode" "SI")
1153    (set_attr "length_immediate" "0")])
1155 (define_insn "*movsi_or"
1156   [(set (match_operand:SI 0 "register_operand" "=r")
1157         (match_operand:SI 1 "immediate_operand" "i"))
1158    (clobber (reg:CC FLAGS_REG))]
1159   "reload_completed
1160    && operands[1] == constm1_rtx
1161    && (TARGET_PENTIUM || optimize_size)"
1163   operands[1] = constm1_rtx;
1164   return "or{l}\t{%1, %0|%0, %1}";
1166   [(set_attr "type" "alu1")
1167    (set_attr "mode" "SI")
1168    (set_attr "length_immediate" "1")])
1170 (define_insn "*movsi_1"
1171   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1172         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1173   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1174    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1176   switch (get_attr_type (insn))
1177     {
1178     case TYPE_SSEMOV:
1179       if (get_attr_mode (insn) == MODE_TI)
1180         return "movdqa\t{%1, %0|%0, %1}";
1181       return "movd\t{%1, %0|%0, %1}";
1183     case TYPE_MMXMOV:
1184       if (get_attr_mode (insn) == MODE_DI)
1185         return "movq\t{%1, %0|%0, %1}";
1186       return "movd\t{%1, %0|%0, %1}";
1188     case TYPE_LEA:
1189       return "lea{l}\t{%1, %0|%0, %1}";
1191     default:
1192       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1193         abort();
1194       return "mov{l}\t{%1, %0|%0, %1}";
1195     }
1197   [(set (attr "type")
1198      (cond [(eq_attr "alternative" "2,3,4")
1199               (const_string "mmxmov")
1200             (eq_attr "alternative" "5,6,7")
1201               (const_string "ssemov")
1202             (and (ne (symbol_ref "flag_pic") (const_int 0))
1203                  (match_operand:SI 1 "symbolic_operand" ""))
1204               (const_string "lea")
1205            ]
1206            (const_string "imov")))
1207    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1209 (define_insn "*movsi_1_nointernunit"
1210   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1211         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1212   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1213    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1215   switch (get_attr_type (insn))
1216     {
1217     case TYPE_SSEMOV:
1218       if (get_attr_mode (insn) == MODE_TI)
1219         return "movdqa\t{%1, %0|%0, %1}";
1220       return "movd\t{%1, %0|%0, %1}";
1222     case TYPE_MMXMOV:
1223       if (get_attr_mode (insn) == MODE_DI)
1224         return "movq\t{%1, %0|%0, %1}";
1225       return "movd\t{%1, %0|%0, %1}";
1227     case TYPE_LEA:
1228       return "lea{l}\t{%1, %0|%0, %1}";
1230     default:
1231       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1232         abort();
1233       return "mov{l}\t{%1, %0|%0, %1}";
1234     }
1236   [(set (attr "type")
1237      (cond [(eq_attr "alternative" "2,3,4")
1238               (const_string "mmxmov")
1239             (eq_attr "alternative" "5,6,7")
1240               (const_string "ssemov")
1241             (and (ne (symbol_ref "flag_pic") (const_int 0))
1242                  (match_operand:SI 1 "symbolic_operand" ""))
1243               (const_string "lea")
1244            ]
1245            (const_string "imov")))
1246    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1248 ;; Stores and loads of ax to arbitrary constant address.
1249 ;; We fake an second form of instruction to force reload to load address
1250 ;; into register when rax is not available
1251 (define_insn "*movabssi_1_rex64"
1252   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1253         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1254   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1255   "@
1256    movabs{l}\t{%1, %P0|%P0, %1}
1257    mov{l}\t{%1, %a0|%a0, %1}"
1258   [(set_attr "type" "imov")
1259    (set_attr "modrm" "0,*")
1260    (set_attr "length_address" "8,0")
1261    (set_attr "length_immediate" "0,*")
1262    (set_attr "memory" "store")
1263    (set_attr "mode" "SI")])
1265 (define_insn "*movabssi_2_rex64"
1266   [(set (match_operand:SI 0 "register_operand" "=a,r")
1267         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1268   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1269   "@
1270    movabs{l}\t{%P1, %0|%0, %P1}
1271    mov{l}\t{%a1, %0|%0, %a1}"
1272   [(set_attr "type" "imov")
1273    (set_attr "modrm" "0,*")
1274    (set_attr "length_address" "8,0")
1275    (set_attr "length_immediate" "0")
1276    (set_attr "memory" "load")
1277    (set_attr "mode" "SI")])
1279 (define_insn "*swapsi"
1280   [(set (match_operand:SI 0 "register_operand" "+r")
1281         (match_operand:SI 1 "register_operand" "+r"))
1282    (set (match_dup 1)
1283         (match_dup 0))]
1284   ""
1285   "xchg{l}\t%1, %0"
1286   [(set_attr "type" "imov")
1287    (set_attr "pent_pair" "np")
1288    (set_attr "athlon_decode" "vector")
1289    (set_attr "mode" "SI")
1290    (set_attr "modrm" "0")])
1292 (define_expand "movhi"
1293   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1294         (match_operand:HI 1 "general_operand" ""))]
1295   ""
1296   "ix86_expand_move (HImode, operands); DONE;")
1298 (define_insn "*pushhi2"
1299   [(set (match_operand:HI 0 "push_operand" "=<,<")
1300         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1301   "!TARGET_64BIT"
1302   "@
1303    push{w}\t{|WORD PTR }%1
1304    push{w}\t%1"
1305   [(set_attr "type" "push")
1306    (set_attr "mode" "HI")])
1308 ;; For 64BIT abi we always round up to 8 bytes.
1309 (define_insn "*pushhi2_rex64"
1310   [(set (match_operand:HI 0 "push_operand" "=X")
1311         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1312   "TARGET_64BIT"
1313   "push{q}\t%q1"
1314   [(set_attr "type" "push")
1315    (set_attr "mode" "QI")])
1317 (define_insn "*movhi_1"
1318   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1319         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1320   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1322   switch (get_attr_type (insn))
1323     {
1324     case TYPE_IMOVX:
1325       /* movzwl is faster than movw on p2 due to partial word stalls,
1326          though not as fast as an aligned movl.  */
1327       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1328     default:
1329       if (get_attr_mode (insn) == MODE_SI)
1330         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1331       else
1332         return "mov{w}\t{%1, %0|%0, %1}";
1333     }
1335   [(set (attr "type")
1336      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1337               (const_string "imov")
1338             (and (eq_attr "alternative" "0")
1339                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340                           (const_int 0))
1341                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1342                           (const_int 0))))
1343               (const_string "imov")
1344             (and (eq_attr "alternative" "1,2")
1345                  (match_operand:HI 1 "aligned_operand" ""))
1346               (const_string "imov")
1347             (and (ne (symbol_ref "TARGET_MOVX")
1348                      (const_int 0))
1349                  (eq_attr "alternative" "0,2"))
1350               (const_string "imovx")
1351            ]
1352            (const_string "imov")))
1353     (set (attr "mode")
1354       (cond [(eq_attr "type" "imovx")
1355                (const_string "SI")
1356              (and (eq_attr "alternative" "1,2")
1357                   (match_operand:HI 1 "aligned_operand" ""))
1358                (const_string "SI")
1359              (and (eq_attr "alternative" "0")
1360                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1361                            (const_int 0))
1362                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1363                            (const_int 0))))
1364                (const_string "SI")
1365             ]
1366             (const_string "HI")))])
1368 ;; Stores and loads of ax to arbitrary constant address.
1369 ;; We fake an second form of instruction to force reload to load address
1370 ;; into register when rax is not available
1371 (define_insn "*movabshi_1_rex64"
1372   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1373         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1374   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1375   "@
1376    movabs{w}\t{%1, %P0|%P0, %1}
1377    mov{w}\t{%1, %a0|%a0, %1}"
1378   [(set_attr "type" "imov")
1379    (set_attr "modrm" "0,*")
1380    (set_attr "length_address" "8,0")
1381    (set_attr "length_immediate" "0,*")
1382    (set_attr "memory" "store")
1383    (set_attr "mode" "HI")])
1385 (define_insn "*movabshi_2_rex64"
1386   [(set (match_operand:HI 0 "register_operand" "=a,r")
1387         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1388   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1389   "@
1390    movabs{w}\t{%P1, %0|%0, %P1}
1391    mov{w}\t{%a1, %0|%0, %a1}"
1392   [(set_attr "type" "imov")
1393    (set_attr "modrm" "0,*")
1394    (set_attr "length_address" "8,0")
1395    (set_attr "length_immediate" "0")
1396    (set_attr "memory" "load")
1397    (set_attr "mode" "HI")])
1399 (define_insn "*swaphi_1"
1400   [(set (match_operand:HI 0 "register_operand" "+r")
1401         (match_operand:HI 1 "register_operand" "+r"))
1402    (set (match_dup 1)
1403         (match_dup 0))]
1404   "TARGET_PARTIAL_REG_STALL"
1405   "xchg{w}\t%1, %0"
1406   [(set_attr "type" "imov")
1407    (set_attr "pent_pair" "np")
1408    (set_attr "mode" "HI")
1409    (set_attr "modrm" "0")])
1411 (define_insn "*swaphi_2"
1412   [(set (match_operand:HI 0 "register_operand" "+r")
1413         (match_operand:HI 1 "register_operand" "+r"))
1414    (set (match_dup 1)
1415         (match_dup 0))]
1416   "! TARGET_PARTIAL_REG_STALL"
1417   "xchg{l}\t%k1, %k0"
1418   [(set_attr "type" "imov")
1419    (set_attr "pent_pair" "np")
1420    (set_attr "mode" "SI")
1421    (set_attr "modrm" "0")])
1423 (define_expand "movstricthi"
1424   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1425         (match_operand:HI 1 "general_operand" ""))]
1426   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1428   /* Don't generate memory->memory moves, go through a register */
1429   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1430     operands[1] = force_reg (HImode, operands[1]);
1433 (define_insn "*movstricthi_1"
1434   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1435         (match_operand:HI 1 "general_operand" "rn,m"))]
1436   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1437    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1438   "mov{w}\t{%1, %0|%0, %1}"
1439   [(set_attr "type" "imov")
1440    (set_attr "mode" "HI")])
1442 (define_insn "*movstricthi_xor"
1443   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1444         (match_operand:HI 1 "const0_operand" "i"))
1445    (clobber (reg:CC FLAGS_REG))]
1446   "reload_completed
1447    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1448   "xor{w}\t{%0, %0|%0, %0}"
1449   [(set_attr "type" "alu1")
1450    (set_attr "mode" "HI")
1451    (set_attr "length_immediate" "0")])
1453 (define_expand "movqi"
1454   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1455         (match_operand:QI 1 "general_operand" ""))]
1456   ""
1457   "ix86_expand_move (QImode, operands); DONE;")
1459 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1460 ;; "push a byte".  But actually we use pushw, which has the effect
1461 ;; of rounding the amount pushed up to a halfword.
1463 (define_insn "*pushqi2"
1464   [(set (match_operand:QI 0 "push_operand" "=X,X")
1465         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1466   "!TARGET_64BIT"
1467   "@
1468    push{w}\t{|word ptr }%1
1469    push{w}\t%w1"
1470   [(set_attr "type" "push")
1471    (set_attr "mode" "HI")])
1473 ;; For 64BIT abi we always round up to 8 bytes.
1474 (define_insn "*pushqi2_rex64"
1475   [(set (match_operand:QI 0 "push_operand" "=X")
1476         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1477   "TARGET_64BIT"
1478   "push{q}\t%q1"
1479   [(set_attr "type" "push")
1480    (set_attr "mode" "QI")])
1482 ;; Situation is quite tricky about when to choose full sized (SImode) move
1483 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1484 ;; partial register dependency machines (such as AMD Athlon), where QImode
1485 ;; moves issue extra dependency and for partial register stalls machines
1486 ;; that don't use QImode patterns (and QImode move cause stall on the next
1487 ;; instruction).
1489 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1490 ;; register stall machines with, where we use QImode instructions, since
1491 ;; partial register stall can be caused there.  Then we use movzx.
1492 (define_insn "*movqi_1"
1493   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1494         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1495   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1497   switch (get_attr_type (insn))
1498     {
1499     case TYPE_IMOVX:
1500       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1501         abort ();
1502       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1503     default:
1504       if (get_attr_mode (insn) == MODE_SI)
1505         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1506       else
1507         return "mov{b}\t{%1, %0|%0, %1}";
1508     }
1510   [(set (attr "type")
1511      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1512               (const_string "imov")
1513             (and (eq_attr "alternative" "3")
1514                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1515                           (const_int 0))
1516                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1517                           (const_int 0))))
1518               (const_string "imov")
1519             (eq_attr "alternative" "3,5")
1520               (const_string "imovx")
1521             (and (ne (symbol_ref "TARGET_MOVX")
1522                      (const_int 0))
1523                  (eq_attr "alternative" "2"))
1524               (const_string "imovx")
1525            ]
1526            (const_string "imov")))
1527    (set (attr "mode")
1528       (cond [(eq_attr "alternative" "3,4,5")
1529                (const_string "SI")
1530              (eq_attr "alternative" "6")
1531                (const_string "QI")
1532              (eq_attr "type" "imovx")
1533                (const_string "SI")
1534              (and (eq_attr "type" "imov")
1535                   (and (eq_attr "alternative" "0,1,2")
1536                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1537                            (const_int 0))))
1538                (const_string "SI")
1539              ;; Avoid partial register stalls when not using QImode arithmetic
1540              (and (eq_attr "type" "imov")
1541                   (and (eq_attr "alternative" "0,1,2")
1542                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1543                                 (const_int 0))
1544                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1545                                 (const_int 0)))))
1546                (const_string "SI")
1547            ]
1548            (const_string "QI")))])
1550 (define_expand "reload_outqi"
1551   [(parallel [(match_operand:QI 0 "" "=m")
1552               (match_operand:QI 1 "register_operand" "r")
1553               (match_operand:QI 2 "register_operand" "=&q")])]
1554   ""
1556   rtx op0, op1, op2;
1557   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1559   if (reg_overlap_mentioned_p (op2, op0))
1560     abort ();
1561   if (! q_regs_operand (op1, QImode))
1562     {
1563       emit_insn (gen_movqi (op2, op1));
1564       op1 = op2;
1565     }
1566   emit_insn (gen_movqi (op0, op1));
1567   DONE;
1570 (define_insn "*swapqi"
1571   [(set (match_operand:QI 0 "register_operand" "+r")
1572         (match_operand:QI 1 "register_operand" "+r"))
1573    (set (match_dup 1)
1574         (match_dup 0))]
1575   ""
1576   "xchg{b}\t%1, %0"
1577   [(set_attr "type" "imov")
1578    (set_attr "pent_pair" "np")
1579    (set_attr "mode" "QI")
1580    (set_attr "modrm" "0")])
1582 (define_expand "movstrictqi"
1583   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1584         (match_operand:QI 1 "general_operand" ""))]
1585   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1587   /* Don't generate memory->memory moves, go through a register.  */
1588   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1589     operands[1] = force_reg (QImode, operands[1]);
1592 (define_insn "*movstrictqi_1"
1593   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1594         (match_operand:QI 1 "general_operand" "*qn,m"))]
1595   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1596    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1597   "mov{b}\t{%1, %0|%0, %1}"
1598   [(set_attr "type" "imov")
1599    (set_attr "mode" "QI")])
1601 (define_insn "*movstrictqi_xor"
1602   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1603         (match_operand:QI 1 "const0_operand" "i"))
1604    (clobber (reg:CC FLAGS_REG))]
1605   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1606   "xor{b}\t{%0, %0|%0, %0}"
1607   [(set_attr "type" "alu1")
1608    (set_attr "mode" "QI")
1609    (set_attr "length_immediate" "0")])
1611 (define_insn "*movsi_extv_1"
1612   [(set (match_operand:SI 0 "register_operand" "=R")
1613         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1614                          (const_int 8)
1615                          (const_int 8)))]
1616   ""
1617   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1618   [(set_attr "type" "imovx")
1619    (set_attr "mode" "SI")])
1621 (define_insn "*movhi_extv_1"
1622   [(set (match_operand:HI 0 "register_operand" "=R")
1623         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1624                          (const_int 8)
1625                          (const_int 8)))]
1626   ""
1627   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1628   [(set_attr "type" "imovx")
1629    (set_attr "mode" "SI")])
1631 (define_insn "*movqi_extv_1"
1632   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1633         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1634                          (const_int 8)
1635                          (const_int 8)))]
1636   "!TARGET_64BIT"
1638   switch (get_attr_type (insn))
1639     {
1640     case TYPE_IMOVX:
1641       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1642     default:
1643       return "mov{b}\t{%h1, %0|%0, %h1}";
1644     }
1646   [(set (attr "type")
1647      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1648                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1649                              (ne (symbol_ref "TARGET_MOVX")
1650                                  (const_int 0))))
1651         (const_string "imovx")
1652         (const_string "imov")))
1653    (set (attr "mode")
1654      (if_then_else (eq_attr "type" "imovx")
1655         (const_string "SI")
1656         (const_string "QI")))])
1658 (define_insn "*movqi_extv_1_rex64"
1659   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1660         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1661                          (const_int 8)
1662                          (const_int 8)))]
1663   "TARGET_64BIT"
1665   switch (get_attr_type (insn))
1666     {
1667     case TYPE_IMOVX:
1668       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1669     default:
1670       return "mov{b}\t{%h1, %0|%0, %h1}";
1671     }
1673   [(set (attr "type")
1674      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1675                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1676                              (ne (symbol_ref "TARGET_MOVX")
1677                                  (const_int 0))))
1678         (const_string "imovx")
1679         (const_string "imov")))
1680    (set (attr "mode")
1681      (if_then_else (eq_attr "type" "imovx")
1682         (const_string "SI")
1683         (const_string "QI")))])
1685 ;; Stores and loads of ax to arbitrary constant address.
1686 ;; We fake an second form of instruction to force reload to load address
1687 ;; into register when rax is not available
1688 (define_insn "*movabsqi_1_rex64"
1689   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1690         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1691   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1692   "@
1693    movabs{b}\t{%1, %P0|%P0, %1}
1694    mov{b}\t{%1, %a0|%a0, %1}"
1695   [(set_attr "type" "imov")
1696    (set_attr "modrm" "0,*")
1697    (set_attr "length_address" "8,0")
1698    (set_attr "length_immediate" "0,*")
1699    (set_attr "memory" "store")
1700    (set_attr "mode" "QI")])
1702 (define_insn "*movabsqi_2_rex64"
1703   [(set (match_operand:QI 0 "register_operand" "=a,r")
1704         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1705   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1706   "@
1707    movabs{b}\t{%P1, %0|%0, %P1}
1708    mov{b}\t{%a1, %0|%0, %a1}"
1709   [(set_attr "type" "imov")
1710    (set_attr "modrm" "0,*")
1711    (set_attr "length_address" "8,0")
1712    (set_attr "length_immediate" "0")
1713    (set_attr "memory" "load")
1714    (set_attr "mode" "QI")])
1716 (define_insn "*movsi_extzv_1"
1717   [(set (match_operand:SI 0 "register_operand" "=R")
1718         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1719                          (const_int 8)
1720                          (const_int 8)))]
1721   ""
1722   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1723   [(set_attr "type" "imovx")
1724    (set_attr "mode" "SI")])
1726 (define_insn "*movqi_extzv_2"
1727   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1728         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1729                                     (const_int 8)
1730                                     (const_int 8)) 0))]
1731   "!TARGET_64BIT"
1733   switch (get_attr_type (insn))
1734     {
1735     case TYPE_IMOVX:
1736       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1737     default:
1738       return "mov{b}\t{%h1, %0|%0, %h1}";
1739     }
1741   [(set (attr "type")
1742      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1743                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1744                              (ne (symbol_ref "TARGET_MOVX")
1745                                  (const_int 0))))
1746         (const_string "imovx")
1747         (const_string "imov")))
1748    (set (attr "mode")
1749      (if_then_else (eq_attr "type" "imovx")
1750         (const_string "SI")
1751         (const_string "QI")))])
1753 (define_insn "*movqi_extzv_2_rex64"
1754   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1755         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1756                                     (const_int 8)
1757                                     (const_int 8)) 0))]
1758   "TARGET_64BIT"
1760   switch (get_attr_type (insn))
1761     {
1762     case TYPE_IMOVX:
1763       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1764     default:
1765       return "mov{b}\t{%h1, %0|%0, %h1}";
1766     }
1768   [(set (attr "type")
1769      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1770                         (ne (symbol_ref "TARGET_MOVX")
1771                             (const_int 0)))
1772         (const_string "imovx")
1773         (const_string "imov")))
1774    (set (attr "mode")
1775      (if_then_else (eq_attr "type" "imovx")
1776         (const_string "SI")
1777         (const_string "QI")))])
1779 (define_insn "movsi_insv_1"
1780   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1781                          (const_int 8)
1782                          (const_int 8))
1783         (match_operand:SI 1 "general_operand" "Qmn"))]
1784   "!TARGET_64BIT"
1785   "mov{b}\t{%b1, %h0|%h0, %b1}"
1786   [(set_attr "type" "imov")
1787    (set_attr "mode" "QI")])
1789 (define_insn "movdi_insv_1_rex64"
1790   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1791                          (const_int 8)
1792                          (const_int 8))
1793         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1794   "TARGET_64BIT"
1795   "mov{b}\t{%b1, %h0|%h0, %b1}"
1796   [(set_attr "type" "imov")
1797    (set_attr "mode" "QI")])
1799 (define_insn "*movqi_insv_2"
1800   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1801                          (const_int 8)
1802                          (const_int 8))
1803         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1804                      (const_int 8)))]
1805   ""
1806   "mov{b}\t{%h1, %h0|%h0, %h1}"
1807   [(set_attr "type" "imov")
1808    (set_attr "mode" "QI")])
1810 (define_expand "movdi"
1811   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1812         (match_operand:DI 1 "general_operand" ""))]
1813   ""
1814   "ix86_expand_move (DImode, operands); DONE;")
1816 (define_insn "*pushdi"
1817   [(set (match_operand:DI 0 "push_operand" "=<")
1818         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1819   "!TARGET_64BIT"
1820   "#")
1822 (define_insn "pushdi2_rex64"
1823   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1824         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1825   "TARGET_64BIT"
1826   "@
1827    push{q}\t%1
1828    #"
1829   [(set_attr "type" "push,multi")
1830    (set_attr "mode" "DI")])
1832 ;; Convert impossible pushes of immediate to existing instructions.
1833 ;; First try to get scratch register and go through it.  In case this
1834 ;; fails, push sign extended lower part first and then overwrite
1835 ;; upper part by 32bit move.
1836 (define_peephole2
1837   [(match_scratch:DI 2 "r")
1838    (set (match_operand:DI 0 "push_operand" "")
1839         (match_operand:DI 1 "immediate_operand" ""))]
1840   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1841    && !x86_64_immediate_operand (operands[1], DImode)"
1842   [(set (match_dup 2) (match_dup 1))
1843    (set (match_dup 0) (match_dup 2))]
1844   "")
1846 ;; We need to define this as both peepholer and splitter for case
1847 ;; peephole2 pass is not run.
1848 (define_peephole2
1849   [(set (match_operand:DI 0 "push_operand" "")
1850         (match_operand:DI 1 "immediate_operand" ""))]
1851   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1852    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1853   [(set (match_dup 0) (match_dup 1))
1854    (set (match_dup 2) (match_dup 3))]
1855   "split_di (operands + 1, 1, operands + 2, operands + 3);
1856    operands[1] = gen_lowpart (DImode, operands[2]);
1857    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1858                                                     GEN_INT (4)));
1859   ")
1861 (define_split
1862   [(set (match_operand:DI 0 "push_operand" "")
1863         (match_operand:DI 1 "immediate_operand" ""))]
1864   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1865    && !symbolic_operand (operands[1], DImode)
1866    && !x86_64_immediate_operand (operands[1], DImode)"
1867   [(set (match_dup 0) (match_dup 1))
1868    (set (match_dup 2) (match_dup 3))]
1869   "split_di (operands + 1, 1, operands + 2, operands + 3);
1870    operands[1] = gen_lowpart (DImode, operands[2]);
1871    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1872                                                     GEN_INT (4)));
1873   ")
1875 (define_insn "*pushdi2_prologue_rex64"
1876   [(set (match_operand:DI 0 "push_operand" "=<")
1877         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1878    (clobber (mem:BLK (scratch)))]
1879   "TARGET_64BIT"
1880   "push{q}\t%1"
1881   [(set_attr "type" "push")
1882    (set_attr "mode" "DI")])
1884 (define_insn "*popdi1_epilogue_rex64"
1885   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1886         (mem:DI (reg:DI SP_REG)))
1887    (set (reg:DI SP_REG)
1888         (plus:DI (reg:DI SP_REG) (const_int 8)))
1889    (clobber (mem:BLK (scratch)))]
1890   "TARGET_64BIT"
1891   "pop{q}\t%0"
1892   [(set_attr "type" "pop")
1893    (set_attr "mode" "DI")])
1895 (define_insn "popdi1"
1896   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1897         (mem:DI (reg:DI SP_REG)))
1898    (set (reg:DI SP_REG)
1899         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1900   "TARGET_64BIT"
1901   "pop{q}\t%0"
1902   [(set_attr "type" "pop")
1903    (set_attr "mode" "DI")])
1905 (define_insn "*movdi_xor_rex64"
1906   [(set (match_operand:DI 0 "register_operand" "=r")
1907         (match_operand:DI 1 "const0_operand" "i"))
1908    (clobber (reg:CC FLAGS_REG))]
1909   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1910    && reload_completed"
1911   "xor{l}\t{%k0, %k0|%k0, %k0}"
1912   [(set_attr "type" "alu1")
1913    (set_attr "mode" "SI")
1914    (set_attr "length_immediate" "0")])
1916 (define_insn "*movdi_or_rex64"
1917   [(set (match_operand:DI 0 "register_operand" "=r")
1918         (match_operand:DI 1 "const_int_operand" "i"))
1919    (clobber (reg:CC FLAGS_REG))]
1920   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1921    && reload_completed
1922    && operands[1] == constm1_rtx"
1924   operands[1] = constm1_rtx;
1925   return "or{q}\t{%1, %0|%0, %1}";
1927   [(set_attr "type" "alu1")
1928    (set_attr "mode" "DI")
1929    (set_attr "length_immediate" "1")])
1931 (define_insn "*movdi_2"
1932   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1933         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1934   "!TARGET_64BIT
1935    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1936   "@
1937    #
1938    #
1939    movq\t{%1, %0|%0, %1}
1940    movq\t{%1, %0|%0, %1}
1941    movq\t{%1, %0|%0, %1}
1942    movdqa\t{%1, %0|%0, %1}
1943    movq\t{%1, %0|%0, %1}"
1944   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1945    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1947 (define_split
1948   [(set (match_operand:DI 0 "push_operand" "")
1949         (match_operand:DI 1 "general_operand" ""))]
1950   "!TARGET_64BIT && reload_completed
1951    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1952   [(const_int 0)]
1953   "ix86_split_long_move (operands); DONE;")
1955 ;; %%% This multiword shite has got to go.
1956 (define_split
1957   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1958         (match_operand:DI 1 "general_operand" ""))]
1959   "!TARGET_64BIT && reload_completed
1960    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1961    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1962   [(const_int 0)]
1963   "ix86_split_long_move (operands); DONE;")
1965 (define_insn "*movdi_1_rex64"
1966   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1967         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1968   "TARGET_64BIT
1969    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1970    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1972   switch (get_attr_type (insn))
1973     {
1974     case TYPE_SSECVT:
1975       if (which_alternative == 11)
1976         return "movq2dq\t{%1, %0|%0, %1}";
1977       else
1978         return "movdq2q\t{%1, %0|%0, %1}";
1979     case TYPE_SSEMOV:
1980       if (get_attr_mode (insn) == MODE_TI)
1981           return "movdqa\t{%1, %0|%0, %1}";
1982       /* FALLTHRU */
1983     case TYPE_MMXMOV:
1984       /* Moves from and into integer register is done using movd opcode with
1985          REX prefix.  */
1986       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1987           return "movd\t{%1, %0|%0, %1}";
1988       return "movq\t{%1, %0|%0, %1}";
1989     case TYPE_MULTI:
1990       return "#";
1991     case TYPE_LEA:
1992       return "lea{q}\t{%a1, %0|%0, %a1}";
1993     default:
1994       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1995         abort ();
1996       if (get_attr_mode (insn) == MODE_SI)
1997         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1998       else if (which_alternative == 2)
1999         return "movabs{q}\t{%1, %0|%0, %1}";
2000       else
2001         return "mov{q}\t{%1, %0|%0, %1}";
2002     }
2004   [(set (attr "type")
2005      (cond [(eq_attr "alternative" "5,6,7")
2006               (const_string "mmxmov")
2007             (eq_attr "alternative" "8,9,10")
2008               (const_string "ssemov")
2009             (eq_attr "alternative" "11,12")
2010               (const_string "ssecvt")
2011             (eq_attr "alternative" "4")
2012               (const_string "multi")
2013             (and (ne (symbol_ref "flag_pic") (const_int 0))
2014                  (match_operand:DI 1 "symbolic_operand" ""))
2015               (const_string "lea")
2016            ]
2017            (const_string "imov")))
2018    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
2019    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2020    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
2022 (define_insn "*movdi_1_rex64_nointerunit"
2023   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2024         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2025   "TARGET_64BIT
2026    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2027    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2029   switch (get_attr_type (insn))
2030     {
2031     case TYPE_SSEMOV:
2032       if (get_attr_mode (insn) == MODE_TI)
2033           return "movdqa\t{%1, %0|%0, %1}";
2034       /* FALLTHRU */
2035     case TYPE_MMXMOV:
2036       return "movq\t{%1, %0|%0, %1}";
2037     case TYPE_MULTI:
2038       return "#";
2039     case TYPE_LEA:
2040       return "lea{q}\t{%a1, %0|%0, %a1}";
2041     default:
2042       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2043         abort ();
2044       if (get_attr_mode (insn) == MODE_SI)
2045         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2046       else if (which_alternative == 2)
2047         return "movabs{q}\t{%1, %0|%0, %1}";
2048       else
2049         return "mov{q}\t{%1, %0|%0, %1}";
2050     }
2052   [(set (attr "type")
2053      (cond [(eq_attr "alternative" "5,6,7")
2054               (const_string "mmxmov")
2055             (eq_attr "alternative" "8,9,10")
2056               (const_string "ssemov")
2057             (eq_attr "alternative" "4")
2058               (const_string "multi")
2059             (and (ne (symbol_ref "flag_pic") (const_int 0))
2060                  (match_operand:DI 1 "symbolic_operand" ""))
2061               (const_string "lea")
2062            ]
2063            (const_string "imov")))
2064    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2065    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2066    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2068 ;; Stores and loads of ax to arbitrary constant address.
2069 ;; We fake an second form of instruction to force reload to load address
2070 ;; into register when rax is not available
2071 (define_insn "*movabsdi_1_rex64"
2072   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2073         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2074   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2075   "@
2076    movabs{q}\t{%1, %P0|%P0, %1}
2077    mov{q}\t{%1, %a0|%a0, %1}"
2078   [(set_attr "type" "imov")
2079    (set_attr "modrm" "0,*")
2080    (set_attr "length_address" "8,0")
2081    (set_attr "length_immediate" "0,*")
2082    (set_attr "memory" "store")
2083    (set_attr "mode" "DI")])
2085 (define_insn "*movabsdi_2_rex64"
2086   [(set (match_operand:DI 0 "register_operand" "=a,r")
2087         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2088   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2089   "@
2090    movabs{q}\t{%P1, %0|%0, %P1}
2091    mov{q}\t{%a1, %0|%0, %a1}"
2092   [(set_attr "type" "imov")
2093    (set_attr "modrm" "0,*")
2094    (set_attr "length_address" "8,0")
2095    (set_attr "length_immediate" "0")
2096    (set_attr "memory" "load")
2097    (set_attr "mode" "DI")])
2099 ;; Convert impossible stores of immediate to existing instructions.
2100 ;; First try to get scratch register and go through it.  In case this
2101 ;; fails, move by 32bit parts.
2102 (define_peephole2
2103   [(match_scratch:DI 2 "r")
2104    (set (match_operand:DI 0 "memory_operand" "")
2105         (match_operand:DI 1 "immediate_operand" ""))]
2106   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2107    && !x86_64_immediate_operand (operands[1], DImode)"
2108   [(set (match_dup 2) (match_dup 1))
2109    (set (match_dup 0) (match_dup 2))]
2110   "")
2112 ;; We need to define this as both peepholer and splitter for case
2113 ;; peephole2 pass is not run.
2114 (define_peephole2
2115   [(set (match_operand:DI 0 "memory_operand" "")
2116         (match_operand:DI 1 "immediate_operand" ""))]
2117   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2119   [(set (match_dup 2) (match_dup 3))
2120    (set (match_dup 4) (match_dup 5))]
2121   "split_di (operands, 2, operands + 2, operands + 4);")
2123 (define_split
2124   [(set (match_operand:DI 0 "memory_operand" "")
2125         (match_operand:DI 1 "immediate_operand" ""))]
2126   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2127    && !symbolic_operand (operands[1], DImode)
2128    && !x86_64_immediate_operand (operands[1], DImode)"
2129   [(set (match_dup 2) (match_dup 3))
2130    (set (match_dup 4) (match_dup 5))]
2131   "split_di (operands, 2, operands + 2, operands + 4);")
2133 (define_insn "*swapdi_rex64"
2134   [(set (match_operand:DI 0 "register_operand" "+r")
2135         (match_operand:DI 1 "register_operand" "+r"))
2136    (set (match_dup 1)
2137         (match_dup 0))]
2138   "TARGET_64BIT"
2139   "xchg{q}\t%1, %0"
2140   [(set_attr "type" "imov")
2141    (set_attr "pent_pair" "np")
2142    (set_attr "athlon_decode" "vector")
2143    (set_attr "mode" "DI")
2144    (set_attr "modrm" "0")])
2146   
2147 (define_expand "movsf"
2148   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2149         (match_operand:SF 1 "general_operand" ""))]
2150   ""
2151   "ix86_expand_move (SFmode, operands); DONE;")
2153 (define_insn "*pushsf"
2154   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2155         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2156   "!TARGET_64BIT"
2158   switch (which_alternative)
2159     {
2160     case 1:
2161       return "push{l}\t%1";
2163     default:
2164       /* This insn should be already split before reg-stack.  */
2165       abort ();
2166     }
2168   [(set_attr "type" "multi,push,multi")
2169    (set_attr "mode" "SF,SI,SF")])
2171 (define_insn "*pushsf_rex64"
2172   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2173         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2174   "TARGET_64BIT"
2176   switch (which_alternative)
2177     {
2178     case 1:
2179       return "push{q}\t%q1";
2181     default:
2182       /* This insn should be already split before reg-stack.  */
2183       abort ();
2184     }
2186   [(set_attr "type" "multi,push,multi")
2187    (set_attr "mode" "SF,DI,SF")])
2189 (define_split
2190   [(set (match_operand:SF 0 "push_operand" "")
2191         (match_operand:SF 1 "memory_operand" ""))]
2192   "reload_completed
2193    && GET_CODE (operands[1]) == MEM
2194    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2195    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2196   [(set (match_dup 0)
2197         (match_dup 1))]
2198   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2201 ;; %%% Kill this when call knows how to work this out.
2202 (define_split
2203   [(set (match_operand:SF 0 "push_operand" "")
2204         (match_operand:SF 1 "any_fp_register_operand" ""))]
2205   "!TARGET_64BIT"
2206   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2207    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2209 (define_split
2210   [(set (match_operand:SF 0 "push_operand" "")
2211         (match_operand:SF 1 "any_fp_register_operand" ""))]
2212   "TARGET_64BIT"
2213   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2214    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2216 (define_insn "*movsf_1"
2217   [(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")
2218         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2219   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2220    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2221    && (reload_in_progress || reload_completed
2222        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2223        || GET_CODE (operands[1]) != CONST_DOUBLE
2224        || memory_operand (operands[0], SFmode))" 
2226   switch (which_alternative)
2227     {
2228     case 0:
2229       return output_387_reg_move (insn, operands);
2231     case 1:
2232       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2233         return "fstp%z0\t%y0";
2234       else
2235         return "fst%z0\t%y0";
2237     case 2:
2238       return standard_80387_constant_opcode (operands[1]);
2240     case 3:
2241     case 4:
2242       return "mov{l}\t{%1, %0|%0, %1}";
2243     case 5:
2244       if (get_attr_mode (insn) == MODE_TI)
2245         return "pxor\t%0, %0";
2246       else
2247         return "xorps\t%0, %0";
2248     case 6:
2249       if (get_attr_mode (insn) == MODE_V4SF)
2250         return "movaps\t{%1, %0|%0, %1}";
2251       else
2252         return "movss\t{%1, %0|%0, %1}";
2253     case 7:
2254     case 8:
2255       return "movss\t{%1, %0|%0, %1}";
2257     case 9:
2258     case 10:
2259       return "movd\t{%1, %0|%0, %1}";
2261     case 11:
2262       return "movq\t{%1, %0|%0, %1}";
2264     default:
2265       abort();
2266     }
2268   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2269    (set (attr "mode")
2270         (cond [(eq_attr "alternative" "3,4,9,10")
2271                  (const_string "SI")
2272                (eq_attr "alternative" "5")
2273                  (if_then_else
2274                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2275                                  (const_int 0))
2276                              (ne (symbol_ref "TARGET_SSE2")
2277                                  (const_int 0)))
2278                         (eq (symbol_ref "optimize_size")
2279                             (const_int 0)))
2280                    (const_string "TI")
2281                    (const_string "V4SF"))
2282                /* For architectures resolving dependencies on
2283                   whole SSE registers use APS move to break dependency
2284                   chains, otherwise use short move to avoid extra work. 
2286                   Do the same for architectures resolving dependencies on
2287                   the parts.  While in DF mode it is better to always handle
2288                   just register parts, the SF mode is different due to lack
2289                   of instructions to load just part of the register.  It is
2290                   better to maintain the whole registers in single format
2291                   to avoid problems on using packed logical operations.  */
2292                (eq_attr "alternative" "6")
2293                  (if_then_else
2294                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2295                             (const_int 0))
2296                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2297                             (const_int 0)))
2298                    (const_string "V4SF")
2299                    (const_string "SF"))
2300                (eq_attr "alternative" "11")
2301                  (const_string "DI")]
2302                (const_string "SF")))])
2304 (define_insn "*movsf_1_nointerunit"
2305   [(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")
2306         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2307   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2308    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2309    && (reload_in_progress || reload_completed
2310        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2311        || GET_CODE (operands[1]) != CONST_DOUBLE
2312        || memory_operand (operands[0], SFmode))" 
2314   switch (which_alternative)
2315     {
2316     case 0:
2317       return output_387_reg_move (insn, operands);
2319     case 1:
2320       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2321         return "fstp%z0\t%y0";
2322       else
2323         return "fst%z0\t%y0";
2325     case 2:
2326       return standard_80387_constant_opcode (operands[1]);
2328     case 3:
2329     case 4:
2330       return "mov{l}\t{%1, %0|%0, %1}";
2331     case 5:
2332       if (get_attr_mode (insn) == MODE_TI)
2333         return "pxor\t%0, %0";
2334       else
2335         return "xorps\t%0, %0";
2336     case 6:
2337       if (get_attr_mode (insn) == MODE_V4SF)
2338         return "movaps\t{%1, %0|%0, %1}";
2339       else
2340         return "movss\t{%1, %0|%0, %1}";
2341     case 7:
2342     case 8:
2343       return "movss\t{%1, %0|%0, %1}";
2345     case 9:
2346     case 10:
2347       return "movd\t{%1, %0|%0, %1}";
2349     case 11:
2350       return "movq\t{%1, %0|%0, %1}";
2352     default:
2353       abort();
2354     }
2356   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2357    (set (attr "mode")
2358         (cond [(eq_attr "alternative" "3,4,9,10")
2359                  (const_string "SI")
2360                (eq_attr "alternative" "5")
2361                  (if_then_else
2362                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2363                                  (const_int 0))
2364                              (ne (symbol_ref "TARGET_SSE2")
2365                                  (const_int 0)))
2366                         (eq (symbol_ref "optimize_size")
2367                             (const_int 0)))
2368                    (const_string "TI")
2369                    (const_string "V4SF"))
2370                /* For architectures resolving dependencies on
2371                   whole SSE registers use APS move to break dependency
2372                   chains, otherwise use short move to avoid extra work. 
2374                   Do the same for architectures resolving dependencies on
2375                   the parts.  While in DF mode it is better to always handle
2376                   just register parts, the SF mode is different due to lack
2377                   of instructions to load just part of the register.  It is
2378                   better to maintain the whole registers in single format
2379                   to avoid problems on using packed logical operations.  */
2380                (eq_attr "alternative" "6")
2381                  (if_then_else
2382                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2383                             (const_int 0))
2384                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2385                             (const_int 0)))
2386                    (const_string "V4SF")
2387                    (const_string "SF"))
2388                (eq_attr "alternative" "11")
2389                  (const_string "DI")]
2390                (const_string "SF")))])
2392 (define_insn "*swapsf"
2393   [(set (match_operand:SF 0 "register_operand" "+f")
2394         (match_operand:SF 1 "register_operand" "+f"))
2395    (set (match_dup 1)
2396         (match_dup 0))]
2397   "reload_completed || !TARGET_SSE"
2399   if (STACK_TOP_P (operands[0]))
2400     return "fxch\t%1";
2401   else
2402     return "fxch\t%0";
2404   [(set_attr "type" "fxch")
2405    (set_attr "mode" "SF")])
2407 (define_expand "movdf"
2408   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2409         (match_operand:DF 1 "general_operand" ""))]
2410   ""
2411   "ix86_expand_move (DFmode, operands); DONE;")
2413 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2414 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2415 ;; On the average, pushdf using integers can be still shorter.  Allow this
2416 ;; pattern for optimize_size too.
2418 (define_insn "*pushdf_nointeger"
2419   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2420         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2421   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2423   /* This insn should be already split before reg-stack.  */
2424   abort ();
2426   [(set_attr "type" "multi")
2427    (set_attr "mode" "DF,SI,SI,DF")])
2429 (define_insn "*pushdf_integer"
2430   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2431         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2432   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2434   /* This insn should be already split before reg-stack.  */
2435   abort ();
2437   [(set_attr "type" "multi")
2438    (set_attr "mode" "DF,SI,DF")])
2440 ;; %%% Kill this when call knows how to work this out.
2441 (define_split
2442   [(set (match_operand:DF 0 "push_operand" "")
2443         (match_operand:DF 1 "any_fp_register_operand" ""))]
2444   "!TARGET_64BIT && reload_completed"
2445   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2446    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2447   "")
2449 (define_split
2450   [(set (match_operand:DF 0 "push_operand" "")
2451         (match_operand:DF 1 "any_fp_register_operand" ""))]
2452   "TARGET_64BIT && reload_completed"
2453   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2454    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2455   "")
2457 (define_split
2458   [(set (match_operand:DF 0 "push_operand" "")
2459         (match_operand:DF 1 "general_operand" ""))]
2460   "reload_completed"
2461   [(const_int 0)]
2462   "ix86_split_long_move (operands); DONE;")
2464 ;; Moving is usually shorter when only FP registers are used. This separate
2465 ;; movdf pattern avoids the use of integer registers for FP operations
2466 ;; when optimizing for size.
2468 (define_insn "*movdf_nointeger"
2469   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2470         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2471   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2472    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2473    && (reload_in_progress || reload_completed
2474        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2475        || GET_CODE (operands[1]) != CONST_DOUBLE
2476        || memory_operand (operands[0], DFmode))" 
2478   switch (which_alternative)
2479     {
2480     case 0:
2481       return output_387_reg_move (insn, operands);
2483     case 1:
2484       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2485         return "fstp%z0\t%y0";
2486       else
2487         return "fst%z0\t%y0";
2489     case 2:
2490       return standard_80387_constant_opcode (operands[1]);
2492     case 3:
2493     case 4:
2494       return "#";
2495     case 5:
2496       switch (get_attr_mode (insn))
2497         {
2498         case MODE_V4SF:
2499           return "xorps\t%0, %0";
2500         case MODE_V2DF:
2501           return "xorpd\t%0, %0";
2502         case MODE_TI:
2503           return "pxor\t%0, %0";
2504         default:
2505           abort ();
2506         }
2507     case 6:
2508       switch (get_attr_mode (insn))
2509         {
2510         case MODE_V4SF:
2511           return "movaps\t{%1, %0|%0, %1}";
2512         case MODE_V2DF:
2513           return "movapd\t{%1, %0|%0, %1}";
2514         case MODE_DF:
2515           return "movsd\t{%1, %0|%0, %1}";
2516         default:
2517           abort ();
2518         }
2519     case 7:
2520       if (get_attr_mode (insn) == MODE_V2DF)
2521         return "movlpd\t{%1, %0|%0, %1}";
2522       else
2523         return "movsd\t{%1, %0|%0, %1}";
2524     case 8:
2525       return "movsd\t{%1, %0|%0, %1}";
2527     default:
2528       abort();
2529     }
2531   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2532    (set (attr "mode")
2533         (cond [(eq_attr "alternative" "3,4")
2534                  (const_string "SI")
2535                /* xorps is one byte shorter.  */
2536                (eq_attr "alternative" "5")
2537                  (cond [(ne (symbol_ref "optimize_size")
2538                             (const_int 0))
2539                           (const_string "V4SF")
2540                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2541                             (const_int 0))
2542                           (const_string "TI")]
2543                        (const_string "V2DF"))
2544                /* For architectures resolving dependencies on
2545                   whole SSE registers use APD move to break dependency
2546                   chains, otherwise use short move to avoid extra work.
2548                   movaps encodes one byte shorter.  */
2549                (eq_attr "alternative" "6")
2550                  (cond
2551                   [(ne (symbol_ref "optimize_size")
2552                        (const_int 0))
2553                      (const_string "V4SF")
2554                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2555                        (const_int 0))
2556                      (const_string "V2DF")]
2557                    (const_string "DF"))
2558                /* For architectures resolving dependencies on register
2559                   parts we may avoid extra work to zero out upper part
2560                   of register.  */
2561                (eq_attr "alternative" "7")
2562                  (if_then_else
2563                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2564                        (const_int 0))
2565                    (const_string "V2DF")
2566                    (const_string "DF"))]
2567                (const_string "DF")))])
2569 (define_insn "*movdf_integer"
2570   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2571         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2572   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2573    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2574    && (reload_in_progress || reload_completed
2575        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2576        || GET_CODE (operands[1]) != CONST_DOUBLE
2577        || memory_operand (operands[0], DFmode))" 
2579   switch (which_alternative)
2580     {
2581     case 0:
2582       return output_387_reg_move (insn, operands);
2584     case 1:
2585       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2586         return "fstp%z0\t%y0";
2587       else
2588         return "fst%z0\t%y0";
2590     case 2:
2591       return standard_80387_constant_opcode (operands[1]);
2593     case 3:
2594     case 4:
2595       return "#";
2597     case 5:
2598       switch (get_attr_mode (insn))
2599         {
2600         case MODE_V4SF:
2601           return "xorps\t%0, %0";
2602         case MODE_V2DF:
2603           return "xorpd\t%0, %0";
2604         case MODE_TI:
2605           return "pxor\t%0, %0";
2606         default:
2607           abort ();
2608         }
2609     case 6:
2610       switch (get_attr_mode (insn))
2611         {
2612         case MODE_V4SF:
2613           return "movaps\t{%1, %0|%0, %1}";
2614         case MODE_V2DF:
2615           return "movapd\t{%1, %0|%0, %1}";
2616         case MODE_DF:
2617           return "movsd\t{%1, %0|%0, %1}";
2618         default:
2619           abort ();
2620         }
2621     case 7:
2622       if (get_attr_mode (insn) == MODE_V2DF)
2623         return "movlpd\t{%1, %0|%0, %1}";
2624       else
2625         return "movsd\t{%1, %0|%0, %1}";
2626     case 8:
2627       return "movsd\t{%1, %0|%0, %1}";
2629     default:
2630       abort();
2631     }
2633   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2634    (set (attr "mode")
2635         (cond [(eq_attr "alternative" "3,4")
2636                  (const_string "SI")
2637                /* xorps is one byte shorter.  */
2638                (eq_attr "alternative" "5")
2639                  (cond [(ne (symbol_ref "optimize_size")
2640                             (const_int 0))
2641                           (const_string "V4SF")
2642                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2643                             (const_int 0))
2644                           (const_string "TI")]
2645                        (const_string "V2DF"))
2646                /* For architectures resolving dependencies on
2647                   whole SSE registers use APD move to break dependency
2648                   chains, otherwise use short move to avoid extra work.  
2650                   movaps encodes one byte shorter.  */
2651                (eq_attr "alternative" "6")
2652                  (cond
2653                   [(ne (symbol_ref "optimize_size")
2654                        (const_int 0))
2655                      (const_string "V4SF")
2656                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2657                        (const_int 0))
2658                      (const_string "V2DF")]
2659                    (const_string "DF"))
2660                /* For architectures resolving dependencies on register
2661                   parts we may avoid extra work to zero out upper part
2662                   of register.  */
2663                (eq_attr "alternative" "7")
2664                  (if_then_else
2665                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2666                        (const_int 0))
2667                    (const_string "V2DF")
2668                    (const_string "DF"))]
2669                (const_string "DF")))])
2671 (define_split
2672   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2673         (match_operand:DF 1 "general_operand" ""))]
2674   "reload_completed
2675    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2676    && ! (ANY_FP_REG_P (operands[0]) || 
2677          (GET_CODE (operands[0]) == SUBREG
2678           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2679    && ! (ANY_FP_REG_P (operands[1]) || 
2680          (GET_CODE (operands[1]) == SUBREG
2681           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2682   [(const_int 0)]
2683   "ix86_split_long_move (operands); DONE;")
2685 (define_insn "*swapdf"
2686   [(set (match_operand:DF 0 "register_operand" "+f")
2687         (match_operand:DF 1 "register_operand" "+f"))
2688    (set (match_dup 1)
2689         (match_dup 0))]
2690   "reload_completed || !TARGET_SSE2"
2692   if (STACK_TOP_P (operands[0]))
2693     return "fxch\t%1";
2694   else
2695     return "fxch\t%0";
2697   [(set_attr "type" "fxch")
2698    (set_attr "mode" "DF")])
2700 (define_expand "movxf"
2701   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2702         (match_operand:XF 1 "general_operand" ""))]
2703   ""
2704   "ix86_expand_move (XFmode, operands); DONE;")
2706 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2707 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2708 ;; Pushing using integer instructions is longer except for constants
2709 ;; and direct memory references.
2710 ;; (assuming that any given constant is pushed only once, but this ought to be
2711 ;;  handled elsewhere).
2713 (define_insn "*pushxf_nointeger"
2714   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2715         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2716   "optimize_size"
2718   /* This insn should be already split before reg-stack.  */
2719   abort ();
2721   [(set_attr "type" "multi")
2722    (set_attr "mode" "XF,SI,SI")])
2724 (define_insn "*pushxf_integer"
2725   [(set (match_operand:XF 0 "push_operand" "=<,<")
2726         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2727   "!optimize_size"
2729   /* This insn should be already split before reg-stack.  */
2730   abort ();
2732   [(set_attr "type" "multi")
2733    (set_attr "mode" "XF,SI")])
2735 (define_split
2736   [(set (match_operand 0 "push_operand" "")
2737         (match_operand 1 "general_operand" ""))]
2738   "reload_completed
2739    && (GET_MODE (operands[0]) == XFmode
2740        || GET_MODE (operands[0]) == DFmode)
2741    && !ANY_FP_REG_P (operands[1])"
2742   [(const_int 0)]
2743   "ix86_split_long_move (operands); DONE;")
2745 (define_split
2746   [(set (match_operand:XF 0 "push_operand" "")
2747         (match_operand:XF 1 "any_fp_register_operand" ""))]
2748   "!TARGET_64BIT"
2749   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2750    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2751   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2753 (define_split
2754   [(set (match_operand:XF 0 "push_operand" "")
2755         (match_operand:XF 1 "any_fp_register_operand" ""))]
2756   "TARGET_64BIT"
2757   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2758    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2759   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2761 ;; Do not use integer registers when optimizing for size
2762 (define_insn "*movxf_nointeger"
2763   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2764         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2765   "optimize_size
2766    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2767    && (reload_in_progress || reload_completed
2768        || GET_CODE (operands[1]) != CONST_DOUBLE
2769        || memory_operand (operands[0], XFmode))" 
2771   switch (which_alternative)
2772     {
2773     case 0:
2774       return output_387_reg_move (insn, operands);
2776     case 1:
2777       /* There is no non-popping store to memory for XFmode.  So if
2778          we need one, follow the store with a load.  */
2779       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2780         return "fstp%z0\t%y0\;fld%z0\t%y0";
2781       else
2782         return "fstp%z0\t%y0";
2784     case 2:
2785       return standard_80387_constant_opcode (operands[1]);
2787     case 3: case 4:
2788       return "#";
2789     }
2790   abort();
2792   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2793    (set_attr "mode" "XF,XF,XF,SI,SI")])
2795 (define_insn "*movxf_integer"
2796   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2797         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2798   "!optimize_size
2799    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2800    && (reload_in_progress || reload_completed
2801        || GET_CODE (operands[1]) != CONST_DOUBLE
2802        || memory_operand (operands[0], XFmode))" 
2804   switch (which_alternative)
2805     {
2806     case 0:
2807       return output_387_reg_move (insn, operands);
2809     case 1:
2810       /* There is no non-popping store to memory for XFmode.  So if
2811          we need one, follow the store with a load.  */
2812       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2813         return "fstp%z0\t%y0\;fld%z0\t%y0";
2814       else
2815         return "fstp%z0\t%y0";
2817     case 2:
2818       return standard_80387_constant_opcode (operands[1]);
2820     case 3: case 4:
2821       return "#";
2822     }
2823   abort();
2825   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2826    (set_attr "mode" "XF,XF,XF,SI,SI")])
2828 (define_split
2829   [(set (match_operand 0 "nonimmediate_operand" "")
2830         (match_operand 1 "general_operand" ""))]
2831   "reload_completed
2832    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2833    && GET_MODE (operands[0]) == XFmode
2834    && ! (ANY_FP_REG_P (operands[0]) || 
2835          (GET_CODE (operands[0]) == SUBREG
2836           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2837    && ! (ANY_FP_REG_P (operands[1]) || 
2838          (GET_CODE (operands[1]) == SUBREG
2839           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2840   [(const_int 0)]
2841   "ix86_split_long_move (operands); DONE;")
2843 (define_split
2844   [(set (match_operand 0 "register_operand" "")
2845         (match_operand 1 "memory_operand" ""))]
2846   "reload_completed
2847    && GET_CODE (operands[1]) == MEM
2848    && (GET_MODE (operands[0]) == XFmode
2849        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2850    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2851    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2852   [(set (match_dup 0) (match_dup 1))]
2854   rtx c = get_pool_constant (XEXP (operands[1], 0));
2855   rtx r = operands[0];
2857   if (GET_CODE (r) == SUBREG)
2858     r = SUBREG_REG (r);
2860   if (SSE_REG_P (r))
2861     {
2862       if (!standard_sse_constant_p (c))
2863         FAIL;
2864     }
2865   else if (FP_REG_P (r))
2866     {
2867       if (!standard_80387_constant_p (c))
2868         FAIL;
2869     }
2870   else if (MMX_REG_P (r))
2871     FAIL;
2873   operands[1] = c;
2876 (define_insn "swapxf"
2877   [(set (match_operand:XF 0 "register_operand" "+f")
2878         (match_operand:XF 1 "register_operand" "+f"))
2879    (set (match_dup 1)
2880         (match_dup 0))]
2881   ""
2883   if (STACK_TOP_P (operands[0]))
2884     return "fxch\t%1";
2885   else
2886     return "fxch\t%0";
2888   [(set_attr "type" "fxch")
2889    (set_attr "mode" "XF")])
2891 ;; Zero extension instructions
2893 (define_expand "zero_extendhisi2"
2894   [(set (match_operand:SI 0 "register_operand" "")
2895      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2896   ""
2898   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2899     {
2900       operands[1] = force_reg (HImode, operands[1]);
2901       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2902       DONE;
2903     }
2906 (define_insn "zero_extendhisi2_and"
2907   [(set (match_operand:SI 0 "register_operand" "=r")
2908      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2909    (clobber (reg:CC FLAGS_REG))]
2910   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2911   "#"
2912   [(set_attr "type" "alu1")
2913    (set_attr "mode" "SI")])
2915 (define_split
2916   [(set (match_operand:SI 0 "register_operand" "")
2917         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2918    (clobber (reg:CC FLAGS_REG))]
2919   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2920   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2921               (clobber (reg:CC FLAGS_REG))])]
2922   "")
2924 (define_insn "*zero_extendhisi2_movzwl"
2925   [(set (match_operand:SI 0 "register_operand" "=r")
2926      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2927   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2928   "movz{wl|x}\t{%1, %0|%0, %1}"
2929   [(set_attr "type" "imovx")
2930    (set_attr "mode" "SI")])
2932 (define_expand "zero_extendqihi2"
2933   [(parallel
2934     [(set (match_operand:HI 0 "register_operand" "")
2935        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2936      (clobber (reg:CC FLAGS_REG))])]
2937   ""
2938   "")
2940 (define_insn "*zero_extendqihi2_and"
2941   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2942      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2943    (clobber (reg:CC FLAGS_REG))]
2944   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2945   "#"
2946   [(set_attr "type" "alu1")
2947    (set_attr "mode" "HI")])
2949 (define_insn "*zero_extendqihi2_movzbw_and"
2950   [(set (match_operand:HI 0 "register_operand" "=r,r")
2951      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2952    (clobber (reg:CC FLAGS_REG))]
2953   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2954   "#"
2955   [(set_attr "type" "imovx,alu1")
2956    (set_attr "mode" "HI")])
2958 (define_insn "*zero_extendqihi2_movzbw"
2959   [(set (match_operand:HI 0 "register_operand" "=r")
2960      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2961   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2962   "movz{bw|x}\t{%1, %0|%0, %1}"
2963   [(set_attr "type" "imovx")
2964    (set_attr "mode" "HI")])
2966 ;; For the movzbw case strip only the clobber
2967 (define_split
2968   [(set (match_operand:HI 0 "register_operand" "")
2969         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2970    (clobber (reg:CC FLAGS_REG))]
2971   "reload_completed 
2972    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2973    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2974   [(set (match_operand:HI 0 "register_operand" "")
2975         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2977 ;; When source and destination does not overlap, clear destination
2978 ;; first and then do the movb
2979 (define_split
2980   [(set (match_operand:HI 0 "register_operand" "")
2981         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2982    (clobber (reg:CC FLAGS_REG))]
2983   "reload_completed
2984    && ANY_QI_REG_P (operands[0])
2985    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2986    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2987   [(set (match_dup 0) (const_int 0))
2988    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2989   "operands[2] = gen_lowpart (QImode, operands[0]);")
2991 ;; Rest is handled by single and.
2992 (define_split
2993   [(set (match_operand:HI 0 "register_operand" "")
2994         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed
2997    && true_regnum (operands[0]) == true_regnum (operands[1])"
2998   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2999               (clobber (reg:CC FLAGS_REG))])]
3000   "")
3002 (define_expand "zero_extendqisi2"
3003   [(parallel
3004     [(set (match_operand:SI 0 "register_operand" "")
3005        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3006      (clobber (reg:CC FLAGS_REG))])]
3007   ""
3008   "")
3010 (define_insn "*zero_extendqisi2_and"
3011   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3012      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3013    (clobber (reg:CC FLAGS_REG))]
3014   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3015   "#"
3016   [(set_attr "type" "alu1")
3017    (set_attr "mode" "SI")])
3019 (define_insn "*zero_extendqisi2_movzbw_and"
3020   [(set (match_operand:SI 0 "register_operand" "=r,r")
3021      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3024   "#"
3025   [(set_attr "type" "imovx,alu1")
3026    (set_attr "mode" "SI")])
3028 (define_insn "*zero_extendqisi2_movzbw"
3029   [(set (match_operand:SI 0 "register_operand" "=r")
3030      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3031   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3032   "movz{bl|x}\t{%1, %0|%0, %1}"
3033   [(set_attr "type" "imovx")
3034    (set_attr "mode" "SI")])
3036 ;; For the movzbl case strip only the clobber
3037 (define_split
3038   [(set (match_operand:SI 0 "register_operand" "")
3039         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3040    (clobber (reg:CC FLAGS_REG))]
3041   "reload_completed 
3042    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3043    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3044   [(set (match_dup 0)
3045         (zero_extend:SI (match_dup 1)))])
3047 ;; When source and destination does not overlap, clear destination
3048 ;; first and then do the movb
3049 (define_split
3050   [(set (match_operand:SI 0 "register_operand" "")
3051         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3052    (clobber (reg:CC FLAGS_REG))]
3053   "reload_completed
3054    && ANY_QI_REG_P (operands[0])
3055    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3056    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3057    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3058   [(set (match_dup 0) (const_int 0))
3059    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3060   "operands[2] = gen_lowpart (QImode, operands[0]);")
3062 ;; Rest is handled by single and.
3063 (define_split
3064   [(set (match_operand:SI 0 "register_operand" "")
3065         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3066    (clobber (reg:CC FLAGS_REG))]
3067   "reload_completed
3068    && true_regnum (operands[0]) == true_regnum (operands[1])"
3069   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3070               (clobber (reg:CC FLAGS_REG))])]
3071   "")
3073 ;; %%% Kill me once multi-word ops are sane.
3074 (define_expand "zero_extendsidi2"
3075   [(set (match_operand:DI 0 "register_operand" "=r")
3076      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3077   ""
3078   "if (!TARGET_64BIT)
3079      {
3080        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3081        DONE;
3082      }
3083   ")
3085 (define_insn "zero_extendsidi2_32"
3086   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3087         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3088    (clobber (reg:CC FLAGS_REG))]
3089   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3090   "@
3091    #
3092    #
3093    #
3094    movd\t{%1, %0|%0, %1}
3095    movd\t{%1, %0|%0, %1}"
3096   [(set_attr "mode" "SI,SI,SI,DI,TI")
3097    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3099 (define_insn "*zero_extendsidi2_32_1"
3100   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3101         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3102    (clobber (reg:CC FLAGS_REG))]
3103   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3104   "@
3105    #
3106    #
3107    #
3108    movd\t{%1, %0|%0, %1}
3109    movd\t{%1, %0|%0, %1}"
3110   [(set_attr "mode" "SI,SI,SI,DI,TI")
3111    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3113 (define_insn "zero_extendsidi2_rex64"
3114   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3115      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3116   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3117   "@
3118    mov\t{%k1, %k0|%k0, %k1}
3119    #
3120    movd\t{%1, %0|%0, %1}
3121    movd\t{%1, %0|%0, %1}"
3122   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3123    (set_attr "mode" "SI,DI,DI,TI")])
3125 (define_insn "*zero_extendsidi2_rex64_1"
3126   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3127      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3128   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3129   "@
3130    mov\t{%k1, %k0|%k0, %k1}
3131    #
3132    movd\t{%1, %0|%0, %1}
3133    movd\t{%1, %0|%0, %1}"
3134   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3135    (set_attr "mode" "SI,DI,SI,SI")])
3137 (define_split
3138   [(set (match_operand:DI 0 "memory_operand" "")
3139      (zero_extend:DI (match_dup 0)))]
3140   "TARGET_64BIT"
3141   [(set (match_dup 4) (const_int 0))]
3142   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3144 (define_split 
3145   [(set (match_operand:DI 0 "register_operand" "")
3146         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3147    (clobber (reg:CC FLAGS_REG))]
3148   "!TARGET_64BIT && reload_completed
3149    && true_regnum (operands[0]) == true_regnum (operands[1])"
3150   [(set (match_dup 4) (const_int 0))]
3151   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3153 (define_split 
3154   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3155         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3156    (clobber (reg:CC FLAGS_REG))]
3157   "!TARGET_64BIT && reload_completed
3158    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3159   [(set (match_dup 3) (match_dup 1))
3160    (set (match_dup 4) (const_int 0))]
3161   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3163 (define_insn "zero_extendhidi2"
3164   [(set (match_operand:DI 0 "register_operand" "=r,r")
3165      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3166   "TARGET_64BIT"
3167   "@
3168    movz{wl|x}\t{%1, %k0|%k0, %1}
3169    movz{wq|x}\t{%1, %0|%0, %1}"
3170   [(set_attr "type" "imovx")
3171    (set_attr "mode" "SI,DI")])
3173 (define_insn "zero_extendqidi2"
3174   [(set (match_operand:DI 0 "register_operand" "=r,r")
3175      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3176   "TARGET_64BIT"
3177   "@
3178    movz{bl|x}\t{%1, %k0|%k0, %1}
3179    movz{bq|x}\t{%1, %0|%0, %1}"
3180   [(set_attr "type" "imovx")
3181    (set_attr "mode" "SI,DI")])
3183 ;; Sign extension instructions
3185 (define_expand "extendsidi2"
3186   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3187                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3188               (clobber (reg:CC FLAGS_REG))
3189               (clobber (match_scratch:SI 2 ""))])]
3190   ""
3192   if (TARGET_64BIT)
3193     {
3194       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3195       DONE;
3196     }
3199 (define_insn "*extendsidi2_1"
3200   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3201         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3202    (clobber (reg:CC FLAGS_REG))
3203    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3204   "!TARGET_64BIT"
3205   "#")
3207 (define_insn "extendsidi2_rex64"
3208   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3209         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3210   "TARGET_64BIT"
3211   "@
3212    {cltq|cdqe}
3213    movs{lq|x}\t{%1,%0|%0, %1}"
3214   [(set_attr "type" "imovx")
3215    (set_attr "mode" "DI")
3216    (set_attr "prefix_0f" "0")
3217    (set_attr "modrm" "0,1")])
3219 (define_insn "extendhidi2"
3220   [(set (match_operand:DI 0 "register_operand" "=r")
3221         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3222   "TARGET_64BIT"
3223   "movs{wq|x}\t{%1,%0|%0, %1}"
3224   [(set_attr "type" "imovx")
3225    (set_attr "mode" "DI")])
3227 (define_insn "extendqidi2"
3228   [(set (match_operand:DI 0 "register_operand" "=r")
3229         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3230   "TARGET_64BIT"
3231   "movs{bq|x}\t{%1,%0|%0, %1}"
3232    [(set_attr "type" "imovx")
3233     (set_attr "mode" "DI")])
3235 ;; Extend to memory case when source register does die.
3236 (define_split 
3237   [(set (match_operand:DI 0 "memory_operand" "")
3238         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3239    (clobber (reg:CC FLAGS_REG))
3240    (clobber (match_operand:SI 2 "register_operand" ""))]
3241   "(reload_completed
3242     && dead_or_set_p (insn, operands[1])
3243     && !reg_mentioned_p (operands[1], operands[0]))"
3244   [(set (match_dup 3) (match_dup 1))
3245    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3246               (clobber (reg:CC FLAGS_REG))])
3247    (set (match_dup 4) (match_dup 1))]
3248   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3250 ;; Extend to memory case when source register does not die.
3251 (define_split 
3252   [(set (match_operand:DI 0 "memory_operand" "")
3253         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3254    (clobber (reg:CC FLAGS_REG))
3255    (clobber (match_operand:SI 2 "register_operand" ""))]
3256   "reload_completed"
3257   [(const_int 0)]
3259   split_di (&operands[0], 1, &operands[3], &operands[4]);
3261   emit_move_insn (operands[3], operands[1]);
3263   /* Generate a cltd if possible and doing so it profitable.  */
3264   if (true_regnum (operands[1]) == 0
3265       && true_regnum (operands[2]) == 1
3266       && (optimize_size || TARGET_USE_CLTD))
3267     {
3268       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3269     }
3270   else
3271     {
3272       emit_move_insn (operands[2], operands[1]);
3273       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3274     }
3275   emit_move_insn (operands[4], operands[2]);
3276   DONE;
3279 ;; Extend to register case.  Optimize case where source and destination
3280 ;; registers match and cases where we can use cltd.
3281 (define_split 
3282   [(set (match_operand:DI 0 "register_operand" "")
3283         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3284    (clobber (reg:CC FLAGS_REG))
3285    (clobber (match_scratch:SI 2 ""))]
3286   "reload_completed"
3287   [(const_int 0)]
3289   split_di (&operands[0], 1, &operands[3], &operands[4]);
3291   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3292     emit_move_insn (operands[3], operands[1]);
3294   /* Generate a cltd if possible and doing so it profitable.  */
3295   if (true_regnum (operands[3]) == 0
3296       && (optimize_size || TARGET_USE_CLTD))
3297     {
3298       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3299       DONE;
3300     }
3302   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3303     emit_move_insn (operands[4], operands[1]);
3305   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3306   DONE;
3309 (define_insn "extendhisi2"
3310   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3311         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3312   ""
3314   switch (get_attr_prefix_0f (insn))
3315     {
3316     case 0:
3317       return "{cwtl|cwde}";
3318     default:
3319       return "movs{wl|x}\t{%1,%0|%0, %1}";
3320     }
3322   [(set_attr "type" "imovx")
3323    (set_attr "mode" "SI")
3324    (set (attr "prefix_0f")
3325      ;; movsx is short decodable while cwtl is vector decoded.
3326      (if_then_else (and (eq_attr "cpu" "!k6")
3327                         (eq_attr "alternative" "0"))
3328         (const_string "0")
3329         (const_string "1")))
3330    (set (attr "modrm")
3331      (if_then_else (eq_attr "prefix_0f" "0")
3332         (const_string "0")
3333         (const_string "1")))])
3335 (define_insn "*extendhisi2_zext"
3336   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3337         (zero_extend:DI
3338           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3339   "TARGET_64BIT"
3341   switch (get_attr_prefix_0f (insn))
3342     {
3343     case 0:
3344       return "{cwtl|cwde}";
3345     default:
3346       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3347     }
3349   [(set_attr "type" "imovx")
3350    (set_attr "mode" "SI")
3351    (set (attr "prefix_0f")
3352      ;; movsx is short decodable while cwtl is vector decoded.
3353      (if_then_else (and (eq_attr "cpu" "!k6")
3354                         (eq_attr "alternative" "0"))
3355         (const_string "0")
3356         (const_string "1")))
3357    (set (attr "modrm")
3358      (if_then_else (eq_attr "prefix_0f" "0")
3359         (const_string "0")
3360         (const_string "1")))])
3362 (define_insn "extendqihi2"
3363   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3364         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3365   ""
3367   switch (get_attr_prefix_0f (insn))
3368     {
3369     case 0:
3370       return "{cbtw|cbw}";
3371     default:
3372       return "movs{bw|x}\t{%1,%0|%0, %1}";
3373     }
3375   [(set_attr "type" "imovx")
3376    (set_attr "mode" "HI")
3377    (set (attr "prefix_0f")
3378      ;; movsx is short decodable while cwtl is vector decoded.
3379      (if_then_else (and (eq_attr "cpu" "!k6")
3380                         (eq_attr "alternative" "0"))
3381         (const_string "0")
3382         (const_string "1")))
3383    (set (attr "modrm")
3384      (if_then_else (eq_attr "prefix_0f" "0")
3385         (const_string "0")
3386         (const_string "1")))])
3388 (define_insn "extendqisi2"
3389   [(set (match_operand:SI 0 "register_operand" "=r")
3390         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3391   ""
3392   "movs{bl|x}\t{%1,%0|%0, %1}"
3393    [(set_attr "type" "imovx")
3394     (set_attr "mode" "SI")])
3396 (define_insn "*extendqisi2_zext"
3397   [(set (match_operand:DI 0 "register_operand" "=r")
3398         (zero_extend:DI
3399           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3400   "TARGET_64BIT"
3401   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3402    [(set_attr "type" "imovx")
3403     (set_attr "mode" "SI")])
3405 ;; Conversions between float and double.
3407 ;; These are all no-ops in the model used for the 80387.  So just
3408 ;; emit moves.
3410 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3411 (define_insn "*dummy_extendsfdf2"
3412   [(set (match_operand:DF 0 "push_operand" "=<")
3413         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3414   "0"
3415   "#")
3417 (define_split
3418   [(set (match_operand:DF 0 "push_operand" "")
3419         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3420   "!TARGET_64BIT"
3421   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3422    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3424 (define_split
3425   [(set (match_operand:DF 0 "push_operand" "")
3426         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3427   "TARGET_64BIT"
3428   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3429    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3431 (define_insn "*dummy_extendsfxf2"
3432   [(set (match_operand:XF 0 "push_operand" "=<")
3433         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3434   "0"
3435   "#")
3437 (define_split
3438   [(set (match_operand:XF 0 "push_operand" "")
3439         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3440   ""
3441   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3442    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3443   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3445 (define_split
3446   [(set (match_operand:XF 0 "push_operand" "")
3447         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3448   "TARGET_64BIT"
3449   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3450    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3451   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3453 (define_split
3454   [(set (match_operand:XF 0 "push_operand" "")
3455         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3456   ""
3457   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3458    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3459   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3461 (define_split
3462   [(set (match_operand:XF 0 "push_operand" "")
3463         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3464   "TARGET_64BIT"
3465   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3466    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3467   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3469 (define_expand "extendsfdf2"
3470   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3471         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3472   "TARGET_80387 || TARGET_SSE2"
3474   /* ??? Needed for compress_float_constant since all fp constants
3475      are LEGITIMATE_CONSTANT_P.  */
3476   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3477     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3478   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3479     operands[1] = force_reg (SFmode, operands[1]);
3482 (define_insn "*extendsfdf2_1"
3483   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3484         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3485   "(TARGET_80387 || TARGET_SSE2)
3486    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3488   switch (which_alternative)
3489     {
3490     case 0:
3491       return output_387_reg_move (insn, operands);
3493     case 1:
3494       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3495         return "fstp%z0\t%y0";
3496       else
3497         return "fst%z0\t%y0";
3499     case 2:
3500       return "cvtss2sd\t{%1, %0|%0, %1}";
3502     default:
3503       abort ();
3504     }
3506   [(set_attr "type" "fmov,fmov,ssecvt")
3507    (set_attr "mode" "SF,XF,DF")])
3509 (define_insn "*extendsfdf2_1_sse_only"
3510   [(set (match_operand:DF 0 "register_operand" "=Y")
3511         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3512   "!TARGET_80387 && TARGET_SSE2
3513    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3514   "cvtss2sd\t{%1, %0|%0, %1}"
3515   [(set_attr "type" "ssecvt")
3516    (set_attr "mode" "DF")])
3518 (define_expand "extendsfxf2"
3519   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3520         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3521   "TARGET_80387"
3523   /* ??? Needed for compress_float_constant since all fp constants
3524      are LEGITIMATE_CONSTANT_P.  */
3525   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3526     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3527   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3528     operands[1] = force_reg (SFmode, operands[1]);
3531 (define_insn "*extendsfxf2_1"
3532   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3533         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3534   "TARGET_80387
3535    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3537   switch (which_alternative)
3538     {
3539     case 0:
3540       return output_387_reg_move (insn, operands);
3542     case 1:
3543       /* There is no non-popping store to memory for XFmode.  So if
3544          we need one, follow the store with a load.  */
3545       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3546         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3547       else
3548         return "fstp%z0\t%y0";
3550     default:
3551       abort ();
3552     }
3554   [(set_attr "type" "fmov")
3555    (set_attr "mode" "SF,XF")])
3557 (define_expand "extenddfxf2"
3558   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3559         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3560   "TARGET_80387"
3562   /* ??? Needed for compress_float_constant since all fp constants
3563      are LEGITIMATE_CONSTANT_P.  */
3564   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3565     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3566   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3567     operands[1] = force_reg (DFmode, operands[1]);
3570 (define_insn "*extenddfxf2_1"
3571   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3572         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3573   "TARGET_80387
3574    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3576   switch (which_alternative)
3577     {
3578     case 0:
3579       return output_387_reg_move (insn, operands);
3581     case 1:
3582       /* There is no non-popping store to memory for XFmode.  So if
3583          we need one, follow the store with a load.  */
3584       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3585         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3586       else
3587         return "fstp%z0\t%y0";
3589     default:
3590       abort ();
3591     }
3593   [(set_attr "type" "fmov")
3594    (set_attr "mode" "DF,XF")])
3596 ;; %%% This seems bad bad news.
3597 ;; This cannot output into an f-reg because there is no way to be sure
3598 ;; of truncating in that case.  Otherwise this is just like a simple move
3599 ;; insn.  So we pretend we can output to a reg in order to get better
3600 ;; register preferencing, but we really use a stack slot.
3602 (define_expand "truncdfsf2"
3603   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3604                    (float_truncate:SF
3605                     (match_operand:DF 1 "register_operand" "")))
3606               (clobber (match_dup 2))])]
3607   "TARGET_80387 || TARGET_SSE2"
3608   "
3609    if (!TARGET_80387)
3610      {
3611         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3612         DONE;
3613      }
3614    else if (flag_unsafe_math_optimizations)
3615      {
3616         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3617         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3618         if (reg != operands[0])
3619           emit_move_insn (operands[0], reg);
3620         DONE;
3621      }
3622    else
3623      operands[2] = assign_386_stack_local (SFmode, 0);
3626 (define_insn "truncdfsf2_noop"
3627   [(set (match_operand:SF 0 "register_operand" "=f")
3628         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3629   "TARGET_80387 && flag_unsafe_math_optimizations"
3631   return output_387_reg_move (insn, operands);
3633   [(set_attr "type" "fmov")
3634    (set_attr "mode" "SF")])
3636 (define_insn "*truncdfsf2_1"
3637   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3638         (float_truncate:SF
3639          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3640    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3641   "TARGET_80387 && !TARGET_SSE2"
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     default:
3651       abort ();
3652     }
3654   [(set_attr "type" "fmov,multi,multi,multi")
3655    (set_attr "mode" "SF,SF,SF,SF")])
3657 (define_insn "*truncdfsf2_1_sse"
3658   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3659         (float_truncate:SF
3660          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3661    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3662   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3664   switch (which_alternative)
3665     {
3666     case 0:
3667       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3668         return "fstp%z0\t%y0";
3669       else
3670         return "fst%z0\t%y0";
3671     case 4:
3672       return "#";
3673     default:
3674       abort ();
3675     }
3677   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3678    (set_attr "mode" "SF,SF,SF,SF,DF")])
3680 (define_insn "*truncdfsf2_1_sse_nooverlap"
3681   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3682         (float_truncate:SF
3683          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3684    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3685   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3687   switch (which_alternative)
3688     {
3689     case 0:
3690       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3691         return "fstp%z0\t%y0";
3692       else
3693         return "fst%z0\t%y0";
3694     case 4:
3695       return "#";
3696     default:
3697       abort ();
3698     }
3700   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3701    (set_attr "mode" "SF,SF,SF,SF,DF")])
3703 (define_insn "*truncdfsf2_2"
3704   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3705         (float_truncate:SF
3706          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3707   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3708    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3710   switch (which_alternative)
3711     {
3712     case 0:
3713     case 1:
3714       return "cvtsd2ss\t{%1, %0|%0, %1}";
3715     case 2:
3716       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3717         return "fstp%z0\t%y0";
3718       else
3719         return "fst%z0\t%y0";
3720     default:
3721       abort ();
3722     }
3724   [(set_attr "type" "ssecvt,ssecvt,fmov")
3725    (set_attr "athlon_decode" "vector,double,*")
3726    (set_attr "mode" "SF,SF,SF")])
3728 (define_insn "*truncdfsf2_2_nooverlap"
3729   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3730         (float_truncate:SF
3731          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3732   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3733    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3735   switch (which_alternative)
3736     {
3737     case 0:
3738       return "#";
3739     case 1:
3740       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3741         return "fstp%z0\t%y0";
3742       else
3743         return "fst%z0\t%y0";
3744     default:
3745       abort ();
3746     }
3748   [(set_attr "type" "ssecvt,fmov")
3749    (set_attr "mode" "DF,SF")])
3751 (define_insn "*truncdfsf2_3"
3752   [(set (match_operand:SF 0 "memory_operand" "=m")
3753         (float_truncate:SF
3754          (match_operand:DF 1 "register_operand" "f")))]
3755   "TARGET_80387"
3757   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3758     return "fstp%z0\t%y0";
3759   else
3760     return "fst%z0\t%y0";
3762   [(set_attr "type" "fmov")
3763    (set_attr "mode" "SF")])
3765 (define_insn "truncdfsf2_sse_only"
3766   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3767         (float_truncate:SF
3768          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3769   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3770   "cvtsd2ss\t{%1, %0|%0, %1}"
3771   [(set_attr "type" "ssecvt")
3772    (set_attr "athlon_decode" "vector,double")
3773    (set_attr "mode" "SF")])
3775 (define_insn "*truncdfsf2_sse_only_nooverlap"
3776   [(set (match_operand:SF 0 "register_operand" "=&Y")
3777         (float_truncate:SF
3778          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3779   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3780   "#"
3781   [(set_attr "type" "ssecvt")
3782    (set_attr "mode" "DF")])
3784 (define_split
3785   [(set (match_operand:SF 0 "memory_operand" "")
3786         (float_truncate:SF
3787          (match_operand:DF 1 "register_operand" "")))
3788    (clobber (match_operand:SF 2 "memory_operand" ""))]
3789   "TARGET_80387"
3790   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3791   "")
3793 ; Avoid possible reformatting penalty on the destination by first
3794 ; zeroing it out
3795 (define_split
3796   [(set (match_operand:SF 0 "register_operand" "")
3797         (float_truncate:SF
3798          (match_operand:DF 1 "nonimmediate_operand" "")))
3799    (clobber (match_operand 2 "" ""))]
3800   "TARGET_80387 && reload_completed
3801    && SSE_REG_P (operands[0])
3802    && !STACK_REG_P (operands[1])"
3803   [(const_int 0)]
3805   rtx src, dest;
3806   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3807     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3808   else
3809     {
3810       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3811       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3812       /* simplify_gen_subreg refuses to widen memory references.  */
3813       if (GET_CODE (src) == SUBREG)
3814         alter_subreg (&src);
3815       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3816         abort ();
3817       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3818       emit_insn (gen_cvtsd2ss (dest, dest, src));
3819     }
3820   DONE;
3823 (define_split
3824   [(set (match_operand:SF 0 "register_operand" "")
3825         (float_truncate:SF
3826          (match_operand:DF 1 "nonimmediate_operand" "")))]
3827   "TARGET_80387 && reload_completed
3828    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3829   [(const_int 0)]
3831   rtx src, dest;
3832   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3833   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3834   /* simplify_gen_subreg refuses to widen memory references.  */
3835   if (GET_CODE (src) == SUBREG)
3836     alter_subreg (&src);
3837   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3838     abort ();
3839   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3840   emit_insn (gen_cvtsd2ss (dest, dest, src));
3841   DONE;
3844 (define_split
3845   [(set (match_operand:SF 0 "register_operand" "")
3846         (float_truncate:SF
3847          (match_operand:DF 1 "fp_register_operand" "")))
3848    (clobber (match_operand:SF 2 "memory_operand" ""))]
3849   "TARGET_80387 && reload_completed"
3850   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3851    (set (match_dup 0) (match_dup 2))]
3852   "")
3854 (define_expand "truncxfsf2"
3855   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3856                    (float_truncate:SF
3857                     (match_operand:XF 1 "register_operand" "")))
3858               (clobber (match_dup 2))])]
3859   "TARGET_80387"
3860   "
3861   if (flag_unsafe_math_optimizations)
3862     {
3863       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3864       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3865       if (reg != operands[0])
3866         emit_move_insn (operands[0], reg);
3867       DONE;
3868     }
3869   else
3870     operands[2] = assign_386_stack_local (SFmode, 0);
3871   ")
3873 (define_insn "truncxfsf2_noop"
3874   [(set (match_operand:SF 0 "register_operand" "=f")
3875         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3876   "TARGET_80387 && flag_unsafe_math_optimizations"
3878   return output_387_reg_move (insn, operands);
3880   [(set_attr "type" "fmov")
3881    (set_attr "mode" "SF")])
3883 (define_insn "*truncxfsf2_1"
3884   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3885         (float_truncate:SF
3886          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3887    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3888   "TARGET_80387"
3890   switch (which_alternative)
3891     {
3892     case 0:
3893       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3894         return "fstp%z0\t%y0";
3895       else
3896         return "fst%z0\t%y0";
3897     default:
3898       abort();
3899     }
3901   [(set_attr "type" "fmov,multi,multi,multi")
3902    (set_attr "mode" "SF")])
3904 (define_insn "*truncxfsf2_2"
3905   [(set (match_operand:SF 0 "memory_operand" "=m")
3906         (float_truncate:SF
3907          (match_operand:XF 1 "register_operand" "f")))]
3908   "TARGET_80387"
3910   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3911     return "fstp%z0\t%y0";
3912   else
3913     return "fst%z0\t%y0";
3915   [(set_attr "type" "fmov")
3916    (set_attr "mode" "SF")])
3918 (define_split
3919   [(set (match_operand:SF 0 "memory_operand" "")
3920         (float_truncate:SF
3921          (match_operand:XF 1 "register_operand" "")))
3922    (clobber (match_operand:SF 2 "memory_operand" ""))]
3923   "TARGET_80387"
3924   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3925   "")
3927 (define_split
3928   [(set (match_operand:SF 0 "register_operand" "")
3929         (float_truncate:SF
3930          (match_operand:XF 1 "register_operand" "")))
3931    (clobber (match_operand:SF 2 "memory_operand" ""))]
3932   "TARGET_80387 && reload_completed"
3933   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3934    (set (match_dup 0) (match_dup 2))]
3935   "")
3937 (define_expand "truncxfdf2"
3938   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3939                    (float_truncate:DF
3940                     (match_operand:XF 1 "register_operand" "")))
3941               (clobber (match_dup 2))])]
3942   "TARGET_80387"
3943   "
3944   if (flag_unsafe_math_optimizations)
3945     {
3946       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3947       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3948       if (reg != operands[0])
3949         emit_move_insn (operands[0], reg);
3950       DONE;
3951     }
3952   else
3953     operands[2] = assign_386_stack_local (DFmode, 0);
3954   ")
3956 (define_insn "truncxfdf2_noop"
3957   [(set (match_operand:DF 0 "register_operand" "=f")
3958         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3959   "TARGET_80387 && flag_unsafe_math_optimizations"
3961   return output_387_reg_move (insn, operands);
3963   [(set_attr "type" "fmov")
3964    (set_attr "mode" "DF")])
3966 (define_insn "*truncxfdf2_1"
3967   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3968         (float_truncate:DF
3969          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3970    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3971   "TARGET_80387"
3973   switch (which_alternative)
3974     {
3975     case 0:
3976       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977         return "fstp%z0\t%y0";
3978       else
3979         return "fst%z0\t%y0";
3980     default:
3981       abort();
3982     }
3983   abort ();
3985   [(set_attr "type" "fmov,multi,multi,multi")
3986    (set_attr "mode" "DF")])
3988 (define_insn "*truncxfdf2_2"
3989   [(set (match_operand:DF 0 "memory_operand" "=m")
3990         (float_truncate:DF
3991           (match_operand:XF 1 "register_operand" "f")))]
3992   "TARGET_80387"
3994   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3995     return "fstp%z0\t%y0";
3996   else
3997     return "fst%z0\t%y0";
3999   [(set_attr "type" "fmov")
4000    (set_attr "mode" "DF")])
4002 (define_split
4003   [(set (match_operand:DF 0 "memory_operand" "")
4004         (float_truncate:DF
4005          (match_operand:XF 1 "register_operand" "")))
4006    (clobber (match_operand:DF 2 "memory_operand" ""))]
4007   "TARGET_80387"
4008   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4009   "")
4011 (define_split
4012   [(set (match_operand:DF 0 "register_operand" "")
4013         (float_truncate:DF
4014          (match_operand:XF 1 "register_operand" "")))
4015    (clobber (match_operand:DF 2 "memory_operand" ""))]
4016   "TARGET_80387 && reload_completed"
4017   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4018    (set (match_dup 0) (match_dup 2))]
4019   "")
4022 ;; %%% Break up all these bad boys.
4024 ;; Signed conversion to DImode.
4026 (define_expand "fix_truncxfdi2"
4027   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4029               (clobber (reg:CC FLAGS_REG))])]
4030   "TARGET_80387"
4031   "")
4033 (define_expand "fix_truncdfdi2"
4034   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4035                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4036               (clobber (reg:CC FLAGS_REG))])]
4037   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4039   if (TARGET_64BIT && TARGET_SSE2)
4040    {
4041      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4042      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4043      if (out != operands[0])
4044         emit_move_insn (operands[0], out);
4045      DONE;
4046    }
4049 (define_expand "fix_truncsfdi2"
4050   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4051                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4052               (clobber (reg:CC FLAGS_REG))])] 
4053   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4055   if (TARGET_SSE && TARGET_64BIT)
4056    {
4057      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4058      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4059      if (out != operands[0])
4060         emit_move_insn (operands[0], out);
4061      DONE;
4062    }
4065 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4066 ;; of the machinery.
4067 (define_insn_and_split "*fix_truncdi_1"
4068   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4069         (fix:DI (match_operand 1 "register_operand" "f,f")))
4070    (clobber (reg:CC FLAGS_REG))]
4071   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4072    && !reload_completed && !reload_in_progress
4073    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4074   "#"
4075   "&& 1"
4076   [(const_int 0)]
4078   ix86_optimize_mode_switching = 1;
4079   operands[2] = assign_386_stack_local (HImode, 1);
4080   operands[3] = assign_386_stack_local (HImode, 2);
4081   if (memory_operand (operands[0], VOIDmode))
4082     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4083                                        operands[2], operands[3]));
4084   else
4085     {
4086       operands[4] = assign_386_stack_local (DImode, 0);
4087       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4088                                            operands[2], operands[3],
4089                                            operands[4]));
4090     }
4091   DONE;
4093   [(set_attr "type" "fistp")
4094    (set_attr "mode" "DI")])
4096 (define_insn "fix_truncdi_nomemory"
4097   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4098         (fix:DI (match_operand 1 "register_operand" "f,f")))
4099    (use (match_operand:HI 2 "memory_operand" "m,m"))
4100    (use (match_operand:HI 3 "memory_operand" "m,m"))
4101    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4102    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4103   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4104    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4105   "#"
4106   [(set_attr "type" "fistp")
4107    (set_attr "mode" "DI")])
4109 (define_insn "fix_truncdi_memory"
4110   [(set (match_operand:DI 0 "memory_operand" "=m")
4111         (fix:DI (match_operand 1 "register_operand" "f")))
4112    (use (match_operand:HI 2 "memory_operand" "m"))
4113    (use (match_operand:HI 3 "memory_operand" "m"))
4114    (clobber (match_scratch:DF 4 "=&1f"))]
4115   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4116    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4117   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4118   [(set_attr "type" "fistp")
4119    (set_attr "mode" "DI")])
4121 (define_split 
4122   [(set (match_operand:DI 0 "register_operand" "")
4123         (fix:DI (match_operand 1 "register_operand" "")))
4124    (use (match_operand:HI 2 "memory_operand" ""))
4125    (use (match_operand:HI 3 "memory_operand" ""))
4126    (clobber (match_operand:DI 4 "memory_operand" ""))
4127    (clobber (match_scratch 5 ""))]
4128   "reload_completed"
4129   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4130               (use (match_dup 2))
4131               (use (match_dup 3))
4132               (clobber (match_dup 5))])
4133    (set (match_dup 0) (match_dup 4))]
4134   "")
4136 (define_split 
4137   [(set (match_operand:DI 0 "memory_operand" "")
4138         (fix:DI (match_operand 1 "register_operand" "")))
4139    (use (match_operand:HI 2 "memory_operand" ""))
4140    (use (match_operand:HI 3 "memory_operand" ""))
4141    (clobber (match_operand:DI 4 "memory_operand" ""))
4142    (clobber (match_scratch 5 ""))]
4143   "reload_completed"
4144   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4145               (use (match_dup 2))
4146               (use (match_dup 3))
4147               (clobber (match_dup 5))])]
4148   "")
4150 ;; When SSE available, it is always faster to use it!
4151 (define_insn "fix_truncsfdi_sse"
4152   [(set (match_operand:DI 0 "register_operand" "=r,r")
4153         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4154   "TARGET_64BIT && TARGET_SSE"
4155   "cvttss2si{q}\t{%1, %0|%0, %1}"
4156   [(set_attr "type" "sseicvt")
4157    (set_attr "mode" "SF")
4158    (set_attr "athlon_decode" "double,vector")])
4160 ;; Avoid vector decoded form of the instruction.
4161 (define_peephole2
4162   [(match_scratch:SF 2 "x")
4163    (set (match_operand:DI 0 "register_operand" "")
4164         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4165   "TARGET_K8 && !optimize_size"
4166   [(set (match_dup 2) (match_dup 1))
4167    (set (match_dup 0) (fix:DI (match_dup 2)))]
4168   "")
4170 (define_insn "fix_truncdfdi_sse"
4171   [(set (match_operand:DI 0 "register_operand" "=r,r")
4172         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4173   "TARGET_64BIT && TARGET_SSE2"
4174   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4175   [(set_attr "type" "sseicvt,sseicvt")
4176    (set_attr "mode" "DF")
4177    (set_attr "athlon_decode" "double,vector")])
4179 ;; Avoid vector decoded form of the instruction.
4180 (define_peephole2
4181   [(match_scratch:DF 2 "Y")
4182    (set (match_operand:DI 0 "register_operand" "")
4183         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4184   "TARGET_K8 && !optimize_size"
4185   [(set (match_dup 2) (match_dup 1))
4186    (set (match_dup 0) (fix:DI (match_dup 2)))]
4187   "")
4189 ;; Signed conversion to SImode.
4191 (define_expand "fix_truncxfsi2"
4192   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4193                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4194               (clobber (reg:CC FLAGS_REG))])]
4195   "TARGET_80387"
4196   "")
4198 (define_expand "fix_truncdfsi2"
4199   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4200                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4201               (clobber (reg:CC FLAGS_REG))])]
4202   "TARGET_80387 || TARGET_SSE2"
4204   if (TARGET_SSE2)
4205    {
4206      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4207      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4208      if (out != operands[0])
4209         emit_move_insn (operands[0], out);
4210      DONE;
4211    }
4214 (define_expand "fix_truncsfsi2"
4215   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4216                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4217               (clobber (reg:CC FLAGS_REG))])] 
4218   "TARGET_80387 || TARGET_SSE"
4220   if (TARGET_SSE)
4221    {
4222      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4223      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4224      if (out != operands[0])
4225         emit_move_insn (operands[0], out);
4226      DONE;
4227    }
4230 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4231 ;; of the machinery.
4232 (define_insn_and_split "*fix_truncsi_1"
4233   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4234         (fix:SI (match_operand 1 "register_operand" "f,f")))
4235    (clobber (reg:CC FLAGS_REG))]
4236   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4237    && !reload_completed && !reload_in_progress
4238    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4239   "#"
4240   "&& 1"
4241   [(const_int 0)]
4243   ix86_optimize_mode_switching = 1;
4244   operands[2] = assign_386_stack_local (HImode, 1);
4245   operands[3] = assign_386_stack_local (HImode, 2);
4246   if (memory_operand (operands[0], VOIDmode))
4247     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4248                                        operands[2], operands[3]));
4249   else
4250     {
4251       operands[4] = assign_386_stack_local (SImode, 0);
4252       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4253                                            operands[2], operands[3],
4254                                            operands[4]));
4255     }
4256   DONE;
4258   [(set_attr "type" "fistp")
4259    (set_attr "mode" "SI")])
4261 (define_insn "fix_truncsi_nomemory"
4262   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4263         (fix:SI (match_operand 1 "register_operand" "f,f")))
4264    (use (match_operand:HI 2 "memory_operand" "m,m"))
4265    (use (match_operand:HI 3 "memory_operand" "m,m"))
4266    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4267   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4268    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4269   "#"
4270   [(set_attr "type" "fistp")
4271    (set_attr "mode" "SI")])
4273 (define_insn "fix_truncsi_memory"
4274   [(set (match_operand:SI 0 "memory_operand" "=m")
4275         (fix:SI (match_operand 1 "register_operand" "f")))
4276    (use (match_operand:HI 2 "memory_operand" "m"))
4277    (use (match_operand:HI 3 "memory_operand" "m"))]
4278   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4279    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4280   "* return output_fix_trunc (insn, operands);"
4281   [(set_attr "type" "fistp")
4282    (set_attr "mode" "SI")])
4284 ;; When SSE available, it is always faster to use it!
4285 (define_insn "fix_truncsfsi_sse"
4286   [(set (match_operand:SI 0 "register_operand" "=r,r")
4287         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4288   "TARGET_SSE"
4289   "cvttss2si\t{%1, %0|%0, %1}"
4290   [(set_attr "type" "sseicvt")
4291    (set_attr "mode" "DF")
4292    (set_attr "athlon_decode" "double,vector")])
4294 ;; Avoid vector decoded form of the instruction.
4295 (define_peephole2
4296   [(match_scratch:SF 2 "x")
4297    (set (match_operand:SI 0 "register_operand" "")
4298         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4299   "TARGET_K8 && !optimize_size"
4300   [(set (match_dup 2) (match_dup 1))
4301    (set (match_dup 0) (fix:SI (match_dup 2)))]
4302   "")
4304 (define_insn "fix_truncdfsi_sse"
4305   [(set (match_operand:SI 0 "register_operand" "=r,r")
4306         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4307   "TARGET_SSE2"
4308   "cvttsd2si\t{%1, %0|%0, %1}"
4309   [(set_attr "type" "sseicvt")
4310    (set_attr "mode" "DF")
4311    (set_attr "athlon_decode" "double,vector")])
4313 ;; Avoid vector decoded form of the instruction.
4314 (define_peephole2
4315   [(match_scratch:DF 2 "Y")
4316    (set (match_operand:SI 0 "register_operand" "")
4317         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4318   "TARGET_K8 && !optimize_size"
4319   [(set (match_dup 2) (match_dup 1))
4320    (set (match_dup 0) (fix:SI (match_dup 2)))]
4321   "")
4323 (define_split 
4324   [(set (match_operand:SI 0 "register_operand" "")
4325         (fix:SI (match_operand 1 "register_operand" "")))
4326    (use (match_operand:HI 2 "memory_operand" ""))
4327    (use (match_operand:HI 3 "memory_operand" ""))
4328    (clobber (match_operand:SI 4 "memory_operand" ""))]
4329   "reload_completed"
4330   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4331               (use (match_dup 2))
4332               (use (match_dup 3))])
4333    (set (match_dup 0) (match_dup 4))]
4334   "")
4336 (define_split 
4337   [(set (match_operand:SI 0 "memory_operand" "")
4338         (fix:SI (match_operand 1 "register_operand" "")))
4339    (use (match_operand:HI 2 "memory_operand" ""))
4340    (use (match_operand:HI 3 "memory_operand" ""))
4341    (clobber (match_operand:SI 4 "memory_operand" ""))]
4342   "reload_completed"
4343   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4344               (use (match_dup 2))
4345               (use (match_dup 3))])]
4346   "")
4348 ;; Signed conversion to HImode.
4350 (define_expand "fix_truncxfhi2"
4351   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4352                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4353               (clobber (reg:CC FLAGS_REG))])] 
4354   "TARGET_80387"
4355   "")
4357 (define_expand "fix_truncdfhi2"
4358   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4359                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4360               (clobber (reg:CC FLAGS_REG))])]
4361   "TARGET_80387 && !TARGET_SSE2"
4362   "")
4364 (define_expand "fix_truncsfhi2"
4365   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4366                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4367                (clobber (reg:CC FLAGS_REG))])]
4368   "TARGET_80387 && !TARGET_SSE"
4369   "")
4371 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4372 ;; of the machinery.
4373 (define_insn_and_split "*fix_trunchi_1"
4374   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4375         (fix:HI (match_operand 1 "register_operand" "f,f")))
4376    (clobber (reg:CC FLAGS_REG))]
4377   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4378    && !reload_completed && !reload_in_progress
4379    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4380   "#"
4381   ""
4382   [(const_int 0)]
4384   ix86_optimize_mode_switching = 1;
4385   operands[2] = assign_386_stack_local (HImode, 1);
4386   operands[3] = assign_386_stack_local (HImode, 2);
4387   if (memory_operand (operands[0], VOIDmode))
4388     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4389                                        operands[2], operands[3]));
4390   else
4391     {
4392       operands[4] = assign_386_stack_local (HImode, 0);
4393       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4394                                            operands[2], operands[3],
4395                                            operands[4]));
4396     }
4397   DONE;
4399   [(set_attr "type" "fistp")
4400    (set_attr "mode" "HI")])
4402 (define_insn "fix_trunchi_nomemory"
4403   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4404         (fix:HI (match_operand 1 "register_operand" "f,f")))
4405    (use (match_operand:HI 2 "memory_operand" "m,m"))
4406    (use (match_operand:HI 3 "memory_operand" "m,m"))
4407    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4408   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4409    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4410   "#"
4411   [(set_attr "type" "fistp")
4412    (set_attr "mode" "HI")])
4414 (define_insn "fix_trunchi_memory"
4415   [(set (match_operand:HI 0 "memory_operand" "=m")
4416         (fix:HI (match_operand 1 "register_operand" "f")))
4417    (use (match_operand:HI 2 "memory_operand" "m"))
4418    (use (match_operand:HI 3 "memory_operand" "m"))]
4419   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4420    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4421   "* return output_fix_trunc (insn, operands);"
4422   [(set_attr "type" "fistp")
4423    (set_attr "mode" "HI")])
4425 (define_split 
4426   [(set (match_operand:HI 0 "memory_operand" "")
4427         (fix:HI (match_operand 1 "register_operand" "")))
4428    (use (match_operand:HI 2 "memory_operand" ""))
4429    (use (match_operand:HI 3 "memory_operand" ""))
4430    (clobber (match_operand:HI 4 "memory_operand" ""))]
4431   "reload_completed"
4432   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4433               (use (match_dup 2))
4434               (use (match_dup 3))])]
4435   "")
4437 (define_split 
4438   [(set (match_operand:HI 0 "register_operand" "")
4439         (fix:HI (match_operand 1 "register_operand" "")))
4440    (use (match_operand:HI 2 "memory_operand" ""))
4441    (use (match_operand:HI 3 "memory_operand" ""))
4442    (clobber (match_operand:HI 4 "memory_operand" ""))]
4443   "reload_completed"
4444   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4445               (use (match_dup 2))
4446               (use (match_dup 3))
4447               (clobber (match_dup 4))])
4448    (set (match_dup 0) (match_dup 4))]
4449   "")
4451 ;; %% Not used yet.
4452 (define_insn "x86_fnstcw_1"
4453   [(set (match_operand:HI 0 "memory_operand" "=m")
4454         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4455   "TARGET_80387"
4456   "fnstcw\t%0"
4457   [(set_attr "length" "2")
4458    (set_attr "mode" "HI")
4459    (set_attr "unit" "i387")])
4461 (define_insn "x86_fldcw_1"
4462   [(set (reg:HI FPSR_REG)
4463         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4464   "TARGET_80387"
4465   "fldcw\t%0"
4466   [(set_attr "length" "2")
4467    (set_attr "mode" "HI")
4468    (set_attr "unit" "i387")
4469    (set_attr "athlon_decode" "vector")])
4471 ;; Conversion between fixed point and floating point.
4473 ;; Even though we only accept memory inputs, the backend _really_
4474 ;; wants to be able to do this between registers.
4476 (define_expand "floathisf2"
4477   [(set (match_operand:SF 0 "register_operand" "")
4478         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4479   "TARGET_SSE || TARGET_80387"
4481   if (TARGET_SSE && TARGET_SSE_MATH)
4482     {
4483       emit_insn (gen_floatsisf2 (operands[0],
4484                                  convert_to_mode (SImode, operands[1], 0)));
4485       DONE;
4486     }
4489 (define_insn "*floathisf2_1"
4490   [(set (match_operand:SF 0 "register_operand" "=f,f")
4491         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4492   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4493   "@
4494    fild%z1\t%1
4495    #"
4496   [(set_attr "type" "fmov,multi")
4497    (set_attr "mode" "SF")
4498    (set_attr "fp_int_src" "true")])
4500 (define_expand "floatsisf2"
4501   [(set (match_operand:SF 0 "register_operand" "")
4502         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4503   "TARGET_SSE || TARGET_80387"
4504   "")
4506 (define_insn "*floatsisf2_i387"
4507   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4508         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4509   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4510   "@
4511    fild%z1\t%1
4512    #
4513    cvtsi2ss\t{%1, %0|%0, %1}
4514    cvtsi2ss\t{%1, %0|%0, %1}"
4515   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4516    (set_attr "mode" "SF")
4517    (set_attr "athlon_decode" "*,*,vector,double")
4518    (set_attr "fp_int_src" "true")])
4520 (define_insn "*floatsisf2_sse"
4521   [(set (match_operand:SF 0 "register_operand" "=x,x")
4522         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4523   "TARGET_SSE"
4524   "cvtsi2ss\t{%1, %0|%0, %1}"
4525   [(set_attr "type" "sseicvt")
4526    (set_attr "mode" "SF")
4527    (set_attr "athlon_decode" "vector,double")
4528    (set_attr "fp_int_src" "true")])
4530 ; Avoid possible reformatting penalty on the destination by first
4531 ; zeroing it out
4532 (define_split
4533   [(set (match_operand:SF 0 "register_operand" "")
4534         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4535   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4536    && SSE_REG_P (operands[0])"
4537   [(const_int 0)]
4539   rtx dest;
4540   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4541   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4542   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4543   DONE;
4546 (define_expand "floatdisf2"
4547   [(set (match_operand:SF 0 "register_operand" "")
4548         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4549   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4550   "")
4552 (define_insn "*floatdisf2_i387_only"
4553   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4554         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4555   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4556   "@
4557    fild%z1\t%1
4558    #"
4559   [(set_attr "type" "fmov,multi")
4560    (set_attr "mode" "SF")
4561    (set_attr "fp_int_src" "true")])
4563 (define_insn "*floatdisf2_i387"
4564   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4565         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4566   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4567   "@
4568    fild%z1\t%1
4569    #
4570    cvtsi2ss{q}\t{%1, %0|%0, %1}
4571    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4572   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4573    (set_attr "mode" "SF")
4574    (set_attr "athlon_decode" "*,*,vector,double")
4575    (set_attr "fp_int_src" "true")])
4577 (define_insn "*floatdisf2_sse"
4578   [(set (match_operand:SF 0 "register_operand" "=x,x")
4579         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4580   "TARGET_64BIT && TARGET_SSE"
4581   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4582   [(set_attr "type" "sseicvt")
4583    (set_attr "mode" "SF")
4584    (set_attr "athlon_decode" "vector,double")
4585    (set_attr "fp_int_src" "true")])
4587 ; Avoid possible reformatting penalty on the destination by first
4588 ; zeroing it out
4589 (define_split
4590   [(set (match_operand:SF 0 "register_operand" "")
4591         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4592   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4593    && SSE_REG_P (operands[0])"
4594   [(const_int 0)]
4596   rtx dest;
4597   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4598   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4599   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4600   DONE;
4603 (define_expand "floathidf2"
4604   [(set (match_operand:DF 0 "register_operand" "")
4605         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4606   "TARGET_SSE2 || TARGET_80387"
4608   if (TARGET_SSE && TARGET_SSE_MATH)
4609     {
4610       emit_insn (gen_floatsidf2 (operands[0],
4611                                  convert_to_mode (SImode, operands[1], 0)));
4612       DONE;
4613     }
4616 (define_insn "*floathidf2_1"
4617   [(set (match_operand:DF 0 "register_operand" "=f,f")
4618         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4619   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4620   "@
4621    fild%z1\t%1
4622    #"
4623   [(set_attr "type" "fmov,multi")
4624    (set_attr "mode" "DF")
4625    (set_attr "fp_int_src" "true")])
4627 (define_expand "floatsidf2"
4628   [(set (match_operand:DF 0 "register_operand" "")
4629         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4630   "TARGET_80387 || TARGET_SSE2"
4631   "")
4633 (define_insn "*floatsidf2_i387"
4634   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4635         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4636   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4637   "@
4638    fild%z1\t%1
4639    #
4640    cvtsi2sd\t{%1, %0|%0, %1}
4641    cvtsi2sd\t{%1, %0|%0, %1}"
4642   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4643    (set_attr "mode" "DF")
4644    (set_attr "athlon_decode" "*,*,double,direct")
4645    (set_attr "fp_int_src" "true")])
4647 (define_insn "*floatsidf2_sse"
4648   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4649         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4650   "TARGET_SSE2"
4651   "cvtsi2sd\t{%1, %0|%0, %1}"
4652   [(set_attr "type" "sseicvt")
4653    (set_attr "mode" "DF")
4654    (set_attr "athlon_decode" "double,direct")
4655    (set_attr "fp_int_src" "true")])
4657 (define_expand "floatdidf2"
4658   [(set (match_operand:DF 0 "register_operand" "")
4659         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4660   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4661   "")
4663 (define_insn "*floatdidf2_i387_only"
4664   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4665         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4666   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4667   "@
4668    fild%z1\t%1
4669    #"
4670   [(set_attr "type" "fmov,multi")
4671    (set_attr "mode" "DF")
4672    (set_attr "fp_int_src" "true")])
4674 (define_insn "*floatdidf2_i387"
4675   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4676         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4677   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4678   "@
4679    fild%z1\t%1
4680    #
4681    cvtsi2sd{q}\t{%1, %0|%0, %1}
4682    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4683   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4684    (set_attr "mode" "DF")
4685    (set_attr "athlon_decode" "*,*,double,direct")
4686    (set_attr "fp_int_src" "true")])
4688 (define_insn "*floatdidf2_sse"
4689   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4690         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4691   "TARGET_SSE2"
4692   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4693   [(set_attr "type" "sseicvt")
4694    (set_attr "mode" "DF")
4695    (set_attr "athlon_decode" "double,direct")
4696    (set_attr "fp_int_src" "true")])
4698 (define_insn "floathixf2"
4699   [(set (match_operand:XF 0 "register_operand" "=f,f")
4700         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4701   "TARGET_80387"
4702   "@
4703    fild%z1\t%1
4704    #"
4705   [(set_attr "type" "fmov,multi")
4706    (set_attr "mode" "XF")
4707    (set_attr "fp_int_src" "true")])
4709 (define_insn "floatsixf2"
4710   [(set (match_operand:XF 0 "register_operand" "=f,f")
4711         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4712   "TARGET_80387"
4713   "@
4714    fild%z1\t%1
4715    #"
4716   [(set_attr "type" "fmov,multi")
4717    (set_attr "mode" "XF")
4718    (set_attr "fp_int_src" "true")])
4720 (define_insn "floatdixf2"
4721   [(set (match_operand:XF 0 "register_operand" "=f,f")
4722         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4723   "TARGET_80387"
4724   "@
4725    fild%z1\t%1
4726    #"
4727   [(set_attr "type" "fmov,multi")
4728    (set_attr "mode" "XF")
4729    (set_attr "fp_int_src" "true")])
4731 ;; %%% Kill these when reload knows how to do it.
4732 (define_split
4733   [(set (match_operand 0 "fp_register_operand" "")
4734         (float (match_operand 1 "register_operand" "")))]
4735   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4736   [(const_int 0)]
4738   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4739   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4740   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4741   ix86_free_from_memory (GET_MODE (operands[1]));
4742   DONE;
4745 (define_expand "floatunssisf2"
4746   [(use (match_operand:SF 0 "register_operand" ""))
4747    (use (match_operand:SI 1 "register_operand" ""))]
4748   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4749   "x86_emit_floatuns (operands); DONE;")
4751 (define_expand "floatunsdisf2"
4752   [(use (match_operand:SF 0 "register_operand" ""))
4753    (use (match_operand:DI 1 "register_operand" ""))]
4754   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4755   "x86_emit_floatuns (operands); DONE;")
4757 (define_expand "floatunsdidf2"
4758   [(use (match_operand:DF 0 "register_operand" ""))
4759    (use (match_operand:DI 1 "register_operand" ""))]
4760   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4761   "x86_emit_floatuns (operands); DONE;")
4763 ;; SSE extract/set expanders
4765 (define_expand "vec_setv2df"
4766   [(match_operand:V2DF 0 "register_operand" "")
4767    (match_operand:DF 1 "register_operand" "")
4768    (match_operand 2 "const_int_operand" "")]
4769   "TARGET_SSE2"
4771   switch (INTVAL (operands[2]))
4772     {
4773     case 0:
4774       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4775                                  simplify_gen_subreg (V2DFmode, operands[1],
4776                                                       DFmode, 0)));
4777       break;
4778     case 1:
4779       {
4780         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4782         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4783       }
4784       break;
4785     default:
4786       abort ();
4787     }
4788   DONE;
4791 (define_expand "vec_extractv2df"
4792   [(match_operand:DF 0 "register_operand" "")
4793    (match_operand:V2DF 1 "register_operand" "")
4794    (match_operand 2 "const_int_operand" "")]
4795   "TARGET_SSE2"
4797   switch (INTVAL (operands[2]))
4798     {
4799     case 0:
4800       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4801       break;
4802     case 1:
4803       {
4804         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4806         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4807       }
4808       break;
4809     default:
4810       abort ();
4811     }
4812   DONE;
4815 (define_expand "vec_initv2df"
4816   [(match_operand:V2DF 0 "register_operand" "")
4817    (match_operand 1 "" "")]
4818   "TARGET_SSE2"
4820   ix86_expand_vector_init (operands[0], operands[1]);
4821   DONE;
4824 (define_expand "vec_setv4sf"
4825   [(match_operand:V4SF 0 "register_operand" "")
4826    (match_operand:SF 1 "register_operand" "")
4827    (match_operand 2 "const_int_operand" "")]
4828   "TARGET_SSE"
4830   switch (INTVAL (operands[2]))
4831     {
4832     case 0:
4833       emit_insn (gen_sse_movss (operands[0], operands[0],
4834                                 simplify_gen_subreg (V4SFmode, operands[1],
4835                                                      SFmode, 0)));
4836       break;
4837     case 1:
4838       {
4839         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4840         rtx tmp = gen_reg_rtx (V4SFmode);
4842         emit_move_insn (tmp, operands[0]);
4843         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4844         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4845         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4846                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4847       }
4848       break;
4849     case 2:
4850       {
4851         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4852         rtx tmp = gen_reg_rtx (V4SFmode);
4854         emit_move_insn (tmp, operands[0]);
4855         emit_insn (gen_sse_movss (tmp, tmp, op1));
4856         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4857                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4858       }
4859       break;
4860     case 3:
4861       {
4862         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4863         rtx tmp = gen_reg_rtx (V4SFmode);
4865         emit_move_insn (tmp, operands[0]);
4866         emit_insn (gen_sse_movss (tmp, tmp, op1));
4867         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4868                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4869       }
4870       break;
4871     default:
4872       abort ();
4873     }
4874   DONE;
4877 (define_expand "vec_extractv4sf"
4878   [(match_operand:SF 0 "register_operand" "")
4879    (match_operand:V4SF 1 "register_operand" "")
4880    (match_operand 2 "const_int_operand" "")]
4881   "TARGET_SSE"
4883   switch (INTVAL (operands[2]))
4884     {
4885     case 0:
4886       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4887       break;
4888     case 1:
4889       {
4890         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4891         rtx tmp = gen_reg_rtx (V4SFmode);
4893         emit_move_insn (tmp, operands[1]);
4894         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4895                                    const1_rtx));
4896       }
4897       break;
4898     case 2:
4899       {
4900         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4901         rtx tmp = gen_reg_rtx (V4SFmode);
4903         emit_move_insn (tmp, operands[1]);
4904         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4905       }
4906       break;
4907     case 3:
4908       {
4909         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4910         rtx tmp = gen_reg_rtx (V4SFmode);
4912         emit_move_insn (tmp, operands[1]);
4913         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4914                                    GEN_INT (3)));
4915       }
4916       break;
4917     default:
4918       abort ();
4919     }
4920   DONE;
4923 (define_expand "vec_initv4sf"
4924   [(match_operand:V4SF 0 "register_operand" "")
4925    (match_operand 1 "" "")]
4926   "TARGET_SSE"
4928   ix86_expand_vector_init (operands[0], operands[1]);
4929   DONE;
4932 ;; Add instructions
4934 ;; %%% splits for addsidi3
4935 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4936 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4937 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4939 (define_expand "adddi3"
4940   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4941         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4942                  (match_operand:DI 2 "x86_64_general_operand" "")))
4943    (clobber (reg:CC FLAGS_REG))]
4944   ""
4945   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4947 (define_insn "*adddi3_1"
4948   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4949         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4950                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4951    (clobber (reg:CC FLAGS_REG))]
4952   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4953   "#")
4955 (define_split
4956   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4957         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4958                  (match_operand:DI 2 "general_operand" "")))
4959    (clobber (reg:CC FLAGS_REG))]
4960   "!TARGET_64BIT && reload_completed"
4961   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4962                                           UNSPEC_ADD_CARRY))
4963               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4964    (parallel [(set (match_dup 3)
4965                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4966                                      (match_dup 4))
4967                             (match_dup 5)))
4968               (clobber (reg:CC FLAGS_REG))])]
4969   "split_di (operands+0, 1, operands+0, operands+3);
4970    split_di (operands+1, 1, operands+1, operands+4);
4971    split_di (operands+2, 1, operands+2, operands+5);")
4973 (define_insn "adddi3_carry_rex64"
4974   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4975           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4976                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4977                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4978    (clobber (reg:CC FLAGS_REG))]
4979   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4980   "adc{q}\t{%2, %0|%0, %2}"
4981   [(set_attr "type" "alu")
4982    (set_attr "pent_pair" "pu")
4983    (set_attr "mode" "DI")])
4985 (define_insn "*adddi3_cc_rex64"
4986   [(set (reg:CC FLAGS_REG)
4987         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4988                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4989                    UNSPEC_ADD_CARRY))
4990    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4991         (plus:DI (match_dup 1) (match_dup 2)))]
4992   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4993   "add{q}\t{%2, %0|%0, %2}"
4994   [(set_attr "type" "alu")
4995    (set_attr "mode" "DI")])
4997 (define_insn "addqi3_carry"
4998   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4999           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5000                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5001                    (match_operand:QI 2 "general_operand" "qi,qm")))
5002    (clobber (reg:CC FLAGS_REG))]
5003   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5004   "adc{b}\t{%2, %0|%0, %2}"
5005   [(set_attr "type" "alu")
5006    (set_attr "pent_pair" "pu")
5007    (set_attr "mode" "QI")])
5009 (define_insn "addhi3_carry"
5010   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5011           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5012                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5013                    (match_operand:HI 2 "general_operand" "ri,rm")))
5014    (clobber (reg:CC FLAGS_REG))]
5015   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5016   "adc{w}\t{%2, %0|%0, %2}"
5017   [(set_attr "type" "alu")
5018    (set_attr "pent_pair" "pu")
5019    (set_attr "mode" "HI")])
5021 (define_insn "addsi3_carry"
5022   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5023           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5024                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5025                    (match_operand:SI 2 "general_operand" "ri,rm")))
5026    (clobber (reg:CC FLAGS_REG))]
5027   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5028   "adc{l}\t{%2, %0|%0, %2}"
5029   [(set_attr "type" "alu")
5030    (set_attr "pent_pair" "pu")
5031    (set_attr "mode" "SI")])
5033 (define_insn "*addsi3_carry_zext"
5034   [(set (match_operand:DI 0 "register_operand" "=r")
5035           (zero_extend:DI 
5036             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5037                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5038                      (match_operand:SI 2 "general_operand" "rim"))))
5039    (clobber (reg:CC FLAGS_REG))]
5040   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5041   "adc{l}\t{%2, %k0|%k0, %2}"
5042   [(set_attr "type" "alu")
5043    (set_attr "pent_pair" "pu")
5044    (set_attr "mode" "SI")])
5046 (define_insn "*addsi3_cc"
5047   [(set (reg:CC FLAGS_REG)
5048         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5049                     (match_operand:SI 2 "general_operand" "ri,rm")]
5050                    UNSPEC_ADD_CARRY))
5051    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5052         (plus:SI (match_dup 1) (match_dup 2)))]
5053   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5054   "add{l}\t{%2, %0|%0, %2}"
5055   [(set_attr "type" "alu")
5056    (set_attr "mode" "SI")])
5058 (define_insn "addqi3_cc"
5059   [(set (reg:CC FLAGS_REG)
5060         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5061                     (match_operand:QI 2 "general_operand" "qi,qm")]
5062                    UNSPEC_ADD_CARRY))
5063    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5064         (plus:QI (match_dup 1) (match_dup 2)))]
5065   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5066   "add{b}\t{%2, %0|%0, %2}"
5067   [(set_attr "type" "alu")
5068    (set_attr "mode" "QI")])
5070 (define_expand "addsi3"
5071   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5072                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5073                             (match_operand:SI 2 "general_operand" "")))
5074               (clobber (reg:CC FLAGS_REG))])]
5075   ""
5076   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5078 (define_insn "*lea_1"
5079   [(set (match_operand:SI 0 "register_operand" "=r")
5080         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5081   "!TARGET_64BIT"
5082   "lea{l}\t{%a1, %0|%0, %a1}"
5083   [(set_attr "type" "lea")
5084    (set_attr "mode" "SI")])
5086 (define_insn "*lea_1_rex64"
5087   [(set (match_operand:SI 0 "register_operand" "=r")
5088         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5089   "TARGET_64BIT"
5090   "lea{l}\t{%a1, %0|%0, %a1}"
5091   [(set_attr "type" "lea")
5092    (set_attr "mode" "SI")])
5094 (define_insn "*lea_1_zext"
5095   [(set (match_operand:DI 0 "register_operand" "=r")
5096         (zero_extend:DI
5097          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5098   "TARGET_64BIT"
5099   "lea{l}\t{%a1, %k0|%k0, %a1}"
5100   [(set_attr "type" "lea")
5101    (set_attr "mode" "SI")])
5103 (define_insn "*lea_2_rex64"
5104   [(set (match_operand:DI 0 "register_operand" "=r")
5105         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5106   "TARGET_64BIT"
5107   "lea{q}\t{%a1, %0|%0, %a1}"
5108   [(set_attr "type" "lea")
5109    (set_attr "mode" "DI")])
5111 ;; The lea patterns for non-Pmodes needs to be matched by several
5112 ;; insns converted to real lea by splitters.
5114 (define_insn_and_split "*lea_general_1"
5115   [(set (match_operand 0 "register_operand" "=r")
5116         (plus (plus (match_operand 1 "index_register_operand" "r")
5117                     (match_operand 2 "register_operand" "r"))
5118               (match_operand 3 "immediate_operand" "i")))]
5119   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5120     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5121    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5122    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5123    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5124    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5125        || GET_MODE (operands[3]) == VOIDmode)"
5126   "#"
5127   "&& reload_completed"
5128   [(const_int 0)]
5130   rtx pat;
5131   operands[0] = gen_lowpart (SImode, operands[0]);
5132   operands[1] = gen_lowpart (Pmode, operands[1]);
5133   operands[2] = gen_lowpart (Pmode, operands[2]);
5134   operands[3] = gen_lowpart (Pmode, operands[3]);
5135   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5136                       operands[3]);
5137   if (Pmode != SImode)
5138     pat = gen_rtx_SUBREG (SImode, pat, 0);
5139   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5140   DONE;
5142   [(set_attr "type" "lea")
5143    (set_attr "mode" "SI")])
5145 (define_insn_and_split "*lea_general_1_zext"
5146   [(set (match_operand:DI 0 "register_operand" "=r")
5147         (zero_extend:DI
5148           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5149                             (match_operand:SI 2 "register_operand" "r"))
5150                    (match_operand:SI 3 "immediate_operand" "i"))))]
5151   "TARGET_64BIT"
5152   "#"
5153   "&& reload_completed"
5154   [(set (match_dup 0)
5155         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5156                                                      (match_dup 2))
5157                                             (match_dup 3)) 0)))]
5159   operands[1] = gen_lowpart (Pmode, operands[1]);
5160   operands[2] = gen_lowpart (Pmode, operands[2]);
5161   operands[3] = gen_lowpart (Pmode, operands[3]);
5163   [(set_attr "type" "lea")
5164    (set_attr "mode" "SI")])
5166 (define_insn_and_split "*lea_general_2"
5167   [(set (match_operand 0 "register_operand" "=r")
5168         (plus (mult (match_operand 1 "index_register_operand" "r")
5169                     (match_operand 2 "const248_operand" "i"))
5170               (match_operand 3 "nonmemory_operand" "ri")))]
5171   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5172     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5173    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5174    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5175    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5176        || GET_MODE (operands[3]) == VOIDmode)"
5177   "#"
5178   "&& reload_completed"
5179   [(const_int 0)]
5181   rtx pat;
5182   operands[0] = gen_lowpart (SImode, operands[0]);
5183   operands[1] = gen_lowpart (Pmode, operands[1]);
5184   operands[3] = gen_lowpart (Pmode, operands[3]);
5185   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5186                       operands[3]);
5187   if (Pmode != SImode)
5188     pat = gen_rtx_SUBREG (SImode, pat, 0);
5189   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5190   DONE;
5192   [(set_attr "type" "lea")
5193    (set_attr "mode" "SI")])
5195 (define_insn_and_split "*lea_general_2_zext"
5196   [(set (match_operand:DI 0 "register_operand" "=r")
5197         (zero_extend:DI
5198           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5199                             (match_operand:SI 2 "const248_operand" "n"))
5200                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5201   "TARGET_64BIT"
5202   "#"
5203   "&& reload_completed"
5204   [(set (match_dup 0)
5205         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5206                                                      (match_dup 2))
5207                                             (match_dup 3)) 0)))]
5209   operands[1] = gen_lowpart (Pmode, operands[1]);
5210   operands[3] = gen_lowpart (Pmode, operands[3]);
5212   [(set_attr "type" "lea")
5213    (set_attr "mode" "SI")])
5215 (define_insn_and_split "*lea_general_3"
5216   [(set (match_operand 0 "register_operand" "=r")
5217         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5218                           (match_operand 2 "const248_operand" "i"))
5219                     (match_operand 3 "register_operand" "r"))
5220               (match_operand 4 "immediate_operand" "i")))]
5221   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5222     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5223    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5224    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5225    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5226   "#"
5227   "&& reload_completed"
5228   [(const_int 0)]
5230   rtx pat;
5231   operands[0] = gen_lowpart (SImode, operands[0]);
5232   operands[1] = gen_lowpart (Pmode, operands[1]);
5233   operands[3] = gen_lowpart (Pmode, operands[3]);
5234   operands[4] = gen_lowpart (Pmode, operands[4]);
5235   pat = gen_rtx_PLUS (Pmode,
5236                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5237                                                          operands[2]),
5238                                     operands[3]),
5239                       operands[4]);
5240   if (Pmode != SImode)
5241     pat = gen_rtx_SUBREG (SImode, pat, 0);
5242   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5243   DONE;
5245   [(set_attr "type" "lea")
5246    (set_attr "mode" "SI")])
5248 (define_insn_and_split "*lea_general_3_zext"
5249   [(set (match_operand:DI 0 "register_operand" "=r")
5250         (zero_extend:DI
5251           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5252                                      (match_operand:SI 2 "const248_operand" "n"))
5253                             (match_operand:SI 3 "register_operand" "r"))
5254                    (match_operand:SI 4 "immediate_operand" "i"))))]
5255   "TARGET_64BIT"
5256   "#"
5257   "&& reload_completed"
5258   [(set (match_dup 0)
5259         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5260                                                               (match_dup 2))
5261                                                      (match_dup 3))
5262                                             (match_dup 4)) 0)))]
5264   operands[1] = gen_lowpart (Pmode, operands[1]);
5265   operands[3] = gen_lowpart (Pmode, operands[3]);
5266   operands[4] = gen_lowpart (Pmode, operands[4]);
5268   [(set_attr "type" "lea")
5269    (set_attr "mode" "SI")])
5271 (define_insn "*adddi_1_rex64"
5272   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5273         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5274                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5275    (clobber (reg:CC FLAGS_REG))]
5276   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5278   switch (get_attr_type (insn))
5279     {
5280     case TYPE_LEA:
5281       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5282       return "lea{q}\t{%a2, %0|%0, %a2}";
5284     case TYPE_INCDEC:
5285       if (! rtx_equal_p (operands[0], operands[1]))
5286         abort ();
5287       if (operands[2] == const1_rtx)
5288         return "inc{q}\t%0";
5289       else if (operands[2] == constm1_rtx)
5290         return "dec{q}\t%0";
5291       else
5292         abort ();
5294     default:
5295       if (! rtx_equal_p (operands[0], operands[1]))
5296         abort ();
5298       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5299          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5300       if (GET_CODE (operands[2]) == CONST_INT
5301           /* Avoid overflows.  */
5302           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5303           && (INTVAL (operands[2]) == 128
5304               || (INTVAL (operands[2]) < 0
5305                   && INTVAL (operands[2]) != -128)))
5306         {
5307           operands[2] = GEN_INT (-INTVAL (operands[2]));
5308           return "sub{q}\t{%2, %0|%0, %2}";
5309         }
5310       return "add{q}\t{%2, %0|%0, %2}";
5311     }
5313   [(set (attr "type")
5314      (cond [(eq_attr "alternative" "2")
5315               (const_string "lea")
5316             ; Current assemblers are broken and do not allow @GOTOFF in
5317             ; ought but a memory context.
5318             (match_operand:DI 2 "pic_symbolic_operand" "")
5319               (const_string "lea")
5320             (match_operand:DI 2 "incdec_operand" "")
5321               (const_string "incdec")
5322            ]
5323            (const_string "alu")))
5324    (set_attr "mode" "DI")])
5326 ;; Convert lea to the lea pattern to avoid flags dependency.
5327 (define_split
5328   [(set (match_operand:DI 0 "register_operand" "")
5329         (plus:DI (match_operand:DI 1 "register_operand" "")
5330                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5331    (clobber (reg:CC FLAGS_REG))]
5332   "TARGET_64BIT && reload_completed
5333    && true_regnum (operands[0]) != true_regnum (operands[1])"
5334   [(set (match_dup 0)
5335         (plus:DI (match_dup 1)
5336                  (match_dup 2)))]
5337   "")
5339 (define_insn "*adddi_2_rex64"
5340   [(set (reg 17)
5341         (compare
5342           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5343                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5344           (const_int 0)))                       
5345    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5346         (plus:DI (match_dup 1) (match_dup 2)))]
5347   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5348    && ix86_binary_operator_ok (PLUS, DImode, operands)
5349    /* Current assemblers are broken and do not allow @GOTOFF in
5350       ought but a memory context.  */
5351    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5353   switch (get_attr_type (insn))
5354     {
5355     case TYPE_INCDEC:
5356       if (! rtx_equal_p (operands[0], operands[1]))
5357         abort ();
5358       if (operands[2] == const1_rtx)
5359         return "inc{q}\t%0";
5360       else if (operands[2] == constm1_rtx)
5361         return "dec{q}\t%0";
5362       else
5363         abort ();
5365     default:
5366       if (! rtx_equal_p (operands[0], operands[1]))
5367         abort ();
5368       /* ???? We ought to handle there the 32bit case too
5369          - do we need new constraint?  */
5370       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5372       if (GET_CODE (operands[2]) == CONST_INT
5373           /* Avoid overflows.  */
5374           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5375           && (INTVAL (operands[2]) == 128
5376               || (INTVAL (operands[2]) < 0
5377                   && INTVAL (operands[2]) != -128)))
5378         {
5379           operands[2] = GEN_INT (-INTVAL (operands[2]));
5380           return "sub{q}\t{%2, %0|%0, %2}";
5381         }
5382       return "add{q}\t{%2, %0|%0, %2}";
5383     }
5385   [(set (attr "type")
5386      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5387         (const_string "incdec")
5388         (const_string "alu")))
5389    (set_attr "mode" "DI")])
5391 (define_insn "*adddi_3_rex64"
5392   [(set (reg 17)
5393         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5394                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5395    (clobber (match_scratch:DI 0 "=r"))]
5396   "TARGET_64BIT
5397    && ix86_match_ccmode (insn, CCZmode)
5398    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5399    /* Current assemblers are broken and do not allow @GOTOFF in
5400       ought but a memory context.  */
5401    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5403   switch (get_attr_type (insn))
5404     {
5405     case TYPE_INCDEC:
5406       if (! rtx_equal_p (operands[0], operands[1]))
5407         abort ();
5408       if (operands[2] == const1_rtx)
5409         return "inc{q}\t%0";
5410       else if (operands[2] == constm1_rtx)
5411         return "dec{q}\t%0";
5412       else
5413         abort ();
5415     default:
5416       if (! rtx_equal_p (operands[0], operands[1]))
5417         abort ();
5418       /* ???? We ought to handle there the 32bit case too
5419          - do we need new constraint?  */
5420       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5421          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5422       if (GET_CODE (operands[2]) == CONST_INT
5423           /* Avoid overflows.  */
5424           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5425           && (INTVAL (operands[2]) == 128
5426               || (INTVAL (operands[2]) < 0
5427                   && INTVAL (operands[2]) != -128)))
5428         {
5429           operands[2] = GEN_INT (-INTVAL (operands[2]));
5430           return "sub{q}\t{%2, %0|%0, %2}";
5431         }
5432       return "add{q}\t{%2, %0|%0, %2}";
5433     }
5435   [(set (attr "type")
5436      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5437         (const_string "incdec")
5438         (const_string "alu")))
5439    (set_attr "mode" "DI")])
5441 ; For comparisons against 1, -1 and 128, we may generate better code
5442 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5443 ; is matched then.  We can't accept general immediate, because for
5444 ; case of overflows,  the result is messed up.
5445 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5446 ; when negated.
5447 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5448 ; only for comparisons not depending on it.
5449 (define_insn "*adddi_4_rex64"
5450   [(set (reg 17)
5451         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5452                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5453    (clobber (match_scratch:DI 0 "=rm"))]
5454   "TARGET_64BIT
5455    &&  ix86_match_ccmode (insn, CCGCmode)"
5457   switch (get_attr_type (insn))
5458     {
5459     case TYPE_INCDEC:
5460       if (operands[2] == constm1_rtx)
5461         return "inc{q}\t%0";
5462       else if (operands[2] == const1_rtx)
5463         return "dec{q}\t%0";
5464       else
5465         abort();
5467     default:
5468       if (! rtx_equal_p (operands[0], operands[1]))
5469         abort ();
5470       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5471          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5472       if ((INTVAL (operands[2]) == -128
5473            || (INTVAL (operands[2]) > 0
5474                && INTVAL (operands[2]) != 128))
5475           /* Avoid overflows.  */
5476           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5477         return "sub{q}\t{%2, %0|%0, %2}";
5478       operands[2] = GEN_INT (-INTVAL (operands[2]));
5479       return "add{q}\t{%2, %0|%0, %2}";
5480     }
5482   [(set (attr "type")
5483      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5484         (const_string "incdec")
5485         (const_string "alu")))
5486    (set_attr "mode" "DI")])
5488 (define_insn "*adddi_5_rex64"
5489   [(set (reg 17)
5490         (compare
5491           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5492                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5493           (const_int 0)))                       
5494    (clobber (match_scratch:DI 0 "=r"))]
5495   "TARGET_64BIT
5496    && ix86_match_ccmode (insn, CCGOCmode)
5497    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5498    /* Current assemblers are broken and do not allow @GOTOFF in
5499       ought but a memory context.  */
5500    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5502   switch (get_attr_type (insn))
5503     {
5504     case TYPE_INCDEC:
5505       if (! rtx_equal_p (operands[0], operands[1]))
5506         abort ();
5507       if (operands[2] == const1_rtx)
5508         return "inc{q}\t%0";
5509       else if (operands[2] == constm1_rtx)
5510         return "dec{q}\t%0";
5511       else
5512         abort();
5514     default:
5515       if (! rtx_equal_p (operands[0], operands[1]))
5516         abort ();
5517       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5518          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5519       if (GET_CODE (operands[2]) == CONST_INT
5520           /* Avoid overflows.  */
5521           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5522           && (INTVAL (operands[2]) == 128
5523               || (INTVAL (operands[2]) < 0
5524                   && INTVAL (operands[2]) != -128)))
5525         {
5526           operands[2] = GEN_INT (-INTVAL (operands[2]));
5527           return "sub{q}\t{%2, %0|%0, %2}";
5528         }
5529       return "add{q}\t{%2, %0|%0, %2}";
5530     }
5532   [(set (attr "type")
5533      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5534         (const_string "incdec")
5535         (const_string "alu")))
5536    (set_attr "mode" "DI")])
5539 (define_insn "*addsi_1"
5540   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5541         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5542                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5543    (clobber (reg:CC FLAGS_REG))]
5544   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5546   switch (get_attr_type (insn))
5547     {
5548     case TYPE_LEA:
5549       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5550       return "lea{l}\t{%a2, %0|%0, %a2}";
5552     case TYPE_INCDEC:
5553       if (! rtx_equal_p (operands[0], operands[1]))
5554         abort ();
5555       if (operands[2] == const1_rtx)
5556         return "inc{l}\t%0";
5557       else if (operands[2] == constm1_rtx)
5558         return "dec{l}\t%0";
5559       else
5560         abort();
5562     default:
5563       if (! rtx_equal_p (operands[0], operands[1]))
5564         abort ();
5566       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5567          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5568       if (GET_CODE (operands[2]) == CONST_INT
5569           && (INTVAL (operands[2]) == 128
5570               || (INTVAL (operands[2]) < 0
5571                   && INTVAL (operands[2]) != -128)))
5572         {
5573           operands[2] = GEN_INT (-INTVAL (operands[2]));
5574           return "sub{l}\t{%2, %0|%0, %2}";
5575         }
5576       return "add{l}\t{%2, %0|%0, %2}";
5577     }
5579   [(set (attr "type")
5580      (cond [(eq_attr "alternative" "2")
5581               (const_string "lea")
5582             ; Current assemblers are broken and do not allow @GOTOFF in
5583             ; ought but a memory context.
5584             (match_operand:SI 2 "pic_symbolic_operand" "")
5585               (const_string "lea")
5586             (match_operand:SI 2 "incdec_operand" "")
5587               (const_string "incdec")
5588            ]
5589            (const_string "alu")))
5590    (set_attr "mode" "SI")])
5592 ;; Convert lea to the lea pattern to avoid flags dependency.
5593 (define_split
5594   [(set (match_operand 0 "register_operand" "")
5595         (plus (match_operand 1 "register_operand" "")
5596               (match_operand 2 "nonmemory_operand" "")))
5597    (clobber (reg:CC FLAGS_REG))]
5598   "reload_completed
5599    && true_regnum (operands[0]) != true_regnum (operands[1])"
5600   [(const_int 0)]
5602   rtx pat;
5603   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5604      may confuse gen_lowpart.  */
5605   if (GET_MODE (operands[0]) != Pmode)
5606     {
5607       operands[1] = gen_lowpart (Pmode, operands[1]);
5608       operands[2] = gen_lowpart (Pmode, operands[2]);
5609     }
5610   operands[0] = gen_lowpart (SImode, operands[0]);
5611   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5612   if (Pmode != SImode)
5613     pat = gen_rtx_SUBREG (SImode, pat, 0);
5614   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5615   DONE;
5618 ;; It may seem that nonimmediate operand is proper one for operand 1.
5619 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5620 ;; we take care in ix86_binary_operator_ok to not allow two memory
5621 ;; operands so proper swapping will be done in reload.  This allow
5622 ;; patterns constructed from addsi_1 to match.
5623 (define_insn "addsi_1_zext"
5624   [(set (match_operand:DI 0 "register_operand" "=r,r")
5625         (zero_extend:DI
5626           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5627                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5628    (clobber (reg:CC FLAGS_REG))]
5629   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5631   switch (get_attr_type (insn))
5632     {
5633     case TYPE_LEA:
5634       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5635       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5637     case TYPE_INCDEC:
5638       if (operands[2] == const1_rtx)
5639         return "inc{l}\t%k0";
5640       else if (operands[2] == constm1_rtx)
5641         return "dec{l}\t%k0";
5642       else
5643         abort();
5645     default:
5646       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5647          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5648       if (GET_CODE (operands[2]) == CONST_INT
5649           && (INTVAL (operands[2]) == 128
5650               || (INTVAL (operands[2]) < 0
5651                   && INTVAL (operands[2]) != -128)))
5652         {
5653           operands[2] = GEN_INT (-INTVAL (operands[2]));
5654           return "sub{l}\t{%2, %k0|%k0, %2}";
5655         }
5656       return "add{l}\t{%2, %k0|%k0, %2}";
5657     }
5659   [(set (attr "type")
5660      (cond [(eq_attr "alternative" "1")
5661               (const_string "lea")
5662             ; Current assemblers are broken and do not allow @GOTOFF in
5663             ; ought but a memory context.
5664             (match_operand:SI 2 "pic_symbolic_operand" "")
5665               (const_string "lea")
5666             (match_operand:SI 2 "incdec_operand" "")
5667               (const_string "incdec")
5668            ]
5669            (const_string "alu")))
5670    (set_attr "mode" "SI")])
5672 ;; Convert lea to the lea pattern to avoid flags dependency.
5673 (define_split
5674   [(set (match_operand:DI 0 "register_operand" "")
5675         (zero_extend:DI
5676           (plus:SI (match_operand:SI 1 "register_operand" "")
5677                    (match_operand:SI 2 "nonmemory_operand" ""))))
5678    (clobber (reg:CC FLAGS_REG))]
5679   "TARGET_64BIT && reload_completed
5680    && true_regnum (operands[0]) != true_regnum (operands[1])"
5681   [(set (match_dup 0)
5682         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5684   operands[1] = gen_lowpart (Pmode, operands[1]);
5685   operands[2] = gen_lowpart (Pmode, operands[2]);
5688 (define_insn "*addsi_2"
5689   [(set (reg 17)
5690         (compare
5691           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5692                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5693           (const_int 0)))                       
5694    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5695         (plus:SI (match_dup 1) (match_dup 2)))]
5696   "ix86_match_ccmode (insn, CCGOCmode)
5697    && ix86_binary_operator_ok (PLUS, SImode, operands)
5698    /* Current assemblers are broken and do not allow @GOTOFF in
5699       ought but a memory context.  */
5700    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5702   switch (get_attr_type (insn))
5703     {
5704     case TYPE_INCDEC:
5705       if (! rtx_equal_p (operands[0], operands[1]))
5706         abort ();
5707       if (operands[2] == const1_rtx)
5708         return "inc{l}\t%0";
5709       else if (operands[2] == constm1_rtx)
5710         return "dec{l}\t%0";
5711       else
5712         abort();
5714     default:
5715       if (! rtx_equal_p (operands[0], operands[1]))
5716         abort ();
5717       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5718          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5719       if (GET_CODE (operands[2]) == CONST_INT
5720           && (INTVAL (operands[2]) == 128
5721               || (INTVAL (operands[2]) < 0
5722                   && INTVAL (operands[2]) != -128)))
5723         {
5724           operands[2] = GEN_INT (-INTVAL (operands[2]));
5725           return "sub{l}\t{%2, %0|%0, %2}";
5726         }
5727       return "add{l}\t{%2, %0|%0, %2}";
5728     }
5730   [(set (attr "type")
5731      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5732         (const_string "incdec")
5733         (const_string "alu")))
5734    (set_attr "mode" "SI")])
5736 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5737 (define_insn "*addsi_2_zext"
5738   [(set (reg 17)
5739         (compare
5740           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5741                    (match_operand:SI 2 "general_operand" "rmni"))
5742           (const_int 0)))                       
5743    (set (match_operand:DI 0 "register_operand" "=r")
5744         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5745   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5746    && ix86_binary_operator_ok (PLUS, SImode, operands)
5747    /* Current assemblers are broken and do not allow @GOTOFF in
5748       ought but a memory context.  */
5749    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5751   switch (get_attr_type (insn))
5752     {
5753     case TYPE_INCDEC:
5754       if (operands[2] == const1_rtx)
5755         return "inc{l}\t%k0";
5756       else if (operands[2] == constm1_rtx)
5757         return "dec{l}\t%k0";
5758       else
5759         abort();
5761     default:
5762       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5763          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5764       if (GET_CODE (operands[2]) == CONST_INT
5765           && (INTVAL (operands[2]) == 128
5766               || (INTVAL (operands[2]) < 0
5767                   && INTVAL (operands[2]) != -128)))
5768         {
5769           operands[2] = GEN_INT (-INTVAL (operands[2]));
5770           return "sub{l}\t{%2, %k0|%k0, %2}";
5771         }
5772       return "add{l}\t{%2, %k0|%k0, %2}";
5773     }
5775   [(set (attr "type")
5776      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5777         (const_string "incdec")
5778         (const_string "alu")))
5779    (set_attr "mode" "SI")])
5781 (define_insn "*addsi_3"
5782   [(set (reg 17)
5783         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5784                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5785    (clobber (match_scratch:SI 0 "=r"))]
5786   "ix86_match_ccmode (insn, CCZmode)
5787    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5788    /* Current assemblers are broken and do not allow @GOTOFF in
5789       ought but a memory context.  */
5790    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5792   switch (get_attr_type (insn))
5793     {
5794     case TYPE_INCDEC:
5795       if (! rtx_equal_p (operands[0], operands[1]))
5796         abort ();
5797       if (operands[2] == const1_rtx)
5798         return "inc{l}\t%0";
5799       else if (operands[2] == constm1_rtx)
5800         return "dec{l}\t%0";
5801       else
5802         abort();
5804     default:
5805       if (! rtx_equal_p (operands[0], operands[1]))
5806         abort ();
5807       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5808          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5809       if (GET_CODE (operands[2]) == CONST_INT
5810           && (INTVAL (operands[2]) == 128
5811               || (INTVAL (operands[2]) < 0
5812                   && INTVAL (operands[2]) != -128)))
5813         {
5814           operands[2] = GEN_INT (-INTVAL (operands[2]));
5815           return "sub{l}\t{%2, %0|%0, %2}";
5816         }
5817       return "add{l}\t{%2, %0|%0, %2}";
5818     }
5820   [(set (attr "type")
5821      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5822         (const_string "incdec")
5823         (const_string "alu")))
5824    (set_attr "mode" "SI")])
5826 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5827 (define_insn "*addsi_3_zext"
5828   [(set (reg 17)
5829         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5830                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5831    (set (match_operand:DI 0 "register_operand" "=r")
5832         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5833   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5834    && ix86_binary_operator_ok (PLUS, SImode, operands)
5835    /* Current assemblers are broken and do not allow @GOTOFF in
5836       ought but a memory context.  */
5837    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5839   switch (get_attr_type (insn))
5840     {
5841     case TYPE_INCDEC:
5842       if (operands[2] == const1_rtx)
5843         return "inc{l}\t%k0";
5844       else if (operands[2] == constm1_rtx)
5845         return "dec{l}\t%k0";
5846       else
5847         abort();
5849     default:
5850       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5851          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5852       if (GET_CODE (operands[2]) == CONST_INT
5853           && (INTVAL (operands[2]) == 128
5854               || (INTVAL (operands[2]) < 0
5855                   && INTVAL (operands[2]) != -128)))
5856         {
5857           operands[2] = GEN_INT (-INTVAL (operands[2]));
5858           return "sub{l}\t{%2, %k0|%k0, %2}";
5859         }
5860       return "add{l}\t{%2, %k0|%k0, %2}";
5861     }
5863   [(set (attr "type")
5864      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5865         (const_string "incdec")
5866         (const_string "alu")))
5867    (set_attr "mode" "SI")])
5869 ; For comparisons against 1, -1 and 128, we may generate better code
5870 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5871 ; is matched then.  We can't accept general immediate, because for
5872 ; case of overflows,  the result is messed up.
5873 ; This pattern also don't hold of 0x80000000, since the value overflows
5874 ; when negated.
5875 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5876 ; only for comparisons not depending on it.
5877 (define_insn "*addsi_4"
5878   [(set (reg 17)
5879         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5880                  (match_operand:SI 2 "const_int_operand" "n")))
5881    (clobber (match_scratch:SI 0 "=rm"))]
5882   "ix86_match_ccmode (insn, CCGCmode)
5883    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5885   switch (get_attr_type (insn))
5886     {
5887     case TYPE_INCDEC:
5888       if (operands[2] == constm1_rtx)
5889         return "inc{l}\t%0";
5890       else if (operands[2] == const1_rtx)
5891         return "dec{l}\t%0";
5892       else
5893         abort();
5895     default:
5896       if (! rtx_equal_p (operands[0], operands[1]))
5897         abort ();
5898       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5899          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5900       if ((INTVAL (operands[2]) == -128
5901            || (INTVAL (operands[2]) > 0
5902                && INTVAL (operands[2]) != 128)))
5903         return "sub{l}\t{%2, %0|%0, %2}";
5904       operands[2] = GEN_INT (-INTVAL (operands[2]));
5905       return "add{l}\t{%2, %0|%0, %2}";
5906     }
5908   [(set (attr "type")
5909      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5910         (const_string "incdec")
5911         (const_string "alu")))
5912    (set_attr "mode" "SI")])
5914 (define_insn "*addsi_5"
5915   [(set (reg 17)
5916         (compare
5917           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5918                    (match_operand:SI 2 "general_operand" "rmni"))
5919           (const_int 0)))                       
5920    (clobber (match_scratch:SI 0 "=r"))]
5921   "ix86_match_ccmode (insn, CCGOCmode)
5922    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5923    /* Current assemblers are broken and do not allow @GOTOFF in
5924       ought but a memory context.  */
5925    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5927   switch (get_attr_type (insn))
5928     {
5929     case TYPE_INCDEC:
5930       if (! rtx_equal_p (operands[0], operands[1]))
5931         abort ();
5932       if (operands[2] == const1_rtx)
5933         return "inc{l}\t%0";
5934       else if (operands[2] == constm1_rtx)
5935         return "dec{l}\t%0";
5936       else
5937         abort();
5939     default:
5940       if (! rtx_equal_p (operands[0], operands[1]))
5941         abort ();
5942       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5943          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5944       if (GET_CODE (operands[2]) == CONST_INT
5945           && (INTVAL (operands[2]) == 128
5946               || (INTVAL (operands[2]) < 0
5947                   && INTVAL (operands[2]) != -128)))
5948         {
5949           operands[2] = GEN_INT (-INTVAL (operands[2]));
5950           return "sub{l}\t{%2, %0|%0, %2}";
5951         }
5952       return "add{l}\t{%2, %0|%0, %2}";
5953     }
5955   [(set (attr "type")
5956      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5957         (const_string "incdec")
5958         (const_string "alu")))
5959    (set_attr "mode" "SI")])
5961 (define_expand "addhi3"
5962   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5963                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5964                             (match_operand:HI 2 "general_operand" "")))
5965               (clobber (reg:CC FLAGS_REG))])]
5966   "TARGET_HIMODE_MATH"
5967   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5969 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5970 ;; type optimizations enabled by define-splits.  This is not important
5971 ;; for PII, and in fact harmful because of partial register stalls.
5973 (define_insn "*addhi_1_lea"
5974   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5975         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5976                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5977    (clobber (reg:CC FLAGS_REG))]
5978   "!TARGET_PARTIAL_REG_STALL
5979    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5981   switch (get_attr_type (insn))
5982     {
5983     case TYPE_LEA:
5984       return "#";
5985     case TYPE_INCDEC:
5986       if (operands[2] == const1_rtx)
5987         return "inc{w}\t%0";
5988       else if (operands[2] == constm1_rtx)
5989         return "dec{w}\t%0";
5990       abort();
5992     default:
5993       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5994          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5995       if (GET_CODE (operands[2]) == CONST_INT
5996           && (INTVAL (operands[2]) == 128
5997               || (INTVAL (operands[2]) < 0
5998                   && INTVAL (operands[2]) != -128)))
5999         {
6000           operands[2] = GEN_INT (-INTVAL (operands[2]));
6001           return "sub{w}\t{%2, %0|%0, %2}";
6002         }
6003       return "add{w}\t{%2, %0|%0, %2}";
6004     }
6006   [(set (attr "type")
6007      (if_then_else (eq_attr "alternative" "2")
6008         (const_string "lea")
6009         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6010            (const_string "incdec")
6011            (const_string "alu"))))
6012    (set_attr "mode" "HI,HI,SI")])
6014 (define_insn "*addhi_1"
6015   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6016         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6017                  (match_operand:HI 2 "general_operand" "ri,rm")))
6018    (clobber (reg:CC FLAGS_REG))]
6019   "TARGET_PARTIAL_REG_STALL
6020    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6022   switch (get_attr_type (insn))
6023     {
6024     case TYPE_INCDEC:
6025       if (operands[2] == const1_rtx)
6026         return "inc{w}\t%0";
6027       else if (operands[2] == constm1_rtx)
6028         return "dec{w}\t%0";
6029       abort();
6031     default:
6032       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6033          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6034       if (GET_CODE (operands[2]) == CONST_INT
6035           && (INTVAL (operands[2]) == 128
6036               || (INTVAL (operands[2]) < 0
6037                   && INTVAL (operands[2]) != -128)))
6038         {
6039           operands[2] = GEN_INT (-INTVAL (operands[2]));
6040           return "sub{w}\t{%2, %0|%0, %2}";
6041         }
6042       return "add{w}\t{%2, %0|%0, %2}";
6043     }
6045   [(set (attr "type")
6046      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6047         (const_string "incdec")
6048         (const_string "alu")))
6049    (set_attr "mode" "HI")])
6051 (define_insn "*addhi_2"
6052   [(set (reg 17)
6053         (compare
6054           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6055                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6056           (const_int 0)))                       
6057    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6058         (plus:HI (match_dup 1) (match_dup 2)))]
6059   "ix86_match_ccmode (insn, CCGOCmode)
6060    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6062   switch (get_attr_type (insn))
6063     {
6064     case TYPE_INCDEC:
6065       if (operands[2] == const1_rtx)
6066         return "inc{w}\t%0";
6067       else if (operands[2] == constm1_rtx)
6068         return "dec{w}\t%0";
6069       abort();
6071     default:
6072       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6073          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6074       if (GET_CODE (operands[2]) == CONST_INT
6075           && (INTVAL (operands[2]) == 128
6076               || (INTVAL (operands[2]) < 0
6077                   && INTVAL (operands[2]) != -128)))
6078         {
6079           operands[2] = GEN_INT (-INTVAL (operands[2]));
6080           return "sub{w}\t{%2, %0|%0, %2}";
6081         }
6082       return "add{w}\t{%2, %0|%0, %2}";
6083     }
6085   [(set (attr "type")
6086      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6087         (const_string "incdec")
6088         (const_string "alu")))
6089    (set_attr "mode" "HI")])
6091 (define_insn "*addhi_3"
6092   [(set (reg 17)
6093         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6094                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6095    (clobber (match_scratch:HI 0 "=r"))]
6096   "ix86_match_ccmode (insn, CCZmode)
6097    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6099   switch (get_attr_type (insn))
6100     {
6101     case TYPE_INCDEC:
6102       if (operands[2] == const1_rtx)
6103         return "inc{w}\t%0";
6104       else if (operands[2] == constm1_rtx)
6105         return "dec{w}\t%0";
6106       abort();
6108     default:
6109       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6110          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6111       if (GET_CODE (operands[2]) == CONST_INT
6112           && (INTVAL (operands[2]) == 128
6113               || (INTVAL (operands[2]) < 0
6114                   && INTVAL (operands[2]) != -128)))
6115         {
6116           operands[2] = GEN_INT (-INTVAL (operands[2]));
6117           return "sub{w}\t{%2, %0|%0, %2}";
6118         }
6119       return "add{w}\t{%2, %0|%0, %2}";
6120     }
6122   [(set (attr "type")
6123      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6124         (const_string "incdec")
6125         (const_string "alu")))
6126    (set_attr "mode" "HI")])
6128 ; See comments above addsi_3_imm for details.
6129 (define_insn "*addhi_4"
6130   [(set (reg 17)
6131         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6132                  (match_operand:HI 2 "const_int_operand" "n")))
6133    (clobber (match_scratch:HI 0 "=rm"))]
6134   "ix86_match_ccmode (insn, CCGCmode)
6135    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6137   switch (get_attr_type (insn))
6138     {
6139     case TYPE_INCDEC:
6140       if (operands[2] == constm1_rtx)
6141         return "inc{w}\t%0";
6142       else if (operands[2] == const1_rtx)
6143         return "dec{w}\t%0";
6144       else
6145         abort();
6147     default:
6148       if (! rtx_equal_p (operands[0], operands[1]))
6149         abort ();
6150       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6151          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6152       if ((INTVAL (operands[2]) == -128
6153            || (INTVAL (operands[2]) > 0
6154                && INTVAL (operands[2]) != 128)))
6155         return "sub{w}\t{%2, %0|%0, %2}";
6156       operands[2] = GEN_INT (-INTVAL (operands[2]));
6157       return "add{w}\t{%2, %0|%0, %2}";
6158     }
6160   [(set (attr "type")
6161      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6162         (const_string "incdec")
6163         (const_string "alu")))
6164    (set_attr "mode" "SI")])
6167 (define_insn "*addhi_5"
6168   [(set (reg 17)
6169         (compare
6170           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6171                    (match_operand:HI 2 "general_operand" "rmni"))
6172           (const_int 0)))                       
6173    (clobber (match_scratch:HI 0 "=r"))]
6174   "ix86_match_ccmode (insn, CCGOCmode)
6175    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6177   switch (get_attr_type (insn))
6178     {
6179     case TYPE_INCDEC:
6180       if (operands[2] == const1_rtx)
6181         return "inc{w}\t%0";
6182       else if (operands[2] == constm1_rtx)
6183         return "dec{w}\t%0";
6184       abort();
6186     default:
6187       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6188          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6189       if (GET_CODE (operands[2]) == CONST_INT
6190           && (INTVAL (operands[2]) == 128
6191               || (INTVAL (operands[2]) < 0
6192                   && INTVAL (operands[2]) != -128)))
6193         {
6194           operands[2] = GEN_INT (-INTVAL (operands[2]));
6195           return "sub{w}\t{%2, %0|%0, %2}";
6196         }
6197       return "add{w}\t{%2, %0|%0, %2}";
6198     }
6200   [(set (attr "type")
6201      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6202         (const_string "incdec")
6203         (const_string "alu")))
6204    (set_attr "mode" "HI")])
6206 (define_expand "addqi3"
6207   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6208                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6209                             (match_operand:QI 2 "general_operand" "")))
6210               (clobber (reg:CC FLAGS_REG))])]
6211   "TARGET_QIMODE_MATH"
6212   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6214 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6215 (define_insn "*addqi_1_lea"
6216   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6217         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6218                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6219    (clobber (reg:CC FLAGS_REG))]
6220   "!TARGET_PARTIAL_REG_STALL
6221    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6223   int widen = (which_alternative == 2);
6224   switch (get_attr_type (insn))
6225     {
6226     case TYPE_LEA:
6227       return "#";
6228     case TYPE_INCDEC:
6229       if (operands[2] == const1_rtx)
6230         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6231       else if (operands[2] == constm1_rtx)
6232         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6233       abort();
6235     default:
6236       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6237          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6238       if (GET_CODE (operands[2]) == CONST_INT
6239           && (INTVAL (operands[2]) == 128
6240               || (INTVAL (operands[2]) < 0
6241                   && INTVAL (operands[2]) != -128)))
6242         {
6243           operands[2] = GEN_INT (-INTVAL (operands[2]));
6244           if (widen)
6245             return "sub{l}\t{%2, %k0|%k0, %2}";
6246           else
6247             return "sub{b}\t{%2, %0|%0, %2}";
6248         }
6249       if (widen)
6250         return "add{l}\t{%k2, %k0|%k0, %k2}";
6251       else
6252         return "add{b}\t{%2, %0|%0, %2}";
6253     }
6255   [(set (attr "type")
6256      (if_then_else (eq_attr "alternative" "3")
6257         (const_string "lea")
6258         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6259            (const_string "incdec")
6260            (const_string "alu"))))
6261    (set_attr "mode" "QI,QI,SI,SI")])
6263 (define_insn "*addqi_1"
6264   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6265         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6266                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6267    (clobber (reg:CC FLAGS_REG))]
6268   "TARGET_PARTIAL_REG_STALL
6269    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6271   int widen = (which_alternative == 2);
6272   switch (get_attr_type (insn))
6273     {
6274     case TYPE_INCDEC:
6275       if (operands[2] == const1_rtx)
6276         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6277       else if (operands[2] == constm1_rtx)
6278         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6279       abort();
6281     default:
6282       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6283          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6284       if (GET_CODE (operands[2]) == CONST_INT
6285           && (INTVAL (operands[2]) == 128
6286               || (INTVAL (operands[2]) < 0
6287                   && INTVAL (operands[2]) != -128)))
6288         {
6289           operands[2] = GEN_INT (-INTVAL (operands[2]));
6290           if (widen)
6291             return "sub{l}\t{%2, %k0|%k0, %2}";
6292           else
6293             return "sub{b}\t{%2, %0|%0, %2}";
6294         }
6295       if (widen)
6296         return "add{l}\t{%k2, %k0|%k0, %k2}";
6297       else
6298         return "add{b}\t{%2, %0|%0, %2}";
6299     }
6301   [(set (attr "type")
6302      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6303         (const_string "incdec")
6304         (const_string "alu")))
6305    (set_attr "mode" "QI,QI,SI")])
6307 (define_insn "*addqi_1_slp"
6308   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6309         (plus:QI (match_dup 0)
6310                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6311    (clobber (reg:CC FLAGS_REG))]
6312   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6313    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6315   switch (get_attr_type (insn))
6316     {
6317     case TYPE_INCDEC:
6318       if (operands[1] == const1_rtx)
6319         return "inc{b}\t%0";
6320       else if (operands[1] == constm1_rtx)
6321         return "dec{b}\t%0";
6322       abort();
6324     default:
6325       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6326       if (GET_CODE (operands[1]) == CONST_INT
6327           && INTVAL (operands[1]) < 0)
6328         {
6329           operands[1] = GEN_INT (-INTVAL (operands[1]));
6330           return "sub{b}\t{%1, %0|%0, %1}";
6331         }
6332       return "add{b}\t{%1, %0|%0, %1}";
6333     }
6335   [(set (attr "type")
6336      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6337         (const_string "incdec")
6338         (const_string "alu1")))
6339    (set_attr "mode" "QI")])
6341 (define_insn "*addqi_2"
6342   [(set (reg 17)
6343         (compare
6344           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6345                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6346           (const_int 0)))
6347    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6348         (plus:QI (match_dup 1) (match_dup 2)))]
6349   "ix86_match_ccmode (insn, CCGOCmode)
6350    && ix86_binary_operator_ok (PLUS, QImode, operands)"
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 (define_insn "*addqi_3"
6381   [(set (reg 17)
6382         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6383                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6384    (clobber (match_scratch:QI 0 "=q"))]
6385   "ix86_match_ccmode (insn, CCZmode)
6386    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6388   switch (get_attr_type (insn))
6389     {
6390     case TYPE_INCDEC:
6391       if (operands[2] == const1_rtx)
6392         return "inc{b}\t%0";
6393       else if (operands[2] == constm1_rtx
6394                || (GET_CODE (operands[2]) == CONST_INT
6395                    && INTVAL (operands[2]) == 255))
6396         return "dec{b}\t%0";
6397       abort();
6399     default:
6400       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6401       if (GET_CODE (operands[2]) == CONST_INT
6402           && INTVAL (operands[2]) < 0)
6403         {
6404           operands[2] = GEN_INT (-INTVAL (operands[2]));
6405           return "sub{b}\t{%2, %0|%0, %2}";
6406         }
6407       return "add{b}\t{%2, %0|%0, %2}";
6408     }
6410   [(set (attr "type")
6411      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6412         (const_string "incdec")
6413         (const_string "alu")))
6414    (set_attr "mode" "QI")])
6416 ; See comments above addsi_3_imm for details.
6417 (define_insn "*addqi_4"
6418   [(set (reg 17)
6419         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6420                  (match_operand:QI 2 "const_int_operand" "n")))
6421    (clobber (match_scratch:QI 0 "=qm"))]
6422   "ix86_match_ccmode (insn, CCGCmode)
6423    && (INTVAL (operands[2]) & 0xff) != 0x80"
6425   switch (get_attr_type (insn))
6426     {
6427     case TYPE_INCDEC:
6428       if (operands[2] == constm1_rtx
6429           || (GET_CODE (operands[2]) == CONST_INT
6430               && INTVAL (operands[2]) == 255))
6431         return "inc{b}\t%0";
6432       else if (operands[2] == const1_rtx)
6433         return "dec{b}\t%0";
6434       else
6435         abort();
6437     default:
6438       if (! rtx_equal_p (operands[0], operands[1]))
6439         abort ();
6440       if (INTVAL (operands[2]) < 0)
6441         {
6442           operands[2] = GEN_INT (-INTVAL (operands[2]));
6443           return "add{b}\t{%2, %0|%0, %2}";
6444         }
6445       return "sub{b}\t{%2, %0|%0, %2}";
6446     }
6448   [(set (attr "type")
6449      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6450         (const_string "incdec")
6451         (const_string "alu")))
6452    (set_attr "mode" "QI")])
6455 (define_insn "*addqi_5"
6456   [(set (reg 17)
6457         (compare
6458           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6459                    (match_operand:QI 2 "general_operand" "qmni"))
6460           (const_int 0)))
6461    (clobber (match_scratch:QI 0 "=q"))]
6462   "ix86_match_ccmode (insn, CCGOCmode)
6463    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6465   switch (get_attr_type (insn))
6466     {
6467     case TYPE_INCDEC:
6468       if (operands[2] == const1_rtx)
6469         return "inc{b}\t%0";
6470       else if (operands[2] == constm1_rtx
6471                || (GET_CODE (operands[2]) == CONST_INT
6472                    && INTVAL (operands[2]) == 255))
6473         return "dec{b}\t%0";
6474       abort();
6476     default:
6477       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6478       if (GET_CODE (operands[2]) == CONST_INT
6479           && INTVAL (operands[2]) < 0)
6480         {
6481           operands[2] = GEN_INT (-INTVAL (operands[2]));
6482           return "sub{b}\t{%2, %0|%0, %2}";
6483         }
6484       return "add{b}\t{%2, %0|%0, %2}";
6485     }
6487   [(set (attr "type")
6488      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6489         (const_string "incdec")
6490         (const_string "alu")))
6491    (set_attr "mode" "QI")])
6494 (define_insn "addqi_ext_1"
6495   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6496                          (const_int 8)
6497                          (const_int 8))
6498         (plus:SI
6499           (zero_extract:SI
6500             (match_operand 1 "ext_register_operand" "0")
6501             (const_int 8)
6502             (const_int 8))
6503           (match_operand:QI 2 "general_operand" "Qmn")))
6504    (clobber (reg:CC FLAGS_REG))]
6505   "!TARGET_64BIT"
6507   switch (get_attr_type (insn))
6508     {
6509     case TYPE_INCDEC:
6510       if (operands[2] == const1_rtx)
6511         return "inc{b}\t%h0";
6512       else if (operands[2] == constm1_rtx
6513                || (GET_CODE (operands[2]) == CONST_INT
6514                    && INTVAL (operands[2]) == 255))
6515         return "dec{b}\t%h0";
6516       abort();
6518     default:
6519       return "add{b}\t{%2, %h0|%h0, %2}";
6520     }
6522   [(set (attr "type")
6523      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6524         (const_string "incdec")
6525         (const_string "alu")))
6526    (set_attr "mode" "QI")])
6528 (define_insn "*addqi_ext_1_rex64"
6529   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6530                          (const_int 8)
6531                          (const_int 8))
6532         (plus:SI
6533           (zero_extract:SI
6534             (match_operand 1 "ext_register_operand" "0")
6535             (const_int 8)
6536             (const_int 8))
6537           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6538    (clobber (reg:CC FLAGS_REG))]
6539   "TARGET_64BIT"
6541   switch (get_attr_type (insn))
6542     {
6543     case TYPE_INCDEC:
6544       if (operands[2] == const1_rtx)
6545         return "inc{b}\t%h0";
6546       else if (operands[2] == constm1_rtx
6547                || (GET_CODE (operands[2]) == CONST_INT
6548                    && INTVAL (operands[2]) == 255))
6549         return "dec{b}\t%h0";
6550       abort();
6552     default:
6553       return "add{b}\t{%2, %h0|%h0, %2}";
6554     }
6556   [(set (attr "type")
6557      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6558         (const_string "incdec")
6559         (const_string "alu")))
6560    (set_attr "mode" "QI")])
6562 (define_insn "*addqi_ext_2"
6563   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6564                          (const_int 8)
6565                          (const_int 8))
6566         (plus:SI
6567           (zero_extract:SI
6568             (match_operand 1 "ext_register_operand" "%0")
6569             (const_int 8)
6570             (const_int 8))
6571           (zero_extract:SI
6572             (match_operand 2 "ext_register_operand" "Q")
6573             (const_int 8)
6574             (const_int 8))))
6575    (clobber (reg:CC FLAGS_REG))]
6576   ""
6577   "add{b}\t{%h2, %h0|%h0, %h2}"
6578   [(set_attr "type" "alu")
6579    (set_attr "mode" "QI")])
6581 ;; The patterns that match these are at the end of this file.
6583 (define_expand "addxf3"
6584   [(set (match_operand:XF 0 "register_operand" "")
6585         (plus:XF (match_operand:XF 1 "register_operand" "")
6586                  (match_operand:XF 2 "register_operand" "")))]
6587   "TARGET_80387"
6588   "")
6590 (define_expand "adddf3"
6591   [(set (match_operand:DF 0 "register_operand" "")
6592         (plus:DF (match_operand:DF 1 "register_operand" "")
6593                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6594   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6595   "")
6597 (define_expand "addsf3"
6598   [(set (match_operand:SF 0 "register_operand" "")
6599         (plus:SF (match_operand:SF 1 "register_operand" "")
6600                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6601   "TARGET_80387 || TARGET_SSE_MATH"
6602   "")
6604 ;; Subtract instructions
6606 ;; %%% splits for subsidi3
6608 (define_expand "subdi3"
6609   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6610                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6611                              (match_operand:DI 2 "x86_64_general_operand" "")))
6612               (clobber (reg:CC FLAGS_REG))])]
6613   ""
6614   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6616 (define_insn "*subdi3_1"
6617   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6618         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6619                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6622   "#")
6624 (define_split
6625   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6626         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6627                   (match_operand:DI 2 "general_operand" "")))
6628    (clobber (reg:CC FLAGS_REG))]
6629   "!TARGET_64BIT && reload_completed"
6630   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6631               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6632    (parallel [(set (match_dup 3)
6633                    (minus:SI (match_dup 4)
6634                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6635                                       (match_dup 5))))
6636               (clobber (reg:CC FLAGS_REG))])]
6637   "split_di (operands+0, 1, operands+0, operands+3);
6638    split_di (operands+1, 1, operands+1, operands+4);
6639    split_di (operands+2, 1, operands+2, operands+5);")
6641 (define_insn "subdi3_carry_rex64"
6642   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6643           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6644             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6645                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6646    (clobber (reg:CC FLAGS_REG))]
6647   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6648   "sbb{q}\t{%2, %0|%0, %2}"
6649   [(set_attr "type" "alu")
6650    (set_attr "pent_pair" "pu")
6651    (set_attr "mode" "DI")])
6653 (define_insn "*subdi_1_rex64"
6654   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6655         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6656                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6657    (clobber (reg:CC FLAGS_REG))]
6658   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6659   "sub{q}\t{%2, %0|%0, %2}"
6660   [(set_attr "type" "alu")
6661    (set_attr "mode" "DI")])
6663 (define_insn "*subdi_2_rex64"
6664   [(set (reg 17)
6665         (compare
6666           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6667                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6668           (const_int 0)))
6669    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6670         (minus:DI (match_dup 1) (match_dup 2)))]
6671   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6672    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6673   "sub{q}\t{%2, %0|%0, %2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "mode" "DI")])
6677 (define_insn "*subdi_3_rex63"
6678   [(set (reg 17)
6679         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6680                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6681    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6682         (minus:DI (match_dup 1) (match_dup 2)))]
6683   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6684    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6685   "sub{q}\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "mode" "DI")])
6689 (define_insn "subqi3_carry"
6690   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6691           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6692             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6693                (match_operand:QI 2 "general_operand" "qi,qm"))))
6694    (clobber (reg:CC FLAGS_REG))]
6695   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6696   "sbb{b}\t{%2, %0|%0, %2}"
6697   [(set_attr "type" "alu")
6698    (set_attr "pent_pair" "pu")
6699    (set_attr "mode" "QI")])
6701 (define_insn "subhi3_carry"
6702   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6703           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6704             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6705                (match_operand:HI 2 "general_operand" "ri,rm"))))
6706    (clobber (reg:CC FLAGS_REG))]
6707   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6708   "sbb{w}\t{%2, %0|%0, %2}"
6709   [(set_attr "type" "alu")
6710    (set_attr "pent_pair" "pu")
6711    (set_attr "mode" "HI")])
6713 (define_insn "subsi3_carry"
6714   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6715           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6716             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6717                (match_operand:SI 2 "general_operand" "ri,rm"))))
6718    (clobber (reg:CC FLAGS_REG))]
6719   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6720   "sbb{l}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "pent_pair" "pu")
6723    (set_attr "mode" "SI")])
6725 (define_insn "subsi3_carry_zext"
6726   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6727           (zero_extend:DI
6728             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6729               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6730                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6731    (clobber (reg:CC FLAGS_REG))]
6732   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6733   "sbb{l}\t{%2, %k0|%k0, %2}"
6734   [(set_attr "type" "alu")
6735    (set_attr "pent_pair" "pu")
6736    (set_attr "mode" "SI")])
6738 (define_expand "subsi3"
6739   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6740                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6741                              (match_operand:SI 2 "general_operand" "")))
6742               (clobber (reg:CC FLAGS_REG))])]
6743   ""
6744   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6746 (define_insn "*subsi_1"
6747   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6748         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6749                   (match_operand:SI 2 "general_operand" "ri,rm")))
6750    (clobber (reg:CC FLAGS_REG))]
6751   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6752   "sub{l}\t{%2, %0|%0, %2}"
6753   [(set_attr "type" "alu")
6754    (set_attr "mode" "SI")])
6756 (define_insn "*subsi_1_zext"
6757   [(set (match_operand:DI 0 "register_operand" "=r")
6758         (zero_extend:DI
6759           (minus:SI (match_operand:SI 1 "register_operand" "0")
6760                     (match_operand:SI 2 "general_operand" "rim"))))
6761    (clobber (reg:CC FLAGS_REG))]
6762   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763   "sub{l}\t{%2, %k0|%k0, %2}"
6764   [(set_attr "type" "alu")
6765    (set_attr "mode" "SI")])
6767 (define_insn "*subsi_2"
6768   [(set (reg 17)
6769         (compare
6770           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6771                     (match_operand:SI 2 "general_operand" "ri,rm"))
6772           (const_int 0)))
6773    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6774         (minus:SI (match_dup 1) (match_dup 2)))]
6775   "ix86_match_ccmode (insn, CCGOCmode)
6776    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777   "sub{l}\t{%2, %0|%0, %2}"
6778   [(set_attr "type" "alu")
6779    (set_attr "mode" "SI")])
6781 (define_insn "*subsi_2_zext"
6782   [(set (reg 17)
6783         (compare
6784           (minus:SI (match_operand:SI 1 "register_operand" "0")
6785                     (match_operand:SI 2 "general_operand" "rim"))
6786           (const_int 0)))
6787    (set (match_operand:DI 0 "register_operand" "=r")
6788         (zero_extend:DI
6789           (minus:SI (match_dup 1)
6790                     (match_dup 2))))]
6791   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6792    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6793   "sub{l}\t{%2, %k0|%k0, %2}"
6794   [(set_attr "type" "alu")
6795    (set_attr "mode" "SI")])
6797 (define_insn "*subsi_3"
6798   [(set (reg 17)
6799         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6800                  (match_operand:SI 2 "general_operand" "ri,rm")))
6801    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6802         (minus:SI (match_dup 1) (match_dup 2)))]
6803   "ix86_match_ccmode (insn, CCmode)
6804    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6805   "sub{l}\t{%2, %0|%0, %2}"
6806   [(set_attr "type" "alu")
6807    (set_attr "mode" "SI")])
6809 (define_insn "*subsi_3_zext"
6810   [(set (reg 17)
6811         (compare (match_operand:SI 1 "register_operand" "0")
6812                  (match_operand:SI 2 "general_operand" "rim")))
6813    (set (match_operand:DI 0 "register_operand" "=r")
6814         (zero_extend:DI
6815           (minus:SI (match_dup 1)
6816                     (match_dup 2))))]
6817   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6818    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6819   "sub{q}\t{%2, %0|%0, %2}"
6820   [(set_attr "type" "alu")
6821    (set_attr "mode" "DI")])
6823 (define_expand "subhi3"
6824   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6825                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6826                              (match_operand:HI 2 "general_operand" "")))
6827               (clobber (reg:CC FLAGS_REG))])]
6828   "TARGET_HIMODE_MATH"
6829   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6831 (define_insn "*subhi_1"
6832   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6833         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6834                   (match_operand:HI 2 "general_operand" "ri,rm")))
6835    (clobber (reg:CC FLAGS_REG))]
6836   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6837   "sub{w}\t{%2, %0|%0, %2}"
6838   [(set_attr "type" "alu")
6839    (set_attr "mode" "HI")])
6841 (define_insn "*subhi_2"
6842   [(set (reg 17)
6843         (compare
6844           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6845                     (match_operand:HI 2 "general_operand" "ri,rm"))
6846           (const_int 0)))
6847    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6848         (minus:HI (match_dup 1) (match_dup 2)))]
6849   "ix86_match_ccmode (insn, CCGOCmode)
6850    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6851   "sub{w}\t{%2, %0|%0, %2}"
6852   [(set_attr "type" "alu")
6853    (set_attr "mode" "HI")])
6855 (define_insn "*subhi_3"
6856   [(set (reg 17)
6857         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6858                  (match_operand:HI 2 "general_operand" "ri,rm")))
6859    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6860         (minus:HI (match_dup 1) (match_dup 2)))]
6861   "ix86_match_ccmode (insn, CCmode)
6862    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6863   "sub{w}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "alu")
6865    (set_attr "mode" "HI")])
6867 (define_expand "subqi3"
6868   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6869                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6870                              (match_operand:QI 2 "general_operand" "")))
6871               (clobber (reg:CC FLAGS_REG))])]
6872   "TARGET_QIMODE_MATH"
6873   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6875 (define_insn "*subqi_1"
6876   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6877         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6878                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6879    (clobber (reg:CC FLAGS_REG))]
6880   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6881   "sub{b}\t{%2, %0|%0, %2}"
6882   [(set_attr "type" "alu")
6883    (set_attr "mode" "QI")])
6885 (define_insn "*subqi_1_slp"
6886   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6887         (minus:QI (match_dup 0)
6888                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6889    (clobber (reg:CC FLAGS_REG))]
6890   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6891    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6892   "sub{b}\t{%1, %0|%0, %1}"
6893   [(set_attr "type" "alu1")
6894    (set_attr "mode" "QI")])
6896 (define_insn "*subqi_2"
6897   [(set (reg 17)
6898         (compare
6899           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6900                     (match_operand:QI 2 "general_operand" "qi,qm"))
6901           (const_int 0)))
6902    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6903         (minus:HI (match_dup 1) (match_dup 2)))]
6904   "ix86_match_ccmode (insn, CCGOCmode)
6905    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6906   "sub{b}\t{%2, %0|%0, %2}"
6907   [(set_attr "type" "alu")
6908    (set_attr "mode" "QI")])
6910 (define_insn "*subqi_3"
6911   [(set (reg 17)
6912         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6913                  (match_operand:QI 2 "general_operand" "qi,qm")))
6914    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6915         (minus:HI (match_dup 1) (match_dup 2)))]
6916   "ix86_match_ccmode (insn, CCmode)
6917    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6918   "sub{b}\t{%2, %0|%0, %2}"
6919   [(set_attr "type" "alu")
6920    (set_attr "mode" "QI")])
6922 ;; The patterns that match these are at the end of this file.
6924 (define_expand "subxf3"
6925   [(set (match_operand:XF 0 "register_operand" "")
6926         (minus:XF (match_operand:XF 1 "register_operand" "")
6927                   (match_operand:XF 2 "register_operand" "")))]
6928   "TARGET_80387"
6929   "")
6931 (define_expand "subdf3"
6932   [(set (match_operand:DF 0 "register_operand" "")
6933         (minus:DF (match_operand:DF 1 "register_operand" "")
6934                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6935   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6936   "")
6938 (define_expand "subsf3"
6939   [(set (match_operand:SF 0 "register_operand" "")
6940         (minus:SF (match_operand:SF 1 "register_operand" "")
6941                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6942   "TARGET_80387 || TARGET_SSE_MATH"
6943   "")
6945 ;; Multiply instructions
6947 (define_expand "muldi3"
6948   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6949                    (mult:DI (match_operand:DI 1 "register_operand" "")
6950                             (match_operand:DI 2 "x86_64_general_operand" "")))
6951               (clobber (reg:CC FLAGS_REG))])]
6952   "TARGET_64BIT"
6953   "")
6955 (define_insn "*muldi3_1_rex64"
6956   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6957         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6958                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6959    (clobber (reg:CC FLAGS_REG))]
6960   "TARGET_64BIT
6961    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6962   "@
6963    imul{q}\t{%2, %1, %0|%0, %1, %2}
6964    imul{q}\t{%2, %1, %0|%0, %1, %2}
6965    imul{q}\t{%2, %0|%0, %2}"
6966   [(set_attr "type" "imul")
6967    (set_attr "prefix_0f" "0,0,1")
6968    (set (attr "athlon_decode")
6969         (cond [(eq_attr "cpu" "athlon")
6970                   (const_string "vector")
6971                (eq_attr "alternative" "1")
6972                   (const_string "vector")
6973                (and (eq_attr "alternative" "2")
6974                     (match_operand 1 "memory_operand" ""))
6975                   (const_string "vector")]
6976               (const_string "direct")))
6977    (set_attr "mode" "DI")])
6979 (define_expand "mulsi3"
6980   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6981                    (mult:SI (match_operand:SI 1 "register_operand" "")
6982                             (match_operand:SI 2 "general_operand" "")))
6983               (clobber (reg:CC FLAGS_REG))])]
6984   ""
6985   "")
6987 (define_insn "*mulsi3_1"
6988   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6989         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6990                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6991    (clobber (reg:CC FLAGS_REG))]
6992   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6993   "@
6994    imul{l}\t{%2, %1, %0|%0, %1, %2}
6995    imul{l}\t{%2, %1, %0|%0, %1, %2}
6996    imul{l}\t{%2, %0|%0, %2}"
6997   [(set_attr "type" "imul")
6998    (set_attr "prefix_0f" "0,0,1")
6999    (set (attr "athlon_decode")
7000         (cond [(eq_attr "cpu" "athlon")
7001                   (const_string "vector")
7002                (eq_attr "alternative" "1")
7003                   (const_string "vector")
7004                (and (eq_attr "alternative" "2")
7005                     (match_operand 1 "memory_operand" ""))
7006                   (const_string "vector")]
7007               (const_string "direct")))
7008    (set_attr "mode" "SI")])
7010 (define_insn "*mulsi3_1_zext"
7011   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7012         (zero_extend:DI
7013           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7014                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7015    (clobber (reg:CC FLAGS_REG))]
7016   "TARGET_64BIT
7017    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7018   "@
7019    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7020    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7021    imul{l}\t{%2, %k0|%k0, %2}"
7022   [(set_attr "type" "imul")
7023    (set_attr "prefix_0f" "0,0,1")
7024    (set (attr "athlon_decode")
7025         (cond [(eq_attr "cpu" "athlon")
7026                   (const_string "vector")
7027                (eq_attr "alternative" "1")
7028                   (const_string "vector")
7029                (and (eq_attr "alternative" "2")
7030                     (match_operand 1 "memory_operand" ""))
7031                   (const_string "vector")]
7032               (const_string "direct")))
7033    (set_attr "mode" "SI")])
7035 (define_expand "mulhi3"
7036   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7037                    (mult:HI (match_operand:HI 1 "register_operand" "")
7038                             (match_operand:HI 2 "general_operand" "")))
7039               (clobber (reg:CC FLAGS_REG))])]
7040   "TARGET_HIMODE_MATH"
7041   "")
7043 (define_insn "*mulhi3_1"
7044   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7045         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7046                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7047    (clobber (reg:CC FLAGS_REG))]
7048   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7049   "@
7050    imul{w}\t{%2, %1, %0|%0, %1, %2}
7051    imul{w}\t{%2, %1, %0|%0, %1, %2}
7052    imul{w}\t{%2, %0|%0, %2}"
7053   [(set_attr "type" "imul")
7054    (set_attr "prefix_0f" "0,0,1")
7055    (set (attr "athlon_decode")
7056         (cond [(eq_attr "cpu" "athlon")
7057                   (const_string "vector")
7058                (eq_attr "alternative" "1,2")
7059                   (const_string "vector")]
7060               (const_string "direct")))
7061    (set_attr "mode" "HI")])
7063 (define_expand "mulqi3"
7064   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7065                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7066                             (match_operand:QI 2 "register_operand" "")))
7067               (clobber (reg:CC FLAGS_REG))])]
7068   "TARGET_QIMODE_MATH"
7069   "")
7071 (define_insn "*mulqi3_1"
7072   [(set (match_operand:QI 0 "register_operand" "=a")
7073         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7074                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7075    (clobber (reg:CC FLAGS_REG))]
7076   "TARGET_QIMODE_MATH
7077    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7078   "mul{b}\t%2"
7079   [(set_attr "type" "imul")
7080    (set_attr "length_immediate" "0")
7081    (set (attr "athlon_decode")
7082      (if_then_else (eq_attr "cpu" "athlon")
7083         (const_string "vector")
7084         (const_string "direct")))
7085    (set_attr "mode" "QI")])
7087 (define_expand "umulqihi3"
7088   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7089                    (mult:HI (zero_extend:HI
7090                               (match_operand:QI 1 "nonimmediate_operand" ""))
7091                             (zero_extend:HI
7092                               (match_operand:QI 2 "register_operand" ""))))
7093               (clobber (reg:CC FLAGS_REG))])]
7094   "TARGET_QIMODE_MATH"
7095   "")
7097 (define_insn "*umulqihi3_1"
7098   [(set (match_operand:HI 0 "register_operand" "=a")
7099         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7100                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7101    (clobber (reg:CC FLAGS_REG))]
7102   "TARGET_QIMODE_MATH
7103    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7104   "mul{b}\t%2"
7105   [(set_attr "type" "imul")
7106    (set_attr "length_immediate" "0")
7107    (set (attr "athlon_decode")
7108      (if_then_else (eq_attr "cpu" "athlon")
7109         (const_string "vector")
7110         (const_string "direct")))
7111    (set_attr "mode" "QI")])
7113 (define_expand "mulqihi3"
7114   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7115                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7116                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7117               (clobber (reg:CC FLAGS_REG))])]
7118   "TARGET_QIMODE_MATH"
7119   "")
7121 (define_insn "*mulqihi3_insn"
7122   [(set (match_operand:HI 0 "register_operand" "=a")
7123         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7124                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7125    (clobber (reg:CC FLAGS_REG))]
7126   "TARGET_QIMODE_MATH
7127    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7128   "imul{b}\t%2"
7129   [(set_attr "type" "imul")
7130    (set_attr "length_immediate" "0")
7131    (set (attr "athlon_decode")
7132      (if_then_else (eq_attr "cpu" "athlon")
7133         (const_string "vector")
7134         (const_string "direct")))
7135    (set_attr "mode" "QI")])
7137 (define_expand "umulditi3"
7138   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7139                    (mult:TI (zero_extend:TI
7140                               (match_operand:DI 1 "nonimmediate_operand" ""))
7141                             (zero_extend:TI
7142                               (match_operand:DI 2 "register_operand" ""))))
7143               (clobber (reg:CC FLAGS_REG))])]
7144   "TARGET_64BIT"
7145   "")
7147 (define_insn "*umulditi3_insn"
7148   [(set (match_operand:TI 0 "register_operand" "=A")
7149         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7150                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7151    (clobber (reg:CC FLAGS_REG))]
7152   "TARGET_64BIT
7153    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7154   "mul{q}\t%2"
7155   [(set_attr "type" "imul")
7156    (set_attr "length_immediate" "0")
7157    (set (attr "athlon_decode")
7158      (if_then_else (eq_attr "cpu" "athlon")
7159         (const_string "vector")
7160         (const_string "double")))
7161    (set_attr "mode" "DI")])
7163 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7164 (define_expand "umulsidi3"
7165   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7166                    (mult:DI (zero_extend:DI
7167                               (match_operand:SI 1 "nonimmediate_operand" ""))
7168                             (zero_extend:DI
7169                               (match_operand:SI 2 "register_operand" ""))))
7170               (clobber (reg:CC FLAGS_REG))])]
7171   "!TARGET_64BIT"
7172   "")
7174 (define_insn "*umulsidi3_insn"
7175   [(set (match_operand:DI 0 "register_operand" "=A")
7176         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7177                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7178    (clobber (reg:CC FLAGS_REG))]
7179   "!TARGET_64BIT
7180    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7181   "mul{l}\t%2"
7182   [(set_attr "type" "imul")
7183    (set_attr "length_immediate" "0")
7184    (set (attr "athlon_decode")
7185      (if_then_else (eq_attr "cpu" "athlon")
7186         (const_string "vector")
7187         (const_string "double")))
7188    (set_attr "mode" "SI")])
7190 (define_expand "mulditi3"
7191   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7192                    (mult:TI (sign_extend:TI
7193                               (match_operand:DI 1 "nonimmediate_operand" ""))
7194                             (sign_extend:TI
7195                               (match_operand:DI 2 "register_operand" ""))))
7196               (clobber (reg:CC FLAGS_REG))])]
7197   "TARGET_64BIT"
7198   "")
7200 (define_insn "*mulditi3_insn"
7201   [(set (match_operand:TI 0 "register_operand" "=A")
7202         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7203                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7204    (clobber (reg:CC FLAGS_REG))]
7205   "TARGET_64BIT
7206    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7207   "imul{q}\t%2"
7208   [(set_attr "type" "imul")
7209    (set_attr "length_immediate" "0")
7210    (set (attr "athlon_decode")
7211      (if_then_else (eq_attr "cpu" "athlon")
7212         (const_string "vector")
7213         (const_string "double")))
7214    (set_attr "mode" "DI")])
7216 (define_expand "mulsidi3"
7217   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7218                    (mult:DI (sign_extend:DI
7219                               (match_operand:SI 1 "nonimmediate_operand" ""))
7220                             (sign_extend:DI
7221                               (match_operand:SI 2 "register_operand" ""))))
7222               (clobber (reg:CC FLAGS_REG))])]
7223   "!TARGET_64BIT"
7224   "")
7226 (define_insn "*mulsidi3_insn"
7227   [(set (match_operand:DI 0 "register_operand" "=A")
7228         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7229                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7230    (clobber (reg:CC FLAGS_REG))]
7231   "!TARGET_64BIT
7232    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7233   "imul{l}\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" "SI")])
7242 (define_expand "umuldi3_highpart"
7243   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7244                    (truncate:DI
7245                      (lshiftrt:TI
7246                        (mult:TI (zero_extend:TI
7247                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7248                                 (zero_extend:TI
7249                                   (match_operand:DI 2 "register_operand" "")))
7250                        (const_int 64))))
7251               (clobber (match_scratch:DI 3 ""))
7252               (clobber (reg:CC FLAGS_REG))])]
7253   "TARGET_64BIT"
7254   "")
7256 (define_insn "*umuldi3_highpart_rex64"
7257   [(set (match_operand:DI 0 "register_operand" "=d")
7258         (truncate:DI
7259           (lshiftrt:TI
7260             (mult:TI (zero_extend:TI
7261                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7262                      (zero_extend:TI
7263                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7264             (const_int 64))))
7265    (clobber (match_scratch:DI 3 "=1"))
7266    (clobber (reg:CC FLAGS_REG))]
7267   "TARGET_64BIT
7268    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7269   "mul{q}\t%2"
7270   [(set_attr "type" "imul")
7271    (set_attr "length_immediate" "0")
7272    (set (attr "athlon_decode")
7273      (if_then_else (eq_attr "cpu" "athlon")
7274         (const_string "vector")
7275         (const_string "double")))
7276    (set_attr "mode" "DI")])
7278 (define_expand "umulsi3_highpart"
7279   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7280                    (truncate:SI
7281                      (lshiftrt:DI
7282                        (mult:DI (zero_extend:DI
7283                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7284                                 (zero_extend:DI
7285                                   (match_operand:SI 2 "register_operand" "")))
7286                        (const_int 32))))
7287               (clobber (match_scratch:SI 3 ""))
7288               (clobber (reg:CC FLAGS_REG))])]
7289   ""
7290   "")
7292 (define_insn "*umulsi3_highpart_insn"
7293   [(set (match_operand:SI 0 "register_operand" "=d")
7294         (truncate:SI
7295           (lshiftrt:DI
7296             (mult:DI (zero_extend:DI
7297                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7298                      (zero_extend:DI
7299                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7300             (const_int 32))))
7301    (clobber (match_scratch:SI 3 "=1"))
7302    (clobber (reg:CC FLAGS_REG))]
7303   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7304   "mul{l}\t%2"
7305   [(set_attr "type" "imul")
7306    (set_attr "length_immediate" "0")
7307    (set (attr "athlon_decode")
7308      (if_then_else (eq_attr "cpu" "athlon")
7309         (const_string "vector")
7310         (const_string "double")))
7311    (set_attr "mode" "SI")])
7313 (define_insn "*umulsi3_highpart_zext"
7314   [(set (match_operand:DI 0 "register_operand" "=d")
7315         (zero_extend:DI (truncate:SI
7316           (lshiftrt:DI
7317             (mult:DI (zero_extend:DI
7318                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7319                      (zero_extend:DI
7320                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7321             (const_int 32)))))
7322    (clobber (match_scratch:SI 3 "=1"))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_64BIT
7325    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7326   "mul{l}\t%2"
7327   [(set_attr "type" "imul")
7328    (set_attr "length_immediate" "0")
7329    (set (attr "athlon_decode")
7330      (if_then_else (eq_attr "cpu" "athlon")
7331         (const_string "vector")
7332         (const_string "double")))
7333    (set_attr "mode" "SI")])
7335 (define_expand "smuldi3_highpart"
7336   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7337                    (truncate:DI
7338                      (lshiftrt:TI
7339                        (mult:TI (sign_extend:TI
7340                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7341                                 (sign_extend:TI
7342                                   (match_operand:DI 2 "register_operand" "")))
7343                        (const_int 64))))
7344               (clobber (match_scratch:DI 3 ""))
7345               (clobber (reg:CC FLAGS_REG))])]
7346   "TARGET_64BIT"
7347   "")
7349 (define_insn "*smuldi3_highpart_rex64"
7350   [(set (match_operand:DI 0 "register_operand" "=d")
7351         (truncate:DI
7352           (lshiftrt:TI
7353             (mult:TI (sign_extend:TI
7354                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7355                      (sign_extend:TI
7356                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7357             (const_int 64))))
7358    (clobber (match_scratch:DI 3 "=1"))
7359    (clobber (reg:CC FLAGS_REG))]
7360   "TARGET_64BIT
7361    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7362   "imul{q}\t%2"
7363   [(set_attr "type" "imul")
7364    (set (attr "athlon_decode")
7365      (if_then_else (eq_attr "cpu" "athlon")
7366         (const_string "vector")
7367         (const_string "double")))
7368    (set_attr "mode" "DI")])
7370 (define_expand "smulsi3_highpart"
7371   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7372                    (truncate:SI
7373                      (lshiftrt:DI
7374                        (mult:DI (sign_extend:DI
7375                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7376                                 (sign_extend:DI
7377                                   (match_operand:SI 2 "register_operand" "")))
7378                        (const_int 32))))
7379               (clobber (match_scratch:SI 3 ""))
7380               (clobber (reg:CC FLAGS_REG))])]
7381   ""
7382   "")
7384 (define_insn "*smulsi3_highpart_insn"
7385   [(set (match_operand:SI 0 "register_operand" "=d")
7386         (truncate:SI
7387           (lshiftrt:DI
7388             (mult:DI (sign_extend:DI
7389                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7390                      (sign_extend:DI
7391                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7392             (const_int 32))))
7393    (clobber (match_scratch:SI 3 "=1"))
7394    (clobber (reg:CC FLAGS_REG))]
7395   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7396   "imul{l}\t%2"
7397   [(set_attr "type" "imul")
7398    (set (attr "athlon_decode")
7399      (if_then_else (eq_attr "cpu" "athlon")
7400         (const_string "vector")
7401         (const_string "double")))
7402    (set_attr "mode" "SI")])
7404 (define_insn "*smulsi3_highpart_zext"
7405   [(set (match_operand:DI 0 "register_operand" "=d")
7406         (zero_extend:DI (truncate:SI
7407           (lshiftrt:DI
7408             (mult:DI (sign_extend:DI
7409                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7410                      (sign_extend:DI
7411                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7412             (const_int 32)))))
7413    (clobber (match_scratch:SI 3 "=1"))
7414    (clobber (reg:CC FLAGS_REG))]
7415   "TARGET_64BIT
7416    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7417   "imul{l}\t%2"
7418   [(set_attr "type" "imul")
7419    (set (attr "athlon_decode")
7420      (if_then_else (eq_attr "cpu" "athlon")
7421         (const_string "vector")
7422         (const_string "double")))
7423    (set_attr "mode" "SI")])
7425 ;; The patterns that match these are at the end of this file.
7427 (define_expand "mulxf3"
7428   [(set (match_operand:XF 0 "register_operand" "")
7429         (mult:XF (match_operand:XF 1 "register_operand" "")
7430                  (match_operand:XF 2 "register_operand" "")))]
7431   "TARGET_80387"
7432   "")
7434 (define_expand "muldf3"
7435   [(set (match_operand:DF 0 "register_operand" "")
7436         (mult:DF (match_operand:DF 1 "register_operand" "")
7437                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7438   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7439   "")
7441 (define_expand "mulsf3"
7442   [(set (match_operand:SF 0 "register_operand" "")
7443         (mult:SF (match_operand:SF 1 "register_operand" "")
7444                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7445   "TARGET_80387 || TARGET_SSE_MATH"
7446   "")
7448 ;; Divide instructions
7450 (define_insn "divqi3"
7451   [(set (match_operand:QI 0 "register_operand" "=a")
7452         (div:QI (match_operand:HI 1 "register_operand" "0")
7453                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7454    (clobber (reg:CC FLAGS_REG))]
7455   "TARGET_QIMODE_MATH"
7456   "idiv{b}\t%2"
7457   [(set_attr "type" "idiv")
7458    (set_attr "mode" "QI")])
7460 (define_insn "udivqi3"
7461   [(set (match_operand:QI 0 "register_operand" "=a")
7462         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7463                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7464    (clobber (reg:CC FLAGS_REG))]
7465   "TARGET_QIMODE_MATH"
7466   "div{b}\t%2"
7467   [(set_attr "type" "idiv")
7468    (set_attr "mode" "QI")])
7470 ;; The patterns that match these are at the end of this file.
7472 (define_expand "divxf3"
7473   [(set (match_operand:XF 0 "register_operand" "")
7474         (div:XF (match_operand:XF 1 "register_operand" "")
7475                 (match_operand:XF 2 "register_operand" "")))]
7476   "TARGET_80387"
7477   "")
7479 (define_expand "divdf3"
7480   [(set (match_operand:DF 0 "register_operand" "")
7481         (div:DF (match_operand:DF 1 "register_operand" "")
7482                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7483    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7484    "")
7486 (define_expand "divsf3"
7487   [(set (match_operand:SF 0 "register_operand" "")
7488         (div:SF (match_operand:SF 1 "register_operand" "")
7489                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7490   "TARGET_80387 || TARGET_SSE_MATH"
7491   "")
7493 ;; Remainder instructions.
7495 (define_expand "divmoddi4"
7496   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7497                    (div:DI (match_operand:DI 1 "register_operand" "")
7498                            (match_operand:DI 2 "nonimmediate_operand" "")))
7499               (set (match_operand:DI 3 "register_operand" "")
7500                    (mod:DI (match_dup 1) (match_dup 2)))
7501               (clobber (reg:CC FLAGS_REG))])]
7502   "TARGET_64BIT"
7503   "")
7505 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7506 ;; Penalize eax case slightly because it results in worse scheduling
7507 ;; of code.
7508 (define_insn "*divmoddi4_nocltd_rex64"
7509   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7510         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7511                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7512    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7513         (mod:DI (match_dup 2) (match_dup 3)))
7514    (clobber (reg:CC FLAGS_REG))]
7515   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7516   "#"
7517   [(set_attr "type" "multi")])
7519 (define_insn "*divmoddi4_cltd_rex64"
7520   [(set (match_operand:DI 0 "register_operand" "=a")
7521         (div:DI (match_operand:DI 2 "register_operand" "a")
7522                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7523    (set (match_operand:DI 1 "register_operand" "=&d")
7524         (mod:DI (match_dup 2) (match_dup 3)))
7525    (clobber (reg:CC FLAGS_REG))]
7526   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7527   "#"
7528   [(set_attr "type" "multi")])
7530 (define_insn "*divmoddi_noext_rex64"
7531   [(set (match_operand:DI 0 "register_operand" "=a")
7532         (div:DI (match_operand:DI 1 "register_operand" "0")
7533                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7534    (set (match_operand:DI 3 "register_operand" "=d")
7535         (mod:DI (match_dup 1) (match_dup 2)))
7536    (use (match_operand:DI 4 "register_operand" "3"))
7537    (clobber (reg:CC FLAGS_REG))]
7538   "TARGET_64BIT"
7539   "idiv{q}\t%2"
7540   [(set_attr "type" "idiv")
7541    (set_attr "mode" "DI")])
7543 (define_split
7544   [(set (match_operand:DI 0 "register_operand" "")
7545         (div:DI (match_operand:DI 1 "register_operand" "")
7546                 (match_operand:DI 2 "nonimmediate_operand" "")))
7547    (set (match_operand:DI 3 "register_operand" "")
7548         (mod:DI (match_dup 1) (match_dup 2)))
7549    (clobber (reg:CC FLAGS_REG))]
7550   "TARGET_64BIT && reload_completed"
7551   [(parallel [(set (match_dup 3)
7552                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7553               (clobber (reg:CC FLAGS_REG))])
7554    (parallel [(set (match_dup 0)
7555                    (div:DI (reg:DI 0) (match_dup 2)))
7556               (set (match_dup 3)
7557                    (mod:DI (reg:DI 0) (match_dup 2)))
7558               (use (match_dup 3))
7559               (clobber (reg:CC FLAGS_REG))])]
7561   /* Avoid use of cltd in favor of a mov+shift.  */
7562   if (!TARGET_USE_CLTD && !optimize_size)
7563     {
7564       if (true_regnum (operands[1]))
7565         emit_move_insn (operands[0], operands[1]);
7566       else
7567         emit_move_insn (operands[3], operands[1]);
7568       operands[4] = operands[3];
7569     }
7570   else
7571     {
7572       if (true_regnum (operands[1]))
7573         abort();
7574       operands[4] = operands[1];
7575     }
7579 (define_expand "divmodsi4"
7580   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7581                    (div:SI (match_operand:SI 1 "register_operand" "")
7582                            (match_operand:SI 2 "nonimmediate_operand" "")))
7583               (set (match_operand:SI 3 "register_operand" "")
7584                    (mod:SI (match_dup 1) (match_dup 2)))
7585               (clobber (reg:CC FLAGS_REG))])]
7586   ""
7587   "")
7589 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7590 ;; Penalize eax case slightly because it results in worse scheduling
7591 ;; of code.
7592 (define_insn "*divmodsi4_nocltd"
7593   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7594         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7595                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7596    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7597         (mod:SI (match_dup 2) (match_dup 3)))
7598    (clobber (reg:CC FLAGS_REG))]
7599   "!optimize_size && !TARGET_USE_CLTD"
7600   "#"
7601   [(set_attr "type" "multi")])
7603 (define_insn "*divmodsi4_cltd"
7604   [(set (match_operand:SI 0 "register_operand" "=a")
7605         (div:SI (match_operand:SI 2 "register_operand" "a")
7606                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7607    (set (match_operand:SI 1 "register_operand" "=&d")
7608         (mod:SI (match_dup 2) (match_dup 3)))
7609    (clobber (reg:CC FLAGS_REG))]
7610   "optimize_size || TARGET_USE_CLTD"
7611   "#"
7612   [(set_attr "type" "multi")])
7614 (define_insn "*divmodsi_noext"
7615   [(set (match_operand:SI 0 "register_operand" "=a")
7616         (div:SI (match_operand:SI 1 "register_operand" "0")
7617                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7618    (set (match_operand:SI 3 "register_operand" "=d")
7619         (mod:SI (match_dup 1) (match_dup 2)))
7620    (use (match_operand:SI 4 "register_operand" "3"))
7621    (clobber (reg:CC FLAGS_REG))]
7622   ""
7623   "idiv{l}\t%2"
7624   [(set_attr "type" "idiv")
7625    (set_attr "mode" "SI")])
7627 (define_split
7628   [(set (match_operand:SI 0 "register_operand" "")
7629         (div:SI (match_operand:SI 1 "register_operand" "")
7630                 (match_operand:SI 2 "nonimmediate_operand" "")))
7631    (set (match_operand:SI 3 "register_operand" "")
7632         (mod:SI (match_dup 1) (match_dup 2)))
7633    (clobber (reg:CC FLAGS_REG))]
7634   "reload_completed"
7635   [(parallel [(set (match_dup 3)
7636                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7637               (clobber (reg:CC FLAGS_REG))])
7638    (parallel [(set (match_dup 0)
7639                    (div:SI (reg:SI 0) (match_dup 2)))
7640               (set (match_dup 3)
7641                    (mod:SI (reg:SI 0) (match_dup 2)))
7642               (use (match_dup 3))
7643               (clobber (reg:CC FLAGS_REG))])]
7645   /* Avoid use of cltd in favor of a mov+shift.  */
7646   if (!TARGET_USE_CLTD && !optimize_size)
7647     {
7648       if (true_regnum (operands[1]))
7649         emit_move_insn (operands[0], operands[1]);
7650       else
7651         emit_move_insn (operands[3], operands[1]);
7652       operands[4] = operands[3];
7653     }
7654   else
7655     {
7656       if (true_regnum (operands[1]))
7657         abort();
7658       operands[4] = operands[1];
7659     }
7661 ;; %%% Split me.
7662 (define_insn "divmodhi4"
7663   [(set (match_operand:HI 0 "register_operand" "=a")
7664         (div:HI (match_operand:HI 1 "register_operand" "0")
7665                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7666    (set (match_operand:HI 3 "register_operand" "=&d")
7667         (mod:HI (match_dup 1) (match_dup 2)))
7668    (clobber (reg:CC FLAGS_REG))]
7669   "TARGET_HIMODE_MATH"
7670   "cwtd\;idiv{w}\t%2"
7671   [(set_attr "type" "multi")
7672    (set_attr "length_immediate" "0")
7673    (set_attr "mode" "SI")])
7675 (define_insn "udivmoddi4"
7676   [(set (match_operand:DI 0 "register_operand" "=a")
7677         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7678                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7679    (set (match_operand:DI 3 "register_operand" "=&d")
7680         (umod:DI (match_dup 1) (match_dup 2)))
7681    (clobber (reg:CC FLAGS_REG))]
7682   "TARGET_64BIT"
7683   "xor{q}\t%3, %3\;div{q}\t%2"
7684   [(set_attr "type" "multi")
7685    (set_attr "length_immediate" "0")
7686    (set_attr "mode" "DI")])
7688 (define_insn "*udivmoddi4_noext"
7689   [(set (match_operand:DI 0 "register_operand" "=a")
7690         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7691                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7692    (set (match_operand:DI 3 "register_operand" "=d")
7693         (umod:DI (match_dup 1) (match_dup 2)))
7694    (use (match_dup 3))
7695    (clobber (reg:CC FLAGS_REG))]
7696   "TARGET_64BIT"
7697   "div{q}\t%2"
7698   [(set_attr "type" "idiv")
7699    (set_attr "mode" "DI")])
7701 (define_split
7702   [(set (match_operand:DI 0 "register_operand" "")
7703         (udiv:DI (match_operand:DI 1 "register_operand" "")
7704                  (match_operand:DI 2 "nonimmediate_operand" "")))
7705    (set (match_operand:DI 3 "register_operand" "")
7706         (umod:DI (match_dup 1) (match_dup 2)))
7707    (clobber (reg:CC FLAGS_REG))]
7708   "TARGET_64BIT && reload_completed"
7709   [(set (match_dup 3) (const_int 0))
7710    (parallel [(set (match_dup 0)
7711                    (udiv:DI (match_dup 1) (match_dup 2)))
7712               (set (match_dup 3)
7713                    (umod:DI (match_dup 1) (match_dup 2)))
7714               (use (match_dup 3))
7715               (clobber (reg:CC FLAGS_REG))])]
7716   "")
7718 (define_insn "udivmodsi4"
7719   [(set (match_operand:SI 0 "register_operand" "=a")
7720         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7721                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7722    (set (match_operand:SI 3 "register_operand" "=&d")
7723         (umod:SI (match_dup 1) (match_dup 2)))
7724    (clobber (reg:CC FLAGS_REG))]
7725   ""
7726   "xor{l}\t%3, %3\;div{l}\t%2"
7727   [(set_attr "type" "multi")
7728    (set_attr "length_immediate" "0")
7729    (set_attr "mode" "SI")])
7731 (define_insn "*udivmodsi4_noext"
7732   [(set (match_operand:SI 0 "register_operand" "=a")
7733         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7734                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7735    (set (match_operand:SI 3 "register_operand" "=d")
7736         (umod:SI (match_dup 1) (match_dup 2)))
7737    (use (match_dup 3))
7738    (clobber (reg:CC FLAGS_REG))]
7739   ""
7740   "div{l}\t%2"
7741   [(set_attr "type" "idiv")
7742    (set_attr "mode" "SI")])
7744 (define_split
7745   [(set (match_operand:SI 0 "register_operand" "")
7746         (udiv:SI (match_operand:SI 1 "register_operand" "")
7747                  (match_operand:SI 2 "nonimmediate_operand" "")))
7748    (set (match_operand:SI 3 "register_operand" "")
7749         (umod:SI (match_dup 1) (match_dup 2)))
7750    (clobber (reg:CC FLAGS_REG))]
7751   "reload_completed"
7752   [(set (match_dup 3) (const_int 0))
7753    (parallel [(set (match_dup 0)
7754                    (udiv:SI (match_dup 1) (match_dup 2)))
7755               (set (match_dup 3)
7756                    (umod:SI (match_dup 1) (match_dup 2)))
7757               (use (match_dup 3))
7758               (clobber (reg:CC FLAGS_REG))])]
7759   "")
7761 (define_expand "udivmodhi4"
7762   [(set (match_dup 4) (const_int 0))
7763    (parallel [(set (match_operand:HI 0 "register_operand" "")
7764                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7765                             (match_operand:HI 2 "nonimmediate_operand" "")))
7766               (set (match_operand:HI 3 "register_operand" "")
7767                    (umod:HI (match_dup 1) (match_dup 2)))
7768               (use (match_dup 4))
7769               (clobber (reg:CC FLAGS_REG))])]
7770   "TARGET_HIMODE_MATH"
7771   "operands[4] = gen_reg_rtx (HImode);")
7773 (define_insn "*udivmodhi_noext"
7774   [(set (match_operand:HI 0 "register_operand" "=a")
7775         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7776                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7777    (set (match_operand:HI 3 "register_operand" "=d")
7778         (umod:HI (match_dup 1) (match_dup 2)))
7779    (use (match_operand:HI 4 "register_operand" "3"))
7780    (clobber (reg:CC FLAGS_REG))]
7781   ""
7782   "div{w}\t%2"
7783   [(set_attr "type" "idiv")
7784    (set_attr "mode" "HI")])
7786 ;; We can not use div/idiv for double division, because it causes
7787 ;; "division by zero" on the overflow and that's not what we expect
7788 ;; from truncate.  Because true (non truncating) double division is
7789 ;; never generated, we can't create this insn anyway.
7791 ;(define_insn ""
7792 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7793 ;       (truncate:SI
7794 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7795 ;                  (zero_extend:DI
7796 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7797 ;   (set (match_operand:SI 3 "register_operand" "=d")
7798 ;       (truncate:SI
7799 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7800 ;   (clobber (reg:CC FLAGS_REG))]
7801 ;  ""
7802 ;  "div{l}\t{%2, %0|%0, %2}"
7803 ;  [(set_attr "type" "idiv")])
7805 ;;- Logical AND instructions
7807 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7808 ;; Note that this excludes ah.
7810 (define_insn "*testdi_1_rex64"
7811   [(set (reg 17)
7812         (compare
7813           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7814                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7815           (const_int 0)))]
7816   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7817    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7818   "@
7819    test{l}\t{%k1, %k0|%k0, %k1}
7820    test{l}\t{%k1, %k0|%k0, %k1}
7821    test{q}\t{%1, %0|%0, %1}
7822    test{q}\t{%1, %0|%0, %1}
7823    test{q}\t{%1, %0|%0, %1}"
7824   [(set_attr "type" "test")
7825    (set_attr "modrm" "0,1,0,1,1")
7826    (set_attr "mode" "SI,SI,DI,DI,DI")
7827    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7829 (define_insn "testsi_1"
7830   [(set (reg 17)
7831         (compare
7832           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7833                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7834           (const_int 0)))]
7835   "ix86_match_ccmode (insn, CCNOmode)
7836    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7837   "test{l}\t{%1, %0|%0, %1}"
7838   [(set_attr "type" "test")
7839    (set_attr "modrm" "0,1,1")
7840    (set_attr "mode" "SI")
7841    (set_attr "pent_pair" "uv,np,uv")])
7843 (define_expand "testsi_ccno_1"
7844   [(set (reg:CCNO FLAGS_REG)
7845         (compare:CCNO
7846           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7847                   (match_operand:SI 1 "nonmemory_operand" ""))
7848           (const_int 0)))]
7849   ""
7850   "")
7852 (define_insn "*testhi_1"
7853   [(set (reg 17)
7854         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7855                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7856                  (const_int 0)))]
7857   "ix86_match_ccmode (insn, CCNOmode)
7858    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7859   "test{w}\t{%1, %0|%0, %1}"
7860   [(set_attr "type" "test")
7861    (set_attr "modrm" "0,1,1")
7862    (set_attr "mode" "HI")
7863    (set_attr "pent_pair" "uv,np,uv")])
7865 (define_expand "testqi_ccz_1"
7866   [(set (reg:CCZ FLAGS_REG)
7867         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7868                              (match_operand:QI 1 "nonmemory_operand" ""))
7869                  (const_int 0)))]
7870   ""
7871   "")
7873 (define_insn "*testqi_1"
7874   [(set (reg 17)
7875         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7876                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7877                  (const_int 0)))]
7878   "ix86_match_ccmode (insn, CCNOmode)
7879    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7881   if (which_alternative == 3)
7882     {
7883       if (GET_CODE (operands[1]) == CONST_INT
7884           && (INTVAL (operands[1]) & 0xffffff00))
7885         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7886       return "test{l}\t{%1, %k0|%k0, %1}";
7887     }
7888   return "test{b}\t{%1, %0|%0, %1}";
7890   [(set_attr "type" "test")
7891    (set_attr "modrm" "0,1,1,1")
7892    (set_attr "mode" "QI,QI,QI,SI")
7893    (set_attr "pent_pair" "uv,np,uv,np")])
7895 (define_expand "testqi_ext_ccno_0"
7896   [(set (reg:CCNO FLAGS_REG)
7897         (compare:CCNO
7898           (and:SI
7899             (zero_extract:SI
7900               (match_operand 0 "ext_register_operand" "")
7901               (const_int 8)
7902               (const_int 8))
7903             (match_operand 1 "const_int_operand" ""))
7904           (const_int 0)))]
7905   ""
7906   "")
7908 (define_insn "*testqi_ext_0"
7909   [(set (reg 17)
7910         (compare
7911           (and:SI
7912             (zero_extract:SI
7913               (match_operand 0 "ext_register_operand" "Q")
7914               (const_int 8)
7915               (const_int 8))
7916             (match_operand 1 "const_int_operand" "n"))
7917           (const_int 0)))]
7918   "ix86_match_ccmode (insn, CCNOmode)"
7919   "test{b}\t{%1, %h0|%h0, %1}"
7920   [(set_attr "type" "test")
7921    (set_attr "mode" "QI")
7922    (set_attr "length_immediate" "1")
7923    (set_attr "pent_pair" "np")])
7925 (define_insn "*testqi_ext_1"
7926   [(set (reg 17)
7927         (compare
7928           (and:SI
7929             (zero_extract:SI
7930               (match_operand 0 "ext_register_operand" "Q")
7931               (const_int 8)
7932               (const_int 8))
7933             (zero_extend:SI
7934               (match_operand:QI 1 "general_operand" "Qm")))
7935           (const_int 0)))]
7936   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7938   "test{b}\t{%1, %h0|%h0, %1}"
7939   [(set_attr "type" "test")
7940    (set_attr "mode" "QI")])
7942 (define_insn "*testqi_ext_1_rex64"
7943   [(set (reg 17)
7944         (compare
7945           (and:SI
7946             (zero_extract:SI
7947               (match_operand 0 "ext_register_operand" "Q")
7948               (const_int 8)
7949               (const_int 8))
7950             (zero_extend:SI
7951               (match_operand:QI 1 "register_operand" "Q")))
7952           (const_int 0)))]
7953   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7954   "test{b}\t{%1, %h0|%h0, %1}"
7955   [(set_attr "type" "test")
7956    (set_attr "mode" "QI")])
7958 (define_insn "*testqi_ext_2"
7959   [(set (reg 17)
7960         (compare
7961           (and:SI
7962             (zero_extract:SI
7963               (match_operand 0 "ext_register_operand" "Q")
7964               (const_int 8)
7965               (const_int 8))
7966             (zero_extract:SI
7967               (match_operand 1 "ext_register_operand" "Q")
7968               (const_int 8)
7969               (const_int 8)))
7970           (const_int 0)))]
7971   "ix86_match_ccmode (insn, CCNOmode)"
7972   "test{b}\t{%h1, %h0|%h0, %h1}"
7973   [(set_attr "type" "test")
7974    (set_attr "mode" "QI")])
7976 ;; Combine likes to form bit extractions for some tests.  Humor it.
7977 (define_insn "*testqi_ext_3"
7978   [(set (reg 17)
7979         (compare (zero_extract:SI
7980                    (match_operand 0 "nonimmediate_operand" "rm")
7981                    (match_operand:SI 1 "const_int_operand" "")
7982                    (match_operand:SI 2 "const_int_operand" ""))
7983                  (const_int 0)))]
7984   "ix86_match_ccmode (insn, CCNOmode)
7985    && (GET_MODE (operands[0]) == SImode
7986        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7987        || GET_MODE (operands[0]) == HImode
7988        || GET_MODE (operands[0]) == QImode)"
7989   "#")
7991 (define_insn "*testqi_ext_3_rex64"
7992   [(set (reg 17)
7993         (compare (zero_extract:DI
7994                    (match_operand 0 "nonimmediate_operand" "rm")
7995                    (match_operand:DI 1 "const_int_operand" "")
7996                    (match_operand:DI 2 "const_int_operand" ""))
7997                  (const_int 0)))]
7998   "TARGET_64BIT
7999    && ix86_match_ccmode (insn, CCNOmode)
8000    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8001    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8002    /* Ensure that resulting mask is zero or sign extended operand.  */
8003    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8004        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8005            && INTVAL (operands[1]) > 32))
8006    && (GET_MODE (operands[0]) == SImode
8007        || GET_MODE (operands[0]) == DImode
8008        || GET_MODE (operands[0]) == HImode
8009        || GET_MODE (operands[0]) == QImode)"
8010   "#")
8012 (define_split
8013   [(set (reg 17)
8014         (compare (zero_extract
8015                    (match_operand 0 "nonimmediate_operand" "")
8016                    (match_operand 1 "const_int_operand" "")
8017                    (match_operand 2 "const_int_operand" ""))
8018                  (const_int 0)))]
8019   "ix86_match_ccmode (insn, CCNOmode)"
8020   [(set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
8022   HOST_WIDE_INT len = INTVAL (operands[1]);
8023   HOST_WIDE_INT pos = INTVAL (operands[2]);
8024   HOST_WIDE_INT mask;
8025   enum machine_mode mode, submode;
8027   mode = GET_MODE (operands[0]);
8028   if (GET_CODE (operands[0]) == MEM)
8029     {
8030       /* ??? Combine likes to put non-volatile mem extractions in QImode
8031          no matter the size of the test.  So find a mode that works.  */
8032       if (! MEM_VOLATILE_P (operands[0]))
8033         {
8034           mode = smallest_mode_for_size (pos + len, MODE_INT);
8035           operands[0] = adjust_address (operands[0], mode, 0);
8036         }
8037     }
8038   else if (GET_CODE (operands[0]) == SUBREG
8039            && (submode = GET_MODE (SUBREG_REG (operands[0])),
8040                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8041            && pos + len <= GET_MODE_BITSIZE (submode))
8042     {
8043       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8044       mode = submode;
8045       operands[0] = SUBREG_REG (operands[0]);
8046     }
8047   else if (mode == HImode && pos + len <= 8)
8048     {
8049       /* Small HImode tests can be converted to QImode.  */
8050       mode = QImode;
8051       operands[0] = gen_lowpart (QImode, operands[0]);
8052     }
8054   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8055   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8057   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8060 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8061 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8062 ;; this is relatively important trick.
8063 ;; Do the conversion only post-reload to avoid limiting of the register class
8064 ;; to QI regs.
8065 (define_split
8066   [(set (reg 17)
8067         (compare
8068           (and (match_operand 0 "register_operand" "")
8069                (match_operand 1 "const_int_operand" ""))
8070           (const_int 0)))]
8071    "reload_completed
8072     && QI_REG_P (operands[0])
8073     && ((ix86_match_ccmode (insn, CCZmode)
8074          && !(INTVAL (operands[1]) & ~(255 << 8)))
8075         || (ix86_match_ccmode (insn, CCNOmode)
8076             && !(INTVAL (operands[1]) & ~(127 << 8))))
8077     && GET_MODE (operands[0]) != QImode"
8078   [(set (reg:CCNO FLAGS_REG)
8079         (compare:CCNO
8080           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8081                   (match_dup 1))
8082           (const_int 0)))]
8083   "operands[0] = gen_lowpart (SImode, operands[0]);
8084    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8086 (define_split
8087   [(set (reg 17)
8088         (compare
8089           (and (match_operand 0 "nonimmediate_operand" "")
8090                (match_operand 1 "const_int_operand" ""))
8091           (const_int 0)))]
8092    "reload_completed
8093     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8094     && ((ix86_match_ccmode (insn, CCZmode)
8095          && !(INTVAL (operands[1]) & ~255))
8096         || (ix86_match_ccmode (insn, CCNOmode)
8097             && !(INTVAL (operands[1]) & ~127)))
8098     && GET_MODE (operands[0]) != QImode"
8099   [(set (reg:CCNO FLAGS_REG)
8100         (compare:CCNO
8101           (and:QI (match_dup 0)
8102                   (match_dup 1))
8103           (const_int 0)))]
8104   "operands[0] = gen_lowpart (QImode, operands[0]);
8105    operands[1] = gen_lowpart (QImode, operands[1]);")
8108 ;; %%% This used to optimize known byte-wide and operations to memory,
8109 ;; and sometimes to QImode registers.  If this is considered useful,
8110 ;; it should be done with splitters.
8112 (define_expand "anddi3"
8113   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8114         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8115                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8116    (clobber (reg:CC FLAGS_REG))]
8117   "TARGET_64BIT"
8118   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8120 (define_insn "*anddi_1_rex64"
8121   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8122         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8123                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8124    (clobber (reg:CC FLAGS_REG))]
8125   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8127   switch (get_attr_type (insn))
8128     {
8129     case TYPE_IMOVX:
8130       {
8131         enum machine_mode mode;
8133         if (GET_CODE (operands[2]) != CONST_INT)
8134           abort ();
8135         if (INTVAL (operands[2]) == 0xff)
8136           mode = QImode;
8137         else if (INTVAL (operands[2]) == 0xffff)
8138           mode = HImode;
8139         else
8140           abort ();
8141         
8142         operands[1] = gen_lowpart (mode, operands[1]);
8143         if (mode == QImode)
8144           return "movz{bq|x}\t{%1,%0|%0, %1}";
8145         else
8146           return "movz{wq|x}\t{%1,%0|%0, %1}";
8147       }
8149     default:
8150       if (! rtx_equal_p (operands[0], operands[1]))
8151         abort ();
8152       if (get_attr_mode (insn) == MODE_SI)
8153         return "and{l}\t{%k2, %k0|%k0, %k2}";
8154       else
8155         return "and{q}\t{%2, %0|%0, %2}";
8156     }
8158   [(set_attr "type" "alu,alu,alu,imovx")
8159    (set_attr "length_immediate" "*,*,*,0")
8160    (set_attr "mode" "SI,DI,DI,DI")])
8162 (define_insn "*anddi_2"
8163   [(set (reg 17)
8164         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8165                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8166                  (const_int 0)))
8167    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8168         (and:DI (match_dup 1) (match_dup 2)))]
8169   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8170    && ix86_binary_operator_ok (AND, DImode, operands)"
8171   "@
8172    and{l}\t{%k2, %k0|%k0, %k2}
8173    and{q}\t{%2, %0|%0, %2}
8174    and{q}\t{%2, %0|%0, %2}"
8175   [(set_attr "type" "alu")
8176    (set_attr "mode" "SI,DI,DI")])
8178 (define_expand "andsi3"
8179   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8180         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8181                 (match_operand:SI 2 "general_operand" "")))
8182    (clobber (reg:CC FLAGS_REG))]
8183   ""
8184   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8186 (define_insn "*andsi_1"
8187   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8188         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8189                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8190    (clobber (reg:CC FLAGS_REG))]
8191   "ix86_binary_operator_ok (AND, SImode, operands)"
8193   switch (get_attr_type (insn))
8194     {
8195     case TYPE_IMOVX:
8196       {
8197         enum machine_mode mode;
8199         if (GET_CODE (operands[2]) != CONST_INT)
8200           abort ();
8201         if (INTVAL (operands[2]) == 0xff)
8202           mode = QImode;
8203         else if (INTVAL (operands[2]) == 0xffff)
8204           mode = HImode;
8205         else
8206           abort ();
8207         
8208         operands[1] = gen_lowpart (mode, operands[1]);
8209         if (mode == QImode)
8210           return "movz{bl|x}\t{%1,%0|%0, %1}";
8211         else
8212           return "movz{wl|x}\t{%1,%0|%0, %1}";
8213       }
8215     default:
8216       if (! rtx_equal_p (operands[0], operands[1]))
8217         abort ();
8218       return "and{l}\t{%2, %0|%0, %2}";
8219     }
8221   [(set_attr "type" "alu,alu,imovx")
8222    (set_attr "length_immediate" "*,*,0")
8223    (set_attr "mode" "SI")])
8225 (define_split
8226   [(set (match_operand 0 "register_operand" "")
8227         (and (match_dup 0)
8228              (const_int -65536)))
8229    (clobber (reg:CC FLAGS_REG))]
8230   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8231   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8232   "operands[1] = gen_lowpart (HImode, operands[0]);")
8234 (define_split
8235   [(set (match_operand 0 "ext_register_operand" "")
8236         (and (match_dup 0)
8237              (const_int -256)))
8238    (clobber (reg:CC FLAGS_REG))]
8239   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8240   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8241   "operands[1] = gen_lowpart (QImode, operands[0]);")
8243 (define_split
8244   [(set (match_operand 0 "ext_register_operand" "")
8245         (and (match_dup 0)
8246              (const_int -65281)))
8247    (clobber (reg:CC FLAGS_REG))]
8248   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8249   [(parallel [(set (zero_extract:SI (match_dup 0)
8250                                     (const_int 8)
8251                                     (const_int 8))
8252                    (xor:SI 
8253                      (zero_extract:SI (match_dup 0)
8254                                       (const_int 8)
8255                                       (const_int 8))
8256                      (zero_extract:SI (match_dup 0)
8257                                       (const_int 8)
8258                                       (const_int 8))))
8259               (clobber (reg:CC FLAGS_REG))])]
8260   "operands[0] = gen_lowpart (SImode, operands[0]);")
8262 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8263 (define_insn "*andsi_1_zext"
8264   [(set (match_operand:DI 0 "register_operand" "=r")
8265         (zero_extend:DI
8266           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8267                   (match_operand:SI 2 "general_operand" "rim"))))
8268    (clobber (reg:CC FLAGS_REG))]
8269   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8270   "and{l}\t{%2, %k0|%k0, %2}"
8271   [(set_attr "type" "alu")
8272    (set_attr "mode" "SI")])
8274 (define_insn "*andsi_2"
8275   [(set (reg 17)
8276         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8277                          (match_operand:SI 2 "general_operand" "rim,ri"))
8278                  (const_int 0)))
8279    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8280         (and:SI (match_dup 1) (match_dup 2)))]
8281   "ix86_match_ccmode (insn, CCNOmode)
8282    && ix86_binary_operator_ok (AND, SImode, operands)"
8283   "and{l}\t{%2, %0|%0, %2}"
8284   [(set_attr "type" "alu")
8285    (set_attr "mode" "SI")])
8287 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8288 (define_insn "*andsi_2_zext"
8289   [(set (reg 17)
8290         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8291                          (match_operand:SI 2 "general_operand" "rim"))
8292                  (const_int 0)))
8293    (set (match_operand:DI 0 "register_operand" "=r")
8294         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8295   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8296    && ix86_binary_operator_ok (AND, SImode, operands)"
8297   "and{l}\t{%2, %k0|%k0, %2}"
8298   [(set_attr "type" "alu")
8299    (set_attr "mode" "SI")])
8301 (define_expand "andhi3"
8302   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8303         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8304                 (match_operand:HI 2 "general_operand" "")))
8305    (clobber (reg:CC FLAGS_REG))]
8306   "TARGET_HIMODE_MATH"
8307   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8309 (define_insn "*andhi_1"
8310   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8311         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8312                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "ix86_binary_operator_ok (AND, HImode, operands)"
8316   switch (get_attr_type (insn))
8317     {
8318     case TYPE_IMOVX:
8319       if (GET_CODE (operands[2]) != CONST_INT)
8320         abort ();
8321       if (INTVAL (operands[2]) == 0xff)
8322         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8323       abort ();
8325     default:
8326       if (! rtx_equal_p (operands[0], operands[1]))
8327         abort ();
8329       return "and{w}\t{%2, %0|%0, %2}";
8330     }
8332   [(set_attr "type" "alu,alu,imovx")
8333    (set_attr "length_immediate" "*,*,0")
8334    (set_attr "mode" "HI,HI,SI")])
8336 (define_insn "*andhi_2"
8337   [(set (reg 17)
8338         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8339                          (match_operand:HI 2 "general_operand" "rim,ri"))
8340                  (const_int 0)))
8341    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8342         (and:HI (match_dup 1) (match_dup 2)))]
8343   "ix86_match_ccmode (insn, CCNOmode)
8344    && ix86_binary_operator_ok (AND, HImode, operands)"
8345   "and{w}\t{%2, %0|%0, %2}"
8346   [(set_attr "type" "alu")
8347    (set_attr "mode" "HI")])
8349 (define_expand "andqi3"
8350   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8351         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8352                 (match_operand:QI 2 "general_operand" "")))
8353    (clobber (reg:CC FLAGS_REG))]
8354   "TARGET_QIMODE_MATH"
8355   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8357 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8358 (define_insn "*andqi_1"
8359   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8360         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8361                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8362    (clobber (reg:CC FLAGS_REG))]
8363   "ix86_binary_operator_ok (AND, QImode, operands)"
8364   "@
8365    and{b}\t{%2, %0|%0, %2}
8366    and{b}\t{%2, %0|%0, %2}
8367    and{l}\t{%k2, %k0|%k0, %k2}"
8368   [(set_attr "type" "alu")
8369    (set_attr "mode" "QI,QI,SI")])
8371 (define_insn "*andqi_1_slp"
8372   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8373         (and:QI (match_dup 0)
8374                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8375    (clobber (reg:CC FLAGS_REG))]
8376   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8377    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8378   "and{b}\t{%1, %0|%0, %1}"
8379   [(set_attr "type" "alu1")
8380    (set_attr "mode" "QI")])
8382 (define_insn "*andqi_2"
8383   [(set (reg 17)
8384         (compare (and:QI
8385                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8386                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8387                  (const_int 0)))
8388    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8389         (and:QI (match_dup 1) (match_dup 2)))]
8390   "ix86_match_ccmode (insn, CCNOmode)
8391    && ix86_binary_operator_ok (AND, QImode, operands)"
8393   if (which_alternative == 2)
8394     {
8395       if (GET_CODE (operands[2]) == CONST_INT
8396           && (INTVAL (operands[2]) & 0xffffff00))
8397         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8398       return "and{l}\t{%2, %k0|%k0, %2}";
8399     }
8400   return "and{b}\t{%2, %0|%0, %2}";
8402   [(set_attr "type" "alu")
8403    (set_attr "mode" "QI,QI,SI")])
8405 (define_insn "*andqi_2_slp"
8406   [(set (reg 17)
8407         (compare (and:QI
8408                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8409                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8410                  (const_int 0)))
8411    (set (strict_low_part (match_dup 0))
8412         (and:QI (match_dup 0) (match_dup 1)))]
8413   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8414    && ix86_match_ccmode (insn, CCNOmode)
8415    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8416   "and{b}\t{%1, %0|%0, %1}"
8417   [(set_attr "type" "alu1")
8418    (set_attr "mode" "QI")])
8420 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8421 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8422 ;; for a QImode operand, which of course failed.
8424 (define_insn "andqi_ext_0"
8425   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8426                          (const_int 8)
8427                          (const_int 8))
8428         (and:SI 
8429           (zero_extract:SI
8430             (match_operand 1 "ext_register_operand" "0")
8431             (const_int 8)
8432             (const_int 8))
8433           (match_operand 2 "const_int_operand" "n")))
8434    (clobber (reg:CC FLAGS_REG))]
8435   ""
8436   "and{b}\t{%2, %h0|%h0, %2}"
8437   [(set_attr "type" "alu")
8438    (set_attr "length_immediate" "1")
8439    (set_attr "mode" "QI")])
8441 ;; Generated by peephole translating test to and.  This shows up
8442 ;; often in fp comparisons.
8444 (define_insn "*andqi_ext_0_cc"
8445   [(set (reg 17)
8446         (compare
8447           (and:SI
8448             (zero_extract:SI
8449               (match_operand 1 "ext_register_operand" "0")
8450               (const_int 8)
8451               (const_int 8))
8452             (match_operand 2 "const_int_operand" "n"))
8453           (const_int 0)))
8454    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8455                          (const_int 8)
8456                          (const_int 8))
8457         (and:SI 
8458           (zero_extract:SI
8459             (match_dup 1)
8460             (const_int 8)
8461             (const_int 8))
8462           (match_dup 2)))]
8463   "ix86_match_ccmode (insn, CCNOmode)"
8464   "and{b}\t{%2, %h0|%h0, %2}"
8465   [(set_attr "type" "alu")
8466    (set_attr "length_immediate" "1")
8467    (set_attr "mode" "QI")])
8469 (define_insn "*andqi_ext_1"
8470   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8471                          (const_int 8)
8472                          (const_int 8))
8473         (and:SI 
8474           (zero_extract:SI
8475             (match_operand 1 "ext_register_operand" "0")
8476             (const_int 8)
8477             (const_int 8))
8478           (zero_extend:SI
8479             (match_operand:QI 2 "general_operand" "Qm"))))
8480    (clobber (reg:CC FLAGS_REG))]
8481   "!TARGET_64BIT"
8482   "and{b}\t{%2, %h0|%h0, %2}"
8483   [(set_attr "type" "alu")
8484    (set_attr "length_immediate" "0")
8485    (set_attr "mode" "QI")])
8487 (define_insn "*andqi_ext_1_rex64"
8488   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8489                          (const_int 8)
8490                          (const_int 8))
8491         (and:SI 
8492           (zero_extract:SI
8493             (match_operand 1 "ext_register_operand" "0")
8494             (const_int 8)
8495             (const_int 8))
8496           (zero_extend:SI
8497             (match_operand 2 "ext_register_operand" "Q"))))
8498    (clobber (reg:CC FLAGS_REG))]
8499   "TARGET_64BIT"
8500   "and{b}\t{%2, %h0|%h0, %2}"
8501   [(set_attr "type" "alu")
8502    (set_attr "length_immediate" "0")
8503    (set_attr "mode" "QI")])
8505 (define_insn "*andqi_ext_2"
8506   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8507                          (const_int 8)
8508                          (const_int 8))
8509         (and:SI
8510           (zero_extract:SI
8511             (match_operand 1 "ext_register_operand" "%0")
8512             (const_int 8)
8513             (const_int 8))
8514           (zero_extract:SI
8515             (match_operand 2 "ext_register_operand" "Q")
8516             (const_int 8)
8517             (const_int 8))))
8518    (clobber (reg:CC FLAGS_REG))]
8519   ""
8520   "and{b}\t{%h2, %h0|%h0, %h2}"
8521   [(set_attr "type" "alu")
8522    (set_attr "length_immediate" "0")
8523    (set_attr "mode" "QI")])
8525 ;; Convert wide AND instructions with immediate operand to shorter QImode
8526 ;; equivalents when possible.
8527 ;; Don't do the splitting with memory operands, since it introduces risk
8528 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8529 ;; for size, but that can (should?) be handled by generic code instead.
8530 (define_split
8531   [(set (match_operand 0 "register_operand" "")
8532         (and (match_operand 1 "register_operand" "")
8533              (match_operand 2 "const_int_operand" "")))
8534    (clobber (reg:CC FLAGS_REG))]
8535    "reload_completed
8536     && QI_REG_P (operands[0])
8537     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8538     && !(~INTVAL (operands[2]) & ~(255 << 8))
8539     && GET_MODE (operands[0]) != QImode"
8540   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8541                    (and:SI (zero_extract:SI (match_dup 1)
8542                                             (const_int 8) (const_int 8))
8543                            (match_dup 2)))
8544               (clobber (reg:CC FLAGS_REG))])]
8545   "operands[0] = gen_lowpart (SImode, operands[0]);
8546    operands[1] = gen_lowpart (SImode, operands[1]);
8547    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8549 ;; Since AND can be encoded with sign extended immediate, this is only
8550 ;; profitable when 7th bit is not set.
8551 (define_split
8552   [(set (match_operand 0 "register_operand" "")
8553         (and (match_operand 1 "general_operand" "")
8554              (match_operand 2 "const_int_operand" "")))
8555    (clobber (reg:CC FLAGS_REG))]
8556    "reload_completed
8557     && ANY_QI_REG_P (operands[0])
8558     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8559     && !(~INTVAL (operands[2]) & ~255)
8560     && !(INTVAL (operands[2]) & 128)
8561     && GET_MODE (operands[0]) != QImode"
8562   [(parallel [(set (strict_low_part (match_dup 0))
8563                    (and:QI (match_dup 1)
8564                            (match_dup 2)))
8565               (clobber (reg:CC FLAGS_REG))])]
8566   "operands[0] = gen_lowpart (QImode, operands[0]);
8567    operands[1] = gen_lowpart (QImode, operands[1]);
8568    operands[2] = gen_lowpart (QImode, operands[2]);")
8570 ;; Logical inclusive OR instructions
8572 ;; %%% This used to optimize known byte-wide and operations to memory.
8573 ;; If this is considered useful, it should be done with splitters.
8575 (define_expand "iordi3"
8576   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8577         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8578                 (match_operand:DI 2 "x86_64_general_operand" "")))
8579    (clobber (reg:CC FLAGS_REG))]
8580   "TARGET_64BIT"
8581   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8583 (define_insn "*iordi_1_rex64"
8584   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8585         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8586                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8587    (clobber (reg:CC FLAGS_REG))]
8588   "TARGET_64BIT
8589    && ix86_binary_operator_ok (IOR, DImode, operands)"
8590   "or{q}\t{%2, %0|%0, %2}"
8591   [(set_attr "type" "alu")
8592    (set_attr "mode" "DI")])
8594 (define_insn "*iordi_2_rex64"
8595   [(set (reg 17)
8596         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8597                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8598                  (const_int 0)))
8599    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8600         (ior:DI (match_dup 1) (match_dup 2)))]
8601   "TARGET_64BIT
8602    && ix86_match_ccmode (insn, CCNOmode)
8603    && ix86_binary_operator_ok (IOR, DImode, operands)"
8604   "or{q}\t{%2, %0|%0, %2}"
8605   [(set_attr "type" "alu")
8606    (set_attr "mode" "DI")])
8608 (define_insn "*iordi_3_rex64"
8609   [(set (reg 17)
8610         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8611                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8612                  (const_int 0)))
8613    (clobber (match_scratch:DI 0 "=r"))]
8614   "TARGET_64BIT
8615    && ix86_match_ccmode (insn, CCNOmode)
8616    && ix86_binary_operator_ok (IOR, DImode, operands)"
8617   "or{q}\t{%2, %0|%0, %2}"
8618   [(set_attr "type" "alu")
8619    (set_attr "mode" "DI")])
8622 (define_expand "iorsi3"
8623   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8624         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8625                 (match_operand:SI 2 "general_operand" "")))
8626    (clobber (reg:CC FLAGS_REG))]
8627   ""
8628   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8630 (define_insn "*iorsi_1"
8631   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8632         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8633                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8634    (clobber (reg:CC FLAGS_REG))]
8635   "ix86_binary_operator_ok (IOR, SImode, operands)"
8636   "or{l}\t{%2, %0|%0, %2}"
8637   [(set_attr "type" "alu")
8638    (set_attr "mode" "SI")])
8640 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8641 (define_insn "*iorsi_1_zext"
8642   [(set (match_operand:DI 0 "register_operand" "=rm")
8643         (zero_extend:DI
8644           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8645                   (match_operand:SI 2 "general_operand" "rim"))))
8646    (clobber (reg:CC FLAGS_REG))]
8647   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8648   "or{l}\t{%2, %k0|%k0, %2}"
8649   [(set_attr "type" "alu")
8650    (set_attr "mode" "SI")])
8652 (define_insn "*iorsi_1_zext_imm"
8653   [(set (match_operand:DI 0 "register_operand" "=rm")
8654         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8655                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8656    (clobber (reg:CC FLAGS_REG))]
8657   "TARGET_64BIT"
8658   "or{l}\t{%2, %k0|%k0, %2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "mode" "SI")])
8662 (define_insn "*iorsi_2"
8663   [(set (reg 17)
8664         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8665                          (match_operand:SI 2 "general_operand" "rim,ri"))
8666                  (const_int 0)))
8667    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8668         (ior:SI (match_dup 1) (match_dup 2)))]
8669   "ix86_match_ccmode (insn, CCNOmode)
8670    && ix86_binary_operator_ok (IOR, SImode, operands)"
8671   "or{l}\t{%2, %0|%0, %2}"
8672   [(set_attr "type" "alu")
8673    (set_attr "mode" "SI")])
8675 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8676 ;; ??? Special case for immediate operand is missing - it is tricky.
8677 (define_insn "*iorsi_2_zext"
8678   [(set (reg 17)
8679         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8680                          (match_operand:SI 2 "general_operand" "rim"))
8681                  (const_int 0)))
8682    (set (match_operand:DI 0 "register_operand" "=r")
8683         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8684   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8685    && ix86_binary_operator_ok (IOR, SImode, operands)"
8686   "or{l}\t{%2, %k0|%k0, %2}"
8687   [(set_attr "type" "alu")
8688    (set_attr "mode" "SI")])
8690 (define_insn "*iorsi_2_zext_imm"
8691   [(set (reg 17)
8692         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8693                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8694                  (const_int 0)))
8695    (set (match_operand:DI 0 "register_operand" "=r")
8696         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8697   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8698    && ix86_binary_operator_ok (IOR, SImode, operands)"
8699   "or{l}\t{%2, %k0|%k0, %2}"
8700   [(set_attr "type" "alu")
8701    (set_attr "mode" "SI")])
8703 (define_insn "*iorsi_3"
8704   [(set (reg 17)
8705         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8706                          (match_operand:SI 2 "general_operand" "rim"))
8707                  (const_int 0)))
8708    (clobber (match_scratch:SI 0 "=r"))]
8709   "ix86_match_ccmode (insn, CCNOmode)
8710    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8711   "or{l}\t{%2, %0|%0, %2}"
8712   [(set_attr "type" "alu")
8713    (set_attr "mode" "SI")])
8715 (define_expand "iorhi3"
8716   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8717         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8718                 (match_operand:HI 2 "general_operand" "")))
8719    (clobber (reg:CC FLAGS_REG))]
8720   "TARGET_HIMODE_MATH"
8721   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8723 (define_insn "*iorhi_1"
8724   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8725         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8726                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8727    (clobber (reg:CC FLAGS_REG))]
8728   "ix86_binary_operator_ok (IOR, HImode, operands)"
8729   "or{w}\t{%2, %0|%0, %2}"
8730   [(set_attr "type" "alu")
8731    (set_attr "mode" "HI")])
8733 (define_insn "*iorhi_2"
8734   [(set (reg 17)
8735         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8736                          (match_operand:HI 2 "general_operand" "rim,ri"))
8737                  (const_int 0)))
8738    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8739         (ior:HI (match_dup 1) (match_dup 2)))]
8740   "ix86_match_ccmode (insn, CCNOmode)
8741    && ix86_binary_operator_ok (IOR, HImode, operands)"
8742   "or{w}\t{%2, %0|%0, %2}"
8743   [(set_attr "type" "alu")
8744    (set_attr "mode" "HI")])
8746 (define_insn "*iorhi_3"
8747   [(set (reg 17)
8748         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8749                          (match_operand:HI 2 "general_operand" "rim"))
8750                  (const_int 0)))
8751    (clobber (match_scratch:HI 0 "=r"))]
8752   "ix86_match_ccmode (insn, CCNOmode)
8753    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8754   "or{w}\t{%2, %0|%0, %2}"
8755   [(set_attr "type" "alu")
8756    (set_attr "mode" "HI")])
8758 (define_expand "iorqi3"
8759   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8760         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8761                 (match_operand:QI 2 "general_operand" "")))
8762    (clobber (reg:CC FLAGS_REG))]
8763   "TARGET_QIMODE_MATH"
8764   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8766 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8767 (define_insn "*iorqi_1"
8768   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8769         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8770                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8771    (clobber (reg:CC FLAGS_REG))]
8772   "ix86_binary_operator_ok (IOR, QImode, operands)"
8773   "@
8774    or{b}\t{%2, %0|%0, %2}
8775    or{b}\t{%2, %0|%0, %2}
8776    or{l}\t{%k2, %k0|%k0, %k2}"
8777   [(set_attr "type" "alu")
8778    (set_attr "mode" "QI,QI,SI")])
8780 (define_insn "*iorqi_1_slp"
8781   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8782         (ior:QI (match_dup 0)
8783                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8784    (clobber (reg:CC FLAGS_REG))]
8785   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8786    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8787   "or{b}\t{%1, %0|%0, %1}"
8788   [(set_attr "type" "alu1")
8789    (set_attr "mode" "QI")])
8791 (define_insn "*iorqi_2"
8792   [(set (reg 17)
8793         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8794                          (match_operand:QI 2 "general_operand" "qim,qi"))
8795                  (const_int 0)))
8796    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8797         (ior:QI (match_dup 1) (match_dup 2)))]
8798   "ix86_match_ccmode (insn, CCNOmode)
8799    && ix86_binary_operator_ok (IOR, QImode, operands)"
8800   "or{b}\t{%2, %0|%0, %2}"
8801   [(set_attr "type" "alu")
8802    (set_attr "mode" "QI")])
8804 (define_insn "*iorqi_2_slp"
8805   [(set (reg 17)
8806         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8807                          (match_operand:QI 1 "general_operand" "qim,qi"))
8808                  (const_int 0)))
8809    (set (strict_low_part (match_dup 0))
8810         (ior:QI (match_dup 0) (match_dup 1)))]
8811   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8812    && ix86_match_ccmode (insn, CCNOmode)
8813    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8814   "or{b}\t{%1, %0|%0, %1}"
8815   [(set_attr "type" "alu1")
8816    (set_attr "mode" "QI")])
8818 (define_insn "*iorqi_3"
8819   [(set (reg 17)
8820         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8821                          (match_operand:QI 2 "general_operand" "qim"))
8822                  (const_int 0)))
8823    (clobber (match_scratch:QI 0 "=q"))]
8824   "ix86_match_ccmode (insn, CCNOmode)
8825    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8826   "or{b}\t{%2, %0|%0, %2}"
8827   [(set_attr "type" "alu")
8828    (set_attr "mode" "QI")])
8830 (define_insn "iorqi_ext_0"
8831   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8832                          (const_int 8)
8833                          (const_int 8))
8834         (ior:SI 
8835           (zero_extract:SI
8836             (match_operand 1 "ext_register_operand" "0")
8837             (const_int 8)
8838             (const_int 8))
8839           (match_operand 2 "const_int_operand" "n")))
8840    (clobber (reg:CC FLAGS_REG))]
8841   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8842   "or{b}\t{%2, %h0|%h0, %2}"
8843   [(set_attr "type" "alu")
8844    (set_attr "length_immediate" "1")
8845    (set_attr "mode" "QI")])
8847 (define_insn "*iorqi_ext_1"
8848   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8849                          (const_int 8)
8850                          (const_int 8))
8851         (ior:SI 
8852           (zero_extract:SI
8853             (match_operand 1 "ext_register_operand" "0")
8854             (const_int 8)
8855             (const_int 8))
8856           (zero_extend:SI
8857             (match_operand:QI 2 "general_operand" "Qm"))))
8858    (clobber (reg:CC FLAGS_REG))]
8859   "!TARGET_64BIT
8860    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8861   "or{b}\t{%2, %h0|%h0, %2}"
8862   [(set_attr "type" "alu")
8863    (set_attr "length_immediate" "0")
8864    (set_attr "mode" "QI")])
8866 (define_insn "*iorqi_ext_1_rex64"
8867   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8868                          (const_int 8)
8869                          (const_int 8))
8870         (ior:SI 
8871           (zero_extract:SI
8872             (match_operand 1 "ext_register_operand" "0")
8873             (const_int 8)
8874             (const_int 8))
8875           (zero_extend:SI
8876             (match_operand 2 "ext_register_operand" "Q"))))
8877    (clobber (reg:CC FLAGS_REG))]
8878   "TARGET_64BIT
8879    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8880   "or{b}\t{%2, %h0|%h0, %2}"
8881   [(set_attr "type" "alu")
8882    (set_attr "length_immediate" "0")
8883    (set_attr "mode" "QI")])
8885 (define_insn "*iorqi_ext_2"
8886   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8887                          (const_int 8)
8888                          (const_int 8))
8889         (ior:SI 
8890           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8891                            (const_int 8)
8892                            (const_int 8))
8893           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8894                            (const_int 8)
8895                            (const_int 8))))
8896    (clobber (reg:CC FLAGS_REG))]
8897   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8898   "ior{b}\t{%h2, %h0|%h0, %h2}"
8899   [(set_attr "type" "alu")
8900    (set_attr "length_immediate" "0")
8901    (set_attr "mode" "QI")])
8903 (define_split
8904   [(set (match_operand 0 "register_operand" "")
8905         (ior (match_operand 1 "register_operand" "")
8906              (match_operand 2 "const_int_operand" "")))
8907    (clobber (reg:CC FLAGS_REG))]
8908    "reload_completed
8909     && QI_REG_P (operands[0])
8910     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8911     && !(INTVAL (operands[2]) & ~(255 << 8))
8912     && GET_MODE (operands[0]) != QImode"
8913   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8914                    (ior:SI (zero_extract:SI (match_dup 1)
8915                                             (const_int 8) (const_int 8))
8916                            (match_dup 2)))
8917               (clobber (reg:CC FLAGS_REG))])]
8918   "operands[0] = gen_lowpart (SImode, operands[0]);
8919    operands[1] = gen_lowpart (SImode, operands[1]);
8920    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8922 ;; Since OR can be encoded with sign extended immediate, this is only
8923 ;; profitable when 7th bit is set.
8924 (define_split
8925   [(set (match_operand 0 "register_operand" "")
8926         (ior (match_operand 1 "general_operand" "")
8927              (match_operand 2 "const_int_operand" "")))
8928    (clobber (reg:CC FLAGS_REG))]
8929    "reload_completed
8930     && ANY_QI_REG_P (operands[0])
8931     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8932     && !(INTVAL (operands[2]) & ~255)
8933     && (INTVAL (operands[2]) & 128)
8934     && GET_MODE (operands[0]) != QImode"
8935   [(parallel [(set (strict_low_part (match_dup 0))
8936                    (ior:QI (match_dup 1)
8937                            (match_dup 2)))
8938               (clobber (reg:CC FLAGS_REG))])]
8939   "operands[0] = gen_lowpart (QImode, operands[0]);
8940    operands[1] = gen_lowpart (QImode, operands[1]);
8941    operands[2] = gen_lowpart (QImode, operands[2]);")
8943 ;; Logical XOR instructions
8945 ;; %%% This used to optimize known byte-wide and operations to memory.
8946 ;; If this is considered useful, it should be done with splitters.
8948 (define_expand "xordi3"
8949   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8950         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8951                 (match_operand:DI 2 "x86_64_general_operand" "")))
8952    (clobber (reg:CC FLAGS_REG))]
8953   "TARGET_64BIT"
8954   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8956 (define_insn "*xordi_1_rex64"
8957   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8958         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8959                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8960    (clobber (reg:CC FLAGS_REG))]
8961   "TARGET_64BIT
8962    && ix86_binary_operator_ok (XOR, DImode, operands)"
8963   "@
8964    xor{q}\t{%2, %0|%0, %2}
8965    xor{q}\t{%2, %0|%0, %2}"
8966   [(set_attr "type" "alu")
8967    (set_attr "mode" "DI,DI")])
8969 (define_insn "*xordi_2_rex64"
8970   [(set (reg 17)
8971         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8972                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8973                  (const_int 0)))
8974    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8975         (xor:DI (match_dup 1) (match_dup 2)))]
8976   "TARGET_64BIT
8977    && ix86_match_ccmode (insn, CCNOmode)
8978    && ix86_binary_operator_ok (XOR, DImode, operands)"
8979   "@
8980    xor{q}\t{%2, %0|%0, %2}
8981    xor{q}\t{%2, %0|%0, %2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "mode" "DI,DI")])
8985 (define_insn "*xordi_3_rex64"
8986   [(set (reg 17)
8987         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8988                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8989                  (const_int 0)))
8990    (clobber (match_scratch:DI 0 "=r"))]
8991   "TARGET_64BIT
8992    && ix86_match_ccmode (insn, CCNOmode)
8993    && ix86_binary_operator_ok (XOR, DImode, operands)"
8994   "xor{q}\t{%2, %0|%0, %2}"
8995   [(set_attr "type" "alu")
8996    (set_attr "mode" "DI")])
8998 (define_expand "xorsi3"
8999   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9000         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9001                 (match_operand:SI 2 "general_operand" "")))
9002    (clobber (reg:CC FLAGS_REG))]
9003   ""
9004   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9006 (define_insn "*xorsi_1"
9007   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9008         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9009                 (match_operand:SI 2 "general_operand" "ri,rm")))
9010    (clobber (reg:CC FLAGS_REG))]
9011   "ix86_binary_operator_ok (XOR, SImode, operands)"
9012   "xor{l}\t{%2, %0|%0, %2}"
9013   [(set_attr "type" "alu")
9014    (set_attr "mode" "SI")])
9016 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9017 ;; Add speccase for immediates
9018 (define_insn "*xorsi_1_zext"
9019   [(set (match_operand:DI 0 "register_operand" "=r")
9020         (zero_extend:DI
9021           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9022                   (match_operand:SI 2 "general_operand" "rim"))))
9023    (clobber (reg:CC FLAGS_REG))]
9024   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9025   "xor{l}\t{%2, %k0|%k0, %2}"
9026   [(set_attr "type" "alu")
9027    (set_attr "mode" "SI")])
9029 (define_insn "*xorsi_1_zext_imm"
9030   [(set (match_operand:DI 0 "register_operand" "=r")
9031         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9032                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9033    (clobber (reg:CC FLAGS_REG))]
9034   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9035   "xor{l}\t{%2, %k0|%k0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "SI")])
9039 (define_insn "*xorsi_2"
9040   [(set (reg 17)
9041         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9042                          (match_operand:SI 2 "general_operand" "rim,ri"))
9043                  (const_int 0)))
9044    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9045         (xor:SI (match_dup 1) (match_dup 2)))]
9046   "ix86_match_ccmode (insn, CCNOmode)
9047    && ix86_binary_operator_ok (XOR, SImode, operands)"
9048   "xor{l}\t{%2, %0|%0, %2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "SI")])
9052 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9053 ;; ??? Special case for immediate operand is missing - it is tricky.
9054 (define_insn "*xorsi_2_zext"
9055   [(set (reg 17)
9056         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9057                          (match_operand:SI 2 "general_operand" "rim"))
9058                  (const_int 0)))
9059    (set (match_operand:DI 0 "register_operand" "=r")
9060         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9061   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9062    && ix86_binary_operator_ok (XOR, SImode, operands)"
9063   "xor{l}\t{%2, %k0|%k0, %2}"
9064   [(set_attr "type" "alu")
9065    (set_attr "mode" "SI")])
9067 (define_insn "*xorsi_2_zext_imm"
9068   [(set (reg 17)
9069         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9070                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9071                  (const_int 0)))
9072    (set (match_operand:DI 0 "register_operand" "=r")
9073         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9074   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9075    && ix86_binary_operator_ok (XOR, SImode, operands)"
9076   "xor{l}\t{%2, %k0|%k0, %2}"
9077   [(set_attr "type" "alu")
9078    (set_attr "mode" "SI")])
9080 (define_insn "*xorsi_3"
9081   [(set (reg 17)
9082         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9083                          (match_operand:SI 2 "general_operand" "rim"))
9084                  (const_int 0)))
9085    (clobber (match_scratch:SI 0 "=r"))]
9086   "ix86_match_ccmode (insn, CCNOmode)
9087    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9088   "xor{l}\t{%2, %0|%0, %2}"
9089   [(set_attr "type" "alu")
9090    (set_attr "mode" "SI")])
9092 (define_expand "xorhi3"
9093   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9094         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9095                 (match_operand:HI 2 "general_operand" "")))
9096    (clobber (reg:CC FLAGS_REG))]
9097   "TARGET_HIMODE_MATH"
9098   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9100 (define_insn "*xorhi_1"
9101   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9102         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9103                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9104    (clobber (reg:CC FLAGS_REG))]
9105   "ix86_binary_operator_ok (XOR, HImode, operands)"
9106   "xor{w}\t{%2, %0|%0, %2}"
9107   [(set_attr "type" "alu")
9108    (set_attr "mode" "HI")])
9110 (define_insn "*xorhi_2"
9111   [(set (reg 17)
9112         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9113                          (match_operand:HI 2 "general_operand" "rim,ri"))
9114                  (const_int 0)))
9115    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9116         (xor:HI (match_dup 1) (match_dup 2)))]
9117   "ix86_match_ccmode (insn, CCNOmode)
9118    && ix86_binary_operator_ok (XOR, HImode, operands)"
9119   "xor{w}\t{%2, %0|%0, %2}"
9120   [(set_attr "type" "alu")
9121    (set_attr "mode" "HI")])
9123 (define_insn "*xorhi_3"
9124   [(set (reg 17)
9125         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9126                          (match_operand:HI 2 "general_operand" "rim"))
9127                  (const_int 0)))
9128    (clobber (match_scratch:HI 0 "=r"))]
9129   "ix86_match_ccmode (insn, CCNOmode)
9130    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9131   "xor{w}\t{%2, %0|%0, %2}"
9132   [(set_attr "type" "alu")
9133    (set_attr "mode" "HI")])
9135 (define_expand "xorqi3"
9136   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9137         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9138                 (match_operand:QI 2 "general_operand" "")))
9139    (clobber (reg:CC FLAGS_REG))]
9140   "TARGET_QIMODE_MATH"
9141   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9143 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9144 (define_insn "*xorqi_1"
9145   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9146         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9147                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9148    (clobber (reg:CC FLAGS_REG))]
9149   "ix86_binary_operator_ok (XOR, QImode, operands)"
9150   "@
9151    xor{b}\t{%2, %0|%0, %2}
9152    xor{b}\t{%2, %0|%0, %2}
9153    xor{l}\t{%k2, %k0|%k0, %k2}"
9154   [(set_attr "type" "alu")
9155    (set_attr "mode" "QI,QI,SI")])
9157 (define_insn "*xorqi_1_slp"
9158   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9159         (xor:QI (match_dup 0)
9160                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9161    (clobber (reg:CC FLAGS_REG))]
9162   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9164   "xor{b}\t{%1, %0|%0, %1}"
9165   [(set_attr "type" "alu1")
9166    (set_attr "mode" "QI")])
9168 (define_insn "xorqi_ext_0"
9169   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9170                          (const_int 8)
9171                          (const_int 8))
9172         (xor:SI 
9173           (zero_extract:SI
9174             (match_operand 1 "ext_register_operand" "0")
9175             (const_int 8)
9176             (const_int 8))
9177           (match_operand 2 "const_int_operand" "n")))
9178    (clobber (reg:CC FLAGS_REG))]
9179   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9180   "xor{b}\t{%2, %h0|%h0, %2}"
9181   [(set_attr "type" "alu")
9182    (set_attr "length_immediate" "1")
9183    (set_attr "mode" "QI")])
9185 (define_insn "*xorqi_ext_1"
9186   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9187                          (const_int 8)
9188                          (const_int 8))
9189         (xor:SI 
9190           (zero_extract:SI
9191             (match_operand 1 "ext_register_operand" "0")
9192             (const_int 8)
9193             (const_int 8))
9194           (zero_extend:SI
9195             (match_operand:QI 2 "general_operand" "Qm"))))
9196    (clobber (reg:CC FLAGS_REG))]
9197   "!TARGET_64BIT
9198    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9199   "xor{b}\t{%2, %h0|%h0, %2}"
9200   [(set_attr "type" "alu")
9201    (set_attr "length_immediate" "0")
9202    (set_attr "mode" "QI")])
9204 (define_insn "*xorqi_ext_1_rex64"
9205   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9206                          (const_int 8)
9207                          (const_int 8))
9208         (xor:SI 
9209           (zero_extract:SI
9210             (match_operand 1 "ext_register_operand" "0")
9211             (const_int 8)
9212             (const_int 8))
9213           (zero_extend:SI
9214             (match_operand 2 "ext_register_operand" "Q"))))
9215    (clobber (reg:CC FLAGS_REG))]
9216   "TARGET_64BIT
9217    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9218   "xor{b}\t{%2, %h0|%h0, %2}"
9219   [(set_attr "type" "alu")
9220    (set_attr "length_immediate" "0")
9221    (set_attr "mode" "QI")])
9223 (define_insn "*xorqi_ext_2"
9224   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9225                          (const_int 8)
9226                          (const_int 8))
9227         (xor:SI 
9228           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9229                            (const_int 8)
9230                            (const_int 8))
9231           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9232                            (const_int 8)
9233                            (const_int 8))))
9234    (clobber (reg:CC FLAGS_REG))]
9235   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9236   "xor{b}\t{%h2, %h0|%h0, %h2}"
9237   [(set_attr "type" "alu")
9238    (set_attr "length_immediate" "0")
9239    (set_attr "mode" "QI")])
9241 (define_insn "*xorqi_cc_1"
9242   [(set (reg 17)
9243         (compare
9244           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9245                   (match_operand:QI 2 "general_operand" "qim,qi"))
9246           (const_int 0)))
9247    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9248         (xor:QI (match_dup 1) (match_dup 2)))]
9249   "ix86_match_ccmode (insn, CCNOmode)
9250    && ix86_binary_operator_ok (XOR, QImode, operands)"
9251   "xor{b}\t{%2, %0|%0, %2}"
9252   [(set_attr "type" "alu")
9253    (set_attr "mode" "QI")])
9255 (define_insn "*xorqi_2_slp"
9256   [(set (reg 17)
9257         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9258                          (match_operand:QI 1 "general_operand" "qim,qi"))
9259                  (const_int 0)))
9260    (set (strict_low_part (match_dup 0))
9261         (xor:QI (match_dup 0) (match_dup 1)))]
9262   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9263    && ix86_match_ccmode (insn, CCNOmode)
9264    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9265   "xor{b}\t{%1, %0|%0, %1}"
9266   [(set_attr "type" "alu1")
9267    (set_attr "mode" "QI")])
9269 (define_insn "*xorqi_cc_2"
9270   [(set (reg 17)
9271         (compare
9272           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9273                   (match_operand:QI 2 "general_operand" "qim"))
9274           (const_int 0)))
9275    (clobber (match_scratch:QI 0 "=q"))]
9276   "ix86_match_ccmode (insn, CCNOmode)
9277    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9278   "xor{b}\t{%2, %0|%0, %2}"
9279   [(set_attr "type" "alu")
9280    (set_attr "mode" "QI")])
9282 (define_insn "*xorqi_cc_ext_1"
9283   [(set (reg 17)
9284         (compare
9285           (xor:SI
9286             (zero_extract:SI
9287               (match_operand 1 "ext_register_operand" "0")
9288               (const_int 8)
9289               (const_int 8))
9290             (match_operand:QI 2 "general_operand" "qmn"))
9291           (const_int 0)))
9292    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9293                          (const_int 8)
9294                          (const_int 8))
9295         (xor:SI 
9296           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9297           (match_dup 2)))]
9298   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9299   "xor{b}\t{%2, %h0|%h0, %2}"
9300   [(set_attr "type" "alu")
9301    (set_attr "mode" "QI")])
9303 (define_insn "*xorqi_cc_ext_1_rex64"
9304   [(set (reg 17)
9305         (compare
9306           (xor:SI
9307             (zero_extract:SI
9308               (match_operand 1 "ext_register_operand" "0")
9309               (const_int 8)
9310               (const_int 8))
9311             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9312           (const_int 0)))
9313    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9314                          (const_int 8)
9315                          (const_int 8))
9316         (xor:SI 
9317           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9318           (match_dup 2)))]
9319   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9320   "xor{b}\t{%2, %h0|%h0, %2}"
9321   [(set_attr "type" "alu")
9322    (set_attr "mode" "QI")])
9324 (define_expand "xorqi_cc_ext_1"
9325   [(parallel [
9326      (set (reg:CCNO FLAGS_REG)
9327           (compare:CCNO
9328             (xor:SI
9329               (zero_extract:SI
9330                 (match_operand 1 "ext_register_operand" "")
9331                 (const_int 8)
9332                 (const_int 8))
9333               (match_operand:QI 2 "general_operand" ""))
9334             (const_int 0)))
9335      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9336                            (const_int 8)
9337                            (const_int 8))
9338           (xor:SI 
9339             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9340             (match_dup 2)))])]
9341   ""
9342   "")
9344 (define_split
9345   [(set (match_operand 0 "register_operand" "")
9346         (xor (match_operand 1 "register_operand" "")
9347              (match_operand 2 "const_int_operand" "")))
9348    (clobber (reg:CC FLAGS_REG))]
9349    "reload_completed
9350     && QI_REG_P (operands[0])
9351     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9352     && !(INTVAL (operands[2]) & ~(255 << 8))
9353     && GET_MODE (operands[0]) != QImode"
9354   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9355                    (xor:SI (zero_extract:SI (match_dup 1)
9356                                             (const_int 8) (const_int 8))
9357                            (match_dup 2)))
9358               (clobber (reg:CC FLAGS_REG))])]
9359   "operands[0] = gen_lowpart (SImode, operands[0]);
9360    operands[1] = gen_lowpart (SImode, operands[1]);
9361    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9363 ;; Since XOR can be encoded with sign extended immediate, this is only
9364 ;; profitable when 7th bit is set.
9365 (define_split
9366   [(set (match_operand 0 "register_operand" "")
9367         (xor (match_operand 1 "general_operand" "")
9368              (match_operand 2 "const_int_operand" "")))
9369    (clobber (reg:CC FLAGS_REG))]
9370    "reload_completed
9371     && ANY_QI_REG_P (operands[0])
9372     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9373     && !(INTVAL (operands[2]) & ~255)
9374     && (INTVAL (operands[2]) & 128)
9375     && GET_MODE (operands[0]) != QImode"
9376   [(parallel [(set (strict_low_part (match_dup 0))
9377                    (xor:QI (match_dup 1)
9378                            (match_dup 2)))
9379               (clobber (reg:CC FLAGS_REG))])]
9380   "operands[0] = gen_lowpart (QImode, operands[0]);
9381    operands[1] = gen_lowpart (QImode, operands[1]);
9382    operands[2] = gen_lowpart (QImode, operands[2]);")
9384 ;; Negation instructions
9386 (define_expand "negdi2"
9387   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9388                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9389               (clobber (reg:CC FLAGS_REG))])]
9390   ""
9391   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9393 (define_insn "*negdi2_1"
9394   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9395         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9396    (clobber (reg:CC FLAGS_REG))]
9397   "!TARGET_64BIT
9398    && ix86_unary_operator_ok (NEG, DImode, operands)"
9399   "#")
9401 (define_split
9402   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9403         (neg:DI (match_operand:DI 1 "general_operand" "")))
9404    (clobber (reg:CC FLAGS_REG))]
9405   "!TARGET_64BIT && reload_completed"
9406   [(parallel
9407     [(set (reg:CCZ FLAGS_REG)
9408           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9409      (set (match_dup 0) (neg:SI (match_dup 2)))])
9410    (parallel
9411     [(set (match_dup 1)
9412           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9413                             (match_dup 3))
9414                    (const_int 0)))
9415      (clobber (reg:CC FLAGS_REG))])
9416    (parallel
9417     [(set (match_dup 1)
9418           (neg:SI (match_dup 1)))
9419      (clobber (reg:CC FLAGS_REG))])]
9420   "split_di (operands+1, 1, operands+2, operands+3);
9421    split_di (operands+0, 1, operands+0, operands+1);")
9423 (define_insn "*negdi2_1_rex64"
9424   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9425         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9426    (clobber (reg:CC FLAGS_REG))]
9427   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9428   "neg{q}\t%0"
9429   [(set_attr "type" "negnot")
9430    (set_attr "mode" "DI")])
9432 ;; The problem with neg is that it does not perform (compare x 0),
9433 ;; it really performs (compare 0 x), which leaves us with the zero
9434 ;; flag being the only useful item.
9436 (define_insn "*negdi2_cmpz_rex64"
9437   [(set (reg:CCZ FLAGS_REG)
9438         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9439                      (const_int 0)))
9440    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9441         (neg:DI (match_dup 1)))]
9442   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9443   "neg{q}\t%0"
9444   [(set_attr "type" "negnot")
9445    (set_attr "mode" "DI")])
9448 (define_expand "negsi2"
9449   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9450                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9451               (clobber (reg:CC FLAGS_REG))])]
9452   ""
9453   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9455 (define_insn "*negsi2_1"
9456   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9457         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9458    (clobber (reg:CC FLAGS_REG))]
9459   "ix86_unary_operator_ok (NEG, SImode, operands)"
9460   "neg{l}\t%0"
9461   [(set_attr "type" "negnot")
9462    (set_attr "mode" "SI")])
9464 ;; Combine is quite creative about this pattern.
9465 (define_insn "*negsi2_1_zext"
9466   [(set (match_operand:DI 0 "register_operand" "=r")
9467         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9468                                         (const_int 32)))
9469                      (const_int 32)))
9470    (clobber (reg:CC FLAGS_REG))]
9471   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9472   "neg{l}\t%k0"
9473   [(set_attr "type" "negnot")
9474    (set_attr "mode" "SI")])
9476 ;; The problem with neg is that it does not perform (compare x 0),
9477 ;; it really performs (compare 0 x), which leaves us with the zero
9478 ;; flag being the only useful item.
9480 (define_insn "*negsi2_cmpz"
9481   [(set (reg:CCZ FLAGS_REG)
9482         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9483                      (const_int 0)))
9484    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9485         (neg:SI (match_dup 1)))]
9486   "ix86_unary_operator_ok (NEG, SImode, operands)"
9487   "neg{l}\t%0"
9488   [(set_attr "type" "negnot")
9489    (set_attr "mode" "SI")])
9491 (define_insn "*negsi2_cmpz_zext"
9492   [(set (reg:CCZ FLAGS_REG)
9493         (compare:CCZ (lshiftrt:DI
9494                        (neg:DI (ashift:DI
9495                                  (match_operand:DI 1 "register_operand" "0")
9496                                  (const_int 32)))
9497                        (const_int 32))
9498                      (const_int 0)))
9499    (set (match_operand:DI 0 "register_operand" "=r")
9500         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9501                                         (const_int 32)))
9502                      (const_int 32)))]
9503   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9504   "neg{l}\t%k0"
9505   [(set_attr "type" "negnot")
9506    (set_attr "mode" "SI")])
9508 (define_expand "neghi2"
9509   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9510                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9511               (clobber (reg:CC FLAGS_REG))])]
9512   "TARGET_HIMODE_MATH"
9513   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9515 (define_insn "*neghi2_1"
9516   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9517         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9518    (clobber (reg:CC FLAGS_REG))]
9519   "ix86_unary_operator_ok (NEG, HImode, operands)"
9520   "neg{w}\t%0"
9521   [(set_attr "type" "negnot")
9522    (set_attr "mode" "HI")])
9524 (define_insn "*neghi2_cmpz"
9525   [(set (reg:CCZ FLAGS_REG)
9526         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9527                      (const_int 0)))
9528    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9529         (neg:HI (match_dup 1)))]
9530   "ix86_unary_operator_ok (NEG, HImode, operands)"
9531   "neg{w}\t%0"
9532   [(set_attr "type" "negnot")
9533    (set_attr "mode" "HI")])
9535 (define_expand "negqi2"
9536   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9537                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9538               (clobber (reg:CC FLAGS_REG))])]
9539   "TARGET_QIMODE_MATH"
9540   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9542 (define_insn "*negqi2_1"
9543   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9544         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9545    (clobber (reg:CC FLAGS_REG))]
9546   "ix86_unary_operator_ok (NEG, QImode, operands)"
9547   "neg{b}\t%0"
9548   [(set_attr "type" "negnot")
9549    (set_attr "mode" "QI")])
9551 (define_insn "*negqi2_cmpz"
9552   [(set (reg:CCZ FLAGS_REG)
9553         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9554                      (const_int 0)))
9555    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9556         (neg:QI (match_dup 1)))]
9557   "ix86_unary_operator_ok (NEG, QImode, operands)"
9558   "neg{b}\t%0"
9559   [(set_attr "type" "negnot")
9560    (set_attr "mode" "QI")])
9562 ;; Changing of sign for FP values is doable using integer unit too.
9564 (define_expand "negsf2"
9565   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9566                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9567               (clobber (reg:CC FLAGS_REG))])]
9568   "TARGET_80387"
9569   "if (TARGET_SSE)
9570      {
9571        /* In case operand is in memory,  we will not use SSE.  */
9572        if (memory_operand (operands[0], VOIDmode)
9573            && rtx_equal_p (operands[0], operands[1]))
9574          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9575        else
9576         {
9577           /* Using SSE is tricky, since we need bitwise negation of -0
9578              in register.  */
9579           rtx reg = gen_reg_rtx (SFmode);
9580           rtx dest = operands[0];
9581           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9583           operands[1] = force_reg (SFmode, operands[1]);
9584           operands[0] = force_reg (SFmode, operands[0]);
9585           reg = force_reg (V4SFmode,
9586                            gen_rtx_CONST_VECTOR (V4SFmode,
9587                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9588                                         CONST0_RTX (SFmode),
9589                                         CONST0_RTX (SFmode))));
9590           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9591           if (dest != operands[0])
9592             emit_move_insn (dest, operands[0]);
9593         }
9594        DONE;
9595      }
9596    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9598 (define_insn "negsf2_memory"
9599   [(set (match_operand:SF 0 "memory_operand" "=m")
9600         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9601    (clobber (reg:CC FLAGS_REG))]
9602   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9603   "#")
9605 (define_insn "negsf2_ifs"
9606   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9607         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9608    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9609    (clobber (reg:CC FLAGS_REG))]
9610   "TARGET_SSE
9611    && (reload_in_progress || reload_completed
9612        || (register_operand (operands[0], VOIDmode)
9613            && register_operand (operands[1], VOIDmode)))"
9614   "#")
9616 (define_split
9617   [(set (match_operand:SF 0 "memory_operand" "")
9618         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9619    (use (match_operand:SF 2 "" ""))
9620    (clobber (reg:CC FLAGS_REG))]
9621   ""
9622   [(parallel [(set (match_dup 0)
9623                    (neg:SF (match_dup 1)))
9624               (clobber (reg:CC FLAGS_REG))])])
9626 (define_split
9627   [(set (match_operand:SF 0 "register_operand" "")
9628         (neg:SF (match_operand:SF 1 "register_operand" "")))
9629    (use (match_operand:V4SF 2 "" ""))
9630    (clobber (reg:CC FLAGS_REG))]
9631   "reload_completed && !SSE_REG_P (operands[0])"
9632   [(parallel [(set (match_dup 0)
9633                    (neg:SF (match_dup 1)))
9634               (clobber (reg:CC FLAGS_REG))])])
9636 (define_split
9637   [(set (match_operand:SF 0 "register_operand" "")
9638         (neg:SF (match_operand:SF 1 "register_operand" "")))
9639    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9640    (clobber (reg:CC FLAGS_REG))]
9641   "reload_completed && SSE_REG_P (operands[0])"
9642   [(set (match_dup 0)
9643         (xor:V4SF (match_dup 1)
9644                   (match_dup 2)))]
9646   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9647   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9648   if (operands_match_p (operands[0], operands[2]))
9649     {
9650       rtx tmp;
9651       tmp = operands[1];
9652       operands[1] = operands[2];
9653       operands[2] = tmp;
9654     }
9658 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9659 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9660 ;; to itself.
9661 (define_insn "*negsf2_if"
9662   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9663         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9664    (clobber (reg:CC FLAGS_REG))]
9665   "TARGET_80387 && !TARGET_SSE
9666    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9667   "#")
9669 (define_split
9670   [(set (match_operand:SF 0 "fp_register_operand" "")
9671         (neg:SF (match_operand:SF 1 "register_operand" "")))
9672    (clobber (reg:CC FLAGS_REG))]
9673   "TARGET_80387 && reload_completed"
9674   [(set (match_dup 0)
9675         (neg:SF (match_dup 1)))]
9676   "")
9678 (define_split
9679   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9680         (neg:SF (match_operand:SF 1 "register_operand" "")))
9681    (clobber (reg:CC FLAGS_REG))]
9682   "TARGET_80387 && reload_completed"
9683   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9684               (clobber (reg:CC FLAGS_REG))])]
9685   "operands[1] = gen_int_mode (0x80000000, SImode);
9686    operands[0] = gen_lowpart (SImode, operands[0]);")
9688 (define_split
9689   [(set (match_operand 0 "memory_operand" "")
9690         (neg (match_operand 1 "memory_operand" "")))
9691    (clobber (reg:CC FLAGS_REG))]
9692   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9693   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9694               (clobber (reg:CC FLAGS_REG))])]
9696   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9698   if (GET_MODE (operands[1]) == XFmode)
9699     size = 10;
9700   operands[0] = adjust_address (operands[0], QImode, size - 1);
9701   operands[1] = gen_int_mode (0x80, QImode);
9704 (define_expand "negdf2"
9705   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9706                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9707               (clobber (reg:CC FLAGS_REG))])]
9708   "TARGET_80387"
9709   "if (TARGET_SSE2)
9710      {
9711        /* In case operand is in memory,  we will not use SSE.  */
9712        if (memory_operand (operands[0], VOIDmode)
9713            && rtx_equal_p (operands[0], operands[1]))
9714          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9715        else
9716         {
9717           /* Using SSE is tricky, since we need bitwise negation of -0
9718              in register.  */
9719           rtx reg;
9720 #if HOST_BITS_PER_WIDE_INT >= 64
9721           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9722 #else
9723           rtx imm = immed_double_const (0, 0x80000000, DImode);
9724 #endif
9725           rtx dest = operands[0];
9727           operands[1] = force_reg (DFmode, operands[1]);
9728           operands[0] = force_reg (DFmode, operands[0]);
9729           imm = gen_lowpart (DFmode, imm);
9730           reg = force_reg (V2DFmode,
9731                            gen_rtx_CONST_VECTOR (V2DFmode,
9732                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9733           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9734           if (dest != operands[0])
9735             emit_move_insn (dest, operands[0]);
9736         }
9737        DONE;
9738      }
9739    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9741 (define_insn "negdf2_memory"
9742   [(set (match_operand:DF 0 "memory_operand" "=m")
9743         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9744    (clobber (reg:CC FLAGS_REG))]
9745   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9746   "#")
9748 (define_insn "negdf2_ifs"
9749   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9750         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9751    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9752    (clobber (reg:CC FLAGS_REG))]
9753   "!TARGET_64BIT && TARGET_SSE2
9754    && (reload_in_progress || reload_completed
9755        || (register_operand (operands[0], VOIDmode)
9756            && register_operand (operands[1], VOIDmode)))"
9757   "#")
9759 (define_insn "*negdf2_ifs_rex64"
9760   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9761         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9762    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9763    (clobber (reg:CC FLAGS_REG))]
9764   "TARGET_64BIT && TARGET_SSE2
9765    && (reload_in_progress || reload_completed
9766        || (register_operand (operands[0], VOIDmode)
9767            && register_operand (operands[1], VOIDmode)))"
9768   "#")
9770 (define_split
9771   [(set (match_operand:DF 0 "memory_operand" "")
9772         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9773    (use (match_operand:V2DF 2 "" ""))
9774    (clobber (reg:CC FLAGS_REG))]
9775   ""
9776   [(parallel [(set (match_dup 0)
9777                    (neg:DF (match_dup 1)))
9778               (clobber (reg:CC FLAGS_REG))])])
9780 (define_split
9781   [(set (match_operand:DF 0 "register_operand" "")
9782         (neg:DF (match_operand:DF 1 "register_operand" "")))
9783    (use (match_operand:V2DF 2 "" ""))
9784    (clobber (reg:CC FLAGS_REG))]
9785   "reload_completed && !SSE_REG_P (operands[0])
9786    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9787   [(parallel [(set (match_dup 0)
9788                    (neg:DF (match_dup 1)))
9789               (clobber (reg:CC FLAGS_REG))])])
9791 (define_split
9792   [(set (match_operand:DF 0 "register_operand" "")
9793         (neg:DF (match_operand:DF 1 "register_operand" "")))
9794    (use (match_operand:V2DF 2 "" ""))
9795    (clobber (reg:CC FLAGS_REG))]
9796   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9797   [(parallel [(set (match_dup 0)
9798                    (xor:DI (match_dup 1) (match_dup 2)))
9799               (clobber (reg:CC FLAGS_REG))])]
9800    "operands[0] = gen_lowpart (DImode, operands[0]);
9801     operands[1] = gen_lowpart (DImode, operands[1]);
9802     operands[2] = gen_lowpart (DImode, operands[2]);")
9804 (define_split
9805   [(set (match_operand:DF 0 "register_operand" "")
9806         (neg:DF (match_operand:DF 1 "register_operand" "")))
9807    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9808    (clobber (reg:CC FLAGS_REG))]
9809   "reload_completed && SSE_REG_P (operands[0])"
9810   [(set (match_dup 0)
9811         (xor:V2DF (match_dup 1)
9812                   (match_dup 2)))]
9814   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9815   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9816   /* Avoid possible reformatting on the operands.  */
9817   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9818     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9819   if (operands_match_p (operands[0], operands[2]))
9820     {
9821       rtx tmp;
9822       tmp = operands[1];
9823       operands[1] = operands[2];
9824       operands[2] = tmp;
9825     }
9828 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9829 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9830 ;; to itself.
9831 (define_insn "*negdf2_if"
9832   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9833         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9834    (clobber (reg:CC FLAGS_REG))]
9835   "!TARGET_64BIT && TARGET_80387
9836    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9837   "#")
9839 ;; FIXME: We should to allow integer registers here.  Problem is that
9840 ;; we need another scratch register to get constant from.
9841 ;; Forcing constant to mem if no register available in peep2 should be
9842 ;; safe even for PIC mode, because of RIP relative addressing.
9843 (define_insn "*negdf2_if_rex64"
9844   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9845         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9846    (clobber (reg:CC FLAGS_REG))]
9847   "TARGET_64BIT && TARGET_80387
9848    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9849   "#")
9851 (define_split
9852   [(set (match_operand:DF 0 "fp_register_operand" "")
9853         (neg:DF (match_operand:DF 1 "register_operand" "")))
9854    (clobber (reg:CC FLAGS_REG))]
9855   "TARGET_80387 && reload_completed"
9856   [(set (match_dup 0)
9857         (neg:DF (match_dup 1)))]
9858   "")
9860 (define_split
9861   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9862         (neg:DF (match_operand:DF 1 "register_operand" "")))
9863    (clobber (reg:CC FLAGS_REG))]
9864   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9865   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9866               (clobber (reg:CC FLAGS_REG))])]
9867   "operands[4] = gen_int_mode (0x80000000, SImode);
9868    split_di (operands+0, 1, operands+2, operands+3);")
9870 (define_expand "negxf2"
9871   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9872                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9873               (clobber (reg:CC FLAGS_REG))])]
9874   "TARGET_80387"
9875   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9877 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9878 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9879 ;; to itself.
9880 (define_insn "*negxf2_if"
9881   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9882         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9883    (clobber (reg:CC FLAGS_REG))]
9884   "TARGET_80387
9885    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9886   "#")
9888 (define_split
9889   [(set (match_operand:XF 0 "fp_register_operand" "")
9890         (neg:XF (match_operand:XF 1 "register_operand" "")))
9891    (clobber (reg:CC FLAGS_REG))]
9892   "TARGET_80387 && reload_completed"
9893   [(set (match_dup 0)
9894         (neg:XF (match_dup 1)))]
9895   "")
9897 (define_split
9898   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9899         (neg:XF (match_operand:XF 1 "register_operand" "")))
9900    (clobber (reg:CC FLAGS_REG))]
9901   "TARGET_80387 && reload_completed"
9902   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9903               (clobber (reg:CC FLAGS_REG))])]
9904   "operands[1] = GEN_INT (0x8000);
9905    operands[0] = gen_rtx_REG (SImode,
9906                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9908 ;; Conditionalize these after reload. If they matches before reload, we 
9909 ;; lose the clobber and ability to use integer instructions.
9911 (define_insn "*negsf2_1"
9912   [(set (match_operand:SF 0 "register_operand" "=f")
9913         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9914   "TARGET_80387 && reload_completed"
9915   "fchs"
9916   [(set_attr "type" "fsgn")
9917    (set_attr "mode" "SF")])
9919 (define_insn "*negdf2_1"
9920   [(set (match_operand:DF 0 "register_operand" "=f")
9921         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9922   "TARGET_80387 && reload_completed"
9923   "fchs"
9924   [(set_attr "type" "fsgn")
9925    (set_attr "mode" "DF")])
9927 (define_insn "*negextendsfdf2"
9928   [(set (match_operand:DF 0 "register_operand" "=f")
9929         (neg:DF (float_extend:DF
9930                   (match_operand:SF 1 "register_operand" "0"))))]
9931   "TARGET_80387"
9932   "fchs"
9933   [(set_attr "type" "fsgn")
9934    (set_attr "mode" "DF")])
9936 (define_insn "*negxf2_1"
9937   [(set (match_operand:XF 0 "register_operand" "=f")
9938         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9939   "TARGET_80387 && reload_completed"
9940   "fchs"
9941   [(set_attr "type" "fsgn")
9942    (set_attr "mode" "XF")])
9944 (define_insn "*negextenddfxf2"
9945   [(set (match_operand:XF 0 "register_operand" "=f")
9946         (neg:XF (float_extend:XF
9947                   (match_operand:DF 1 "register_operand" "0"))))]
9948   "TARGET_80387"
9949   "fchs"
9950   [(set_attr "type" "fsgn")
9951    (set_attr "mode" "XF")])
9953 (define_insn "*negextendsfxf2"
9954   [(set (match_operand:XF 0 "register_operand" "=f")
9955         (neg:XF (float_extend:XF
9956                   (match_operand:SF 1 "register_operand" "0"))))]
9957   "TARGET_80387"
9958   "fchs"
9959   [(set_attr "type" "fsgn")
9960    (set_attr "mode" "XF")])
9962 ;; Absolute value instructions
9964 (define_expand "abssf2"
9965   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9966                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9967               (clobber (reg:CC FLAGS_REG))])]
9968   "TARGET_80387"
9969   "if (TARGET_SSE)
9970      {
9971        /* In case operand is in memory,  we will not use SSE.  */
9972        if (memory_operand (operands[0], VOIDmode)
9973            && rtx_equal_p (operands[0], operands[1]))
9974          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9975        else
9976         {
9977           /* Using SSE is tricky, since we need bitwise negation of -0
9978              in register.  */
9979           rtx reg = gen_reg_rtx (V4SFmode);
9980           rtx dest = operands[0];
9981           rtx imm;
9983           operands[1] = force_reg (SFmode, operands[1]);
9984           operands[0] = force_reg (SFmode, operands[0]);
9985           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9986           reg = force_reg (V4SFmode,
9987                            gen_rtx_CONST_VECTOR (V4SFmode,
9988                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
9989                                       CONST0_RTX (SFmode),
9990                                       CONST0_RTX (SFmode))));
9991           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9992           if (dest != operands[0])
9993             emit_move_insn (dest, operands[0]);
9994         }
9995        DONE;
9996      }
9997    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9999 (define_insn "abssf2_memory"
10000   [(set (match_operand:SF 0 "memory_operand" "=m")
10001         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10002    (clobber (reg:CC FLAGS_REG))]
10003   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10004   "#")
10006 (define_insn "abssf2_ifs"
10007   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10008         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10009    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10010    (clobber (reg:CC FLAGS_REG))]
10011   "TARGET_SSE
10012    && (reload_in_progress || reload_completed
10013        || (register_operand (operands[0], VOIDmode)
10014             && register_operand (operands[1], VOIDmode)))"
10015   "#")
10017 (define_split
10018   [(set (match_operand:SF 0 "memory_operand" "")
10019         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10020    (use (match_operand:V4SF 2 "" ""))
10021    (clobber (reg:CC FLAGS_REG))]
10022   ""
10023   [(parallel [(set (match_dup 0)
10024                    (abs:SF (match_dup 1)))
10025               (clobber (reg:CC FLAGS_REG))])])
10027 (define_split
10028   [(set (match_operand:SF 0 "register_operand" "")
10029         (abs:SF (match_operand:SF 1 "register_operand" "")))
10030    (use (match_operand:V4SF 2 "" ""))
10031    (clobber (reg:CC FLAGS_REG))]
10032   "reload_completed && !SSE_REG_P (operands[0])"
10033   [(parallel [(set (match_dup 0)
10034                    (abs:SF (match_dup 1)))
10035               (clobber (reg:CC FLAGS_REG))])])
10037 (define_split
10038   [(set (match_operand:SF 0 "register_operand" "")
10039         (abs:SF (match_operand:SF 1 "register_operand" "")))
10040    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10041    (clobber (reg:CC FLAGS_REG))]
10042   "reload_completed && SSE_REG_P (operands[0])"
10043   [(set (match_dup 0)
10044         (and:V4SF (match_dup 1)
10045                   (match_dup 2)))]
10047   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10048   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10049   if (operands_match_p (operands[0], operands[2]))
10050     {
10051       rtx tmp;
10052       tmp = operands[1];
10053       operands[1] = operands[2];
10054       operands[2] = tmp;
10055     }
10058 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10059 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10060 ;; to itself.
10061 (define_insn "*abssf2_if"
10062   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10063         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10064    (clobber (reg:CC FLAGS_REG))]
10065   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10066   "#")
10068 (define_split
10069   [(set (match_operand:SF 0 "fp_register_operand" "")
10070         (abs:SF (match_operand:SF 1 "register_operand" "")))
10071    (clobber (reg:CC FLAGS_REG))]
10072   "TARGET_80387 && reload_completed"
10073   [(set (match_dup 0)
10074         (abs:SF (match_dup 1)))]
10075   "")
10077 (define_split
10078   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10079         (abs:SF (match_operand:SF 1 "register_operand" "")))
10080    (clobber (reg:CC FLAGS_REG))]
10081   "TARGET_80387 && reload_completed"
10082   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10083               (clobber (reg:CC FLAGS_REG))])]
10084   "operands[1] = gen_int_mode (~0x80000000, SImode);
10085    operands[0] = gen_lowpart (SImode, operands[0]);")
10087 (define_split
10088   [(set (match_operand 0 "memory_operand" "")
10089         (abs (match_operand 1 "memory_operand" "")))
10090    (clobber (reg:CC FLAGS_REG))]
10091   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10092   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10093               (clobber (reg:CC FLAGS_REG))])]
10095   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10097   if (GET_MODE (operands[1]) == XFmode)
10098     size = 10;
10099   operands[0] = adjust_address (operands[0], QImode, size - 1);
10100   operands[1] = gen_int_mode (~0x80, QImode);
10103 (define_expand "absdf2"
10104   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10105                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10106               (clobber (reg:CC FLAGS_REG))])]
10107   "TARGET_80387"
10108   "if (TARGET_SSE2)
10109      {
10110        /* In case operand is in memory,  we will not use SSE.  */
10111        if (memory_operand (operands[0], VOIDmode)
10112            && rtx_equal_p (operands[0], operands[1]))
10113          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10114        else
10115         {
10116           /* Using SSE is tricky, since we need bitwise negation of -0
10117              in register.  */
10118           rtx reg = gen_reg_rtx (V2DFmode);
10119 #if HOST_BITS_PER_WIDE_INT >= 64
10120           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10121 #else
10122           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10123 #endif
10124           rtx dest = operands[0];
10126           operands[1] = force_reg (DFmode, operands[1]);
10127           operands[0] = force_reg (DFmode, operands[0]);
10129           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10130           imm = gen_lowpart (DFmode, imm);
10131           reg = force_reg (V2DFmode,
10132                            gen_rtx_CONST_VECTOR (V2DFmode,
10133                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10134           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10135           if (dest != operands[0])
10136             emit_move_insn (dest, operands[0]);
10137         }
10138        DONE;
10139      }
10140    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10142 (define_insn "absdf2_memory"
10143   [(set (match_operand:DF 0 "memory_operand" "=m")
10144         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10145    (clobber (reg:CC FLAGS_REG))]
10146   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10147   "#")
10149 (define_insn "absdf2_ifs"
10150   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10151         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10152    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10153    (clobber (reg:CC FLAGS_REG))]
10154   "!TARGET_64BIT && TARGET_SSE2
10155    && (reload_in_progress || reload_completed
10156        || (register_operand (operands[0], VOIDmode)
10157            && register_operand (operands[1], VOIDmode)))"
10158   "#")
10160 (define_insn "*absdf2_ifs_rex64"
10161   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10162         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10163    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10164    (clobber (reg:CC FLAGS_REG))]
10165   "TARGET_64BIT && TARGET_SSE2
10166    && (reload_in_progress || reload_completed
10167        || (register_operand (operands[0], VOIDmode)
10168            && register_operand (operands[1], VOIDmode)))"
10169   "#")
10171 (define_split
10172   [(set (match_operand:DF 0 "memory_operand" "")
10173         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10174    (use (match_operand:V2DF 2 "" ""))
10175    (clobber (reg:CC FLAGS_REG))]
10176   ""
10177   [(parallel [(set (match_dup 0)
10178                    (abs:DF (match_dup 1)))
10179               (clobber (reg:CC FLAGS_REG))])])
10181 (define_split
10182   [(set (match_operand:DF 0 "register_operand" "")
10183         (abs:DF (match_operand:DF 1 "register_operand" "")))
10184    (use (match_operand:V2DF 2 "" ""))
10185    (clobber (reg:CC FLAGS_REG))]
10186   "reload_completed && !SSE_REG_P (operands[0])"
10187   [(parallel [(set (match_dup 0)
10188                    (abs:DF (match_dup 1)))
10189               (clobber (reg:CC FLAGS_REG))])])
10191 (define_split
10192   [(set (match_operand:DF 0 "register_operand" "")
10193         (abs:DF (match_operand:DF 1 "register_operand" "")))
10194    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10195    (clobber (reg:CC FLAGS_REG))]
10196   "reload_completed && SSE_REG_P (operands[0])"
10197   [(set (match_dup 0)
10198         (and:V2DF (match_dup 1)
10199                   (match_dup 2)))]
10201   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10202   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10203   /* Avoid possible reformatting on the operands.  */
10204   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10205     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10206   if (operands_match_p (operands[0], operands[2]))
10207     {
10208       rtx tmp;
10209       tmp = operands[1];
10210       operands[1] = operands[2];
10211       operands[2] = tmp;
10212     }
10216 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10217 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10218 ;; to itself.
10219 (define_insn "*absdf2_if"
10220   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10221         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10222    (clobber (reg:CC FLAGS_REG))]
10223   "!TARGET_64BIT && TARGET_80387
10224    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10225   "#")
10227 ;; FIXME: We should to allow integer registers here.  Problem is that
10228 ;; we need another scratch register to get constant from.
10229 ;; Forcing constant to mem if no register available in peep2 should be
10230 ;; safe even for PIC mode, because of RIP relative addressing.
10231 (define_insn "*absdf2_if_rex64"
10232   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10233         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10234    (clobber (reg:CC FLAGS_REG))]
10235   "TARGET_64BIT && TARGET_80387
10236    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10237   "#")
10239 (define_split
10240   [(set (match_operand:DF 0 "fp_register_operand" "")
10241         (abs:DF (match_operand:DF 1 "register_operand" "")))
10242    (clobber (reg:CC FLAGS_REG))]
10243   "TARGET_80387 && reload_completed"
10244   [(set (match_dup 0)
10245         (abs:DF (match_dup 1)))]
10246   "")
10248 (define_split
10249   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10250         (abs:DF (match_operand:DF 1 "register_operand" "")))
10251    (clobber (reg:CC FLAGS_REG))]
10252   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10253   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10254               (clobber (reg:CC FLAGS_REG))])]
10255   "operands[4] = gen_int_mode (~0x80000000, SImode);
10256    split_di (operands+0, 1, operands+2, operands+3);")
10258 (define_expand "absxf2"
10259   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10260                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10261               (clobber (reg:CC FLAGS_REG))])]
10262   "TARGET_80387"
10263   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10265 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10266 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10267 ;; to itself.
10268 (define_insn "*absxf2_if"
10269   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10270         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10271    (clobber (reg:CC FLAGS_REG))]
10272   "TARGET_80387
10273    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10274   "#")
10276 (define_split
10277   [(set (match_operand:XF 0 "fp_register_operand" "")
10278         (abs:XF (match_operand:XF 1 "register_operand" "")))
10279    (clobber (reg:CC FLAGS_REG))]
10280   "TARGET_80387 && reload_completed"
10281   [(set (match_dup 0)
10282         (abs:XF (match_dup 1)))]
10283   "")
10285 (define_split
10286   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10287         (abs:XF (match_operand:XF 1 "register_operand" "")))
10288    (clobber (reg:CC FLAGS_REG))]
10289   "TARGET_80387 && reload_completed"
10290   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10291               (clobber (reg:CC FLAGS_REG))])]
10292   "operands[1] = GEN_INT (~0x8000);
10293    operands[0] = gen_rtx_REG (SImode,
10294                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10296 (define_insn "*abssf2_1"
10297   [(set (match_operand:SF 0 "register_operand" "=f")
10298         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10299   "TARGET_80387 && reload_completed"
10300   "fabs"
10301   [(set_attr "type" "fsgn")
10302    (set_attr "mode" "SF")])
10304 (define_insn "*absdf2_1"
10305   [(set (match_operand:DF 0 "register_operand" "=f")
10306         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10307   "TARGET_80387 && reload_completed"
10308   "fabs"
10309   [(set_attr "type" "fsgn")
10310    (set_attr "mode" "DF")])
10312 (define_insn "*absextendsfdf2"
10313   [(set (match_operand:DF 0 "register_operand" "=f")
10314         (abs:DF (float_extend:DF
10315                   (match_operand:SF 1 "register_operand" "0"))))]
10316   "TARGET_80387"
10317   "fabs"
10318   [(set_attr "type" "fsgn")
10319    (set_attr "mode" "DF")])
10321 (define_insn "*absxf2_1"
10322   [(set (match_operand:XF 0 "register_operand" "=f")
10323         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10324   "TARGET_80387 && reload_completed"
10325   "fabs"
10326   [(set_attr "type" "fsgn")
10327    (set_attr "mode" "DF")])
10329 (define_insn "*absextenddfxf2"
10330   [(set (match_operand:XF 0 "register_operand" "=f")
10331         (abs:XF (float_extend:XF
10332           (match_operand:DF 1 "register_operand" "0"))))]
10333   "TARGET_80387"
10334   "fabs"
10335   [(set_attr "type" "fsgn")
10336    (set_attr "mode" "XF")])
10338 (define_insn "*absextendsfxf2"
10339   [(set (match_operand:XF 0 "register_operand" "=f")
10340         (abs:XF (float_extend:XF
10341           (match_operand:SF 1 "register_operand" "0"))))]
10342   "TARGET_80387"
10343   "fabs"
10344   [(set_attr "type" "fsgn")
10345    (set_attr "mode" "XF")])
10347 ;; One complement instructions
10349 (define_expand "one_cmpldi2"
10350   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10351         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10352   "TARGET_64BIT"
10353   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10355 (define_insn "*one_cmpldi2_1_rex64"
10356   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10357         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10358   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10359   "not{q}\t%0"
10360   [(set_attr "type" "negnot")
10361    (set_attr "mode" "DI")])
10363 (define_insn "*one_cmpldi2_2_rex64"
10364   [(set (reg 17)
10365         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10366                  (const_int 0)))
10367    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10368         (not:DI (match_dup 1)))]
10369   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10370    && ix86_unary_operator_ok (NOT, DImode, operands)"
10371   "#"
10372   [(set_attr "type" "alu1")
10373    (set_attr "mode" "DI")])
10375 (define_split
10376   [(set (reg 17)
10377         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10378                  (const_int 0)))
10379    (set (match_operand:DI 0 "nonimmediate_operand" "")
10380         (not:DI (match_dup 1)))]
10381   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10382   [(parallel [(set (reg:CCNO FLAGS_REG)
10383                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10384                                  (const_int 0)))
10385               (set (match_dup 0)
10386                    (xor:DI (match_dup 1) (const_int -1)))])]
10387   "")
10389 (define_expand "one_cmplsi2"
10390   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10391         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10392   ""
10393   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10395 (define_insn "*one_cmplsi2_1"
10396   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10397         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10398   "ix86_unary_operator_ok (NOT, SImode, operands)"
10399   "not{l}\t%0"
10400   [(set_attr "type" "negnot")
10401    (set_attr "mode" "SI")])
10403 ;; ??? Currently never generated - xor is used instead.
10404 (define_insn "*one_cmplsi2_1_zext"
10405   [(set (match_operand:DI 0 "register_operand" "=r")
10406         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10407   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10408   "not{l}\t%k0"
10409   [(set_attr "type" "negnot")
10410    (set_attr "mode" "SI")])
10412 (define_insn "*one_cmplsi2_2"
10413   [(set (reg 17)
10414         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10415                  (const_int 0)))
10416    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10417         (not:SI (match_dup 1)))]
10418   "ix86_match_ccmode (insn, CCNOmode)
10419    && ix86_unary_operator_ok (NOT, SImode, operands)"
10420   "#"
10421   [(set_attr "type" "alu1")
10422    (set_attr "mode" "SI")])
10424 (define_split
10425   [(set (reg 17)
10426         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10427                  (const_int 0)))
10428    (set (match_operand:SI 0 "nonimmediate_operand" "")
10429         (not:SI (match_dup 1)))]
10430   "ix86_match_ccmode (insn, CCNOmode)"
10431   [(parallel [(set (reg:CCNO FLAGS_REG)
10432                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10433                                  (const_int 0)))
10434               (set (match_dup 0)
10435                    (xor:SI (match_dup 1) (const_int -1)))])]
10436   "")
10438 ;; ??? Currently never generated - xor is used instead.
10439 (define_insn "*one_cmplsi2_2_zext"
10440   [(set (reg 17)
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 (reg 17)
10453         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10454                  (const_int 0)))
10455    (set (match_operand:DI 0 "register_operand" "")
10456         (zero_extend:DI (not:SI (match_dup 1))))]
10457   "ix86_match_ccmode (insn, CCNOmode)"
10458   [(parallel [(set (reg:CCNO FLAGS_REG)
10459                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10460                                  (const_int 0)))
10461               (set (match_dup 0)
10462                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10463   "")
10465 (define_expand "one_cmplhi2"
10466   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10467         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10468   "TARGET_HIMODE_MATH"
10469   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10471 (define_insn "*one_cmplhi2_1"
10472   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10473         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10474   "ix86_unary_operator_ok (NOT, HImode, operands)"
10475   "not{w}\t%0"
10476   [(set_attr "type" "negnot")
10477    (set_attr "mode" "HI")])
10479 (define_insn "*one_cmplhi2_2"
10480   [(set (reg 17)
10481         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10482                  (const_int 0)))
10483    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10484         (not:HI (match_dup 1)))]
10485   "ix86_match_ccmode (insn, CCNOmode)
10486    && ix86_unary_operator_ok (NEG, HImode, operands)"
10487   "#"
10488   [(set_attr "type" "alu1")
10489    (set_attr "mode" "HI")])
10491 (define_split
10492   [(set (reg 17)
10493         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10494                  (const_int 0)))
10495    (set (match_operand:HI 0 "nonimmediate_operand" "")
10496         (not:HI (match_dup 1)))]
10497   "ix86_match_ccmode (insn, CCNOmode)"
10498   [(parallel [(set (reg:CCNO FLAGS_REG)
10499                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10500                                  (const_int 0)))
10501               (set (match_dup 0)
10502                    (xor:HI (match_dup 1) (const_int -1)))])]
10503   "")
10505 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10506 (define_expand "one_cmplqi2"
10507   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10508         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10509   "TARGET_QIMODE_MATH"
10510   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10512 (define_insn "*one_cmplqi2_1"
10513   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10514         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10515   "ix86_unary_operator_ok (NOT, QImode, operands)"
10516   "@
10517    not{b}\t%0
10518    not{l}\t%k0"
10519   [(set_attr "type" "negnot")
10520    (set_attr "mode" "QI,SI")])
10522 (define_insn "*one_cmplqi2_2"
10523   [(set (reg 17)
10524         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10525                  (const_int 0)))
10526    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10527         (not:QI (match_dup 1)))]
10528   "ix86_match_ccmode (insn, CCNOmode)
10529    && ix86_unary_operator_ok (NOT, QImode, operands)"
10530   "#"
10531   [(set_attr "type" "alu1")
10532    (set_attr "mode" "QI")])
10534 (define_split
10535   [(set (reg 17)
10536         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10537                  (const_int 0)))
10538    (set (match_operand:QI 0 "nonimmediate_operand" "")
10539         (not:QI (match_dup 1)))]
10540   "ix86_match_ccmode (insn, CCNOmode)"
10541   [(parallel [(set (reg:CCNO FLAGS_REG)
10542                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10543                                  (const_int 0)))
10544               (set (match_dup 0)
10545                    (xor:QI (match_dup 1) (const_int -1)))])]
10546   "")
10548 ;; Arithmetic shift instructions
10550 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10551 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10552 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10553 ;; from the assembler input.
10555 ;; This instruction shifts the target reg/mem as usual, but instead of
10556 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10557 ;; is a left shift double, bits are taken from the high order bits of
10558 ;; reg, else if the insn is a shift right double, bits are taken from the
10559 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10560 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10562 ;; Since sh[lr]d does not change the `reg' operand, that is done
10563 ;; separately, making all shifts emit pairs of shift double and normal
10564 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10565 ;; support a 63 bit shift, each shift where the count is in a reg expands
10566 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10568 ;; If the shift count is a constant, we need never emit more than one
10569 ;; shift pair, instead using moves and sign extension for counts greater
10570 ;; than 31.
10572 (define_expand "ashldi3"
10573   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10574                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10575                               (match_operand:QI 2 "nonmemory_operand" "")))
10576               (clobber (reg:CC FLAGS_REG))])]
10577   ""
10579   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10580     {
10581       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10582       DONE;
10583     }
10584   ix86_expand_binary_operator (ASHIFT, DImode, operands);
10585   DONE;
10588 (define_insn "*ashldi3_1_rex64"
10589   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10590         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10591                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10592    (clobber (reg:CC FLAGS_REG))]
10593   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10595   switch (get_attr_type (insn))
10596     {
10597     case TYPE_ALU:
10598       if (operands[2] != const1_rtx)
10599         abort ();
10600       if (!rtx_equal_p (operands[0], operands[1]))
10601         abort ();
10602       return "add{q}\t{%0, %0|%0, %0}";
10604     case TYPE_LEA:
10605       if (GET_CODE (operands[2]) != CONST_INT
10606           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10607         abort ();
10608       operands[1] = gen_rtx_MULT (DImode, operands[1],
10609                                   GEN_INT (1 << INTVAL (operands[2])));
10610       return "lea{q}\t{%a1, %0|%0, %a1}";
10612     default:
10613       if (REG_P (operands[2]))
10614         return "sal{q}\t{%b2, %0|%0, %b2}";
10615       else if (operands[2] == const1_rtx
10616                && (TARGET_SHIFT1 || optimize_size))
10617         return "sal{q}\t%0";
10618       else
10619         return "sal{q}\t{%2, %0|%0, %2}";
10620     }
10622   [(set (attr "type")
10623      (cond [(eq_attr "alternative" "1")
10624               (const_string "lea")
10625             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10626                           (const_int 0))
10627                       (match_operand 0 "register_operand" ""))
10628                  (match_operand 2 "const1_operand" ""))
10629               (const_string "alu")
10630            ]
10631            (const_string "ishift")))
10632    (set_attr "mode" "DI")])
10634 ;; Convert lea to the lea pattern to avoid flags dependency.
10635 (define_split
10636   [(set (match_operand:DI 0 "register_operand" "")
10637         (ashift:DI (match_operand:DI 1 "register_operand" "")
10638                    (match_operand:QI 2 "immediate_operand" "")))
10639    (clobber (reg:CC FLAGS_REG))]
10640   "TARGET_64BIT && reload_completed
10641    && true_regnum (operands[0]) != true_regnum (operands[1])"
10642   [(set (match_dup 0)
10643         (mult:DI (match_dup 1)
10644                  (match_dup 2)))]
10645   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10647 ;; This pattern can't accept a variable shift count, since shifts by
10648 ;; zero don't affect the flags.  We assume that shifts by constant
10649 ;; zero are optimized away.
10650 (define_insn "*ashldi3_cmp_rex64"
10651   [(set (reg 17)
10652         (compare
10653           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10654                      (match_operand:QI 2 "immediate_operand" "e"))
10655           (const_int 0)))
10656    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10657         (ashift:DI (match_dup 1) (match_dup 2)))]
10658   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10659    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10661   switch (get_attr_type (insn))
10662     {
10663     case TYPE_ALU:
10664       if (operands[2] != const1_rtx)
10665         abort ();
10666       return "add{q}\t{%0, %0|%0, %0}";
10668     default:
10669       if (REG_P (operands[2]))
10670         return "sal{q}\t{%b2, %0|%0, %b2}";
10671       else if (operands[2] == const1_rtx
10672                && (TARGET_SHIFT1 || optimize_size))
10673         return "sal{q}\t%0";
10674       else
10675         return "sal{q}\t{%2, %0|%0, %2}";
10676     }
10678   [(set (attr "type")
10679      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10680                           (const_int 0))
10681                       (match_operand 0 "register_operand" ""))
10682                  (match_operand 2 "const1_operand" ""))
10683               (const_string "alu")
10684            ]
10685            (const_string "ishift")))
10686    (set_attr "mode" "DI")])
10688 (define_insn "ashldi3_1"
10689   [(set (match_operand:DI 0 "register_operand" "=r")
10690         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10691                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10692    (clobber (match_scratch:SI 3 "=&r"))
10693    (clobber (reg:CC FLAGS_REG))]
10694   "!TARGET_64BIT && TARGET_CMOVE"
10695   "#"
10696   [(set_attr "type" "multi")])
10698 (define_insn "*ashldi3_2"
10699   [(set (match_operand:DI 0 "register_operand" "=r")
10700         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10701                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10702    (clobber (reg:CC FLAGS_REG))]
10703   "!TARGET_64BIT"
10704   "#"
10705   [(set_attr "type" "multi")])
10707 (define_split
10708   [(set (match_operand:DI 0 "register_operand" "")
10709         (ashift:DI (match_operand:DI 1 "register_operand" "")
10710                    (match_operand:QI 2 "nonmemory_operand" "")))
10711    (clobber (match_scratch:SI 3 ""))
10712    (clobber (reg:CC FLAGS_REG))]
10713   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10714   [(const_int 0)]
10715   "ix86_split_ashldi (operands, operands[3]); DONE;")
10717 (define_split
10718   [(set (match_operand:DI 0 "register_operand" "")
10719         (ashift:DI (match_operand:DI 1 "register_operand" "")
10720                    (match_operand:QI 2 "nonmemory_operand" "")))
10721    (clobber (reg:CC FLAGS_REG))]
10722   "!TARGET_64BIT && reload_completed"
10723   [(const_int 0)]
10724   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10726 (define_insn "x86_shld_1"
10727   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10728         (ior:SI (ashift:SI (match_dup 0)
10729                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10730                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10731                   (minus:QI (const_int 32) (match_dup 2)))))
10732    (clobber (reg:CC FLAGS_REG))]
10733   ""
10734   "@
10735    shld{l}\t{%2, %1, %0|%0, %1, %2}
10736    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10737   [(set_attr "type" "ishift")
10738    (set_attr "prefix_0f" "1")
10739    (set_attr "mode" "SI")
10740    (set_attr "pent_pair" "np")
10741    (set_attr "athlon_decode" "vector")])
10743 (define_expand "x86_shift_adj_1"
10744   [(set (reg:CCZ FLAGS_REG)
10745         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10746                              (const_int 32))
10747                      (const_int 0)))
10748    (set (match_operand:SI 0 "register_operand" "")
10749         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10750                          (match_operand:SI 1 "register_operand" "")
10751                          (match_dup 0)))
10752    (set (match_dup 1)
10753         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10754                          (match_operand:SI 3 "register_operand" "r")
10755                          (match_dup 1)))]
10756   "TARGET_CMOVE"
10757   "")
10759 (define_expand "x86_shift_adj_2"
10760   [(use (match_operand:SI 0 "register_operand" ""))
10761    (use (match_operand:SI 1 "register_operand" ""))
10762    (use (match_operand:QI 2 "register_operand" ""))]
10763   ""
10765   rtx label = gen_label_rtx ();
10766   rtx tmp;
10768   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10770   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10771   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10772   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10773                               gen_rtx_LABEL_REF (VOIDmode, label),
10774                               pc_rtx);
10775   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10776   JUMP_LABEL (tmp) = label;
10778   emit_move_insn (operands[0], operands[1]);
10779   emit_move_insn (operands[1], const0_rtx);
10781   emit_label (label);
10782   LABEL_NUSES (label) = 1;
10784   DONE;
10787 (define_expand "ashlsi3"
10788   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10789         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10790                    (match_operand:QI 2 "nonmemory_operand" "")))
10791    (clobber (reg:CC FLAGS_REG))]
10792   ""
10793   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10795 (define_insn "*ashlsi3_1"
10796   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10797         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10798                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10799    (clobber (reg:CC FLAGS_REG))]
10800   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10802   switch (get_attr_type (insn))
10803     {
10804     case TYPE_ALU:
10805       if (operands[2] != const1_rtx)
10806         abort ();
10807       if (!rtx_equal_p (operands[0], operands[1]))
10808         abort ();
10809       return "add{l}\t{%0, %0|%0, %0}";
10811     case TYPE_LEA:
10812       return "#";
10814     default:
10815       if (REG_P (operands[2]))
10816         return "sal{l}\t{%b2, %0|%0, %b2}";
10817       else if (operands[2] == const1_rtx
10818                && (TARGET_SHIFT1 || optimize_size))
10819         return "sal{l}\t%0";
10820       else
10821         return "sal{l}\t{%2, %0|%0, %2}";
10822     }
10824   [(set (attr "type")
10825      (cond [(eq_attr "alternative" "1")
10826               (const_string "lea")
10827             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10828                           (const_int 0))
10829                       (match_operand 0 "register_operand" ""))
10830                  (match_operand 2 "const1_operand" ""))
10831               (const_string "alu")
10832            ]
10833            (const_string "ishift")))
10834    (set_attr "mode" "SI")])
10836 ;; Convert lea to the lea pattern to avoid flags dependency.
10837 (define_split
10838   [(set (match_operand 0 "register_operand" "")
10839         (ashift (match_operand 1 "index_register_operand" "")
10840                 (match_operand:QI 2 "const_int_operand" "")))
10841    (clobber (reg:CC FLAGS_REG))]
10842   "reload_completed
10843    && true_regnum (operands[0]) != true_regnum (operands[1])"
10844   [(const_int 0)]
10846   rtx pat;
10847   operands[0] = gen_lowpart (SImode, operands[0]);
10848   operands[1] = gen_lowpart (Pmode, operands[1]);
10849   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10850   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10851   if (Pmode != SImode)
10852     pat = gen_rtx_SUBREG (SImode, pat, 0);
10853   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10854   DONE;
10857 ;; Rare case of shifting RSP is handled by generating move and shift
10858 (define_split
10859   [(set (match_operand 0 "register_operand" "")
10860         (ashift (match_operand 1 "register_operand" "")
10861                 (match_operand:QI 2 "const_int_operand" "")))
10862    (clobber (reg:CC FLAGS_REG))]
10863   "reload_completed
10864    && true_regnum (operands[0]) != true_regnum (operands[1])"
10865   [(const_int 0)]
10867   rtx pat, clob;
10868   emit_move_insn (operands[1], operands[0]);
10869   pat = gen_rtx_SET (VOIDmode, operands[0],
10870                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10871                                      operands[0], operands[2]));
10872   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10873   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10874   DONE;
10877 (define_insn "*ashlsi3_1_zext"
10878   [(set (match_operand:DI 0 "register_operand" "=r,r")
10879         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10880                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10881    (clobber (reg:CC FLAGS_REG))]
10882   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10884   switch (get_attr_type (insn))
10885     {
10886     case TYPE_ALU:
10887       if (operands[2] != const1_rtx)
10888         abort ();
10889       return "add{l}\t{%k0, %k0|%k0, %k0}";
10891     case TYPE_LEA:
10892       return "#";
10894     default:
10895       if (REG_P (operands[2]))
10896         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10897       else if (operands[2] == const1_rtx
10898                && (TARGET_SHIFT1 || optimize_size))
10899         return "sal{l}\t%k0";
10900       else
10901         return "sal{l}\t{%2, %k0|%k0, %2}";
10902     }
10904   [(set (attr "type")
10905      (cond [(eq_attr "alternative" "1")
10906               (const_string "lea")
10907             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10908                      (const_int 0))
10909                  (match_operand 2 "const1_operand" ""))
10910               (const_string "alu")
10911            ]
10912            (const_string "ishift")))
10913    (set_attr "mode" "SI")])
10915 ;; Convert lea to the lea pattern to avoid flags dependency.
10916 (define_split
10917   [(set (match_operand:DI 0 "register_operand" "")
10918         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10919                                 (match_operand:QI 2 "const_int_operand" ""))))
10920    (clobber (reg:CC FLAGS_REG))]
10921   "TARGET_64BIT && reload_completed
10922    && true_regnum (operands[0]) != true_regnum (operands[1])"
10923   [(set (match_dup 0) (zero_extend:DI
10924                         (subreg:SI (mult:SI (match_dup 1)
10925                                             (match_dup 2)) 0)))]
10927   operands[1] = gen_lowpart (Pmode, operands[1]);
10928   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10931 ;; This pattern can't accept a variable shift count, since shifts by
10932 ;; zero don't affect the flags.  We assume that shifts by constant
10933 ;; zero are optimized away.
10934 (define_insn "*ashlsi3_cmp"
10935   [(set (reg 17)
10936         (compare
10937           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10938                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10939           (const_int 0)))
10940    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10941         (ashift:SI (match_dup 1) (match_dup 2)))]
10942   "ix86_match_ccmode (insn, CCGOCmode)
10943    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10945   switch (get_attr_type (insn))
10946     {
10947     case TYPE_ALU:
10948       if (operands[2] != const1_rtx)
10949         abort ();
10950       return "add{l}\t{%0, %0|%0, %0}";
10952     default:
10953       if (REG_P (operands[2]))
10954         return "sal{l}\t{%b2, %0|%0, %b2}";
10955       else if (operands[2] == const1_rtx
10956                && (TARGET_SHIFT1 || optimize_size))
10957         return "sal{l}\t%0";
10958       else
10959         return "sal{l}\t{%2, %0|%0, %2}";
10960     }
10962   [(set (attr "type")
10963      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10964                           (const_int 0))
10965                       (match_operand 0 "register_operand" ""))
10966                  (match_operand 2 "const1_operand" ""))
10967               (const_string "alu")
10968            ]
10969            (const_string "ishift")))
10970    (set_attr "mode" "SI")])
10972 (define_insn "*ashlsi3_cmp_zext"
10973   [(set (reg 17)
10974         (compare
10975           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10976                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10977           (const_int 0)))
10978    (set (match_operand:DI 0 "register_operand" "=r")
10979         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10980   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10981    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10983   switch (get_attr_type (insn))
10984     {
10985     case TYPE_ALU:
10986       if (operands[2] != const1_rtx)
10987         abort ();
10988       return "add{l}\t{%k0, %k0|%k0, %k0}";
10990     default:
10991       if (REG_P (operands[2]))
10992         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10993       else if (operands[2] == const1_rtx
10994                && (TARGET_SHIFT1 || optimize_size))
10995         return "sal{l}\t%k0";
10996       else
10997         return "sal{l}\t{%2, %k0|%k0, %2}";
10998     }
11000   [(set (attr "type")
11001      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11002                      (const_int 0))
11003                  (match_operand 2 "const1_operand" ""))
11004               (const_string "alu")
11005            ]
11006            (const_string "ishift")))
11007    (set_attr "mode" "SI")])
11009 (define_expand "ashlhi3"
11010   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11011         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11012                    (match_operand:QI 2 "nonmemory_operand" "")))
11013    (clobber (reg:CC FLAGS_REG))]
11014   "TARGET_HIMODE_MATH"
11015   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11017 (define_insn "*ashlhi3_1_lea"
11018   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11019         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11020                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11021    (clobber (reg:CC FLAGS_REG))]
11022   "!TARGET_PARTIAL_REG_STALL
11023    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11025   switch (get_attr_type (insn))
11026     {
11027     case TYPE_LEA:
11028       return "#";
11029     case TYPE_ALU:
11030       if (operands[2] != const1_rtx)
11031         abort ();
11032       return "add{w}\t{%0, %0|%0, %0}";
11034     default:
11035       if (REG_P (operands[2]))
11036         return "sal{w}\t{%b2, %0|%0, %b2}";
11037       else if (operands[2] == const1_rtx
11038                && (TARGET_SHIFT1 || optimize_size))
11039         return "sal{w}\t%0";
11040       else
11041         return "sal{w}\t{%2, %0|%0, %2}";
11042     }
11044   [(set (attr "type")
11045      (cond [(eq_attr "alternative" "1")
11046               (const_string "lea")
11047             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11048                           (const_int 0))
11049                       (match_operand 0 "register_operand" ""))
11050                  (match_operand 2 "const1_operand" ""))
11051               (const_string "alu")
11052            ]
11053            (const_string "ishift")))
11054    (set_attr "mode" "HI,SI")])
11056 (define_insn "*ashlhi3_1"
11057   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11058         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11059                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11060    (clobber (reg:CC FLAGS_REG))]
11061   "TARGET_PARTIAL_REG_STALL
11062    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11064   switch (get_attr_type (insn))
11065     {
11066     case TYPE_ALU:
11067       if (operands[2] != const1_rtx)
11068         abort ();
11069       return "add{w}\t{%0, %0|%0, %0}";
11071     default:
11072       if (REG_P (operands[2]))
11073         return "sal{w}\t{%b2, %0|%0, %b2}";
11074       else if (operands[2] == const1_rtx
11075                && (TARGET_SHIFT1 || optimize_size))
11076         return "sal{w}\t%0";
11077       else
11078         return "sal{w}\t{%2, %0|%0, %2}";
11079     }
11081   [(set (attr "type")
11082      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11083                           (const_int 0))
11084                       (match_operand 0 "register_operand" ""))
11085                  (match_operand 2 "const1_operand" ""))
11086               (const_string "alu")
11087            ]
11088            (const_string "ishift")))
11089    (set_attr "mode" "HI")])
11091 ;; This pattern can't accept a variable shift count, since shifts by
11092 ;; zero don't affect the flags.  We assume that shifts by constant
11093 ;; zero are optimized away.
11094 (define_insn "*ashlhi3_cmp"
11095   [(set (reg 17)
11096         (compare
11097           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11098                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11099           (const_int 0)))
11100    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11101         (ashift:HI (match_dup 1) (match_dup 2)))]
11102   "ix86_match_ccmode (insn, CCGOCmode)
11103    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11105   switch (get_attr_type (insn))
11106     {
11107     case TYPE_ALU:
11108       if (operands[2] != const1_rtx)
11109         abort ();
11110       return "add{w}\t{%0, %0|%0, %0}";
11112     default:
11113       if (REG_P (operands[2]))
11114         return "sal{w}\t{%b2, %0|%0, %b2}";
11115       else if (operands[2] == const1_rtx
11116                && (TARGET_SHIFT1 || optimize_size))
11117         return "sal{w}\t%0";
11118       else
11119         return "sal{w}\t{%2, %0|%0, %2}";
11120     }
11122   [(set (attr "type")
11123      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11124                           (const_int 0))
11125                       (match_operand 0 "register_operand" ""))
11126                  (match_operand 2 "const1_operand" ""))
11127               (const_string "alu")
11128            ]
11129            (const_string "ishift")))
11130    (set_attr "mode" "HI")])
11132 (define_expand "ashlqi3"
11133   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11134         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11135                    (match_operand:QI 2 "nonmemory_operand" "")))
11136    (clobber (reg:CC FLAGS_REG))]
11137   "TARGET_QIMODE_MATH"
11138   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11140 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11142 (define_insn "*ashlqi3_1_lea"
11143   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11144         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11145                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11146    (clobber (reg:CC FLAGS_REG))]
11147   "!TARGET_PARTIAL_REG_STALL
11148    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11150   switch (get_attr_type (insn))
11151     {
11152     case TYPE_LEA:
11153       return "#";
11154     case TYPE_ALU:
11155       if (operands[2] != const1_rtx)
11156         abort ();
11157       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11158         return "add{l}\t{%k0, %k0|%k0, %k0}";
11159       else
11160         return "add{b}\t{%0, %0|%0, %0}";
11162     default:
11163       if (REG_P (operands[2]))
11164         {
11165           if (get_attr_mode (insn) == MODE_SI)
11166             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11167           else
11168             return "sal{b}\t{%b2, %0|%0, %b2}";
11169         }
11170       else if (operands[2] == const1_rtx
11171                && (TARGET_SHIFT1 || optimize_size))
11172         {
11173           if (get_attr_mode (insn) == MODE_SI)
11174             return "sal{l}\t%0";
11175           else
11176             return "sal{b}\t%0";
11177         }
11178       else
11179         {
11180           if (get_attr_mode (insn) == MODE_SI)
11181             return "sal{l}\t{%2, %k0|%k0, %2}";
11182           else
11183             return "sal{b}\t{%2, %0|%0, %2}";
11184         }
11185     }
11187   [(set (attr "type")
11188      (cond [(eq_attr "alternative" "2")
11189               (const_string "lea")
11190             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11191                           (const_int 0))
11192                       (match_operand 0 "register_operand" ""))
11193                  (match_operand 2 "const1_operand" ""))
11194               (const_string "alu")
11195            ]
11196            (const_string "ishift")))
11197    (set_attr "mode" "QI,SI,SI")])
11199 (define_insn "*ashlqi3_1"
11200   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11201         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11202                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11203    (clobber (reg:CC FLAGS_REG))]
11204   "TARGET_PARTIAL_REG_STALL
11205    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11207   switch (get_attr_type (insn))
11208     {
11209     case TYPE_ALU:
11210       if (operands[2] != const1_rtx)
11211         abort ();
11212       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11213         return "add{l}\t{%k0, %k0|%k0, %k0}";
11214       else
11215         return "add{b}\t{%0, %0|%0, %0}";
11217     default:
11218       if (REG_P (operands[2]))
11219         {
11220           if (get_attr_mode (insn) == MODE_SI)
11221             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11222           else
11223             return "sal{b}\t{%b2, %0|%0, %b2}";
11224         }
11225       else if (operands[2] == const1_rtx
11226                && (TARGET_SHIFT1 || optimize_size))
11227         {
11228           if (get_attr_mode (insn) == MODE_SI)
11229             return "sal{l}\t%0";
11230           else
11231             return "sal{b}\t%0";
11232         }
11233       else
11234         {
11235           if (get_attr_mode (insn) == MODE_SI)
11236             return "sal{l}\t{%2, %k0|%k0, %2}";
11237           else
11238             return "sal{b}\t{%2, %0|%0, %2}";
11239         }
11240     }
11242   [(set (attr "type")
11243      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11244                           (const_int 0))
11245                       (match_operand 0 "register_operand" ""))
11246                  (match_operand 2 "const1_operand" ""))
11247               (const_string "alu")
11248            ]
11249            (const_string "ishift")))
11250    (set_attr "mode" "QI,SI")])
11252 ;; This pattern can't accept a variable shift count, since shifts by
11253 ;; zero don't affect the flags.  We assume that shifts by constant
11254 ;; zero are optimized away.
11255 (define_insn "*ashlqi3_cmp"
11256   [(set (reg 17)
11257         (compare
11258           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11259                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11260           (const_int 0)))
11261    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11262         (ashift:QI (match_dup 1) (match_dup 2)))]
11263   "ix86_match_ccmode (insn, CCGOCmode)
11264    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11266   switch (get_attr_type (insn))
11267     {
11268     case TYPE_ALU:
11269       if (operands[2] != const1_rtx)
11270         abort ();
11271       return "add{b}\t{%0, %0|%0, %0}";
11273     default:
11274       if (REG_P (operands[2]))
11275         return "sal{b}\t{%b2, %0|%0, %b2}";
11276       else if (operands[2] == const1_rtx
11277                && (TARGET_SHIFT1 || optimize_size))
11278         return "sal{b}\t%0";
11279       else
11280         return "sal{b}\t{%2, %0|%0, %2}";
11281     }
11283   [(set (attr "type")
11284      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11285                           (const_int 0))
11286                       (match_operand 0 "register_operand" ""))
11287                  (match_operand 2 "const1_operand" ""))
11288               (const_string "alu")
11289            ]
11290            (const_string "ishift")))
11291    (set_attr "mode" "QI")])
11293 ;; See comment above `ashldi3' about how this works.
11295 (define_expand "ashrdi3"
11296   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11297                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11298                                 (match_operand:QI 2 "nonmemory_operand" "")))
11299               (clobber (reg:CC FLAGS_REG))])]
11300   ""
11302   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11303     {
11304       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11305       DONE;
11306     }
11307   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11308   DONE;
11311 (define_insn "ashrdi3_63_rex64"
11312   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11313         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11314                      (match_operand:DI 2 "const_int_operand" "i,i")))
11315    (clobber (reg:CC FLAGS_REG))]
11316   "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11317    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11318   "@
11319    {cqto|cqo}
11320    sar{q}\t{%2, %0|%0, %2}"
11321   [(set_attr "type" "imovx,ishift")
11322    (set_attr "prefix_0f" "0,*")
11323    (set_attr "length_immediate" "0,*")
11324    (set_attr "modrm" "0,1")
11325    (set_attr "mode" "DI")])
11327 (define_insn "*ashrdi3_1_one_bit_rex64"
11328   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11329         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11330                      (match_operand:QI 2 "const1_operand" "")))
11331    (clobber (reg:CC FLAGS_REG))]
11332   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11333    && (TARGET_SHIFT1 || optimize_size)"
11334   "sar{q}\t%0"
11335   [(set_attr "type" "ishift")
11336    (set (attr "length") 
11337      (if_then_else (match_operand:DI 0 "register_operand" "") 
11338         (const_string "2")
11339         (const_string "*")))])
11341 (define_insn "*ashrdi3_1_rex64"
11342   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11343         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11344                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11345    (clobber (reg:CC FLAGS_REG))]
11346   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11347   "@
11348    sar{q}\t{%2, %0|%0, %2}
11349    sar{q}\t{%b2, %0|%0, %b2}"
11350   [(set_attr "type" "ishift")
11351    (set_attr "mode" "DI")])
11353 ;; This pattern can't accept a variable shift count, since shifts by
11354 ;; zero don't affect the flags.  We assume that shifts by constant
11355 ;; zero are optimized away.
11356 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11357   [(set (reg 17)
11358         (compare
11359           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11360                        (match_operand:QI 2 "const1_operand" ""))
11361           (const_int 0)))
11362    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11363         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11364   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11365    && (TARGET_SHIFT1 || optimize_size)
11366    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11367   "sar{q}\t%0"
11368   [(set_attr "type" "ishift")
11369    (set (attr "length") 
11370      (if_then_else (match_operand:DI 0 "register_operand" "") 
11371         (const_string "2")
11372         (const_string "*")))])
11374 ;; This pattern can't accept a variable shift count, since shifts by
11375 ;; zero don't affect the flags.  We assume that shifts by constant
11376 ;; zero are optimized away.
11377 (define_insn "*ashrdi3_cmp_rex64"
11378   [(set (reg 17)
11379         (compare
11380           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11381                        (match_operand:QI 2 "const_int_operand" "n"))
11382           (const_int 0)))
11383    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11384         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11385   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11386    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11387   "sar{q}\t{%2, %0|%0, %2}"
11388   [(set_attr "type" "ishift")
11389    (set_attr "mode" "DI")])
11392 (define_insn "ashrdi3_1"
11393   [(set (match_operand:DI 0 "register_operand" "=r")
11394         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11395                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11396    (clobber (match_scratch:SI 3 "=&r"))
11397    (clobber (reg:CC FLAGS_REG))]
11398   "!TARGET_64BIT && TARGET_CMOVE"
11399   "#"
11400   [(set_attr "type" "multi")])
11402 (define_insn "*ashrdi3_2"
11403   [(set (match_operand:DI 0 "register_operand" "=r")
11404         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11405                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11406    (clobber (reg:CC FLAGS_REG))]
11407   "!TARGET_64BIT"
11408   "#"
11409   [(set_attr "type" "multi")])
11411 (define_split
11412   [(set (match_operand:DI 0 "register_operand" "")
11413         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11414                      (match_operand:QI 2 "nonmemory_operand" "")))
11415    (clobber (match_scratch:SI 3 ""))
11416    (clobber (reg:CC FLAGS_REG))]
11417   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11418   [(const_int 0)]
11419   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11421 (define_split
11422   [(set (match_operand:DI 0 "register_operand" "")
11423         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11424                      (match_operand:QI 2 "nonmemory_operand" "")))
11425    (clobber (reg:CC FLAGS_REG))]
11426   "!TARGET_64BIT && reload_completed"
11427   [(const_int 0)]
11428   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11430 (define_insn "x86_shrd_1"
11431   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11432         (ior:SI (ashiftrt:SI (match_dup 0)
11433                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11434                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11435                   (minus:QI (const_int 32) (match_dup 2)))))
11436    (clobber (reg:CC FLAGS_REG))]
11437   ""
11438   "@
11439    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11440    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11441   [(set_attr "type" "ishift")
11442    (set_attr "prefix_0f" "1")
11443    (set_attr "pent_pair" "np")
11444    (set_attr "mode" "SI")])
11446 (define_expand "x86_shift_adj_3"
11447   [(use (match_operand:SI 0 "register_operand" ""))
11448    (use (match_operand:SI 1 "register_operand" ""))
11449    (use (match_operand:QI 2 "register_operand" ""))]
11450   ""
11452   rtx label = gen_label_rtx ();
11453   rtx tmp;
11455   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11457   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11458   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11459   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11460                               gen_rtx_LABEL_REF (VOIDmode, label),
11461                               pc_rtx);
11462   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11463   JUMP_LABEL (tmp) = label;
11465   emit_move_insn (operands[0], operands[1]);
11466   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11468   emit_label (label);
11469   LABEL_NUSES (label) = 1;
11471   DONE;
11474 (define_insn "ashrsi3_31"
11475   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11476         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11477                      (match_operand:SI 2 "const_int_operand" "i,i")))
11478    (clobber (reg:CC FLAGS_REG))]
11479   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11480    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11481   "@
11482    {cltd|cdq}
11483    sar{l}\t{%2, %0|%0, %2}"
11484   [(set_attr "type" "imovx,ishift")
11485    (set_attr "prefix_0f" "0,*")
11486    (set_attr "length_immediate" "0,*")
11487    (set_attr "modrm" "0,1")
11488    (set_attr "mode" "SI")])
11490 (define_insn "*ashrsi3_31_zext"
11491   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11492         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11493                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11494    (clobber (reg:CC FLAGS_REG))]
11495   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11496    && INTVAL (operands[2]) == 31
11497    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11498   "@
11499    {cltd|cdq}
11500    sar{l}\t{%2, %k0|%k0, %2}"
11501   [(set_attr "type" "imovx,ishift")
11502    (set_attr "prefix_0f" "0,*")
11503    (set_attr "length_immediate" "0,*")
11504    (set_attr "modrm" "0,1")
11505    (set_attr "mode" "SI")])
11507 (define_expand "ashrsi3"
11508   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11509         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11510                      (match_operand:QI 2 "nonmemory_operand" "")))
11511    (clobber (reg:CC FLAGS_REG))]
11512   ""
11513   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11515 (define_insn "*ashrsi3_1_one_bit"
11516   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11517         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11518                      (match_operand:QI 2 "const1_operand" "")))
11519    (clobber (reg:CC FLAGS_REG))]
11520   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11521    && (TARGET_SHIFT1 || optimize_size)"
11522   "sar{l}\t%0"
11523   [(set_attr "type" "ishift")
11524    (set (attr "length") 
11525      (if_then_else (match_operand:SI 0 "register_operand" "") 
11526         (const_string "2")
11527         (const_string "*")))])
11529 (define_insn "*ashrsi3_1_one_bit_zext"
11530   [(set (match_operand:DI 0 "register_operand" "=r")
11531         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11532                                      (match_operand:QI 2 "const1_operand" ""))))
11533    (clobber (reg:CC FLAGS_REG))]
11534   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11535    && (TARGET_SHIFT1 || optimize_size)"
11536   "sar{l}\t%k0"
11537   [(set_attr "type" "ishift")
11538    (set_attr "length" "2")])
11540 (define_insn "*ashrsi3_1"
11541   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11542         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11543                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11544    (clobber (reg:CC FLAGS_REG))]
11545   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11546   "@
11547    sar{l}\t{%2, %0|%0, %2}
11548    sar{l}\t{%b2, %0|%0, %b2}"
11549   [(set_attr "type" "ishift")
11550    (set_attr "mode" "SI")])
11552 (define_insn "*ashrsi3_1_zext"
11553   [(set (match_operand:DI 0 "register_operand" "=r,r")
11554         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11555                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11556    (clobber (reg:CC FLAGS_REG))]
11557   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558   "@
11559    sar{l}\t{%2, %k0|%k0, %2}
11560    sar{l}\t{%b2, %k0|%k0, %b2}"
11561   [(set_attr "type" "ishift")
11562    (set_attr "mode" "SI")])
11564 ;; This pattern can't accept a variable shift count, since shifts by
11565 ;; zero don't affect the flags.  We assume that shifts by constant
11566 ;; zero are optimized away.
11567 (define_insn "*ashrsi3_one_bit_cmp"
11568   [(set (reg 17)
11569         (compare
11570           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11571                        (match_operand:QI 2 "const1_operand" ""))
11572           (const_int 0)))
11573    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11574         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11575   "ix86_match_ccmode (insn, CCGOCmode)
11576    && (TARGET_SHIFT1 || optimize_size)
11577    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11578   "sar{l}\t%0"
11579   [(set_attr "type" "ishift")
11580    (set (attr "length") 
11581      (if_then_else (match_operand:SI 0 "register_operand" "") 
11582         (const_string "2")
11583         (const_string "*")))])
11585 (define_insn "*ashrsi3_one_bit_cmp_zext"
11586   [(set (reg 17)
11587         (compare
11588           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11589                        (match_operand:QI 2 "const1_operand" ""))
11590           (const_int 0)))
11591    (set (match_operand:DI 0 "register_operand" "=r")
11592         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11593   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11594    && (TARGET_SHIFT1 || optimize_size)
11595    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11596   "sar{l}\t%k0"
11597   [(set_attr "type" "ishift")
11598    (set_attr "length" "2")])
11600 ;; This pattern can't accept a variable shift count, since shifts by
11601 ;; zero don't affect the flags.  We assume that shifts by constant
11602 ;; zero are optimized away.
11603 (define_insn "*ashrsi3_cmp"
11604   [(set (reg 17)
11605         (compare
11606           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11607                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11608           (const_int 0)))
11609    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11610         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11611   "ix86_match_ccmode (insn, CCGOCmode)
11612    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11613   "sar{l}\t{%2, %0|%0, %2}"
11614   [(set_attr "type" "ishift")
11615    (set_attr "mode" "SI")])
11617 (define_insn "*ashrsi3_cmp_zext"
11618   [(set (reg 17)
11619         (compare
11620           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11621                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11622           (const_int 0)))
11623    (set (match_operand:DI 0 "register_operand" "=r")
11624         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11625   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11626    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11627   "sar{l}\t{%2, %k0|%k0, %2}"
11628   [(set_attr "type" "ishift")
11629    (set_attr "mode" "SI")])
11631 (define_expand "ashrhi3"
11632   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11633         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11634                      (match_operand:QI 2 "nonmemory_operand" "")))
11635    (clobber (reg:CC FLAGS_REG))]
11636   "TARGET_HIMODE_MATH"
11637   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11639 (define_insn "*ashrhi3_1_one_bit"
11640   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11641         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11642                      (match_operand:QI 2 "const1_operand" "")))
11643    (clobber (reg:CC FLAGS_REG))]
11644   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11645    && (TARGET_SHIFT1 || optimize_size)"
11646   "sar{w}\t%0"
11647   [(set_attr "type" "ishift")
11648    (set (attr "length") 
11649      (if_then_else (match_operand 0 "register_operand" "") 
11650         (const_string "2")
11651         (const_string "*")))])
11653 (define_insn "*ashrhi3_1"
11654   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11655         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11656                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11657    (clobber (reg:CC FLAGS_REG))]
11658   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11659   "@
11660    sar{w}\t{%2, %0|%0, %2}
11661    sar{w}\t{%b2, %0|%0, %b2}"
11662   [(set_attr "type" "ishift")
11663    (set_attr "mode" "HI")])
11665 ;; This pattern can't accept a variable shift count, since shifts by
11666 ;; zero don't affect the flags.  We assume that shifts by constant
11667 ;; zero are optimized away.
11668 (define_insn "*ashrhi3_one_bit_cmp"
11669   [(set (reg 17)
11670         (compare
11671           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11672                        (match_operand:QI 2 "const1_operand" ""))
11673           (const_int 0)))
11674    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11675         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11676   "ix86_match_ccmode (insn, CCGOCmode)
11677    && (TARGET_SHIFT1 || optimize_size)
11678    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11679   "sar{w}\t%0"
11680   [(set_attr "type" "ishift")
11681    (set (attr "length") 
11682      (if_then_else (match_operand 0 "register_operand" "") 
11683         (const_string "2")
11684         (const_string "*")))])
11686 ;; This pattern can't accept a variable shift count, since shifts by
11687 ;; zero don't affect the flags.  We assume that shifts by constant
11688 ;; zero are optimized away.
11689 (define_insn "*ashrhi3_cmp"
11690   [(set (reg 17)
11691         (compare
11692           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11693                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11694           (const_int 0)))
11695    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11696         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11697   "ix86_match_ccmode (insn, CCGOCmode)
11698    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11699   "sar{w}\t{%2, %0|%0, %2}"
11700   [(set_attr "type" "ishift")
11701    (set_attr "mode" "HI")])
11703 (define_expand "ashrqi3"
11704   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11705         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11706                      (match_operand:QI 2 "nonmemory_operand" "")))
11707    (clobber (reg:CC FLAGS_REG))]
11708   "TARGET_QIMODE_MATH"
11709   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11711 (define_insn "*ashrqi3_1_one_bit"
11712   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11713         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11714                      (match_operand:QI 2 "const1_operand" "")))
11715    (clobber (reg:CC FLAGS_REG))]
11716   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11717    && (TARGET_SHIFT1 || optimize_size)"
11718   "sar{b}\t%0"
11719   [(set_attr "type" "ishift")
11720    (set (attr "length") 
11721      (if_then_else (match_operand 0 "register_operand" "") 
11722         (const_string "2")
11723         (const_string "*")))])
11725 (define_insn "*ashrqi3_1_one_bit_slp"
11726   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11727         (ashiftrt:QI (match_dup 0)
11728                      (match_operand:QI 1 "const1_operand" "")))
11729    (clobber (reg:CC FLAGS_REG))]
11730   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11731    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11732    && (TARGET_SHIFT1 || optimize_size)"
11733   "sar{b}\t%0"
11734   [(set_attr "type" "ishift1")
11735    (set (attr "length") 
11736      (if_then_else (match_operand 0 "register_operand" "") 
11737         (const_string "2")
11738         (const_string "*")))])
11740 (define_insn "*ashrqi3_1"
11741   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11742         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11743                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11744    (clobber (reg:CC FLAGS_REG))]
11745   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11746   "@
11747    sar{b}\t{%2, %0|%0, %2}
11748    sar{b}\t{%b2, %0|%0, %b2}"
11749   [(set_attr "type" "ishift")
11750    (set_attr "mode" "QI")])
11752 (define_insn "*ashrqi3_1_slp"
11753   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11754         (ashiftrt:QI (match_dup 0)
11755                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11756    (clobber (reg:CC FLAGS_REG))]
11757   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11758    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11759   "@
11760    sar{b}\t{%1, %0|%0, %1}
11761    sar{b}\t{%b1, %0|%0, %b1}"
11762   [(set_attr "type" "ishift1")
11763    (set_attr "mode" "QI")])
11765 ;; This pattern can't accept a variable shift count, since shifts by
11766 ;; zero don't affect the flags.  We assume that shifts by constant
11767 ;; zero are optimized away.
11768 (define_insn "*ashrqi3_one_bit_cmp"
11769   [(set (reg 17)
11770         (compare
11771           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11772                        (match_operand:QI 2 "const1_operand" "I"))
11773           (const_int 0)))
11774    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11775         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11776   "ix86_match_ccmode (insn, CCGOCmode)
11777    && (TARGET_SHIFT1 || optimize_size)
11778    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11779   "sar{b}\t%0"
11780   [(set_attr "type" "ishift")
11781    (set (attr "length") 
11782      (if_then_else (match_operand 0 "register_operand" "") 
11783         (const_string "2")
11784         (const_string "*")))])
11786 ;; This pattern can't accept a variable shift count, since shifts by
11787 ;; zero don't affect the flags.  We assume that shifts by constant
11788 ;; zero are optimized away.
11789 (define_insn "*ashrqi3_cmp"
11790   [(set (reg 17)
11791         (compare
11792           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11793                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11794           (const_int 0)))
11795    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11796         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11797   "ix86_match_ccmode (insn, CCGOCmode)
11798    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11799   "sar{b}\t{%2, %0|%0, %2}"
11800   [(set_attr "type" "ishift")
11801    (set_attr "mode" "QI")])
11803 ;; Logical shift instructions
11805 ;; See comment above `ashldi3' about how this works.
11807 (define_expand "lshrdi3"
11808   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11809                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11810                                 (match_operand:QI 2 "nonmemory_operand" "")))
11811               (clobber (reg:CC FLAGS_REG))])]
11812   ""
11814   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11815     {
11816       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11817       DONE;
11818     }
11819   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11820   DONE;
11823 (define_insn "*lshrdi3_1_one_bit_rex64"
11824   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11825         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11826                      (match_operand:QI 2 "const1_operand" "")))
11827    (clobber (reg:CC FLAGS_REG))]
11828   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11829    && (TARGET_SHIFT1 || optimize_size)"
11830   "shr{q}\t%0"
11831   [(set_attr "type" "ishift")
11832    (set (attr "length") 
11833      (if_then_else (match_operand:DI 0 "register_operand" "") 
11834         (const_string "2")
11835         (const_string "*")))])
11837 (define_insn "*lshrdi3_1_rex64"
11838   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11839         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11840                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11841    (clobber (reg:CC FLAGS_REG))]
11842   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11843   "@
11844    shr{q}\t{%2, %0|%0, %2}
11845    shr{q}\t{%b2, %0|%0, %b2}"
11846   [(set_attr "type" "ishift")
11847    (set_attr "mode" "DI")])
11849 ;; This pattern can't accept a variable shift count, since shifts by
11850 ;; zero don't affect the flags.  We assume that shifts by constant
11851 ;; zero are optimized away.
11852 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11853   [(set (reg 17)
11854         (compare
11855           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11856                        (match_operand:QI 2 "const1_operand" ""))
11857           (const_int 0)))
11858    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11859         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11860   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11861    && (TARGET_SHIFT1 || optimize_size)
11862    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11863   "shr{q}\t%0"
11864   [(set_attr "type" "ishift")
11865    (set (attr "length") 
11866      (if_then_else (match_operand:DI 0 "register_operand" "") 
11867         (const_string "2")
11868         (const_string "*")))])
11870 ;; This pattern can't accept a variable shift count, since shifts by
11871 ;; zero don't affect the flags.  We assume that shifts by constant
11872 ;; zero are optimized away.
11873 (define_insn "*lshrdi3_cmp_rex64"
11874   [(set (reg 17)
11875         (compare
11876           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11877                        (match_operand:QI 2 "const_int_operand" "e"))
11878           (const_int 0)))
11879    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11880         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11881   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11882    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11883   "shr{q}\t{%2, %0|%0, %2}"
11884   [(set_attr "type" "ishift")
11885    (set_attr "mode" "DI")])
11887 (define_insn "lshrdi3_1"
11888   [(set (match_operand:DI 0 "register_operand" "=r")
11889         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11890                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11891    (clobber (match_scratch:SI 3 "=&r"))
11892    (clobber (reg:CC FLAGS_REG))]
11893   "!TARGET_64BIT && TARGET_CMOVE"
11894   "#"
11895   [(set_attr "type" "multi")])
11897 (define_insn "*lshrdi3_2"
11898   [(set (match_operand:DI 0 "register_operand" "=r")
11899         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11900                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11901    (clobber (reg:CC FLAGS_REG))]
11902   "!TARGET_64BIT"
11903   "#"
11904   [(set_attr "type" "multi")])
11906 (define_split 
11907   [(set (match_operand:DI 0 "register_operand" "")
11908         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11909                      (match_operand:QI 2 "nonmemory_operand" "")))
11910    (clobber (match_scratch:SI 3 ""))
11911    (clobber (reg:CC FLAGS_REG))]
11912   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11913   [(const_int 0)]
11914   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11916 (define_split 
11917   [(set (match_operand:DI 0 "register_operand" "")
11918         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11919                      (match_operand:QI 2 "nonmemory_operand" "")))
11920    (clobber (reg:CC FLAGS_REG))]
11921   "!TARGET_64BIT && reload_completed"
11922   [(const_int 0)]
11923   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11925 (define_expand "lshrsi3"
11926   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11927         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11928                      (match_operand:QI 2 "nonmemory_operand" "")))
11929    (clobber (reg:CC FLAGS_REG))]
11930   ""
11931   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11933 (define_insn "*lshrsi3_1_one_bit"
11934   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11935         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11936                      (match_operand:QI 2 "const1_operand" "")))
11937    (clobber (reg:CC FLAGS_REG))]
11938   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11939    && (TARGET_SHIFT1 || optimize_size)"
11940   "shr{l}\t%0"
11941   [(set_attr "type" "ishift")
11942    (set (attr "length") 
11943      (if_then_else (match_operand:SI 0 "register_operand" "") 
11944         (const_string "2")
11945         (const_string "*")))])
11947 (define_insn "*lshrsi3_1_one_bit_zext"
11948   [(set (match_operand:DI 0 "register_operand" "=r")
11949         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11950                      (match_operand:QI 2 "const1_operand" "")))
11951    (clobber (reg:CC FLAGS_REG))]
11952   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11953    && (TARGET_SHIFT1 || optimize_size)"
11954   "shr{l}\t%k0"
11955   [(set_attr "type" "ishift")
11956    (set_attr "length" "2")])
11958 (define_insn "*lshrsi3_1"
11959   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11960         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11961                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11962    (clobber (reg:CC FLAGS_REG))]
11963   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11964   "@
11965    shr{l}\t{%2, %0|%0, %2}
11966    shr{l}\t{%b2, %0|%0, %b2}"
11967   [(set_attr "type" "ishift")
11968    (set_attr "mode" "SI")])
11970 (define_insn "*lshrsi3_1_zext"
11971   [(set (match_operand:DI 0 "register_operand" "=r,r")
11972         (zero_extend:DI
11973           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11974                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11975    (clobber (reg:CC FLAGS_REG))]
11976   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11977   "@
11978    shr{l}\t{%2, %k0|%k0, %2}
11979    shr{l}\t{%b2, %k0|%k0, %b2}"
11980   [(set_attr "type" "ishift")
11981    (set_attr "mode" "SI")])
11983 ;; This pattern can't accept a variable shift count, since shifts by
11984 ;; zero don't affect the flags.  We assume that shifts by constant
11985 ;; zero are optimized away.
11986 (define_insn "*lshrsi3_one_bit_cmp"
11987   [(set (reg 17)
11988         (compare
11989           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11990                        (match_operand:QI 2 "const1_operand" ""))
11991           (const_int 0)))
11992    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11993         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11994   "ix86_match_ccmode (insn, CCGOCmode)
11995    && (TARGET_SHIFT1 || optimize_size)
11996    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11997   "shr{l}\t%0"
11998   [(set_attr "type" "ishift")
11999    (set (attr "length") 
12000      (if_then_else (match_operand:SI 0 "register_operand" "") 
12001         (const_string "2")
12002         (const_string "*")))])
12004 (define_insn "*lshrsi3_cmp_one_bit_zext"
12005   [(set (reg 17)
12006         (compare
12007           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12008                        (match_operand:QI 2 "const1_operand" ""))
12009           (const_int 0)))
12010    (set (match_operand:DI 0 "register_operand" "=r")
12011         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12012   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12013    && (TARGET_SHIFT1 || optimize_size)
12014    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12015   "shr{l}\t%k0"
12016   [(set_attr "type" "ishift")
12017    (set_attr "length" "2")])
12019 ;; This pattern can't accept a variable shift count, since shifts by
12020 ;; zero don't affect the flags.  We assume that shifts by constant
12021 ;; zero are optimized away.
12022 (define_insn "*lshrsi3_cmp"
12023   [(set (reg 17)
12024         (compare
12025           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12026                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12027           (const_int 0)))
12028    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12029         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12030   "ix86_match_ccmode (insn, CCGOCmode)
12031    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12032   "shr{l}\t{%2, %0|%0, %2}"
12033   [(set_attr "type" "ishift")
12034    (set_attr "mode" "SI")])
12036 (define_insn "*lshrsi3_cmp_zext"
12037   [(set (reg 17)
12038         (compare
12039           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12040                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12041           (const_int 0)))
12042    (set (match_operand:DI 0 "register_operand" "=r")
12043         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12044   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12045    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12046   "shr{l}\t{%2, %k0|%k0, %2}"
12047   [(set_attr "type" "ishift")
12048    (set_attr "mode" "SI")])
12050 (define_expand "lshrhi3"
12051   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12052         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12053                      (match_operand:QI 2 "nonmemory_operand" "")))
12054    (clobber (reg:CC FLAGS_REG))]
12055   "TARGET_HIMODE_MATH"
12056   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12058 (define_insn "*lshrhi3_1_one_bit"
12059   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12060         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12061                      (match_operand:QI 2 "const1_operand" "")))
12062    (clobber (reg:CC FLAGS_REG))]
12063   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12064    && (TARGET_SHIFT1 || optimize_size)"
12065   "shr{w}\t%0"
12066   [(set_attr "type" "ishift")
12067    (set (attr "length") 
12068      (if_then_else (match_operand 0 "register_operand" "") 
12069         (const_string "2")
12070         (const_string "*")))])
12072 (define_insn "*lshrhi3_1"
12073   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12074         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12075                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12076    (clobber (reg:CC FLAGS_REG))]
12077   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12078   "@
12079    shr{w}\t{%2, %0|%0, %2}
12080    shr{w}\t{%b2, %0|%0, %b2}"
12081   [(set_attr "type" "ishift")
12082    (set_attr "mode" "HI")])
12084 ;; This pattern can't accept a variable shift count, since shifts by
12085 ;; zero don't affect the flags.  We assume that shifts by constant
12086 ;; zero are optimized away.
12087 (define_insn "*lshrhi3_one_bit_cmp"
12088   [(set (reg 17)
12089         (compare
12090           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12091                        (match_operand:QI 2 "const1_operand" ""))
12092           (const_int 0)))
12093    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12094         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12095   "ix86_match_ccmode (insn, CCGOCmode)
12096    && (TARGET_SHIFT1 || optimize_size)
12097    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12098   "shr{w}\t%0"
12099   [(set_attr "type" "ishift")
12100    (set (attr "length") 
12101      (if_then_else (match_operand:SI 0 "register_operand" "") 
12102         (const_string "2")
12103         (const_string "*")))])
12105 ;; This pattern can't accept a variable shift count, since shifts by
12106 ;; zero don't affect the flags.  We assume that shifts by constant
12107 ;; zero are optimized away.
12108 (define_insn "*lshrhi3_cmp"
12109   [(set (reg 17)
12110         (compare
12111           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12112                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12113           (const_int 0)))
12114    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12115         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12116   "ix86_match_ccmode (insn, CCGOCmode)
12117    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12118   "shr{w}\t{%2, %0|%0, %2}"
12119   [(set_attr "type" "ishift")
12120    (set_attr "mode" "HI")])
12122 (define_expand "lshrqi3"
12123   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12124         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12125                      (match_operand:QI 2 "nonmemory_operand" "")))
12126    (clobber (reg:CC FLAGS_REG))]
12127   "TARGET_QIMODE_MATH"
12128   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12130 (define_insn "*lshrqi3_1_one_bit"
12131   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12132         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12133                      (match_operand:QI 2 "const1_operand" "")))
12134    (clobber (reg:CC FLAGS_REG))]
12135   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12136    && (TARGET_SHIFT1 || optimize_size)"
12137   "shr{b}\t%0"
12138   [(set_attr "type" "ishift")
12139    (set (attr "length") 
12140      (if_then_else (match_operand 0 "register_operand" "") 
12141         (const_string "2")
12142         (const_string "*")))])
12144 (define_insn "*lshrqi3_1_one_bit_slp"
12145   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12146         (lshiftrt:QI (match_dup 0)
12147                      (match_operand:QI 1 "const1_operand" "")))
12148    (clobber (reg:CC FLAGS_REG))]
12149   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12150    && (TARGET_SHIFT1 || optimize_size)"
12151   "shr{b}\t%0"
12152   [(set_attr "type" "ishift1")
12153    (set (attr "length") 
12154      (if_then_else (match_operand 0 "register_operand" "") 
12155         (const_string "2")
12156         (const_string "*")))])
12158 (define_insn "*lshrqi3_1"
12159   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12160         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12161                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12164   "@
12165    shr{b}\t{%2, %0|%0, %2}
12166    shr{b}\t{%b2, %0|%0, %b2}"
12167   [(set_attr "type" "ishift")
12168    (set_attr "mode" "QI")])
12170 (define_insn "*lshrqi3_1_slp"
12171   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12172         (lshiftrt:QI (match_dup 0)
12173                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12174    (clobber (reg:CC FLAGS_REG))]
12175   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12176    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12177   "@
12178    shr{b}\t{%1, %0|%0, %1}
12179    shr{b}\t{%b1, %0|%0, %b1}"
12180   [(set_attr "type" "ishift1")
12181    (set_attr "mode" "QI")])
12183 ;; This pattern can't accept a variable shift count, since shifts by
12184 ;; zero don't affect the flags.  We assume that shifts by constant
12185 ;; zero are optimized away.
12186 (define_insn "*lshrqi2_one_bit_cmp"
12187   [(set (reg 17)
12188         (compare
12189           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12190                        (match_operand:QI 2 "const1_operand" ""))
12191           (const_int 0)))
12192    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12193         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12194   "ix86_match_ccmode (insn, CCGOCmode)
12195    && (TARGET_SHIFT1 || optimize_size)
12196    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12197   "shr{b}\t%0"
12198   [(set_attr "type" "ishift")
12199    (set (attr "length") 
12200      (if_then_else (match_operand:SI 0 "register_operand" "") 
12201         (const_string "2")
12202         (const_string "*")))])
12204 ;; This pattern can't accept a variable shift count, since shifts by
12205 ;; zero don't affect the flags.  We assume that shifts by constant
12206 ;; zero are optimized away.
12207 (define_insn "*lshrqi2_cmp"
12208   [(set (reg 17)
12209         (compare
12210           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12211                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12212           (const_int 0)))
12213    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12214         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12215   "ix86_match_ccmode (insn, CCGOCmode)
12216    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12217   "shr{b}\t{%2, %0|%0, %2}"
12218   [(set_attr "type" "ishift")
12219    (set_attr "mode" "QI")])
12221 ;; Rotate instructions
12223 (define_expand "rotldi3"
12224   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12225         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12226                    (match_operand:QI 2 "nonmemory_operand" "")))
12227    (clobber (reg:CC FLAGS_REG))]
12228   "TARGET_64BIT"
12229   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12231 (define_insn "*rotlsi3_1_one_bit_rex64"
12232   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12233         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12234                    (match_operand:QI 2 "const1_operand" "")))
12235    (clobber (reg:CC FLAGS_REG))]
12236   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12237    && (TARGET_SHIFT1 || optimize_size)"
12238   "rol{q}\t%0"
12239   [(set_attr "type" "rotate")
12240    (set (attr "length") 
12241      (if_then_else (match_operand:DI 0 "register_operand" "") 
12242         (const_string "2")
12243         (const_string "*")))])
12245 (define_insn "*rotldi3_1_rex64"
12246   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12247         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12248                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12249    (clobber (reg:CC FLAGS_REG))]
12250   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12251   "@
12252    rol{q}\t{%2, %0|%0, %2}
12253    rol{q}\t{%b2, %0|%0, %b2}"
12254   [(set_attr "type" "rotate")
12255    (set_attr "mode" "DI")])
12257 (define_expand "rotlsi3"
12258   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12259         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12260                    (match_operand:QI 2 "nonmemory_operand" "")))
12261    (clobber (reg:CC FLAGS_REG))]
12262   ""
12263   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12265 (define_insn "*rotlsi3_1_one_bit"
12266   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12267         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12268                    (match_operand:QI 2 "const1_operand" "")))
12269    (clobber (reg:CC FLAGS_REG))]
12270   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12271    && (TARGET_SHIFT1 || optimize_size)"
12272   "rol{l}\t%0"
12273   [(set_attr "type" "rotate")
12274    (set (attr "length") 
12275      (if_then_else (match_operand:SI 0 "register_operand" "") 
12276         (const_string "2")
12277         (const_string "*")))])
12279 (define_insn "*rotlsi3_1_one_bit_zext"
12280   [(set (match_operand:DI 0 "register_operand" "=r")
12281         (zero_extend:DI
12282           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12283                      (match_operand:QI 2 "const1_operand" ""))))
12284    (clobber (reg:CC FLAGS_REG))]
12285   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12286    && (TARGET_SHIFT1 || optimize_size)"
12287   "rol{l}\t%k0"
12288   [(set_attr "type" "rotate")
12289    (set_attr "length" "2")])
12291 (define_insn "*rotlsi3_1"
12292   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12293         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12294                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12295    (clobber (reg:CC FLAGS_REG))]
12296   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12297   "@
12298    rol{l}\t{%2, %0|%0, %2}
12299    rol{l}\t{%b2, %0|%0, %b2}"
12300   [(set_attr "type" "rotate")
12301    (set_attr "mode" "SI")])
12303 (define_insn "*rotlsi3_1_zext"
12304   [(set (match_operand:DI 0 "register_operand" "=r,r")
12305         (zero_extend:DI
12306           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12307                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12308    (clobber (reg:CC FLAGS_REG))]
12309   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12310   "@
12311    rol{l}\t{%2, %k0|%k0, %2}
12312    rol{l}\t{%b2, %k0|%k0, %b2}"
12313   [(set_attr "type" "rotate")
12314    (set_attr "mode" "SI")])
12316 (define_expand "rotlhi3"
12317   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12318         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12319                    (match_operand:QI 2 "nonmemory_operand" "")))
12320    (clobber (reg:CC FLAGS_REG))]
12321   "TARGET_HIMODE_MATH"
12322   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12324 (define_insn "*rotlhi3_1_one_bit"
12325   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12326         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12327                    (match_operand:QI 2 "const1_operand" "")))
12328    (clobber (reg:CC FLAGS_REG))]
12329   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12330    && (TARGET_SHIFT1 || optimize_size)"
12331   "rol{w}\t%0"
12332   [(set_attr "type" "rotate")
12333    (set (attr "length") 
12334      (if_then_else (match_operand 0 "register_operand" "") 
12335         (const_string "2")
12336         (const_string "*")))])
12338 (define_insn "*rotlhi3_1"
12339   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12340         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12341                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12342    (clobber (reg:CC FLAGS_REG))]
12343   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12344   "@
12345    rol{w}\t{%2, %0|%0, %2}
12346    rol{w}\t{%b2, %0|%0, %b2}"
12347   [(set_attr "type" "rotate")
12348    (set_attr "mode" "HI")])
12350 (define_expand "rotlqi3"
12351   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12352         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12353                    (match_operand:QI 2 "nonmemory_operand" "")))
12354    (clobber (reg:CC FLAGS_REG))]
12355   "TARGET_QIMODE_MATH"
12356   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12358 (define_insn "*rotlqi3_1_one_bit_slp"
12359   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12360         (rotate:QI (match_dup 0)
12361                    (match_operand:QI 1 "const1_operand" "")))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12364    && (TARGET_SHIFT1 || optimize_size)"
12365   "rol{b}\t%0"
12366   [(set_attr "type" "rotate1")
12367    (set (attr "length") 
12368      (if_then_else (match_operand 0 "register_operand" "") 
12369         (const_string "2")
12370         (const_string "*")))])
12372 (define_insn "*rotlqi3_1_one_bit"
12373   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12374         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12375                    (match_operand:QI 2 "const1_operand" "")))
12376    (clobber (reg:CC FLAGS_REG))]
12377   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12378    && (TARGET_SHIFT1 || optimize_size)"
12379   "rol{b}\t%0"
12380   [(set_attr "type" "rotate")
12381    (set (attr "length") 
12382      (if_then_else (match_operand 0 "register_operand" "") 
12383         (const_string "2")
12384         (const_string "*")))])
12386 (define_insn "*rotlqi3_1_slp"
12387   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12388         (rotate:QI (match_dup 0)
12389                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12390    (clobber (reg:CC FLAGS_REG))]
12391   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12392    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12393   "@
12394    rol{b}\t{%1, %0|%0, %1}
12395    rol{b}\t{%b1, %0|%0, %b1}"
12396   [(set_attr "type" "rotate1")
12397    (set_attr "mode" "QI")])
12399 (define_insn "*rotlqi3_1"
12400   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12401         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12402                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12403    (clobber (reg:CC FLAGS_REG))]
12404   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12405   "@
12406    rol{b}\t{%2, %0|%0, %2}
12407    rol{b}\t{%b2, %0|%0, %b2}"
12408   [(set_attr "type" "rotate")
12409    (set_attr "mode" "QI")])
12411 (define_expand "rotrdi3"
12412   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12413         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12414                      (match_operand:QI 2 "nonmemory_operand" "")))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "TARGET_64BIT"
12417   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12419 (define_insn "*rotrdi3_1_one_bit_rex64"
12420   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12421         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12422                      (match_operand:QI 2 "const1_operand" "")))
12423    (clobber (reg:CC FLAGS_REG))]
12424   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12425    && (TARGET_SHIFT1 || optimize_size)"
12426   "ror{q}\t%0"
12427   [(set_attr "type" "rotate")
12428    (set (attr "length") 
12429      (if_then_else (match_operand:DI 0 "register_operand" "") 
12430         (const_string "2")
12431         (const_string "*")))])
12433 (define_insn "*rotrdi3_1_rex64"
12434   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12435         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12436                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12437    (clobber (reg:CC FLAGS_REG))]
12438   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12439   "@
12440    ror{q}\t{%2, %0|%0, %2}
12441    ror{q}\t{%b2, %0|%0, %b2}"
12442   [(set_attr "type" "rotate")
12443    (set_attr "mode" "DI")])
12445 (define_expand "rotrsi3"
12446   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12447         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12448                      (match_operand:QI 2 "nonmemory_operand" "")))
12449    (clobber (reg:CC FLAGS_REG))]
12450   ""
12451   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12453 (define_insn "*rotrsi3_1_one_bit"
12454   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12455         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12456                      (match_operand:QI 2 "const1_operand" "")))
12457    (clobber (reg:CC FLAGS_REG))]
12458   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12459    && (TARGET_SHIFT1 || optimize_size)"
12460   "ror{l}\t%0"
12461   [(set_attr "type" "rotate")
12462    (set (attr "length") 
12463      (if_then_else (match_operand:SI 0 "register_operand" "") 
12464         (const_string "2")
12465         (const_string "*")))])
12467 (define_insn "*rotrsi3_1_one_bit_zext"
12468   [(set (match_operand:DI 0 "register_operand" "=r")
12469         (zero_extend:DI
12470           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12471                        (match_operand:QI 2 "const1_operand" ""))))
12472    (clobber (reg:CC FLAGS_REG))]
12473   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12474    && (TARGET_SHIFT1 || optimize_size)"
12475   "ror{l}\t%k0"
12476   [(set_attr "type" "rotate")
12477    (set (attr "length") 
12478      (if_then_else (match_operand:SI 0 "register_operand" "") 
12479         (const_string "2")
12480         (const_string "*")))])
12482 (define_insn "*rotrsi3_1"
12483   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12484         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12485                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12486    (clobber (reg:CC FLAGS_REG))]
12487   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12488   "@
12489    ror{l}\t{%2, %0|%0, %2}
12490    ror{l}\t{%b2, %0|%0, %b2}"
12491   [(set_attr "type" "rotate")
12492    (set_attr "mode" "SI")])
12494 (define_insn "*rotrsi3_1_zext"
12495   [(set (match_operand:DI 0 "register_operand" "=r,r")
12496         (zero_extend:DI
12497           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12498                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12499    (clobber (reg:CC FLAGS_REG))]
12500   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12501   "@
12502    ror{l}\t{%2, %k0|%k0, %2}
12503    ror{l}\t{%b2, %k0|%k0, %b2}"
12504   [(set_attr "type" "rotate")
12505    (set_attr "mode" "SI")])
12507 (define_expand "rotrhi3"
12508   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12509         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12510                      (match_operand:QI 2 "nonmemory_operand" "")))
12511    (clobber (reg:CC FLAGS_REG))]
12512   "TARGET_HIMODE_MATH"
12513   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12515 (define_insn "*rotrhi3_one_bit"
12516   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12517         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12518                      (match_operand:QI 2 "const1_operand" "")))
12519    (clobber (reg:CC FLAGS_REG))]
12520   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12521    && (TARGET_SHIFT1 || optimize_size)"
12522   "ror{w}\t%0"
12523   [(set_attr "type" "rotate")
12524    (set (attr "length") 
12525      (if_then_else (match_operand 0 "register_operand" "") 
12526         (const_string "2")
12527         (const_string "*")))])
12529 (define_insn "*rotrhi3"
12530   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12531         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12532                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12533    (clobber (reg:CC FLAGS_REG))]
12534   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12535   "@
12536    ror{w}\t{%2, %0|%0, %2}
12537    ror{w}\t{%b2, %0|%0, %b2}"
12538   [(set_attr "type" "rotate")
12539    (set_attr "mode" "HI")])
12541 (define_expand "rotrqi3"
12542   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12543         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12544                      (match_operand:QI 2 "nonmemory_operand" "")))
12545    (clobber (reg:CC FLAGS_REG))]
12546   "TARGET_QIMODE_MATH"
12547   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12549 (define_insn "*rotrqi3_1_one_bit"
12550   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12551         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12552                      (match_operand:QI 2 "const1_operand" "")))
12553    (clobber (reg:CC FLAGS_REG))]
12554   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12555    && (TARGET_SHIFT1 || optimize_size)"
12556   "ror{b}\t%0"
12557   [(set_attr "type" "rotate")
12558    (set (attr "length") 
12559      (if_then_else (match_operand 0 "register_operand" "") 
12560         (const_string "2")
12561         (const_string "*")))])
12563 (define_insn "*rotrqi3_1_one_bit_slp"
12564   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12565         (rotatert:QI (match_dup 0)
12566                      (match_operand:QI 1 "const1_operand" "")))
12567    (clobber (reg:CC FLAGS_REG))]
12568   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12569    && (TARGET_SHIFT1 || optimize_size)"
12570   "ror{b}\t%0"
12571   [(set_attr "type" "rotate1")
12572    (set (attr "length") 
12573      (if_then_else (match_operand 0 "register_operand" "") 
12574         (const_string "2")
12575         (const_string "*")))])
12577 (define_insn "*rotrqi3_1"
12578   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12579         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12580                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12581    (clobber (reg:CC FLAGS_REG))]
12582   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12583   "@
12584    ror{b}\t{%2, %0|%0, %2}
12585    ror{b}\t{%b2, %0|%0, %b2}"
12586   [(set_attr "type" "rotate")
12587    (set_attr "mode" "QI")])
12589 (define_insn "*rotrqi3_1_slp"
12590   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12591         (rotatert:QI (match_dup 0)
12592                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12593    (clobber (reg:CC FLAGS_REG))]
12594   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12595    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12596   "@
12597    ror{b}\t{%1, %0|%0, %1}
12598    ror{b}\t{%b1, %0|%0, %b1}"
12599   [(set_attr "type" "rotate1")
12600    (set_attr "mode" "QI")])
12602 ;; Bit set / bit test instructions
12604 (define_expand "extv"
12605   [(set (match_operand:SI 0 "register_operand" "")
12606         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12607                          (match_operand:SI 2 "immediate_operand" "")
12608                          (match_operand:SI 3 "immediate_operand" "")))]
12609   ""
12611   /* Handle extractions from %ah et al.  */
12612   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12613     FAIL;
12615   /* From mips.md: extract_bit_field doesn't verify that our source
12616      matches the predicate, so check it again here.  */
12617   if (! register_operand (operands[1], VOIDmode))
12618     FAIL;
12621 (define_expand "extzv"
12622   [(set (match_operand:SI 0 "register_operand" "")
12623         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12624                          (match_operand:SI 2 "immediate_operand" "")
12625                          (match_operand:SI 3 "immediate_operand" "")))]
12626   ""
12628   /* Handle extractions from %ah et al.  */
12629   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12630     FAIL;
12632   /* From mips.md: extract_bit_field doesn't verify that our source
12633      matches the predicate, so check it again here.  */
12634   if (! register_operand (operands[1], VOIDmode))
12635     FAIL;
12638 (define_expand "insv"
12639   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12640                       (match_operand 1 "immediate_operand" "")
12641                       (match_operand 2 "immediate_operand" ""))
12642         (match_operand 3 "register_operand" ""))]
12643   ""
12645   /* Handle extractions from %ah et al.  */
12646   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12647     FAIL;
12649   /* From mips.md: insert_bit_field doesn't verify that our source
12650      matches the predicate, so check it again here.  */
12651   if (! register_operand (operands[0], VOIDmode))
12652     FAIL;
12654   if (TARGET_64BIT)
12655     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12656   else
12657     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12659   DONE;
12662 ;; %%% bts, btr, btc, bt.
12664 ;; Store-flag instructions.
12666 ;; For all sCOND expanders, also expand the compare or test insn that
12667 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12669 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12670 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12671 ;; way, which can later delete the movzx if only QImode is needed.
12673 (define_expand "seq"
12674   [(set (match_operand:QI 0 "register_operand" "")
12675         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12676   ""
12677   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12679 (define_expand "sne"
12680   [(set (match_operand:QI 0 "register_operand" "")
12681         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12682   ""
12683   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12685 (define_expand "sgt"
12686   [(set (match_operand:QI 0 "register_operand" "")
12687         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12688   ""
12689   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12691 (define_expand "sgtu"
12692   [(set (match_operand:QI 0 "register_operand" "")
12693         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12694   ""
12695   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12697 (define_expand "slt"
12698   [(set (match_operand:QI 0 "register_operand" "")
12699         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12700   ""
12701   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12703 (define_expand "sltu"
12704   [(set (match_operand:QI 0 "register_operand" "")
12705         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12706   ""
12707   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12709 (define_expand "sge"
12710   [(set (match_operand:QI 0 "register_operand" "")
12711         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12712   ""
12713   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12715 (define_expand "sgeu"
12716   [(set (match_operand:QI 0 "register_operand" "")
12717         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12718   ""
12719   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12721 (define_expand "sle"
12722   [(set (match_operand:QI 0 "register_operand" "")
12723         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12724   ""
12725   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12727 (define_expand "sleu"
12728   [(set (match_operand:QI 0 "register_operand" "")
12729         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12730   ""
12731   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12733 (define_expand "sunordered"
12734   [(set (match_operand:QI 0 "register_operand" "")
12735         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12736   "TARGET_80387 || TARGET_SSE"
12737   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12739 (define_expand "sordered"
12740   [(set (match_operand:QI 0 "register_operand" "")
12741         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12742   "TARGET_80387"
12743   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12745 (define_expand "suneq"
12746   [(set (match_operand:QI 0 "register_operand" "")
12747         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12748   "TARGET_80387 || TARGET_SSE"
12749   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12751 (define_expand "sunge"
12752   [(set (match_operand:QI 0 "register_operand" "")
12753         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12754   "TARGET_80387 || TARGET_SSE"
12755   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12757 (define_expand "sungt"
12758   [(set (match_operand:QI 0 "register_operand" "")
12759         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12760   "TARGET_80387 || TARGET_SSE"
12761   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12763 (define_expand "sunle"
12764   [(set (match_operand:QI 0 "register_operand" "")
12765         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12766   "TARGET_80387 || TARGET_SSE"
12767   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12769 (define_expand "sunlt"
12770   [(set (match_operand:QI 0 "register_operand" "")
12771         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12772   "TARGET_80387 || TARGET_SSE"
12773   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12775 (define_expand "sltgt"
12776   [(set (match_operand:QI 0 "register_operand" "")
12777         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12778   "TARGET_80387 || TARGET_SSE"
12779   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12781 (define_insn "*setcc_1"
12782   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12783         (match_operator:QI 1 "ix86_comparison_operator"
12784           [(reg 17) (const_int 0)]))]
12785   ""
12786   "set%C1\t%0"
12787   [(set_attr "type" "setcc")
12788    (set_attr "mode" "QI")])
12790 (define_insn "setcc_2"
12791   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12792         (match_operator:QI 1 "ix86_comparison_operator"
12793           [(reg 17) (const_int 0)]))]
12794   ""
12795   "set%C1\t%0"
12796   [(set_attr "type" "setcc")
12797    (set_attr "mode" "QI")])
12799 ;; In general it is not safe to assume too much about CCmode registers,
12800 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12801 ;; conditions this is safe on x86, so help combine not create
12803 ;;      seta    %al
12804 ;;      testb   %al, %al
12805 ;;      sete    %al
12807 (define_split 
12808   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12809         (ne:QI (match_operator 1 "ix86_comparison_operator"
12810                  [(reg 17) (const_int 0)])
12811             (const_int 0)))]
12812   ""
12813   [(set (match_dup 0) (match_dup 1))]
12815   PUT_MODE (operands[1], QImode);
12818 (define_split 
12819   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12820         (ne:QI (match_operator 1 "ix86_comparison_operator"
12821                  [(reg 17) (const_int 0)])
12822             (const_int 0)))]
12823   ""
12824   [(set (match_dup 0) (match_dup 1))]
12826   PUT_MODE (operands[1], QImode);
12829 (define_split 
12830   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12831         (eq:QI (match_operator 1 "ix86_comparison_operator"
12832                  [(reg 17) (const_int 0)])
12833             (const_int 0)))]
12834   ""
12835   [(set (match_dup 0) (match_dup 1))]
12837   rtx new_op1 = copy_rtx (operands[1]);
12838   operands[1] = new_op1;
12839   PUT_MODE (new_op1, QImode);
12840   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12841                                              GET_MODE (XEXP (new_op1, 0))));
12843   /* Make sure that (a) the CCmode we have for the flags is strong
12844      enough for the reversed compare or (b) we have a valid FP compare.  */
12845   if (! ix86_comparison_operator (new_op1, VOIDmode))
12846     FAIL;
12849 (define_split 
12850   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12851         (eq:QI (match_operator 1 "ix86_comparison_operator"
12852                  [(reg 17) (const_int 0)])
12853             (const_int 0)))]
12854   ""
12855   [(set (match_dup 0) (match_dup 1))]
12857   rtx new_op1 = copy_rtx (operands[1]);
12858   operands[1] = new_op1;
12859   PUT_MODE (new_op1, QImode);
12860   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12861                                              GET_MODE (XEXP (new_op1, 0))));
12863   /* Make sure that (a) the CCmode we have for the flags is strong
12864      enough for the reversed compare or (b) we have a valid FP compare.  */
12865   if (! ix86_comparison_operator (new_op1, VOIDmode))
12866     FAIL;
12869 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12870 ;; subsequent logical operations are used to imitate conditional moves.
12871 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12872 ;; it directly.  Further holding this value in pseudo register might bring
12873 ;; problem in implicit normalization in spill code.
12874 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12875 ;; instructions after reload by splitting the conditional move patterns.
12877 (define_insn "*sse_setccsf"
12878   [(set (match_operand:SF 0 "register_operand" "=x")
12879         (match_operator:SF 1 "sse_comparison_operator"
12880           [(match_operand:SF 2 "register_operand" "0")
12881            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12882   "TARGET_SSE && reload_completed"
12883   "cmp%D1ss\t{%3, %0|%0, %3}"
12884   [(set_attr "type" "ssecmp")
12885    (set_attr "mode" "SF")])
12887 (define_insn "*sse_setccdf"
12888   [(set (match_operand:DF 0 "register_operand" "=Y")
12889         (match_operator:DF 1 "sse_comparison_operator"
12890           [(match_operand:DF 2 "register_operand" "0")
12891            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12892   "TARGET_SSE2 && reload_completed"
12893   "cmp%D1sd\t{%3, %0|%0, %3}"
12894   [(set_attr "type" "ssecmp")
12895    (set_attr "mode" "DF")])
12897 ;; Basic conditional jump instructions.
12898 ;; We ignore the overflow flag for signed branch instructions.
12900 ;; For all bCOND expanders, also expand the compare or test insn that
12901 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12903 (define_expand "beq"
12904   [(set (pc)
12905         (if_then_else (match_dup 1)
12906                       (label_ref (match_operand 0 "" ""))
12907                       (pc)))]
12908   ""
12909   "ix86_expand_branch (EQ, operands[0]); DONE;")
12911 (define_expand "bne"
12912   [(set (pc)
12913         (if_then_else (match_dup 1)
12914                       (label_ref (match_operand 0 "" ""))
12915                       (pc)))]
12916   ""
12917   "ix86_expand_branch (NE, operands[0]); DONE;")
12919 (define_expand "bgt"
12920   [(set (pc)
12921         (if_then_else (match_dup 1)
12922                       (label_ref (match_operand 0 "" ""))
12923                       (pc)))]
12924   ""
12925   "ix86_expand_branch (GT, operands[0]); DONE;")
12927 (define_expand "bgtu"
12928   [(set (pc)
12929         (if_then_else (match_dup 1)
12930                       (label_ref (match_operand 0 "" ""))
12931                       (pc)))]
12932   ""
12933   "ix86_expand_branch (GTU, operands[0]); DONE;")
12935 (define_expand "blt"
12936   [(set (pc)
12937         (if_then_else (match_dup 1)
12938                       (label_ref (match_operand 0 "" ""))
12939                       (pc)))]
12940   ""
12941   "ix86_expand_branch (LT, operands[0]); DONE;")
12943 (define_expand "bltu"
12944   [(set (pc)
12945         (if_then_else (match_dup 1)
12946                       (label_ref (match_operand 0 "" ""))
12947                       (pc)))]
12948   ""
12949   "ix86_expand_branch (LTU, operands[0]); DONE;")
12951 (define_expand "bge"
12952   [(set (pc)
12953         (if_then_else (match_dup 1)
12954                       (label_ref (match_operand 0 "" ""))
12955                       (pc)))]
12956   ""
12957   "ix86_expand_branch (GE, operands[0]); DONE;")
12959 (define_expand "bgeu"
12960   [(set (pc)
12961         (if_then_else (match_dup 1)
12962                       (label_ref (match_operand 0 "" ""))
12963                       (pc)))]
12964   ""
12965   "ix86_expand_branch (GEU, operands[0]); DONE;")
12967 (define_expand "ble"
12968   [(set (pc)
12969         (if_then_else (match_dup 1)
12970                       (label_ref (match_operand 0 "" ""))
12971                       (pc)))]
12972   ""
12973   "ix86_expand_branch (LE, operands[0]); DONE;")
12975 (define_expand "bleu"
12976   [(set (pc)
12977         (if_then_else (match_dup 1)
12978                       (label_ref (match_operand 0 "" ""))
12979                       (pc)))]
12980   ""
12981   "ix86_expand_branch (LEU, operands[0]); DONE;")
12983 (define_expand "bunordered"
12984   [(set (pc)
12985         (if_then_else (match_dup 1)
12986                       (label_ref (match_operand 0 "" ""))
12987                       (pc)))]
12988   "TARGET_80387 || TARGET_SSE"
12989   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12991 (define_expand "bordered"
12992   [(set (pc)
12993         (if_then_else (match_dup 1)
12994                       (label_ref (match_operand 0 "" ""))
12995                       (pc)))]
12996   "TARGET_80387 || TARGET_SSE"
12997   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12999 (define_expand "buneq"
13000   [(set (pc)
13001         (if_then_else (match_dup 1)
13002                       (label_ref (match_operand 0 "" ""))
13003                       (pc)))]
13004   "TARGET_80387 || TARGET_SSE"
13005   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13007 (define_expand "bunge"
13008   [(set (pc)
13009         (if_then_else (match_dup 1)
13010                       (label_ref (match_operand 0 "" ""))
13011                       (pc)))]
13012   "TARGET_80387 || TARGET_SSE"
13013   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13015 (define_expand "bungt"
13016   [(set (pc)
13017         (if_then_else (match_dup 1)
13018                       (label_ref (match_operand 0 "" ""))
13019                       (pc)))]
13020   "TARGET_80387 || TARGET_SSE"
13021   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13023 (define_expand "bunle"
13024   [(set (pc)
13025         (if_then_else (match_dup 1)
13026                       (label_ref (match_operand 0 "" ""))
13027                       (pc)))]
13028   "TARGET_80387 || TARGET_SSE"
13029   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13031 (define_expand "bunlt"
13032   [(set (pc)
13033         (if_then_else (match_dup 1)
13034                       (label_ref (match_operand 0 "" ""))
13035                       (pc)))]
13036   "TARGET_80387 || TARGET_SSE"
13037   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13039 (define_expand "bltgt"
13040   [(set (pc)
13041         (if_then_else (match_dup 1)
13042                       (label_ref (match_operand 0 "" ""))
13043                       (pc)))]
13044   "TARGET_80387 || TARGET_SSE"
13045   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13047 (define_insn "*jcc_1"
13048   [(set (pc)
13049         (if_then_else (match_operator 1 "ix86_comparison_operator"
13050                                       [(reg 17) (const_int 0)])
13051                       (label_ref (match_operand 0 "" ""))
13052                       (pc)))]
13053   ""
13054   "%+j%C1\t%l0"
13055   [(set_attr "type" "ibr")
13056    (set_attr "modrm" "0")
13057    (set (attr "length")
13058            (if_then_else (and (ge (minus (match_dup 0) (pc))
13059                                   (const_int -126))
13060                               (lt (minus (match_dup 0) (pc))
13061                                   (const_int 128)))
13062              (const_int 2)
13063              (const_int 6)))])
13065 (define_insn "*jcc_2"
13066   [(set (pc)
13067         (if_then_else (match_operator 1 "ix86_comparison_operator"
13068                                       [(reg 17) (const_int 0)])
13069                       (pc)
13070                       (label_ref (match_operand 0 "" ""))))]
13071   ""
13072   "%+j%c1\t%l0"
13073   [(set_attr "type" "ibr")
13074    (set_attr "modrm" "0")
13075    (set (attr "length")
13076            (if_then_else (and (ge (minus (match_dup 0) (pc))
13077                                   (const_int -126))
13078                               (lt (minus (match_dup 0) (pc))
13079                                   (const_int 128)))
13080              (const_int 2)
13081              (const_int 6)))])
13083 ;; In general it is not safe to assume too much about CCmode registers,
13084 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13085 ;; conditions this is safe on x86, so help combine not create
13087 ;;      seta    %al
13088 ;;      testb   %al, %al
13089 ;;      je      Lfoo
13091 (define_split 
13092   [(set (pc)
13093         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13094                                       [(reg 17) (const_int 0)])
13095                           (const_int 0))
13096                       (label_ref (match_operand 1 "" ""))
13097                       (pc)))]
13098   ""
13099   [(set (pc)
13100         (if_then_else (match_dup 0)
13101                       (label_ref (match_dup 1))
13102                       (pc)))]
13104   PUT_MODE (operands[0], VOIDmode);
13106   
13107 (define_split 
13108   [(set (pc)
13109         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13110                                       [(reg 17) (const_int 0)])
13111                           (const_int 0))
13112                       (label_ref (match_operand 1 "" ""))
13113                       (pc)))]
13114   ""
13115   [(set (pc)
13116         (if_then_else (match_dup 0)
13117                       (label_ref (match_dup 1))
13118                       (pc)))]
13120   rtx new_op0 = copy_rtx (operands[0]);
13121   operands[0] = new_op0;
13122   PUT_MODE (new_op0, VOIDmode);
13123   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13124                                              GET_MODE (XEXP (new_op0, 0))));
13126   /* Make sure that (a) the CCmode we have for the flags is strong
13127      enough for the reversed compare or (b) we have a valid FP compare.  */
13128   if (! ix86_comparison_operator (new_op0, VOIDmode))
13129     FAIL;
13132 ;; Define combination compare-and-branch fp compare instructions to use
13133 ;; during early optimization.  Splitting the operation apart early makes
13134 ;; for bad code when we want to reverse the operation.
13136 (define_insn "*fp_jcc_1"
13137   [(set (pc)
13138         (if_then_else (match_operator 0 "comparison_operator"
13139                         [(match_operand 1 "register_operand" "f")
13140                          (match_operand 2 "register_operand" "f")])
13141           (label_ref (match_operand 3 "" ""))
13142           (pc)))
13143    (clobber (reg:CCFP FPSR_REG))
13144    (clobber (reg:CCFP FLAGS_REG))]
13145   "TARGET_CMOVE && TARGET_80387
13146    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13147    && FLOAT_MODE_P (GET_MODE (operands[1]))
13148    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13149    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13150   "#")
13152 (define_insn "*fp_jcc_1_sse"
13153   [(set (pc)
13154         (if_then_else (match_operator 0 "comparison_operator"
13155                         [(match_operand 1 "register_operand" "f#x,x#f")
13156                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13157           (label_ref (match_operand 3 "" ""))
13158           (pc)))
13159    (clobber (reg:CCFP FPSR_REG))
13160    (clobber (reg:CCFP FLAGS_REG))]
13161   "TARGET_80387
13162    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13163    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13164    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13165   "#")
13167 (define_insn "*fp_jcc_1_sse_only"
13168   [(set (pc)
13169         (if_then_else (match_operator 0 "comparison_operator"
13170                         [(match_operand 1 "register_operand" "x")
13171                          (match_operand 2 "nonimmediate_operand" "xm")])
13172           (label_ref (match_operand 3 "" ""))
13173           (pc)))
13174    (clobber (reg:CCFP FPSR_REG))
13175    (clobber (reg:CCFP FLAGS_REG))]
13176   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13177    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13178    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13179   "#")
13181 (define_insn "*fp_jcc_2"
13182   [(set (pc)
13183         (if_then_else (match_operator 0 "comparison_operator"
13184                         [(match_operand 1 "register_operand" "f")
13185                          (match_operand 2 "register_operand" "f")])
13186           (pc)
13187           (label_ref (match_operand 3 "" ""))))
13188    (clobber (reg:CCFP FPSR_REG))
13189    (clobber (reg:CCFP FLAGS_REG))]
13190   "TARGET_CMOVE && TARGET_80387
13191    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13192    && FLOAT_MODE_P (GET_MODE (operands[1]))
13193    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13194    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13195   "#")
13197 (define_insn "*fp_jcc_2_sse"
13198   [(set (pc)
13199         (if_then_else (match_operator 0 "comparison_operator"
13200                         [(match_operand 1 "register_operand" "f#x,x#f")
13201                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13202           (pc)
13203           (label_ref (match_operand 3 "" ""))))
13204    (clobber (reg:CCFP FPSR_REG))
13205    (clobber (reg:CCFP FLAGS_REG))]
13206   "TARGET_80387
13207    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13208    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13209    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13210   "#")
13212 (define_insn "*fp_jcc_2_sse_only"
13213   [(set (pc)
13214         (if_then_else (match_operator 0 "comparison_operator"
13215                         [(match_operand 1 "register_operand" "x")
13216                          (match_operand 2 "nonimmediate_operand" "xm")])
13217           (pc)
13218           (label_ref (match_operand 3 "" ""))))
13219    (clobber (reg:CCFP FPSR_REG))
13220    (clobber (reg:CCFP FLAGS_REG))]
13221   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13222    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13223    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13224   "#")
13226 (define_insn "*fp_jcc_3"
13227   [(set (pc)
13228         (if_then_else (match_operator 0 "comparison_operator"
13229                         [(match_operand 1 "register_operand" "f")
13230                          (match_operand 2 "nonimmediate_operand" "fm")])
13231           (label_ref (match_operand 3 "" ""))
13232           (pc)))
13233    (clobber (reg:CCFP FPSR_REG))
13234    (clobber (reg:CCFP FLAGS_REG))
13235    (clobber (match_scratch:HI 4 "=a"))]
13236   "TARGET_80387
13237    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13238    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13239    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13240    && SELECT_CC_MODE (GET_CODE (operands[0]),
13241                       operands[1], operands[2]) == CCFPmode
13242    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13243   "#")
13245 (define_insn "*fp_jcc_4"
13246   [(set (pc)
13247         (if_then_else (match_operator 0 "comparison_operator"
13248                         [(match_operand 1 "register_operand" "f")
13249                          (match_operand 2 "nonimmediate_operand" "fm")])
13250           (pc)
13251           (label_ref (match_operand 3 "" ""))))
13252    (clobber (reg:CCFP FPSR_REG))
13253    (clobber (reg:CCFP FLAGS_REG))
13254    (clobber (match_scratch:HI 4 "=a"))]
13255   "TARGET_80387
13256    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13257    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13258    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13259    && SELECT_CC_MODE (GET_CODE (operands[0]),
13260                       operands[1], operands[2]) == CCFPmode
13261    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13262   "#")
13264 (define_insn "*fp_jcc_5"
13265   [(set (pc)
13266         (if_then_else (match_operator 0 "comparison_operator"
13267                         [(match_operand 1 "register_operand" "f")
13268                          (match_operand 2 "register_operand" "f")])
13269           (label_ref (match_operand 3 "" ""))
13270           (pc)))
13271    (clobber (reg:CCFP FPSR_REG))
13272    (clobber (reg:CCFP FLAGS_REG))
13273    (clobber (match_scratch:HI 4 "=a"))]
13274   "TARGET_80387
13275    && FLOAT_MODE_P (GET_MODE (operands[1]))
13276    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13277    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13278   "#")
13280 (define_insn "*fp_jcc_6"
13281   [(set (pc)
13282         (if_then_else (match_operator 0 "comparison_operator"
13283                         [(match_operand 1 "register_operand" "f")
13284                          (match_operand 2 "register_operand" "f")])
13285           (pc)
13286           (label_ref (match_operand 3 "" ""))))
13287    (clobber (reg:CCFP FPSR_REG))
13288    (clobber (reg:CCFP FLAGS_REG))
13289    (clobber (match_scratch:HI 4 "=a"))]
13290   "TARGET_80387
13291    && FLOAT_MODE_P (GET_MODE (operands[1]))
13292    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13293    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13294   "#")
13296 (define_split
13297   [(set (pc)
13298         (if_then_else (match_operator 0 "comparison_operator"
13299                         [(match_operand 1 "register_operand" "")
13300                          (match_operand 2 "nonimmediate_operand" "")])
13301           (match_operand 3 "" "")
13302           (match_operand 4 "" "")))
13303    (clobber (reg:CCFP FPSR_REG))
13304    (clobber (reg:CCFP FLAGS_REG))]
13305   "reload_completed"
13306   [(const_int 0)]
13308   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13309                         operands[3], operands[4], NULL_RTX);
13310   DONE;
13313 (define_split
13314   [(set (pc)
13315         (if_then_else (match_operator 0 "comparison_operator"
13316                         [(match_operand 1 "register_operand" "")
13317                          (match_operand 2 "nonimmediate_operand" "")])
13318           (match_operand 3 "" "")
13319           (match_operand 4 "" "")))
13320    (clobber (reg:CCFP FPSR_REG))
13321    (clobber (reg:CCFP FLAGS_REG))
13322    (clobber (match_scratch:HI 5 "=a"))]
13323   "reload_completed"
13324   [(set (pc)
13325         (if_then_else (match_dup 6)
13326           (match_dup 3)
13327           (match_dup 4)))]
13329   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13330                         operands[3], operands[4], operands[5]);
13331   DONE;
13334 ;; Unconditional and other jump instructions
13336 (define_insn "jump"
13337   [(set (pc)
13338         (label_ref (match_operand 0 "" "")))]
13339   ""
13340   "jmp\t%l0"
13341   [(set_attr "type" "ibr")
13342    (set (attr "length")
13343            (if_then_else (and (ge (minus (match_dup 0) (pc))
13344                                   (const_int -126))
13345                               (lt (minus (match_dup 0) (pc))
13346                                   (const_int 128)))
13347              (const_int 2)
13348              (const_int 5)))
13349    (set_attr "modrm" "0")])
13351 (define_expand "indirect_jump"
13352   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13353   ""
13354   "")
13356 (define_insn "*indirect_jump"
13357   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13358   "!TARGET_64BIT"
13359   "jmp\t%A0"
13360   [(set_attr "type" "ibr")
13361    (set_attr "length_immediate" "0")])
13363 (define_insn "*indirect_jump_rtx64"
13364   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13365   "TARGET_64BIT"
13366   "jmp\t%A0"
13367   [(set_attr "type" "ibr")
13368    (set_attr "length_immediate" "0")])
13370 (define_expand "tablejump"
13371   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13372               (use (label_ref (match_operand 1 "" "")))])]
13373   ""
13375   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13376      relative.  Convert the relative address to an absolute address.  */
13377   if (flag_pic)
13378     {
13379       rtx op0, op1;
13380       enum rtx_code code;
13382       if (TARGET_64BIT)
13383         {
13384           code = PLUS;
13385           op0 = operands[0];
13386           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13387         }
13388       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13389         {
13390           code = PLUS;
13391           op0 = operands[0];
13392           op1 = pic_offset_table_rtx;
13393         }
13394       else
13395         {
13396           code = MINUS;
13397           op0 = pic_offset_table_rtx;
13398           op1 = operands[0];
13399         }
13401       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13402                                          OPTAB_DIRECT);
13403     }
13406 (define_insn "*tablejump_1"
13407   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13408    (use (label_ref (match_operand 1 "" "")))]
13409   "!TARGET_64BIT"
13410   "jmp\t%A0"
13411   [(set_attr "type" "ibr")
13412    (set_attr "length_immediate" "0")])
13414 (define_insn "*tablejump_1_rtx64"
13415   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13416    (use (label_ref (match_operand 1 "" "")))]
13417   "TARGET_64BIT"
13418   "jmp\t%A0"
13419   [(set_attr "type" "ibr")
13420    (set_attr "length_immediate" "0")])
13422 ;; Loop instruction
13424 ;; This is all complicated by the fact that since this is a jump insn
13425 ;; we must handle our own reloads.
13427 (define_expand "doloop_end"
13428   [(use (match_operand 0 "" ""))        ; loop pseudo
13429    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13430    (use (match_operand 2 "" ""))        ; max iterations
13431    (use (match_operand 3 "" ""))        ; loop level 
13432    (use (match_operand 4 "" ""))]       ; label
13433   "!TARGET_64BIT && TARGET_USE_LOOP"
13434   "                                 
13436   /* Only use cloop on innermost loops.  */
13437   if (INTVAL (operands[3]) > 1)
13438     FAIL;
13439   if (GET_MODE (operands[0]) != SImode)
13440     FAIL;
13441   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13442                                            operands[0]));
13443   DONE;
13446 (define_insn "doloop_end_internal"
13447   [(set (pc)
13448         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13449                           (const_int 1))
13450                       (label_ref (match_operand 0 "" ""))
13451                       (pc)))
13452    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13453         (plus:SI (match_dup 1)
13454                  (const_int -1)))
13455    (clobber (match_scratch:SI 3 "=X,X,r"))
13456    (clobber (reg:CC FLAGS_REG))]
13457   "!TARGET_64BIT && TARGET_USE_LOOP
13458    && (reload_in_progress || reload_completed
13459        || register_operand (operands[2], VOIDmode))"
13461   if (which_alternative != 0)
13462     return "#";
13463   if (get_attr_length (insn) == 2)
13464     return "%+loop\t%l0";
13465   else
13466     return "dec{l}\t%1\;%+jne\t%l0";
13468   [(set (attr "length")
13469         (if_then_else (and (eq_attr "alternative" "0")
13470                            (and (ge (minus (match_dup 0) (pc))
13471                                     (const_int -126))
13472                                 (lt (minus (match_dup 0) (pc))
13473                                     (const_int 128))))
13474                       (const_int 2)
13475                       (const_int 16)))
13476    ;; We don't know the type before shorten branches.  Optimistically expect
13477    ;; the loop instruction to match.
13478    (set (attr "type") (const_string "ibr"))])
13480 (define_split
13481   [(set (pc)
13482         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13483                           (const_int 1))
13484                       (match_operand 0 "" "")
13485                       (pc)))
13486    (set (match_dup 1)
13487         (plus:SI (match_dup 1)
13488                  (const_int -1)))
13489    (clobber (match_scratch:SI 2 ""))
13490    (clobber (reg:CC FLAGS_REG))]
13491   "!TARGET_64BIT && TARGET_USE_LOOP
13492    && reload_completed
13493    && REGNO (operands[1]) != 2"
13494   [(parallel [(set (reg:CCZ FLAGS_REG)
13495                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13496                                  (const_int 0)))
13497               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13498    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13499                            (match_dup 0)
13500                            (pc)))]
13501   "")
13502   
13503 (define_split
13504   [(set (pc)
13505         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13506                           (const_int 1))
13507                       (match_operand 0 "" "")
13508                       (pc)))
13509    (set (match_operand:SI 2 "nonimmediate_operand" "")
13510         (plus:SI (match_dup 1)
13511                  (const_int -1)))
13512    (clobber (match_scratch:SI 3 ""))
13513    (clobber (reg:CC FLAGS_REG))]
13514   "!TARGET_64BIT && TARGET_USE_LOOP
13515    && reload_completed
13516    && (! REG_P (operands[2])
13517        || ! rtx_equal_p (operands[1], operands[2]))"
13518   [(set (match_dup 3) (match_dup 1))
13519    (parallel [(set (reg:CCZ FLAGS_REG)
13520                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13521                                 (const_int 0)))
13522               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13523    (set (match_dup 2) (match_dup 3))
13524    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13525                            (match_dup 0)
13526                            (pc)))]
13527   "")
13529 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13531 (define_peephole2
13532   [(set (reg 17) (match_operand 0 "" ""))
13533    (set (match_operand:QI 1 "register_operand" "")
13534         (match_operator:QI 2 "ix86_comparison_operator"
13535           [(reg 17) (const_int 0)]))
13536    (set (match_operand 3 "q_regs_operand" "")
13537         (zero_extend (match_dup 1)))]
13538   "(peep2_reg_dead_p (3, operands[1])
13539     || operands_match_p (operands[1], operands[3]))
13540    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13541   [(set (match_dup 4) (match_dup 0))
13542    (set (strict_low_part (match_dup 5))
13543         (match_dup 2))]
13545   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13546   operands[5] = gen_lowpart (QImode, operands[3]);
13547   ix86_expand_clear (operands[3]);
13550 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13552 (define_peephole2
13553   [(set (reg 17) (match_operand 0 "" ""))
13554    (set (match_operand:QI 1 "register_operand" "")
13555         (match_operator:QI 2 "ix86_comparison_operator"
13556           [(reg 17) (const_int 0)]))
13557    (parallel [(set (match_operand 3 "q_regs_operand" "")
13558                    (zero_extend (match_dup 1)))
13559               (clobber (reg:CC FLAGS_REG))])]
13560   "(peep2_reg_dead_p (3, operands[1])
13561     || operands_match_p (operands[1], operands[3]))
13562    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13563   [(set (match_dup 4) (match_dup 0))
13564    (set (strict_low_part (match_dup 5))
13565         (match_dup 2))]
13567   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13568   operands[5] = gen_lowpart (QImode, operands[3]);
13569   ix86_expand_clear (operands[3]);
13572 ;; Call instructions.
13574 ;; The predicates normally associated with named expanders are not properly
13575 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13576 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13578 ;; Call subroutine returning no value.
13580 (define_expand "call_pop"
13581   [(parallel [(call (match_operand:QI 0 "" "")
13582                     (match_operand:SI 1 "" ""))
13583               (set (reg:SI SP_REG)
13584                    (plus:SI (reg:SI SP_REG)
13585                             (match_operand:SI 3 "" "")))])]
13586   "!TARGET_64BIT"
13588   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13589   DONE;
13592 (define_insn "*call_pop_0"
13593   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13594          (match_operand:SI 1 "" ""))
13595    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13596                             (match_operand:SI 2 "immediate_operand" "")))]
13597   "!TARGET_64BIT"
13599   if (SIBLING_CALL_P (insn))
13600     return "jmp\t%P0";
13601   else
13602     return "call\t%P0";
13604   [(set_attr "type" "call")])
13605   
13606 (define_insn "*call_pop_1"
13607   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13608          (match_operand:SI 1 "" ""))
13609    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13610                             (match_operand:SI 2 "immediate_operand" "i")))]
13611   "!TARGET_64BIT"
13613   if (constant_call_address_operand (operands[0], Pmode))
13614     {
13615       if (SIBLING_CALL_P (insn))
13616         return "jmp\t%P0";
13617       else
13618         return "call\t%P0";
13619     }
13620   if (SIBLING_CALL_P (insn))
13621     return "jmp\t%A0";
13622   else
13623     return "call\t%A0";
13625   [(set_attr "type" "call")])
13627 (define_expand "call"
13628   [(call (match_operand:QI 0 "" "")
13629          (match_operand 1 "" ""))
13630    (use (match_operand 2 "" ""))]
13631   ""
13633   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13634   DONE;
13637 (define_expand "sibcall"
13638   [(call (match_operand:QI 0 "" "")
13639          (match_operand 1 "" ""))
13640    (use (match_operand 2 "" ""))]
13641   ""
13643   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13644   DONE;
13647 (define_insn "*call_0"
13648   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13649          (match_operand 1 "" ""))]
13650   ""
13652   if (SIBLING_CALL_P (insn))
13653     return "jmp\t%P0";
13654   else
13655     return "call\t%P0";
13657   [(set_attr "type" "call")])
13659 (define_insn "*call_1"
13660   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13661          (match_operand 1 "" ""))]
13662   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13664   if (constant_call_address_operand (operands[0], QImode))
13665     return "call\t%P0";
13666   return "call\t%A0";
13668   [(set_attr "type" "call")])
13670 (define_insn "*sibcall_1"
13671   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13672          (match_operand 1 "" ""))]
13673   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13675   if (constant_call_address_operand (operands[0], QImode))
13676     return "jmp\t%P0";
13677   return "jmp\t%A0";
13679   [(set_attr "type" "call")])
13681 (define_insn "*call_1_rex64"
13682   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13683          (match_operand 1 "" ""))]
13684   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13686   if (constant_call_address_operand (operands[0], QImode))
13687     return "call\t%P0";
13688   return "call\t%A0";
13690   [(set_attr "type" "call")])
13692 (define_insn "*sibcall_1_rex64"
13693   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13694          (match_operand 1 "" ""))]
13695   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13696   "jmp\t%P0"
13697   [(set_attr "type" "call")])
13699 (define_insn "*sibcall_1_rex64_v"
13700   [(call (mem:QI (reg:DI 40))
13701          (match_operand 0 "" ""))]
13702   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13703   "jmp\t*%%r11"
13704   [(set_attr "type" "call")])
13707 ;; Call subroutine, returning value in operand 0
13709 (define_expand "call_value_pop"
13710   [(parallel [(set (match_operand 0 "" "")
13711                    (call (match_operand:QI 1 "" "")
13712                          (match_operand:SI 2 "" "")))
13713               (set (reg:SI SP_REG)
13714                    (plus:SI (reg:SI SP_REG)
13715                             (match_operand:SI 4 "" "")))])]
13716   "!TARGET_64BIT"
13718   ix86_expand_call (operands[0], operands[1], operands[2],
13719                     operands[3], operands[4], 0);
13720   DONE;
13723 (define_expand "call_value"
13724   [(set (match_operand 0 "" "")
13725         (call (match_operand:QI 1 "" "")
13726               (match_operand:SI 2 "" "")))
13727    (use (match_operand:SI 3 "" ""))]
13728   ;; Operand 2 not used on the i386.
13729   ""
13731   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13732   DONE;
13735 (define_expand "sibcall_value"
13736   [(set (match_operand 0 "" "")
13737         (call (match_operand:QI 1 "" "")
13738               (match_operand:SI 2 "" "")))
13739    (use (match_operand:SI 3 "" ""))]
13740   ;; Operand 2 not used on the i386.
13741   ""
13743   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13744   DONE;
13747 ;; Call subroutine returning any type.
13749 (define_expand "untyped_call"
13750   [(parallel [(call (match_operand 0 "" "")
13751                     (const_int 0))
13752               (match_operand 1 "" "")
13753               (match_operand 2 "" "")])]
13754   ""
13756   int i;
13758   /* In order to give reg-stack an easier job in validating two
13759      coprocessor registers as containing a possible return value,
13760      simply pretend the untyped call returns a complex long double
13761      value.  */
13763   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13764                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13765                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13766                     NULL, 0);
13768   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13769     {
13770       rtx set = XVECEXP (operands[2], 0, i);
13771       emit_move_insn (SET_DEST (set), SET_SRC (set));
13772     }
13774   /* The optimizer does not know that the call sets the function value
13775      registers we stored in the result block.  We avoid problems by
13776      claiming that all hard registers are used and clobbered at this
13777      point.  */
13778   emit_insn (gen_blockage (const0_rtx));
13780   DONE;
13783 ;; Prologue and epilogue instructions
13785 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13786 ;; all of memory.  This blocks insns from being moved across this point.
13788 (define_insn "blockage"
13789   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13790   ""
13791   ""
13792   [(set_attr "length" "0")])
13794 ;; Insn emitted into the body of a function to return from a function.
13795 ;; This is only done if the function's epilogue is known to be simple.
13796 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13798 (define_expand "return"
13799   [(return)]
13800   "ix86_can_use_return_insn_p ()"
13802   if (current_function_pops_args)
13803     {
13804       rtx popc = GEN_INT (current_function_pops_args);
13805       emit_jump_insn (gen_return_pop_internal (popc));
13806       DONE;
13807     }
13810 (define_insn "return_internal"
13811   [(return)]
13812   "reload_completed"
13813   "ret"
13814   [(set_attr "length" "1")
13815    (set_attr "length_immediate" "0")
13816    (set_attr "modrm" "0")])
13818 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13819 ;; instruction Athlon and K8 have.
13821 (define_insn "return_internal_long"
13822   [(return)
13823    (unspec [(const_int 0)] UNSPEC_REP)]
13824   "reload_completed"
13825   "rep {;} ret"
13826   [(set_attr "length" "1")
13827    (set_attr "length_immediate" "0")
13828    (set_attr "prefix_rep" "1")
13829    (set_attr "modrm" "0")])
13831 (define_insn "return_pop_internal"
13832   [(return)
13833    (use (match_operand:SI 0 "const_int_operand" ""))]
13834   "reload_completed"
13835   "ret\t%0"
13836   [(set_attr "length" "3")
13837    (set_attr "length_immediate" "2")
13838    (set_attr "modrm" "0")])
13840 (define_insn "return_indirect_internal"
13841   [(return)
13842    (use (match_operand:SI 0 "register_operand" "r"))]
13843   "reload_completed"
13844   "jmp\t%A0"
13845   [(set_attr "type" "ibr")
13846    (set_attr "length_immediate" "0")])
13848 (define_insn "nop"
13849   [(const_int 0)]
13850   ""
13851   "nop"
13852   [(set_attr "length" "1")
13853    (set_attr "length_immediate" "0")
13854    (set_attr "modrm" "0")])
13856 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13857 ;; branch prediction penalty for the third jump in a 16-byte
13858 ;; block on K8.
13860 (define_insn "align"
13861   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13862   ""
13864 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13865   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13866 #else
13867   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13868      The align insn is used to avoid 3 jump instructions in the row to improve
13869      branch prediction and the benefits hardly outweight the cost of extra 8
13870      nops on the average inserted by full alignment pseudo operation.  */
13871 #endif
13872   return "";
13874   [(set_attr "length" "16")])
13876 (define_expand "prologue"
13877   [(const_int 1)]
13878   ""
13879   "ix86_expand_prologue (); DONE;")
13881 (define_insn "set_got"
13882   [(set (match_operand:SI 0 "register_operand" "=r")
13883         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13884    (clobber (reg:CC FLAGS_REG))]
13885   "!TARGET_64BIT"
13886   { return output_set_got (operands[0]); }
13887   [(set_attr "type" "multi")
13888    (set_attr "length" "12")])
13890 (define_expand "epilogue"
13891   [(const_int 1)]
13892   ""
13893   "ix86_expand_epilogue (1); DONE;")
13895 (define_expand "sibcall_epilogue"
13896   [(const_int 1)]
13897   ""
13898   "ix86_expand_epilogue (0); DONE;")
13900 (define_expand "eh_return"
13901   [(use (match_operand 0 "register_operand" ""))]
13902   ""
13904   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13906   /* Tricky bit: we write the address of the handler to which we will
13907      be returning into someone else's stack frame, one word below the
13908      stack address we wish to restore.  */
13909   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13910   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13911   tmp = gen_rtx_MEM (Pmode, tmp);
13912   emit_move_insn (tmp, ra);
13914   if (Pmode == SImode)
13915     emit_jump_insn (gen_eh_return_si (sa));
13916   else
13917     emit_jump_insn (gen_eh_return_di (sa));
13918   emit_barrier ();
13919   DONE;
13922 (define_insn_and_split "eh_return_si"
13923   [(set (pc) 
13924         (unspec [(match_operand:SI 0 "register_operand" "c")]
13925                  UNSPEC_EH_RETURN))]
13926   "!TARGET_64BIT"
13927   "#"
13928   "reload_completed"
13929   [(const_int 1)]
13930   "ix86_expand_epilogue (2); DONE;")
13932 (define_insn_and_split "eh_return_di"
13933   [(set (pc) 
13934         (unspec [(match_operand:DI 0 "register_operand" "c")]
13935                  UNSPEC_EH_RETURN))]
13936   "TARGET_64BIT"
13937   "#"
13938   "reload_completed"
13939   [(const_int 1)]
13940   "ix86_expand_epilogue (2); DONE;")
13942 (define_insn "leave"
13943   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13944    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13945    (clobber (mem:BLK (scratch)))]
13946   "!TARGET_64BIT"
13947   "leave"
13948   [(set_attr "type" "leave")])
13950 (define_insn "leave_rex64"
13951   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13952    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13953    (clobber (mem:BLK (scratch)))]
13954   "TARGET_64BIT"
13955   "leave"
13956   [(set_attr "type" "leave")])
13958 (define_expand "ffssi2"
13959   [(parallel
13960      [(set (match_operand:SI 0 "register_operand" "") 
13961            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13962       (clobber (match_scratch:SI 2 ""))
13963       (clobber (reg:CC FLAGS_REG))])]
13964   ""
13965   "")
13967 (define_insn_and_split "*ffs_cmove"
13968   [(set (match_operand:SI 0 "register_operand" "=r") 
13969         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13970    (clobber (match_scratch:SI 2 "=&r"))
13971    (clobber (reg:CC FLAGS_REG))]
13972   "TARGET_CMOVE"
13973   "#"
13974   "&& reload_completed"
13975   [(set (match_dup 2) (const_int -1))
13976    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13977               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13978    (set (match_dup 0) (if_then_else:SI
13979                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13980                         (match_dup 2)
13981                         (match_dup 0)))
13982    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13983               (clobber (reg:CC FLAGS_REG))])]
13984   "")
13986 (define_insn_and_split "*ffs_no_cmove"
13987   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13988         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13989    (clobber (match_scratch:SI 2 "=&q"))
13990    (clobber (reg:CC FLAGS_REG))]
13991   ""
13992   "#"
13993   "reload_completed"
13994   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13995               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13996    (set (strict_low_part (match_dup 3))
13997         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13998    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13999               (clobber (reg:CC FLAGS_REG))])
14000    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14001               (clobber (reg:CC FLAGS_REG))])
14002    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14003               (clobber (reg:CC FLAGS_REG))])]
14005   operands[3] = gen_lowpart (QImode, operands[2]);
14006   ix86_expand_clear (operands[2]);
14009 (define_insn "*ffssi_1"
14010   [(set (reg:CCZ FLAGS_REG)
14011         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14012                      (const_int 0)))
14013    (set (match_operand:SI 0 "register_operand" "=r")
14014         (ctz:SI (match_dup 1)))]
14015   ""
14016   "bsf{l}\t{%1, %0|%0, %1}"
14017   [(set_attr "prefix_0f" "1")])
14019 (define_expand "ffsdi2"
14020   [(parallel
14021      [(set (match_operand:DI 0 "register_operand" "") 
14022            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14023       (clobber (match_scratch:DI 2 ""))
14024       (clobber (reg:CC 17))])]
14025   "TARGET_64BIT && TARGET_CMOVE"
14026   "")
14028 (define_insn_and_split "*ffs_rex64"
14029   [(set (match_operand:DI 0 "register_operand" "=r") 
14030         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14031    (clobber (match_scratch:DI 2 "=&r"))
14032    (clobber (reg:CC 17))]
14033   "TARGET_64BIT && TARGET_CMOVE"
14034   "#"
14035   "&& reload_completed"
14036   [(set (match_dup 2) (const_int -1))
14037    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14038               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14039    (set (match_dup 0) (if_then_else:DI
14040                         (eq (reg:CCZ 17) (const_int 0))
14041                         (match_dup 2)
14042                         (match_dup 0)))
14043    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14044               (clobber (reg:CC 17))])]
14045   "")
14047 (define_insn "*ffsdi_1"
14048   [(set (reg:CCZ 17)
14049         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14050                      (const_int 0)))
14051    (set (match_operand:DI 0 "register_operand" "=r")
14052         (ctz:DI (match_dup 1)))]
14053   "TARGET_64BIT"
14054   "bsf{q}\t{%1, %0|%0, %1}"
14055   [(set_attr "prefix_0f" "1")])
14057 (define_insn "ctzsi2"
14058   [(set (match_operand:SI 0 "register_operand" "=r")
14059         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14060    (clobber (reg:CC FLAGS_REG))]
14061   ""
14062   "bsf{l}\t{%1, %0|%0, %1}"
14063   [(set_attr "prefix_0f" "1")])
14065 (define_insn "ctzdi2"
14066   [(set (match_operand:DI 0 "register_operand" "=r")
14067         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14068    (clobber (reg:CC 17))]
14069   "TARGET_64BIT"
14070   "bsf{q}\t{%1, %0|%0, %1}"
14071   [(set_attr "prefix_0f" "1")])
14073 (define_expand "clzsi2"
14074   [(parallel
14075      [(set (match_operand:SI 0 "register_operand" "")
14076            (minus:SI (const_int 31)
14077                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14078       (clobber (reg:CC FLAGS_REG))])
14079    (parallel
14080      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14081       (clobber (reg:CC FLAGS_REG))])]
14082   ""
14083   "")
14085 (define_insn "*bsr"
14086   [(set (match_operand:SI 0 "register_operand" "=r")
14087         (minus:SI (const_int 31)
14088                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14089    (clobber (reg:CC FLAGS_REG))]
14090   ""
14091   "bsr{l}\t{%1, %0|%0, %1}"
14092   [(set_attr "prefix_0f" "1")])
14094 (define_expand "clzdi2"
14095   [(parallel
14096      [(set (match_operand:DI 0 "register_operand" "")
14097            (minus:DI (const_int 63)
14098                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14099       (clobber (reg:CC 17))])
14100    (parallel
14101      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14102       (clobber (reg:CC 17))])]
14103   "TARGET_64BIT"
14104   "")
14106 (define_insn "*bsr_rex64"
14107   [(set (match_operand:DI 0 "register_operand" "=r")
14108         (minus:DI (const_int 63)
14109                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14110    (clobber (reg:CC 17))]
14111   "TARGET_64BIT"
14112   "bsr{q}\t{%1, %0|%0, %1}"
14113   [(set_attr "prefix_0f" "1")])
14115 ;; Thread-local storage patterns for ELF.
14117 ;; Note that these code sequences must appear exactly as shown
14118 ;; in order to allow linker relaxation.
14120 (define_insn "*tls_global_dynamic_32_gnu"
14121   [(set (match_operand:SI 0 "register_operand" "=a")
14122         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14123                     (match_operand:SI 2 "tls_symbolic_operand" "")
14124                     (match_operand:SI 3 "call_insn_operand" "")]
14125                     UNSPEC_TLS_GD))
14126    (clobber (match_scratch:SI 4 "=d"))
14127    (clobber (match_scratch:SI 5 "=c"))
14128    (clobber (reg:CC FLAGS_REG))]
14129   "!TARGET_64BIT && TARGET_GNU_TLS"
14130   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14131   [(set_attr "type" "multi")
14132    (set_attr "length" "12")])
14134 (define_insn "*tls_global_dynamic_32_sun"
14135   [(set (match_operand:SI 0 "register_operand" "=a")
14136         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14137                     (match_operand:SI 2 "tls_symbolic_operand" "")
14138                     (match_operand:SI 3 "call_insn_operand" "")]
14139                     UNSPEC_TLS_GD))
14140    (clobber (match_scratch:SI 4 "=d"))
14141    (clobber (match_scratch:SI 5 "=c"))
14142    (clobber (reg:CC FLAGS_REG))]
14143   "!TARGET_64BIT && TARGET_SUN_TLS"
14144   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14145         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14146   [(set_attr "type" "multi")
14147    (set_attr "length" "14")])
14149 (define_expand "tls_global_dynamic_32"
14150   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14151                    (unspec:SI
14152                     [(match_dup 2)
14153                      (match_operand:SI 1 "tls_symbolic_operand" "")
14154                      (match_dup 3)]
14155                     UNSPEC_TLS_GD))
14156               (clobber (match_scratch:SI 4 ""))
14157               (clobber (match_scratch:SI 5 ""))
14158               (clobber (reg:CC FLAGS_REG))])]
14159   ""
14161   if (flag_pic)
14162     operands[2] = pic_offset_table_rtx;
14163   else
14164     {
14165       operands[2] = gen_reg_rtx (Pmode);
14166       emit_insn (gen_set_got (operands[2]));
14167     }
14168   operands[3] = ix86_tls_get_addr ();
14171 (define_insn "*tls_global_dynamic_64"
14172   [(set (match_operand:DI 0 "register_operand" "=a")
14173         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14174                       (match_operand:DI 3 "" "")))
14175    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14176               UNSPEC_TLS_GD)]
14177   "TARGET_64BIT"
14178   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14179   [(set_attr "type" "multi")
14180    (set_attr "length" "16")])
14182 (define_expand "tls_global_dynamic_64"
14183   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14184                    (call (mem:QI (match_dup 2)) (const_int 0)))
14185               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14186                          UNSPEC_TLS_GD)])]
14187   ""
14189   operands[2] = ix86_tls_get_addr ();
14192 (define_insn "*tls_local_dynamic_base_32_gnu"
14193   [(set (match_operand:SI 0 "register_operand" "=a")
14194         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14195                     (match_operand:SI 2 "call_insn_operand" "")]
14196                    UNSPEC_TLS_LD_BASE))
14197    (clobber (match_scratch:SI 3 "=d"))
14198    (clobber (match_scratch:SI 4 "=c"))
14199    (clobber (reg:CC FLAGS_REG))]
14200   "!TARGET_64BIT && TARGET_GNU_TLS"
14201   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14202   [(set_attr "type" "multi")
14203    (set_attr "length" "11")])
14205 (define_insn "*tls_local_dynamic_base_32_sun"
14206   [(set (match_operand:SI 0 "register_operand" "=a")
14207         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14208                     (match_operand:SI 2 "call_insn_operand" "")]
14209                    UNSPEC_TLS_LD_BASE))
14210    (clobber (match_scratch:SI 3 "=d"))
14211    (clobber (match_scratch:SI 4 "=c"))
14212    (clobber (reg:CC FLAGS_REG))]
14213   "!TARGET_64BIT && TARGET_SUN_TLS"
14214   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14215         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14216   [(set_attr "type" "multi")
14217    (set_attr "length" "13")])
14219 (define_expand "tls_local_dynamic_base_32"
14220   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14221                    (unspec:SI [(match_dup 1) (match_dup 2)]
14222                               UNSPEC_TLS_LD_BASE))
14223               (clobber (match_scratch:SI 3 ""))
14224               (clobber (match_scratch:SI 4 ""))
14225               (clobber (reg:CC FLAGS_REG))])]
14226   ""
14228   if (flag_pic)
14229     operands[1] = pic_offset_table_rtx;
14230   else
14231     {
14232       operands[1] = gen_reg_rtx (Pmode);
14233       emit_insn (gen_set_got (operands[1]));
14234     }
14235   operands[2] = ix86_tls_get_addr ();
14238 (define_insn "*tls_local_dynamic_base_64"
14239   [(set (match_operand:DI 0 "register_operand" "=a")
14240         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14241                       (match_operand:DI 2 "" "")))
14242    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14243   "TARGET_64BIT"
14244   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14245   [(set_attr "type" "multi")
14246    (set_attr "length" "12")])
14248 (define_expand "tls_local_dynamic_base_64"
14249   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14250                    (call (mem:QI (match_dup 1)) (const_int 0)))
14251               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14252   ""
14254   operands[1] = ix86_tls_get_addr ();
14257 ;; Local dynamic of a single variable is a lose.  Show combine how
14258 ;; to convert that back to global dynamic.
14260 (define_insn_and_split "*tls_local_dynamic_32_once"
14261   [(set (match_operand:SI 0 "register_operand" "=a")
14262         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14263                              (match_operand:SI 2 "call_insn_operand" "")]
14264                             UNSPEC_TLS_LD_BASE)
14265                  (const:SI (unspec:SI
14266                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14267                             UNSPEC_DTPOFF))))
14268    (clobber (match_scratch:SI 4 "=d"))
14269    (clobber (match_scratch:SI 5 "=c"))
14270    (clobber (reg:CC FLAGS_REG))]
14271   ""
14272   "#"
14273   ""
14274   [(parallel [(set (match_dup 0)
14275                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14276                               UNSPEC_TLS_GD))
14277               (clobber (match_dup 4))
14278               (clobber (match_dup 5))
14279               (clobber (reg:CC FLAGS_REG))])]
14280   "")
14282 ;; Load and add the thread base pointer from %gs:0.
14284 (define_insn "*load_tp_si"
14285   [(set (match_operand:SI 0 "register_operand" "=r")
14286         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14287   "!TARGET_64BIT"
14288   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14289   [(set_attr "type" "imov")
14290    (set_attr "modrm" "0")
14291    (set_attr "length" "7")
14292    (set_attr "memory" "load")
14293    (set_attr "imm_disp" "false")])
14295 (define_insn "*add_tp_si"
14296   [(set (match_operand:SI 0 "register_operand" "=r")
14297         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14298                  (match_operand:SI 1 "register_operand" "0")))
14299    (clobber (reg:CC FLAGS_REG))]
14300   "!TARGET_64BIT"
14301   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14302   [(set_attr "type" "alu")
14303    (set_attr "modrm" "0")
14304    (set_attr "length" "7")
14305    (set_attr "memory" "load")
14306    (set_attr "imm_disp" "false")])
14308 (define_insn "*load_tp_di"
14309   [(set (match_operand:DI 0 "register_operand" "=r")
14310         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14311   "TARGET_64BIT"
14312   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14313   [(set_attr "type" "imov")
14314    (set_attr "modrm" "0")
14315    (set_attr "length" "7")
14316    (set_attr "memory" "load")
14317    (set_attr "imm_disp" "false")])
14319 (define_insn "*add_tp_di"
14320   [(set (match_operand:DI 0 "register_operand" "=r")
14321         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14322                  (match_operand:DI 1 "register_operand" "0")))
14323    (clobber (reg:CC FLAGS_REG))]
14324   "TARGET_64BIT"
14325   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14326   [(set_attr "type" "alu")
14327    (set_attr "modrm" "0")
14328    (set_attr "length" "7")
14329    (set_attr "memory" "load")
14330    (set_attr "imm_disp" "false")])
14332 ;; These patterns match the binary 387 instructions for addM3, subM3,
14333 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14334 ;; SFmode.  The first is the normal insn, the second the same insn but
14335 ;; with one operand a conversion, and the third the same insn but with
14336 ;; the other operand a conversion.  The conversion may be SFmode or
14337 ;; SImode if the target mode DFmode, but only SImode if the target mode
14338 ;; is SFmode.
14340 ;; Gcc is slightly more smart about handling normal two address instructions
14341 ;; so use special patterns for add and mull.
14342 (define_insn "*fop_sf_comm_nosse"
14343   [(set (match_operand:SF 0 "register_operand" "=f")
14344         (match_operator:SF 3 "binary_fp_operator"
14345                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14346                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14347   "TARGET_80387 && !TARGET_SSE_MATH
14348    && COMMUTATIVE_ARITH_P (operands[3])
14349    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14350   "* return output_387_binary_op (insn, operands);"
14351   [(set (attr "type") 
14352         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14353            (const_string "fmul")
14354            (const_string "fop")))
14355    (set_attr "mode" "SF")])
14357 (define_insn "*fop_sf_comm"
14358   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14359         (match_operator:SF 3 "binary_fp_operator"
14360                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14361                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14362   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14363    && COMMUTATIVE_ARITH_P (operands[3])
14364    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14365   "* return output_387_binary_op (insn, operands);"
14366   [(set (attr "type") 
14367         (if_then_else (eq_attr "alternative" "1")
14368            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14369               (const_string "ssemul")
14370               (const_string "sseadd"))
14371            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14372               (const_string "fmul")
14373               (const_string "fop"))))
14374    (set_attr "mode" "SF")])
14376 (define_insn "*fop_sf_comm_sse"
14377   [(set (match_operand:SF 0 "register_operand" "=x")
14378         (match_operator:SF 3 "binary_fp_operator"
14379                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14380                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14381   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14382    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14383   "* return output_387_binary_op (insn, operands);"
14384   [(set (attr "type") 
14385         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14386            (const_string "ssemul")
14387            (const_string "sseadd")))
14388    (set_attr "mode" "SF")])
14390 (define_insn "*fop_df_comm_nosse"
14391   [(set (match_operand:DF 0 "register_operand" "=f")
14392         (match_operator:DF 3 "binary_fp_operator"
14393                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14394                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14395   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14396    && COMMUTATIVE_ARITH_P (operands[3])
14397    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14398   "* return output_387_binary_op (insn, operands);"
14399   [(set (attr "type") 
14400         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14401            (const_string "fmul")
14402            (const_string "fop")))
14403    (set_attr "mode" "DF")])
14405 (define_insn "*fop_df_comm"
14406   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14407         (match_operator:DF 3 "binary_fp_operator"
14408                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14409                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14410   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14411    && COMMUTATIVE_ARITH_P (operands[3])
14412    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14413   "* return output_387_binary_op (insn, operands);"
14414   [(set (attr "type") 
14415         (if_then_else (eq_attr "alternative" "1")
14416            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14417               (const_string "ssemul")
14418               (const_string "sseadd"))
14419            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14420               (const_string "fmul")
14421               (const_string "fop"))))
14422    (set_attr "mode" "DF")])
14424 (define_insn "*fop_df_comm_sse"
14425   [(set (match_operand:DF 0 "register_operand" "=Y")
14426         (match_operator:DF 3 "binary_fp_operator"
14427                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14428                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14429   "TARGET_SSE2 && TARGET_SSE_MATH
14430    && COMMUTATIVE_ARITH_P (operands[3])
14431    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14432   "* return output_387_binary_op (insn, operands);"
14433   [(set (attr "type") 
14434         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14435            (const_string "ssemul")
14436            (const_string "sseadd")))
14437    (set_attr "mode" "DF")])
14439 (define_insn "*fop_xf_comm"
14440   [(set (match_operand:XF 0 "register_operand" "=f")
14441         (match_operator:XF 3 "binary_fp_operator"
14442                         [(match_operand:XF 1 "register_operand" "%0")
14443                          (match_operand:XF 2 "register_operand" "f")]))]
14444   "TARGET_80387
14445    && COMMUTATIVE_ARITH_P (operands[3])"
14446   "* return output_387_binary_op (insn, operands);"
14447   [(set (attr "type") 
14448         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14449            (const_string "fmul")
14450            (const_string "fop")))
14451    (set_attr "mode" "XF")])
14453 (define_insn "*fop_sf_1_nosse"
14454   [(set (match_operand:SF 0 "register_operand" "=f,f")
14455         (match_operator:SF 3 "binary_fp_operator"
14456                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14457                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14458   "TARGET_80387 && !TARGET_SSE_MATH
14459    && !COMMUTATIVE_ARITH_P (operands[3])
14460    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14461   "* return output_387_binary_op (insn, operands);"
14462   [(set (attr "type") 
14463         (cond [(match_operand:SF 3 "mult_operator" "") 
14464                  (const_string "fmul")
14465                (match_operand:SF 3 "div_operator" "") 
14466                  (const_string "fdiv")
14467               ]
14468               (const_string "fop")))
14469    (set_attr "mode" "SF")])
14471 (define_insn "*fop_sf_1"
14472   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14473         (match_operator:SF 3 "binary_fp_operator"
14474                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14475                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14476   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14477    && !COMMUTATIVE_ARITH_P (operands[3])
14478    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14479   "* return output_387_binary_op (insn, operands);"
14480   [(set (attr "type") 
14481         (cond [(and (eq_attr "alternative" "2")
14482                     (match_operand:SF 3 "mult_operator" ""))
14483                  (const_string "ssemul")
14484                (and (eq_attr "alternative" "2")
14485                     (match_operand:SF 3 "div_operator" ""))
14486                  (const_string "ssediv")
14487                (eq_attr "alternative" "2")
14488                  (const_string "sseadd")
14489                (match_operand:SF 3 "mult_operator" "") 
14490                  (const_string "fmul")
14491                (match_operand:SF 3 "div_operator" "") 
14492                  (const_string "fdiv")
14493               ]
14494               (const_string "fop")))
14495    (set_attr "mode" "SF")])
14497 (define_insn "*fop_sf_1_sse"
14498   [(set (match_operand:SF 0 "register_operand" "=x")
14499         (match_operator:SF 3 "binary_fp_operator"
14500                         [(match_operand:SF 1 "register_operand" "0")
14501                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14502   "TARGET_SSE_MATH
14503    && !COMMUTATIVE_ARITH_P (operands[3])"
14504   "* return output_387_binary_op (insn, operands);"
14505   [(set (attr "type") 
14506         (cond [(match_operand:SF 3 "mult_operator" "")
14507                  (const_string "ssemul")
14508                (match_operand:SF 3 "div_operator" "")
14509                  (const_string "ssediv")
14510               ]
14511               (const_string "sseadd")))
14512    (set_attr "mode" "SF")])
14514 ;; ??? Add SSE splitters for these!
14515 (define_insn "*fop_sf_2"
14516   [(set (match_operand:SF 0 "register_operand" "=f,f")
14517         (match_operator:SF 3 "binary_fp_operator"
14518           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14519            (match_operand:SF 2 "register_operand" "0,0")]))]
14520   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14521   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14522   [(set (attr "type") 
14523         (cond [(match_operand:SF 3 "mult_operator" "") 
14524                  (const_string "fmul")
14525                (match_operand:SF 3 "div_operator" "") 
14526                  (const_string "fdiv")
14527               ]
14528               (const_string "fop")))
14529    (set_attr "fp_int_src" "true")
14530    (set_attr "mode" "SI")])
14532 (define_insn "*fop_sf_3"
14533   [(set (match_operand:SF 0 "register_operand" "=f,f")
14534         (match_operator:SF 3 "binary_fp_operator"
14535           [(match_operand:SF 1 "register_operand" "0,0")
14536            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14537   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14538   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14539   [(set (attr "type") 
14540         (cond [(match_operand:SF 3 "mult_operator" "") 
14541                  (const_string "fmul")
14542                (match_operand:SF 3 "div_operator" "") 
14543                  (const_string "fdiv")
14544               ]
14545               (const_string "fop")))
14546    (set_attr "fp_int_src" "true")
14547    (set_attr "mode" "SI")])
14549 (define_insn "*fop_df_1_nosse"
14550   [(set (match_operand:DF 0 "register_operand" "=f,f")
14551         (match_operator:DF 3 "binary_fp_operator"
14552                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14553                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14554   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14555    && !COMMUTATIVE_ARITH_P (operands[3])
14556    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14557   "* return output_387_binary_op (insn, operands);"
14558   [(set (attr "type") 
14559         (cond [(match_operand:DF 3 "mult_operator" "") 
14560                  (const_string "fmul")
14561                (match_operand:DF 3 "div_operator" "")
14562                  (const_string "fdiv")
14563               ]
14564               (const_string "fop")))
14565    (set_attr "mode" "DF")])
14568 (define_insn "*fop_df_1"
14569   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14570         (match_operator:DF 3 "binary_fp_operator"
14571                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14572                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14573   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14574    && !COMMUTATIVE_ARITH_P (operands[3])
14575    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14576   "* return output_387_binary_op (insn, operands);"
14577   [(set (attr "type") 
14578         (cond [(and (eq_attr "alternative" "2")
14579                     (match_operand:SF 3 "mult_operator" ""))
14580                  (const_string "ssemul")
14581                (and (eq_attr "alternative" "2")
14582                     (match_operand:SF 3 "div_operator" ""))
14583                  (const_string "ssediv")
14584                (eq_attr "alternative" "2")
14585                  (const_string "sseadd")
14586                (match_operand:DF 3 "mult_operator" "") 
14587                  (const_string "fmul")
14588                (match_operand:DF 3 "div_operator" "") 
14589                  (const_string "fdiv")
14590               ]
14591               (const_string "fop")))
14592    (set_attr "mode" "DF")])
14594 (define_insn "*fop_df_1_sse"
14595   [(set (match_operand:DF 0 "register_operand" "=Y")
14596         (match_operator:DF 3 "binary_fp_operator"
14597                         [(match_operand:DF 1 "register_operand" "0")
14598                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14599   "TARGET_SSE2 && TARGET_SSE_MATH
14600    && !COMMUTATIVE_ARITH_P (operands[3])"
14601   "* return output_387_binary_op (insn, operands);"
14602   [(set_attr "mode" "DF")
14603    (set (attr "type") 
14604         (cond [(match_operand:SF 3 "mult_operator" "")
14605                  (const_string "ssemul")
14606                (match_operand:SF 3 "div_operator" "")
14607                  (const_string "ssediv")
14608               ]
14609               (const_string "sseadd")))])
14611 ;; ??? Add SSE splitters for these!
14612 (define_insn "*fop_df_2"
14613   [(set (match_operand:DF 0 "register_operand" "=f,f")
14614         (match_operator:DF 3 "binary_fp_operator"
14615            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14616             (match_operand:DF 2 "register_operand" "0,0")]))]
14617   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14618   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14619   [(set (attr "type") 
14620         (cond [(match_operand:DF 3 "mult_operator" "") 
14621                  (const_string "fmul")
14622                (match_operand:DF 3 "div_operator" "") 
14623                  (const_string "fdiv")
14624               ]
14625               (const_string "fop")))
14626    (set_attr "fp_int_src" "true")
14627    (set_attr "mode" "SI")])
14629 (define_insn "*fop_df_3"
14630   [(set (match_operand:DF 0 "register_operand" "=f,f")
14631         (match_operator:DF 3 "binary_fp_operator"
14632            [(match_operand:DF 1 "register_operand" "0,0")
14633             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14634   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14635   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14636   [(set (attr "type") 
14637         (cond [(match_operand:DF 3 "mult_operator" "") 
14638                  (const_string "fmul")
14639                (match_operand:DF 3 "div_operator" "") 
14640                  (const_string "fdiv")
14641               ]
14642               (const_string "fop")))
14643    (set_attr "fp_int_src" "true")
14644    (set_attr "mode" "SI")])
14646 (define_insn "*fop_df_4"
14647   [(set (match_operand:DF 0 "register_operand" "=f,f")
14648         (match_operator:DF 3 "binary_fp_operator"
14649            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14650             (match_operand:DF 2 "register_operand" "0,f")]))]
14651   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14652    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14653   "* return output_387_binary_op (insn, operands);"
14654   [(set (attr "type") 
14655         (cond [(match_operand:DF 3 "mult_operator" "") 
14656                  (const_string "fmul")
14657                (match_operand:DF 3 "div_operator" "") 
14658                  (const_string "fdiv")
14659               ]
14660               (const_string "fop")))
14661    (set_attr "mode" "SF")])
14663 (define_insn "*fop_df_5"
14664   [(set (match_operand:DF 0 "register_operand" "=f,f")
14665         (match_operator:DF 3 "binary_fp_operator"
14666           [(match_operand:DF 1 "register_operand" "0,f")
14667            (float_extend:DF
14668             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14669   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14670   "* return output_387_binary_op (insn, operands);"
14671   [(set (attr "type") 
14672         (cond [(match_operand:DF 3 "mult_operator" "") 
14673                  (const_string "fmul")
14674                (match_operand:DF 3 "div_operator" "") 
14675                  (const_string "fdiv")
14676               ]
14677               (const_string "fop")))
14678    (set_attr "mode" "SF")])
14680 (define_insn "*fop_df_6"
14681   [(set (match_operand:DF 0 "register_operand" "=f,f")
14682         (match_operator:DF 3 "binary_fp_operator"
14683           [(float_extend:DF
14684             (match_operand:SF 1 "register_operand" "0,f"))
14685            (float_extend:DF
14686             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14687   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14688   "* return output_387_binary_op (insn, operands);"
14689   [(set (attr "type") 
14690         (cond [(match_operand:DF 3 "mult_operator" "") 
14691                  (const_string "fmul")
14692                (match_operand:DF 3 "div_operator" "") 
14693                  (const_string "fdiv")
14694               ]
14695               (const_string "fop")))
14696    (set_attr "mode" "SF")])
14698 (define_insn "*fop_xf_1"
14699   [(set (match_operand:XF 0 "register_operand" "=f,f")
14700         (match_operator:XF 3 "binary_fp_operator"
14701                         [(match_operand:XF 1 "register_operand" "0,f")
14702                          (match_operand:XF 2 "register_operand" "f,0")]))]
14703   "TARGET_80387
14704    && !COMMUTATIVE_ARITH_P (operands[3])"
14705   "* return output_387_binary_op (insn, operands);"
14706   [(set (attr "type") 
14707         (cond [(match_operand:XF 3 "mult_operator" "") 
14708                  (const_string "fmul")
14709                (match_operand:XF 3 "div_operator" "") 
14710                  (const_string "fdiv")
14711               ]
14712               (const_string "fop")))
14713    (set_attr "mode" "XF")])
14715 (define_insn "*fop_xf_2"
14716   [(set (match_operand:XF 0 "register_operand" "=f,f")
14717         (match_operator:XF 3 "binary_fp_operator"
14718            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14719             (match_operand:XF 2 "register_operand" "0,0")]))]
14720   "TARGET_80387 && TARGET_USE_FIOP"
14721   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14722   [(set (attr "type") 
14723         (cond [(match_operand:XF 3 "mult_operator" "") 
14724                  (const_string "fmul")
14725                (match_operand:XF 3 "div_operator" "") 
14726                  (const_string "fdiv")
14727               ]
14728               (const_string "fop")))
14729    (set_attr "fp_int_src" "true")
14730    (set_attr "mode" "SI")])
14732 (define_insn "*fop_xf_3"
14733   [(set (match_operand:XF 0 "register_operand" "=f,f")
14734         (match_operator:XF 3 "binary_fp_operator"
14735           [(match_operand:XF 1 "register_operand" "0,0")
14736            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14737   "TARGET_80387 && TARGET_USE_FIOP"
14738   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14739   [(set (attr "type") 
14740         (cond [(match_operand:XF 3 "mult_operator" "") 
14741                  (const_string "fmul")
14742                (match_operand:XF 3 "div_operator" "") 
14743                  (const_string "fdiv")
14744               ]
14745               (const_string "fop")))
14746    (set_attr "fp_int_src" "true")
14747    (set_attr "mode" "SI")])
14749 (define_insn "*fop_xf_4"
14750   [(set (match_operand:XF 0 "register_operand" "=f,f")
14751         (match_operator:XF 3 "binary_fp_operator"
14752            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14753             (match_operand:XF 2 "register_operand" "0,f")]))]
14754   "TARGET_80387"
14755   "* return output_387_binary_op (insn, operands);"
14756   [(set (attr "type") 
14757         (cond [(match_operand:XF 3 "mult_operator" "") 
14758                  (const_string "fmul")
14759                (match_operand:XF 3 "div_operator" "") 
14760                  (const_string "fdiv")
14761               ]
14762               (const_string "fop")))
14763    (set_attr "mode" "SF")])
14765 (define_insn "*fop_xf_5"
14766   [(set (match_operand:XF 0 "register_operand" "=f,f")
14767         (match_operator:XF 3 "binary_fp_operator"
14768           [(match_operand:XF 1 "register_operand" "0,f")
14769            (float_extend:XF
14770             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14771   "TARGET_80387"
14772   "* return output_387_binary_op (insn, operands);"
14773   [(set (attr "type") 
14774         (cond [(match_operand:XF 3 "mult_operator" "") 
14775                  (const_string "fmul")
14776                (match_operand:XF 3 "div_operator" "") 
14777                  (const_string "fdiv")
14778               ]
14779               (const_string "fop")))
14780    (set_attr "mode" "SF")])
14782 (define_insn "*fop_xf_6"
14783   [(set (match_operand:XF 0 "register_operand" "=f,f")
14784         (match_operator:XF 3 "binary_fp_operator"
14785           [(float_extend:XF
14786             (match_operand 1 "register_operand" "0,f"))
14787            (float_extend:XF
14788             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14789   "TARGET_80387"
14790   "* return output_387_binary_op (insn, operands);"
14791   [(set (attr "type") 
14792         (cond [(match_operand:XF 3 "mult_operator" "") 
14793                  (const_string "fmul")
14794                (match_operand:XF 3 "div_operator" "") 
14795                  (const_string "fdiv")
14796               ]
14797               (const_string "fop")))
14798    (set_attr "mode" "SF")])
14800 (define_split
14801   [(set (match_operand 0 "register_operand" "")
14802         (match_operator 3 "binary_fp_operator"
14803            [(float (match_operand:SI 1 "register_operand" ""))
14804             (match_operand 2 "register_operand" "")]))]
14805   "TARGET_80387 && reload_completed
14806    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14807   [(const_int 0)]
14809   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14810   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14811   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14812                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14813                                           GET_MODE (operands[3]),
14814                                           operands[4],
14815                                           operands[2])));
14816   ix86_free_from_memory (GET_MODE (operands[1]));
14817   DONE;
14820 (define_split
14821   [(set (match_operand 0 "register_operand" "")
14822         (match_operator 3 "binary_fp_operator"
14823            [(match_operand 1 "register_operand" "")
14824             (float (match_operand:SI 2 "register_operand" ""))]))]
14825   "TARGET_80387 && reload_completed
14826    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14827   [(const_int 0)]
14829   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14830   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14831   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14832                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14833                                           GET_MODE (operands[3]),
14834                                           operands[1],
14835                                           operands[4])));
14836   ix86_free_from_memory (GET_MODE (operands[2]));
14837   DONE;
14840 ;; FPU special functions.
14842 (define_expand "sqrtsf2"
14843   [(set (match_operand:SF 0 "register_operand" "")
14844         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14845   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14847   if (!TARGET_SSE_MATH)
14848     operands[1] = force_reg (SFmode, operands[1]);
14851 (define_insn "sqrtsf2_1"
14852   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14853         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14854   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14855    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14856   "@
14857    fsqrt
14858    sqrtss\t{%1, %0|%0, %1}"
14859   [(set_attr "type" "fpspc,sse")
14860    (set_attr "mode" "SF,SF")
14861    (set_attr "athlon_decode" "direct,*")])
14863 (define_insn "sqrtsf2_1_sse_only"
14864   [(set (match_operand:SF 0 "register_operand" "=x")
14865         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14866   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14867   "sqrtss\t{%1, %0|%0, %1}"
14868   [(set_attr "type" "sse")
14869    (set_attr "mode" "SF")
14870    (set_attr "athlon_decode" "*")])
14872 (define_insn "sqrtsf2_i387"
14873   [(set (match_operand:SF 0 "register_operand" "=f")
14874         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14875   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14876    && !TARGET_SSE_MATH"
14877   "fsqrt"
14878   [(set_attr "type" "fpspc")
14879    (set_attr "mode" "SF")
14880    (set_attr "athlon_decode" "direct")])
14882 (define_expand "sqrtdf2"
14883   [(set (match_operand:DF 0 "register_operand" "")
14884         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14885   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14886    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14888   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14889     operands[1] = force_reg (DFmode, operands[1]);
14892 (define_insn "sqrtdf2_1"
14893   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14894         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14895   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14896    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14897   "@
14898    fsqrt
14899    sqrtsd\t{%1, %0|%0, %1}"
14900   [(set_attr "type" "fpspc,sse")
14901    (set_attr "mode" "DF,DF")
14902    (set_attr "athlon_decode" "direct,*")])
14904 (define_insn "sqrtdf2_1_sse_only"
14905   [(set (match_operand:DF 0 "register_operand" "=Y")
14906         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14907   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14908   "sqrtsd\t{%1, %0|%0, %1}"
14909   [(set_attr "type" "sse")
14910    (set_attr "mode" "DF")
14911    (set_attr "athlon_decode" "*")])
14913 (define_insn "sqrtdf2_i387"
14914   [(set (match_operand:DF 0 "register_operand" "=f")
14915         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14916   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14917    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14918   "fsqrt"
14919   [(set_attr "type" "fpspc")
14920    (set_attr "mode" "DF")
14921    (set_attr "athlon_decode" "direct")])
14923 (define_insn "*sqrtextendsfdf2"
14924   [(set (match_operand:DF 0 "register_operand" "=f")
14925         (sqrt:DF (float_extend:DF
14926                   (match_operand:SF 1 "register_operand" "0"))))]
14927   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14928    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14929   "fsqrt"
14930   [(set_attr "type" "fpspc")
14931    (set_attr "mode" "DF")
14932    (set_attr "athlon_decode" "direct")])
14934 (define_insn "sqrtxf2"
14935   [(set (match_operand:XF 0 "register_operand" "=f")
14936         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14937   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14938    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14939   "fsqrt"
14940   [(set_attr "type" "fpspc")
14941    (set_attr "mode" "XF")
14942    (set_attr "athlon_decode" "direct")])
14944 (define_insn "*sqrtextenddfxf2"
14945   [(set (match_operand:XF 0 "register_operand" "=f")
14946         (sqrt:XF (float_extend:XF
14947                   (match_operand:DF 1 "register_operand" "0"))))]
14948   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14949   "fsqrt"
14950   [(set_attr "type" "fpspc")
14951    (set_attr "mode" "XF")
14952    (set_attr "athlon_decode" "direct")])
14954 (define_insn "*sqrtextendsfxf2"
14955   [(set (match_operand:XF 0 "register_operand" "=f")
14956         (sqrt:XF (float_extend:XF
14957                   (match_operand:SF 1 "register_operand" "0"))))]
14958   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14959   "fsqrt"
14960   [(set_attr "type" "fpspc")
14961    (set_attr "mode" "XF")
14962    (set_attr "athlon_decode" "direct")])
14964 (define_insn "fpremxf4"
14965   [(set (match_operand:XF 0 "register_operand" "=f")
14966         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14967                     (match_operand:XF 3 "register_operand" "1")]
14968                    UNSPEC_FPREM_F))
14969    (set (match_operand:XF 1 "register_operand" "=u")
14970         (unspec:XF [(match_dup 2) (match_dup 3)]
14971                    UNSPEC_FPREM_U))
14972    (set (reg:CCFP FPSR_REG)
14973         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14974   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14975    && flag_unsafe_math_optimizations"
14976   "fprem"
14977   [(set_attr "type" "fpspc")
14978    (set_attr "mode" "XF")])
14980 (define_expand "fmodsf3"
14981   [(use (match_operand:SF 0 "register_operand" ""))
14982    (use (match_operand:SF 1 "register_operand" ""))
14983    (use (match_operand:SF 2 "register_operand" ""))]
14984   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14985    && flag_unsafe_math_optimizations"
14987   rtx label = gen_label_rtx ();
14989   rtx op1 = gen_reg_rtx (XFmode);
14990   rtx op2 = gen_reg_rtx (XFmode);
14992   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14993   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14995   emit_label (label);
14997   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14998   ix86_emit_fp_unordered_jump (label);
15000   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15001   DONE;
15004 (define_expand "fmoddf3"
15005   [(use (match_operand:DF 0 "register_operand" ""))
15006    (use (match_operand:DF 1 "register_operand" ""))
15007    (use (match_operand:DF 2 "register_operand" ""))]
15008   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15009    && flag_unsafe_math_optimizations"
15011   rtx label = gen_label_rtx ();
15013   rtx op1 = gen_reg_rtx (XFmode);
15014   rtx op2 = gen_reg_rtx (XFmode);
15016   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15017   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15019   emit_label (label);
15021   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15022   ix86_emit_fp_unordered_jump (label);
15024   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15025   DONE;
15028 (define_expand "fmodxf3"
15029   [(use (match_operand:XF 0 "register_operand" ""))
15030    (use (match_operand:XF 1 "register_operand" ""))
15031    (use (match_operand:XF 2 "register_operand" ""))]
15032   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15033    && flag_unsafe_math_optimizations"
15035   rtx label = gen_label_rtx ();
15037   emit_label (label);
15039   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15040                            operands[1], operands[2]));
15041   ix86_emit_fp_unordered_jump (label);
15043   emit_move_insn (operands[0], operands[1]);
15044   DONE;
15047 (define_insn "fprem1xf4"
15048   [(set (match_operand:XF 0 "register_operand" "=f")
15049         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15050                     (match_operand:XF 3 "register_operand" "1")]
15051                    UNSPEC_FPREM1_F))
15052    (set (match_operand:XF 1 "register_operand" "=u")
15053         (unspec:XF [(match_dup 2) (match_dup 3)]
15054                    UNSPEC_FPREM1_U))
15055    (set (reg:CCFP FPSR_REG)
15056         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15057   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15058    && flag_unsafe_math_optimizations"
15059   "fprem1"
15060   [(set_attr "type" "fpspc")
15061    (set_attr "mode" "XF")])
15063 (define_expand "dremsf3"
15064   [(use (match_operand:SF 0 "register_operand" ""))
15065    (use (match_operand:SF 1 "register_operand" ""))
15066    (use (match_operand:SF 2 "register_operand" ""))]
15067   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15068    && flag_unsafe_math_optimizations"
15070   rtx label = gen_label_rtx ();
15072   rtx op1 = gen_reg_rtx (XFmode);
15073   rtx op2 = gen_reg_rtx (XFmode);
15075   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15076   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15078   emit_label (label);
15080   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15081   ix86_emit_fp_unordered_jump (label);
15083   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15084   DONE;
15087 (define_expand "dremdf3"
15088   [(use (match_operand:DF 0 "register_operand" ""))
15089    (use (match_operand:DF 1 "register_operand" ""))
15090    (use (match_operand:DF 2 "register_operand" ""))]
15091   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15092    && flag_unsafe_math_optimizations"
15094   rtx label = gen_label_rtx ();
15096   rtx op1 = gen_reg_rtx (XFmode);
15097   rtx op2 = gen_reg_rtx (XFmode);
15099   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15100   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15102   emit_label (label);
15104   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15105   ix86_emit_fp_unordered_jump (label);
15107   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15108   DONE;
15111 (define_expand "dremxf3"
15112   [(use (match_operand:XF 0 "register_operand" ""))
15113    (use (match_operand:XF 1 "register_operand" ""))
15114    (use (match_operand:XF 2 "register_operand" ""))]
15115   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15116    && flag_unsafe_math_optimizations"
15118   rtx label = gen_label_rtx ();
15120   emit_label (label);
15122   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15123                             operands[1], operands[2]));
15124   ix86_emit_fp_unordered_jump (label);
15126   emit_move_insn (operands[0], operands[1]);
15127   DONE;
15130 (define_insn "*sindf2"
15131   [(set (match_operand:DF 0 "register_operand" "=f")
15132         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15133   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15134    && flag_unsafe_math_optimizations"
15135   "fsin"
15136   [(set_attr "type" "fpspc")
15137    (set_attr "mode" "DF")])
15139 (define_insn "*sinsf2"
15140   [(set (match_operand:SF 0 "register_operand" "=f")
15141         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15142   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15143    && flag_unsafe_math_optimizations"
15144   "fsin"
15145   [(set_attr "type" "fpspc")
15146    (set_attr "mode" "SF")])
15148 (define_insn "*sinextendsfdf2"
15149   [(set (match_operand:DF 0 "register_operand" "=f")
15150         (unspec:DF [(float_extend:DF
15151                      (match_operand:SF 1 "register_operand" "0"))]
15152                    UNSPEC_SIN))]
15153   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15154    && flag_unsafe_math_optimizations"
15155   "fsin"
15156   [(set_attr "type" "fpspc")
15157    (set_attr "mode" "DF")])
15159 (define_insn "*sinxf2"
15160   [(set (match_operand:XF 0 "register_operand" "=f")
15161         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15162   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15163    && flag_unsafe_math_optimizations"
15164   "fsin"
15165   [(set_attr "type" "fpspc")
15166    (set_attr "mode" "XF")])
15168 (define_insn "*cosdf2"
15169   [(set (match_operand:DF 0 "register_operand" "=f")
15170         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15171   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15172    && flag_unsafe_math_optimizations"
15173   "fcos"
15174   [(set_attr "type" "fpspc")
15175    (set_attr "mode" "DF")])
15177 (define_insn "*cossf2"
15178   [(set (match_operand:SF 0 "register_operand" "=f")
15179         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15180   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15181    && flag_unsafe_math_optimizations"
15182   "fcos"
15183   [(set_attr "type" "fpspc")
15184    (set_attr "mode" "SF")])
15186 (define_insn "*cosextendsfdf2"
15187   [(set (match_operand:DF 0 "register_operand" "=f")
15188         (unspec:DF [(float_extend:DF
15189                      (match_operand:SF 1 "register_operand" "0"))]
15190                    UNSPEC_COS))]
15191   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15192    && flag_unsafe_math_optimizations"
15193   "fcos"
15194   [(set_attr "type" "fpspc")
15195    (set_attr "mode" "DF")])
15197 (define_insn "*cosxf2"
15198   [(set (match_operand:XF 0 "register_operand" "=f")
15199         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15200   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15201    && flag_unsafe_math_optimizations"
15202   "fcos"
15203   [(set_attr "type" "fpspc")
15204    (set_attr "mode" "XF")])
15206 ;; With sincos pattern defined, sin and cos builtin function will be
15207 ;; expanded to sincos pattern with one of its outputs left unused. 
15208 ;; Cse pass  will detected, if two sincos patterns can be combined,
15209 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15210 ;; depending on the unused output.
15212 (define_insn "sincosdf3"
15213   [(set (match_operand:DF 0 "register_operand" "=f")
15214         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15215                    UNSPEC_SINCOS_COS))
15216    (set (match_operand:DF 1 "register_operand" "=u")
15217         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15218   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15219    && flag_unsafe_math_optimizations"
15220   "fsincos"
15221   [(set_attr "type" "fpspc")
15222    (set_attr "mode" "DF")])
15224 (define_split
15225   [(set (match_operand:DF 0 "register_operand" "")
15226         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15227                    UNSPEC_SINCOS_COS))
15228    (set (match_operand:DF 1 "register_operand" "")
15229         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15230   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15231    && !reload_completed && !reload_in_progress"
15232   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15233   "")
15235 (define_split
15236   [(set (match_operand:DF 0 "register_operand" "")
15237         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15238                    UNSPEC_SINCOS_COS))
15239    (set (match_operand:DF 1 "register_operand" "")
15240         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15241   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15242    && !reload_completed && !reload_in_progress"
15243   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15244   "")
15246 (define_insn "sincossf3"
15247   [(set (match_operand:SF 0 "register_operand" "=f")
15248         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15249                    UNSPEC_SINCOS_COS))
15250    (set (match_operand:SF 1 "register_operand" "=u")
15251         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15252   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15253    && flag_unsafe_math_optimizations"
15254   "fsincos"
15255   [(set_attr "type" "fpspc")
15256    (set_attr "mode" "SF")])
15258 (define_split
15259   [(set (match_operand:SF 0 "register_operand" "")
15260         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15261                    UNSPEC_SINCOS_COS))
15262    (set (match_operand:SF 1 "register_operand" "")
15263         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15264   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15265    && !reload_completed && !reload_in_progress"
15266   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15267   "")
15269 (define_split
15270   [(set (match_operand:SF 0 "register_operand" "")
15271         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15272                    UNSPEC_SINCOS_COS))
15273    (set (match_operand:SF 1 "register_operand" "")
15274         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15275   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15276    && !reload_completed && !reload_in_progress"
15277   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15278   "")
15280 (define_insn "*sincosextendsfdf3"
15281   [(set (match_operand:DF 0 "register_operand" "=f")
15282         (unspec:DF [(float_extend:DF
15283                      (match_operand:SF 2 "register_operand" "0"))]
15284                    UNSPEC_SINCOS_COS))
15285    (set (match_operand:DF 1 "register_operand" "=u")
15286         (unspec:DF [(float_extend:DF
15287                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15288   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15289    && flag_unsafe_math_optimizations"
15290   "fsincos"
15291   [(set_attr "type" "fpspc")
15292    (set_attr "mode" "DF")])
15294 (define_split
15295   [(set (match_operand:DF 0 "register_operand" "")
15296         (unspec:DF [(float_extend:DF
15297                      (match_operand:SF 2 "register_operand" ""))]
15298                    UNSPEC_SINCOS_COS))
15299    (set (match_operand:DF 1 "register_operand" "")
15300         (unspec:DF [(float_extend:DF
15301                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15302   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15303    && !reload_completed && !reload_in_progress"
15304   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15305                                    (match_dup 2))] UNSPEC_SIN))]
15306   "")
15308 (define_split
15309   [(set (match_operand:DF 0 "register_operand" "")
15310         (unspec:DF [(float_extend:DF
15311                      (match_operand:SF 2 "register_operand" ""))]
15312                    UNSPEC_SINCOS_COS))
15313    (set (match_operand:DF 1 "register_operand" "")
15314         (unspec:DF [(float_extend:DF
15315                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15316   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15317    && !reload_completed && !reload_in_progress"
15318   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15319                                    (match_dup 2))] UNSPEC_COS))]
15320   "")
15322 (define_insn "sincosxf3"
15323   [(set (match_operand:XF 0 "register_operand" "=f")
15324         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15325                    UNSPEC_SINCOS_COS))
15326    (set (match_operand:XF 1 "register_operand" "=u")
15327         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15328   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15329    && flag_unsafe_math_optimizations"
15330   "fsincos"
15331   [(set_attr "type" "fpspc")
15332    (set_attr "mode" "XF")])
15334 (define_split
15335   [(set (match_operand:XF 0 "register_operand" "")
15336         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15337                    UNSPEC_SINCOS_COS))
15338    (set (match_operand:XF 1 "register_operand" "")
15339         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15340   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15341    && !reload_completed && !reload_in_progress"
15342   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15343   "")
15345 (define_split
15346   [(set (match_operand:XF 0 "register_operand" "")
15347         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15348                    UNSPEC_SINCOS_COS))
15349    (set (match_operand:XF 1 "register_operand" "")
15350         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15351   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15352    && !reload_completed && !reload_in_progress"
15353   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15354   "")
15356 (define_insn "*tandf3_1"
15357   [(set (match_operand:DF 0 "register_operand" "=f")
15358         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15359                    UNSPEC_TAN_ONE))
15360    (set (match_operand:DF 1 "register_operand" "=u")
15361         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15362   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15363    && flag_unsafe_math_optimizations"
15364   "fptan"
15365   [(set_attr "type" "fpspc")
15366    (set_attr "mode" "DF")])
15368 ;; optimize sequence: fptan
15369 ;;                    fstp    %st(0)
15370 ;;                    fld1
15371 ;; into fptan insn.
15373 (define_peephole2
15374   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15375                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15376                              UNSPEC_TAN_ONE))
15377              (set (match_operand:DF 1 "register_operand" "")
15378                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15379    (set (match_dup 0)
15380         (match_operand:DF 3 "immediate_operand" ""))]
15381   "standard_80387_constant_p (operands[3]) == 2"
15382   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15383              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15384   "")
15386 (define_expand "tandf2"
15387   [(parallel [(set (match_dup 2)
15388                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15389                               UNSPEC_TAN_ONE))
15390               (set (match_operand:DF 0 "register_operand" "")
15391                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15392   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15393    && flag_unsafe_math_optimizations"
15395   operands[2] = gen_reg_rtx (DFmode);
15398 (define_insn "*tansf3_1"
15399   [(set (match_operand:SF 0 "register_operand" "=f")
15400         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15401                    UNSPEC_TAN_ONE))
15402    (set (match_operand:SF 1 "register_operand" "=u")
15403         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15404   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15405    && flag_unsafe_math_optimizations"
15406   "fptan"
15407   [(set_attr "type" "fpspc")
15408    (set_attr "mode" "SF")])
15410 ;; optimize sequence: fptan
15411 ;;                    fstp    %st(0)
15412 ;;                    fld1
15413 ;; into fptan insn.
15415 (define_peephole2
15416   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15417                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15418                              UNSPEC_TAN_ONE))
15419              (set (match_operand:SF 1 "register_operand" "")
15420                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15421    (set (match_dup 0)
15422         (match_operand:SF 3 "immediate_operand" ""))]
15423   "standard_80387_constant_p (operands[3]) == 2"
15424   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15425              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15426   "")
15428 (define_expand "tansf2"
15429   [(parallel [(set (match_dup 2)
15430                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15431                               UNSPEC_TAN_ONE))
15432               (set (match_operand:SF 0 "register_operand" "")
15433                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15434   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15435    && flag_unsafe_math_optimizations"
15437   operands[2] = gen_reg_rtx (SFmode);
15440 (define_insn "*tanxf3_1"
15441   [(set (match_operand:XF 0 "register_operand" "=f")
15442         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15443                    UNSPEC_TAN_ONE))
15444    (set (match_operand:XF 1 "register_operand" "=u")
15445         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15446   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15447    && flag_unsafe_math_optimizations"
15448   "fptan"
15449   [(set_attr "type" "fpspc")
15450    (set_attr "mode" "XF")])
15452 ;; optimize sequence: fptan
15453 ;;                    fstp    %st(0)
15454 ;;                    fld1
15455 ;; into fptan insn.
15457 (define_peephole2
15458   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15459                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15460                              UNSPEC_TAN_ONE))
15461              (set (match_operand:XF 1 "register_operand" "")
15462                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15463    (set (match_dup 0)
15464         (match_operand:XF 3 "immediate_operand" ""))]
15465   "standard_80387_constant_p (operands[3]) == 2"
15466   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15467              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15468   "")
15470 (define_expand "tanxf2"
15471   [(parallel [(set (match_dup 2)
15472                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15473                               UNSPEC_TAN_ONE))
15474               (set (match_operand:XF 0 "register_operand" "")
15475                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15476   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15477    && flag_unsafe_math_optimizations"
15479   operands[2] = gen_reg_rtx (XFmode);
15482 (define_insn "atan2df3_1"
15483   [(set (match_operand:DF 0 "register_operand" "=f")
15484         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15485                     (match_operand:DF 1 "register_operand" "u")]
15486                    UNSPEC_FPATAN))
15487    (clobber (match_scratch:DF 3 "=1"))]
15488   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15489    && flag_unsafe_math_optimizations"
15490   "fpatan"
15491   [(set_attr "type" "fpspc")
15492    (set_attr "mode" "DF")])
15494 (define_expand "atan2df3"
15495   [(use (match_operand:DF 0 "register_operand" "=f"))
15496    (use (match_operand:DF 2 "register_operand" "0"))
15497    (use (match_operand:DF 1 "register_operand" "u"))]
15498   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15499    && flag_unsafe_math_optimizations"
15501   rtx copy = gen_reg_rtx (DFmode);
15502   emit_move_insn (copy, operands[1]);
15503   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15504   DONE;
15507 (define_expand "atandf2"
15508   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15509                    (unspec:DF [(match_dup 2)
15510                                (match_operand:DF 1 "register_operand" "")]
15511                     UNSPEC_FPATAN))
15512               (clobber (match_scratch:DF 3 ""))])]
15513   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15514    && flag_unsafe_math_optimizations"
15516   operands[2] = gen_reg_rtx (DFmode);
15517   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15520 (define_insn "atan2sf3_1"
15521   [(set (match_operand:SF 0 "register_operand" "=f")
15522         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15523                     (match_operand:SF 1 "register_operand" "u")]
15524                    UNSPEC_FPATAN))
15525    (clobber (match_scratch:SF 3 "=1"))]
15526   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15527    && flag_unsafe_math_optimizations"
15528   "fpatan"
15529   [(set_attr "type" "fpspc")
15530    (set_attr "mode" "SF")])
15532 (define_expand "atan2sf3"
15533   [(use (match_operand:SF 0 "register_operand" "=f"))
15534    (use (match_operand:SF 2 "register_operand" "0"))
15535    (use (match_operand:SF 1 "register_operand" "u"))]
15536   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15537    && flag_unsafe_math_optimizations"
15539   rtx copy = gen_reg_rtx (SFmode);
15540   emit_move_insn (copy, operands[1]);
15541   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15542   DONE;
15545 (define_expand "atansf2"
15546   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15547                    (unspec:SF [(match_dup 2)
15548                                (match_operand:SF 1 "register_operand" "")]
15549                     UNSPEC_FPATAN))
15550               (clobber (match_scratch:SF 3 ""))])]
15551   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15552    && flag_unsafe_math_optimizations"
15554   operands[2] = gen_reg_rtx (SFmode);
15555   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15558 (define_insn "atan2xf3_1"
15559   [(set (match_operand:XF 0 "register_operand" "=f")
15560         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15561                     (match_operand:XF 1 "register_operand" "u")]
15562                    UNSPEC_FPATAN))
15563    (clobber (match_scratch:XF 3 "=1"))]
15564   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15565    && flag_unsafe_math_optimizations"
15566   "fpatan"
15567   [(set_attr "type" "fpspc")
15568    (set_attr "mode" "XF")])
15570 (define_expand "atan2xf3"
15571   [(use (match_operand:XF 0 "register_operand" "=f"))
15572    (use (match_operand:XF 2 "register_operand" "0"))
15573    (use (match_operand:XF 1 "register_operand" "u"))]
15574   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15575    && flag_unsafe_math_optimizations"
15577   rtx copy = gen_reg_rtx (XFmode);
15578   emit_move_insn (copy, operands[1]);
15579   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15580   DONE;
15583 (define_expand "atanxf2"
15584   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15585                    (unspec:XF [(match_dup 2)
15586                                (match_operand:XF 1 "register_operand" "")]
15587                     UNSPEC_FPATAN))
15588               (clobber (match_scratch:XF 3 ""))])]
15589   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15590    && flag_unsafe_math_optimizations"
15592   operands[2] = gen_reg_rtx (XFmode);
15593   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15596 (define_expand "asindf2"
15597   [(set (match_dup 2)
15598         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15599    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15600    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15601    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15602    (parallel [(set (match_dup 7)
15603                    (unspec:XF [(match_dup 6) (match_dup 2)]
15604                               UNSPEC_FPATAN))
15605               (clobber (match_scratch:XF 8 ""))])
15606    (set (match_operand:DF 0 "register_operand" "")
15607         (float_truncate:DF (match_dup 7)))]
15608   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15609    && flag_unsafe_math_optimizations"
15611   int i;
15613   for (i=2; i<8; i++)
15614     operands[i] = gen_reg_rtx (XFmode);
15616   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15619 (define_expand "asinsf2"
15620   [(set (match_dup 2)
15621         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15622    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15623    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15624    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15625    (parallel [(set (match_dup 7)
15626                    (unspec:XF [(match_dup 6) (match_dup 2)]
15627                               UNSPEC_FPATAN))
15628               (clobber (match_scratch:XF 8 ""))])
15629    (set (match_operand:SF 0 "register_operand" "")
15630         (float_truncate:SF (match_dup 7)))]
15631   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15632    && flag_unsafe_math_optimizations"
15634   int i;
15636   for (i=2; i<8; i++)
15637     operands[i] = gen_reg_rtx (XFmode);
15639   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15642 (define_expand "asinxf2"
15643   [(set (match_dup 2)
15644         (mult:XF (match_operand:XF 1 "register_operand" "")
15645                  (match_dup 1)))
15646    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15647    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15648    (parallel [(set (match_operand:XF 0 "register_operand" "")
15649                    (unspec:XF [(match_dup 5) (match_dup 1)]
15650                               UNSPEC_FPATAN))
15651               (clobber (match_scratch:XF 6 ""))])]
15652   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15653    && flag_unsafe_math_optimizations"
15655   int i;
15657   for (i=2; i<6; i++)
15658     operands[i] = gen_reg_rtx (XFmode);
15660   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15663 (define_expand "acosdf2"
15664   [(set (match_dup 2)
15665         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15666    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15667    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15668    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15669    (parallel [(set (match_dup 7)
15670                    (unspec:XF [(match_dup 2) (match_dup 6)]
15671                               UNSPEC_FPATAN))
15672               (clobber (match_scratch:XF 8 ""))])
15673    (set (match_operand:DF 0 "register_operand" "")
15674         (float_truncate:DF (match_dup 7)))]
15675   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15676    && flag_unsafe_math_optimizations"
15678   int i;
15680   for (i=2; i<8; i++)
15681     operands[i] = gen_reg_rtx (XFmode);
15683   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15686 (define_expand "acossf2"
15687   [(set (match_dup 2)
15688         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15689    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15690    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15691    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15692    (parallel [(set (match_dup 7)
15693                    (unspec:XF [(match_dup 2) (match_dup 6)]
15694                               UNSPEC_FPATAN))
15695               (clobber (match_scratch:XF 8 ""))])
15696    (set (match_operand:SF 0 "register_operand" "")
15697         (float_truncate:SF (match_dup 7)))]
15698   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15699    && flag_unsafe_math_optimizations"
15701   int i;
15703   for (i=2; i<8; i++)
15704     operands[i] = gen_reg_rtx (XFmode);
15706   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15709 (define_expand "acosxf2"
15710   [(set (match_dup 2)
15711         (mult:XF (match_operand:XF 1 "register_operand" "")
15712                  (match_dup 1)))
15713    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15714    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15715    (parallel [(set (match_operand:XF 0 "register_operand" "")
15716                    (unspec:XF [(match_dup 1) (match_dup 5)]
15717                               UNSPEC_FPATAN))
15718               (clobber (match_scratch:XF 6 ""))])]
15719   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15720    && flag_unsafe_math_optimizations"
15722   int i;
15724   for (i=2; i<6; i++)
15725     operands[i] = gen_reg_rtx (XFmode);
15727   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15730 (define_insn "fyl2x_xf3"
15731   [(set (match_operand:XF 0 "register_operand" "=f")
15732         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15733                     (match_operand:XF 1 "register_operand" "u")]
15734                    UNSPEC_FYL2X))
15735    (clobber (match_scratch:XF 3 "=1"))]
15736   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15737    && flag_unsafe_math_optimizations"
15738   "fyl2x"
15739   [(set_attr "type" "fpspc")
15740    (set_attr "mode" "XF")])
15742 (define_expand "logsf2"
15743   [(set (match_dup 2)
15744         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15745    (parallel [(set (match_dup 4)
15746                    (unspec:XF [(match_dup 2)
15747                                (match_dup 3)] UNSPEC_FYL2X))
15748               (clobber (match_scratch:XF 5 ""))])
15749    (set (match_operand:SF 0 "register_operand" "")
15750         (float_truncate:SF (match_dup 4)))]
15751   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15752    && flag_unsafe_math_optimizations"
15754   rtx temp;
15756   operands[2] = gen_reg_rtx (XFmode);
15757   operands[3] = gen_reg_rtx (XFmode);
15758   operands[4] = gen_reg_rtx (XFmode);
15760   temp = standard_80387_constant_rtx (4); /* fldln2 */
15761   emit_move_insn (operands[3], temp);
15764 (define_expand "logdf2"
15765   [(set (match_dup 2)
15766         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15767    (parallel [(set (match_dup 4)
15768                    (unspec:XF [(match_dup 2)
15769                                (match_dup 3)] UNSPEC_FYL2X))
15770               (clobber (match_scratch:XF 5 ""))])
15771    (set (match_operand:DF 0 "register_operand" "")
15772         (float_truncate:DF (match_dup 4)))]
15773   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15774    && flag_unsafe_math_optimizations"
15776   rtx temp;
15778   operands[2] = gen_reg_rtx (XFmode);
15779   operands[3] = gen_reg_rtx (XFmode);
15780   operands[4] = gen_reg_rtx (XFmode);
15782   temp = standard_80387_constant_rtx (4); /* fldln2 */
15783   emit_move_insn (operands[3], temp);
15786 (define_expand "logxf2"
15787   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15788                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15789                                (match_dup 2)] UNSPEC_FYL2X))
15790               (clobber (match_scratch:XF 3 ""))])]
15791   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15792    && flag_unsafe_math_optimizations"
15794   rtx temp;
15796   operands[2] = gen_reg_rtx (XFmode);
15797   temp = standard_80387_constant_rtx (4); /* fldln2 */
15798   emit_move_insn (operands[2], temp);
15801 (define_expand "log10sf2"
15802   [(set (match_dup 2)
15803         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15804    (parallel [(set (match_dup 4)
15805                    (unspec:XF [(match_dup 2)
15806                                (match_dup 3)] UNSPEC_FYL2X))
15807               (clobber (match_scratch:XF 5 ""))])
15808    (set (match_operand:SF 0 "register_operand" "")
15809         (float_truncate:SF (match_dup 4)))]
15810   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15811    && flag_unsafe_math_optimizations"
15813   rtx temp;
15815   operands[2] = gen_reg_rtx (XFmode);
15816   operands[3] = gen_reg_rtx (XFmode);
15817   operands[4] = gen_reg_rtx (XFmode);
15819   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15820   emit_move_insn (operands[3], temp);
15823 (define_expand "log10df2"
15824   [(set (match_dup 2)
15825         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15826    (parallel [(set (match_dup 4)
15827                    (unspec:XF [(match_dup 2)
15828                                (match_dup 3)] UNSPEC_FYL2X))
15829               (clobber (match_scratch:XF 5 ""))])
15830    (set (match_operand:DF 0 "register_operand" "")
15831         (float_truncate:DF (match_dup 4)))]
15832   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15833    && flag_unsafe_math_optimizations"
15835   rtx temp;
15837   operands[2] = gen_reg_rtx (XFmode);
15838   operands[3] = gen_reg_rtx (XFmode);
15839   operands[4] = gen_reg_rtx (XFmode);
15841   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15842   emit_move_insn (operands[3], temp);
15845 (define_expand "log10xf2"
15846   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15847                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15848                                (match_dup 2)] UNSPEC_FYL2X))
15849               (clobber (match_scratch:XF 3 ""))])]
15850   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15851    && flag_unsafe_math_optimizations"
15853   rtx temp;
15855   operands[2] = gen_reg_rtx (XFmode);
15856   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15857   emit_move_insn (operands[2], temp);
15860 (define_expand "log2sf2"
15861   [(set (match_dup 2)
15862         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15863    (parallel [(set (match_dup 4)
15864                    (unspec:XF [(match_dup 2)
15865                                (match_dup 3)] UNSPEC_FYL2X))
15866               (clobber (match_scratch:XF 5 ""))])
15867    (set (match_operand:SF 0 "register_operand" "")
15868         (float_truncate:SF (match_dup 4)))]
15869   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15870    && flag_unsafe_math_optimizations"
15872   operands[2] = gen_reg_rtx (XFmode);
15873   operands[3] = gen_reg_rtx (XFmode);
15874   operands[4] = gen_reg_rtx (XFmode);
15876   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15879 (define_expand "log2df2"
15880   [(set (match_dup 2)
15881         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15882    (parallel [(set (match_dup 4)
15883                    (unspec:XF [(match_dup 2)
15884                                (match_dup 3)] UNSPEC_FYL2X))
15885               (clobber (match_scratch:XF 5 ""))])
15886    (set (match_operand:DF 0 "register_operand" "")
15887         (float_truncate:DF (match_dup 4)))]
15888   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15889    && flag_unsafe_math_optimizations"
15891   operands[2] = gen_reg_rtx (XFmode);
15892   operands[3] = gen_reg_rtx (XFmode);
15893   operands[4] = gen_reg_rtx (XFmode);
15895   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15898 (define_expand "log2xf2"
15899   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15900                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15901                                (match_dup 2)] UNSPEC_FYL2X))
15902               (clobber (match_scratch:XF 3 ""))])]
15903   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15904    && flag_unsafe_math_optimizations"
15906   operands[2] = gen_reg_rtx (XFmode);
15907   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15910 (define_insn "fyl2xp1_xf3"
15911   [(set (match_operand:XF 0 "register_operand" "=f")
15912         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15913                     (match_operand:XF 1 "register_operand" "u")]
15914                    UNSPEC_FYL2XP1))
15915    (clobber (match_scratch:XF 3 "=1"))]
15916   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15917    && flag_unsafe_math_optimizations"
15918   "fyl2xp1"
15919   [(set_attr "type" "fpspc")
15920    (set_attr "mode" "XF")])
15922 (define_expand "log1psf2"
15923   [(use (match_operand:XF 0 "register_operand" ""))
15924    (use (match_operand:XF 1 "register_operand" ""))]
15925   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15926    && flag_unsafe_math_optimizations"
15928   rtx op0 = gen_reg_rtx (XFmode);
15929   rtx op1 = gen_reg_rtx (XFmode);
15931   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15932   ix86_emit_i387_log1p (op0, op1);
15933   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15934   DONE;
15937 (define_expand "log1pdf2"
15938   [(use (match_operand:XF 0 "register_operand" ""))
15939    (use (match_operand:XF 1 "register_operand" ""))]
15940   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15941    && flag_unsafe_math_optimizations"
15943   rtx op0 = gen_reg_rtx (XFmode);
15944   rtx op1 = gen_reg_rtx (XFmode);
15946   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15947   ix86_emit_i387_log1p (op0, op1);
15948   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15949   DONE;
15952 (define_expand "log1pxf2"
15953   [(use (match_operand:XF 0 "register_operand" ""))
15954    (use (match_operand:XF 1 "register_operand" ""))]
15955   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15956    && flag_unsafe_math_optimizations"
15958   ix86_emit_i387_log1p (operands[0], operands[1]);
15959   DONE;
15962 (define_insn "*fxtractxf3"
15963   [(set (match_operand:XF 0 "register_operand" "=f")
15964         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15965                    UNSPEC_XTRACT_FRACT))
15966    (set (match_operand:XF 1 "register_operand" "=u")
15967         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15968   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15969    && flag_unsafe_math_optimizations"
15970   "fxtract"
15971   [(set_attr "type" "fpspc")
15972    (set_attr "mode" "XF")])
15974 (define_expand "logbsf2"
15975   [(set (match_dup 2)
15976         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15977    (parallel [(set (match_dup 3)
15978                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15979               (set (match_dup 4)
15980                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15981    (set (match_operand:SF 0 "register_operand" "")
15982         (float_truncate:SF (match_dup 4)))]
15983   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15984    && flag_unsafe_math_optimizations"
15986   operands[2] = gen_reg_rtx (XFmode);
15987   operands[3] = gen_reg_rtx (XFmode);
15988   operands[4] = gen_reg_rtx (XFmode);
15991 (define_expand "logbdf2"
15992   [(set (match_dup 2)
15993         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15994    (parallel [(set (match_dup 3)
15995                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15996               (set (match_dup 4)
15997                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15998    (set (match_operand:DF 0 "register_operand" "")
15999         (float_truncate:DF (match_dup 4)))]
16000   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16001    && flag_unsafe_math_optimizations"
16003   operands[2] = gen_reg_rtx (XFmode);
16004   operands[3] = gen_reg_rtx (XFmode);
16005   operands[4] = gen_reg_rtx (XFmode);
16008 (define_expand "logbxf2"
16009   [(parallel [(set (match_dup 2)
16010                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16011                               UNSPEC_XTRACT_FRACT))
16012               (set (match_operand:XF 0 "register_operand" "")
16013                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16014   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16015    && flag_unsafe_math_optimizations"
16017   operands[2] = gen_reg_rtx (XFmode);
16020 (define_expand "ilogbsi2"
16021   [(parallel [(set (match_dup 2)
16022                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16023                               UNSPEC_XTRACT_FRACT))
16024               (set (match_operand:XF 3 "register_operand" "")
16025                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16026    (parallel [(set (match_operand:SI 0 "register_operand" "")
16027                    (fix:SI (match_dup 3)))
16028               (clobber (reg:CC FLAGS_REG))])]
16029   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16030    && flag_unsafe_math_optimizations"
16032   operands[2] = gen_reg_rtx (XFmode);
16033   operands[3] = gen_reg_rtx (XFmode);
16036 (define_insn "*frndintxf2"
16037   [(set (match_operand:XF 0 "register_operand" "=f")
16038         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16039          UNSPEC_FRNDINT))]
16040   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16041    && flag_unsafe_math_optimizations"
16042   "frndint"
16043   [(set_attr "type" "fpspc")
16044    (set_attr "mode" "XF")])
16046 (define_insn "*f2xm1xf2"
16047   [(set (match_operand:XF 0 "register_operand" "=f")
16048         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16049          UNSPEC_F2XM1))]
16050   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16051    && flag_unsafe_math_optimizations"
16052   "f2xm1"
16053   [(set_attr "type" "fpspc")
16054    (set_attr "mode" "XF")])
16056 (define_insn "*fscalexf4"
16057   [(set (match_operand:XF 0 "register_operand" "=f")
16058         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16059                     (match_operand:XF 3 "register_operand" "1")]
16060                    UNSPEC_FSCALE_FRACT))
16061    (set (match_operand:XF 1 "register_operand" "=u")
16062         (unspec:XF [(match_dup 2) (match_dup 3)]
16063                    UNSPEC_FSCALE_EXP))]
16064   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16065    && flag_unsafe_math_optimizations"
16066   "fscale"
16067   [(set_attr "type" "fpspc")
16068    (set_attr "mode" "XF")])
16070 (define_expand "expsf2"
16071   [(set (match_dup 2)
16072         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16073    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16074    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16075    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16076    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16077    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16078    (parallel [(set (match_dup 10)
16079                    (unspec:XF [(match_dup 9) (match_dup 5)]
16080                               UNSPEC_FSCALE_FRACT))
16081               (set (match_dup 11)
16082                    (unspec:XF [(match_dup 9) (match_dup 5)]
16083                               UNSPEC_FSCALE_EXP))])
16084    (set (match_operand:SF 0 "register_operand" "")
16085         (float_truncate:SF (match_dup 10)))]
16086   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16087    && flag_unsafe_math_optimizations"
16089   rtx temp;
16090   int i;
16092   for (i=2; i<12; i++)
16093     operands[i] = gen_reg_rtx (XFmode);
16094   temp = standard_80387_constant_rtx (5); /* fldl2e */
16095   emit_move_insn (operands[3], temp);
16096   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16099 (define_expand "expdf2"
16100   [(set (match_dup 2)
16101         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16102    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16103    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16104    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16105    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16106    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16107    (parallel [(set (match_dup 10)
16108                    (unspec:XF [(match_dup 9) (match_dup 5)]
16109                               UNSPEC_FSCALE_FRACT))
16110               (set (match_dup 11)
16111                    (unspec:XF [(match_dup 9) (match_dup 5)]
16112                               UNSPEC_FSCALE_EXP))])
16113    (set (match_operand:DF 0 "register_operand" "")
16114         (float_truncate:DF (match_dup 10)))]
16115   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16116    && flag_unsafe_math_optimizations"
16118   rtx temp;
16119   int i;
16121   for (i=2; i<12; i++)
16122     operands[i] = gen_reg_rtx (XFmode);
16123   temp = standard_80387_constant_rtx (5); /* fldl2e */
16124   emit_move_insn (operands[3], temp);
16125   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16128 (define_expand "expxf2"
16129   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16130                                (match_dup 2)))
16131    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16132    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16133    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16134    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16135    (parallel [(set (match_operand:XF 0 "register_operand" "")
16136                    (unspec:XF [(match_dup 8) (match_dup 4)]
16137                               UNSPEC_FSCALE_FRACT))
16138               (set (match_dup 9)
16139                    (unspec:XF [(match_dup 8) (match_dup 4)]
16140                               UNSPEC_FSCALE_EXP))])]
16141   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16142    && flag_unsafe_math_optimizations"
16144   rtx temp;
16145   int i;
16147   for (i=2; i<10; i++)
16148     operands[i] = gen_reg_rtx (XFmode);
16149   temp = standard_80387_constant_rtx (5); /* fldl2e */
16150   emit_move_insn (operands[2], temp);
16151   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16154 (define_expand "exp10sf2"
16155   [(set (match_dup 2)
16156         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16157    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16158    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16159    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16160    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16161    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16162    (parallel [(set (match_dup 10)
16163                    (unspec:XF [(match_dup 9) (match_dup 5)]
16164                               UNSPEC_FSCALE_FRACT))
16165               (set (match_dup 11)
16166                    (unspec:XF [(match_dup 9) (match_dup 5)]
16167                               UNSPEC_FSCALE_EXP))])
16168    (set (match_operand:SF 0 "register_operand" "")
16169         (float_truncate:SF (match_dup 10)))]
16170   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16171    && flag_unsafe_math_optimizations"
16173   rtx temp;
16174   int i;
16176   for (i=2; i<12; i++)
16177     operands[i] = gen_reg_rtx (XFmode);
16178   temp = standard_80387_constant_rtx (6); /* fldl2t */
16179   emit_move_insn (operands[3], temp);
16180   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16183 (define_expand "exp10df2"
16184   [(set (match_dup 2)
16185         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16186    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16187    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16188    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16189    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16190    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16191    (parallel [(set (match_dup 10)
16192                    (unspec:XF [(match_dup 9) (match_dup 5)]
16193                               UNSPEC_FSCALE_FRACT))
16194               (set (match_dup 11)
16195                    (unspec:XF [(match_dup 9) (match_dup 5)]
16196                               UNSPEC_FSCALE_EXP))])
16197    (set (match_operand:DF 0 "register_operand" "")
16198         (float_truncate:DF (match_dup 10)))]
16199   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16200    && flag_unsafe_math_optimizations"
16202   rtx temp;
16203   int i;
16205   for (i=2; i<12; i++)
16206     operands[i] = gen_reg_rtx (XFmode);
16207   temp = standard_80387_constant_rtx (6); /* fldl2t */
16208   emit_move_insn (operands[3], temp);
16209   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16212 (define_expand "exp10xf2"
16213   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16214                                (match_dup 2)))
16215    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16216    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16217    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16218    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16219    (parallel [(set (match_operand:XF 0 "register_operand" "")
16220                    (unspec:XF [(match_dup 8) (match_dup 4)]
16221                               UNSPEC_FSCALE_FRACT))
16222               (set (match_dup 9)
16223                    (unspec:XF [(match_dup 8) (match_dup 4)]
16224                               UNSPEC_FSCALE_EXP))])]
16225   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16226    && flag_unsafe_math_optimizations"
16228   rtx temp;
16229   int i;
16231   for (i=2; i<10; i++)
16232     operands[i] = gen_reg_rtx (XFmode);
16233   temp = standard_80387_constant_rtx (6); /* fldl2t */
16234   emit_move_insn (operands[2], temp);
16235   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16238 (define_expand "exp2sf2"
16239   [(set (match_dup 2)
16240         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16241    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16242    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16243    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16244    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16245    (parallel [(set (match_dup 8)
16246                    (unspec:XF [(match_dup 7) (match_dup 3)]
16247                               UNSPEC_FSCALE_FRACT))
16248               (set (match_dup 9)
16249                    (unspec:XF [(match_dup 7) (match_dup 3)]
16250                               UNSPEC_FSCALE_EXP))])
16251    (set (match_operand:SF 0 "register_operand" "")
16252         (float_truncate:SF (match_dup 8)))]
16253   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16254    && flag_unsafe_math_optimizations"
16256   int i;
16258   for (i=2; i<10; i++)
16259     operands[i] = gen_reg_rtx (XFmode);
16260   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16263 (define_expand "exp2df2"
16264   [(set (match_dup 2)
16265         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16266    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16267    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16268    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16269    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16270    (parallel [(set (match_dup 8)
16271                    (unspec:XF [(match_dup 7) (match_dup 3)]
16272                               UNSPEC_FSCALE_FRACT))
16273               (set (match_dup 9)
16274                    (unspec:XF [(match_dup 7) (match_dup 3)]
16275                               UNSPEC_FSCALE_EXP))])
16276    (set (match_operand:DF 0 "register_operand" "")
16277         (float_truncate:DF (match_dup 8)))]
16278   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16279    && flag_unsafe_math_optimizations"
16281   int i;
16283   for (i=2; i<10; i++)
16284     operands[i] = gen_reg_rtx (XFmode);
16285   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16288 (define_expand "exp2xf2"
16289   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16290    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16291    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16292    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16293    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16294    (parallel [(set (match_operand:XF 0 "register_operand" "")
16295                    (unspec:XF [(match_dup 7) (match_dup 3)]
16296                               UNSPEC_FSCALE_FRACT))
16297               (set (match_dup 8)
16298                    (unspec:XF [(match_dup 7) (match_dup 3)]
16299                               UNSPEC_FSCALE_EXP))])]
16300   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16301    && flag_unsafe_math_optimizations"
16303   int i;
16305   for (i=2; i<9; i++)
16306     operands[i] = gen_reg_rtx (XFmode);
16307   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16310 (define_expand "expm1df2"
16311   [(set (match_dup 2)
16312         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16313    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16314    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16315    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16316    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16317    (parallel [(set (match_dup 8)
16318                    (unspec:XF [(match_dup 7) (match_dup 5)]
16319                               UNSPEC_FSCALE_FRACT))
16320                    (set (match_dup 9)
16321                    (unspec:XF [(match_dup 7) (match_dup 5)]
16322                               UNSPEC_FSCALE_EXP))])
16323    (parallel [(set (match_dup 11)
16324                    (unspec:XF [(match_dup 10) (match_dup 9)]
16325                               UNSPEC_FSCALE_FRACT))
16326               (set (match_dup 12)
16327                    (unspec:XF [(match_dup 10) (match_dup 9)]
16328                               UNSPEC_FSCALE_EXP))])
16329    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16330    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16331    (set (match_operand:DF 0 "register_operand" "")
16332         (float_truncate:DF (match_dup 14)))]
16333   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16334    && flag_unsafe_math_optimizations"
16336   rtx temp;
16337   int i;
16339   for (i=2; i<15; i++)
16340     operands[i] = gen_reg_rtx (XFmode);
16341   temp = standard_80387_constant_rtx (5); /* fldl2e */
16342   emit_move_insn (operands[3], temp);
16343   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16346 (define_expand "expm1sf2"
16347   [(set (match_dup 2)
16348         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16349    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16350    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16351    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16352    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16353    (parallel [(set (match_dup 8)
16354                    (unspec:XF [(match_dup 7) (match_dup 5)]
16355                               UNSPEC_FSCALE_FRACT))
16356                    (set (match_dup 9)
16357                    (unspec:XF [(match_dup 7) (match_dup 5)]
16358                               UNSPEC_FSCALE_EXP))])
16359    (parallel [(set (match_dup 11)
16360                    (unspec:XF [(match_dup 10) (match_dup 9)]
16361                               UNSPEC_FSCALE_FRACT))
16362               (set (match_dup 12)
16363                    (unspec:XF [(match_dup 10) (match_dup 9)]
16364                               UNSPEC_FSCALE_EXP))])
16365    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16366    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16367    (set (match_operand:SF 0 "register_operand" "")
16368         (float_truncate:SF (match_dup 14)))]
16369   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16370    && flag_unsafe_math_optimizations"
16372   rtx temp;
16373   int i;
16375   for (i=2; i<15; i++)
16376     operands[i] = gen_reg_rtx (XFmode);
16377   temp = standard_80387_constant_rtx (5); /* fldl2e */
16378   emit_move_insn (operands[3], temp);
16379   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16382 (define_expand "expm1xf2"
16383   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16384                                (match_dup 2)))
16385    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16386    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16387    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16388    (parallel [(set (match_dup 7)
16389                    (unspec:XF [(match_dup 6) (match_dup 4)]
16390                               UNSPEC_FSCALE_FRACT))
16391                    (set (match_dup 8)
16392                    (unspec:XF [(match_dup 6) (match_dup 4)]
16393                               UNSPEC_FSCALE_EXP))])
16394    (parallel [(set (match_dup 10)
16395                    (unspec:XF [(match_dup 9) (match_dup 8)]
16396                               UNSPEC_FSCALE_FRACT))
16397               (set (match_dup 11)
16398                    (unspec:XF [(match_dup 9) (match_dup 8)]
16399                               UNSPEC_FSCALE_EXP))])
16400    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16401    (set (match_operand:XF 0 "register_operand" "")
16402         (plus:XF (match_dup 12) (match_dup 7)))]
16403   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16404    && flag_unsafe_math_optimizations"
16406   rtx temp;
16407   int i;
16409   for (i=2; i<13; i++)
16410     operands[i] = gen_reg_rtx (XFmode);
16411   temp = standard_80387_constant_rtx (5); /* fldl2e */
16412   emit_move_insn (operands[2], temp);
16413   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16416 ;; Block operation instructions
16418 (define_insn "cld"
16419  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16420  ""
16421  "cld"
16422   [(set_attr "type" "cld")])
16424 (define_expand "movmemsi"
16425   [(use (match_operand:BLK 0 "memory_operand" ""))
16426    (use (match_operand:BLK 1 "memory_operand" ""))
16427    (use (match_operand:SI 2 "nonmemory_operand" ""))
16428    (use (match_operand:SI 3 "const_int_operand" ""))]
16429   "! optimize_size"
16431  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16432    DONE;
16433  else
16434    FAIL;
16437 (define_expand "movmemdi"
16438   [(use (match_operand:BLK 0 "memory_operand" ""))
16439    (use (match_operand:BLK 1 "memory_operand" ""))
16440    (use (match_operand:DI 2 "nonmemory_operand" ""))
16441    (use (match_operand:DI 3 "const_int_operand" ""))]
16442   "TARGET_64BIT"
16444  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16445    DONE;
16446  else
16447    FAIL;
16450 ;; Most CPUs don't like single string operations
16451 ;; Handle this case here to simplify previous expander.
16453 (define_expand "strmov"
16454   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16455    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16456    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16457               (clobber (reg:CC FLAGS_REG))])
16458    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16459               (clobber (reg:CC FLAGS_REG))])]
16460   ""
16462   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16464   /* If .md ever supports :P for Pmode, these can be directly
16465      in the pattern above.  */
16466   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16467   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16469   if (TARGET_SINGLE_STRINGOP || optimize_size)
16470     {
16471       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16472                                       operands[2], operands[3],
16473                                       operands[5], operands[6]));
16474       DONE;
16475     }
16477   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16480 (define_expand "strmov_singleop"
16481   [(parallel [(set (match_operand 1 "memory_operand" "")
16482                    (match_operand 3 "memory_operand" ""))
16483               (set (match_operand 0 "register_operand" "")
16484                    (match_operand 4 "" ""))
16485               (set (match_operand 2 "register_operand" "")
16486                    (match_operand 5 "" ""))
16487               (use (reg:SI DIRFLAG_REG))])]
16488   "TARGET_SINGLE_STRINGOP || optimize_size"
16489   "")
16491 (define_insn "*strmovdi_rex_1"
16492   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16493         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16494    (set (match_operand:DI 0 "register_operand" "=D")
16495         (plus:DI (match_dup 2)
16496                  (const_int 8)))
16497    (set (match_operand:DI 1 "register_operand" "=S")
16498         (plus:DI (match_dup 3)
16499                  (const_int 8)))
16500    (use (reg:SI DIRFLAG_REG))]
16501   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16502   "movsq"
16503   [(set_attr "type" "str")
16504    (set_attr "mode" "DI")
16505    (set_attr "memory" "both")])
16507 (define_insn "*strmovsi_1"
16508   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16509         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16510    (set (match_operand:SI 0 "register_operand" "=D")
16511         (plus:SI (match_dup 2)
16512                  (const_int 4)))
16513    (set (match_operand:SI 1 "register_operand" "=S")
16514         (plus:SI (match_dup 3)
16515                  (const_int 4)))
16516    (use (reg:SI DIRFLAG_REG))]
16517   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16518   "{movsl|movsd}"
16519   [(set_attr "type" "str")
16520    (set_attr "mode" "SI")
16521    (set_attr "memory" "both")])
16523 (define_insn "*strmovsi_rex_1"
16524   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16525         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16526    (set (match_operand:DI 0 "register_operand" "=D")
16527         (plus:DI (match_dup 2)
16528                  (const_int 4)))
16529    (set (match_operand:DI 1 "register_operand" "=S")
16530         (plus:DI (match_dup 3)
16531                  (const_int 4)))
16532    (use (reg:SI DIRFLAG_REG))]
16533   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16534   "{movsl|movsd}"
16535   [(set_attr "type" "str")
16536    (set_attr "mode" "SI")
16537    (set_attr "memory" "both")])
16539 (define_insn "*strmovhi_1"
16540   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16541         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16542    (set (match_operand:SI 0 "register_operand" "=D")
16543         (plus:SI (match_dup 2)
16544                  (const_int 2)))
16545    (set (match_operand:SI 1 "register_operand" "=S")
16546         (plus:SI (match_dup 3)
16547                  (const_int 2)))
16548    (use (reg:SI DIRFLAG_REG))]
16549   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16550   "movsw"
16551   [(set_attr "type" "str")
16552    (set_attr "memory" "both")
16553    (set_attr "mode" "HI")])
16555 (define_insn "*strmovhi_rex_1"
16556   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16557         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16558    (set (match_operand:DI 0 "register_operand" "=D")
16559         (plus:DI (match_dup 2)
16560                  (const_int 2)))
16561    (set (match_operand:DI 1 "register_operand" "=S")
16562         (plus:DI (match_dup 3)
16563                  (const_int 2)))
16564    (use (reg:SI DIRFLAG_REG))]
16565   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16566   "movsw"
16567   [(set_attr "type" "str")
16568    (set_attr "memory" "both")
16569    (set_attr "mode" "HI")])
16571 (define_insn "*strmovqi_1"
16572   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16573         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16574    (set (match_operand:SI 0 "register_operand" "=D")
16575         (plus:SI (match_dup 2)
16576                  (const_int 1)))
16577    (set (match_operand:SI 1 "register_operand" "=S")
16578         (plus:SI (match_dup 3)
16579                  (const_int 1)))
16580    (use (reg:SI DIRFLAG_REG))]
16581   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16582   "movsb"
16583   [(set_attr "type" "str")
16584    (set_attr "memory" "both")
16585    (set_attr "mode" "QI")])
16587 (define_insn "*strmovqi_rex_1"
16588   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16589         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16590    (set (match_operand:DI 0 "register_operand" "=D")
16591         (plus:DI (match_dup 2)
16592                  (const_int 1)))
16593    (set (match_operand:DI 1 "register_operand" "=S")
16594         (plus:DI (match_dup 3)
16595                  (const_int 1)))
16596    (use (reg:SI DIRFLAG_REG))]
16597   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16598   "movsb"
16599   [(set_attr "type" "str")
16600    (set_attr "memory" "both")
16601    (set_attr "mode" "QI")])
16603 (define_expand "rep_mov"
16604   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16605               (set (match_operand 0 "register_operand" "")
16606                    (match_operand 5 "" ""))
16607               (set (match_operand 2 "register_operand" "")
16608                    (match_operand 6 "" ""))
16609               (set (match_operand 1 "memory_operand" "")
16610                    (match_operand 3 "memory_operand" ""))
16611               (use (match_dup 4))
16612               (use (reg:SI DIRFLAG_REG))])]
16613   ""
16614   "")
16616 (define_insn "*rep_movdi_rex64"
16617   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16618    (set (match_operand:DI 0 "register_operand" "=D") 
16619         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16620                             (const_int 3))
16621                  (match_operand:DI 3 "register_operand" "0")))
16622    (set (match_operand:DI 1 "register_operand" "=S") 
16623         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16624                  (match_operand:DI 4 "register_operand" "1")))
16625    (set (mem:BLK (match_dup 3))
16626         (mem:BLK (match_dup 4)))
16627    (use (match_dup 5))
16628    (use (reg:SI DIRFLAG_REG))]
16629   "TARGET_64BIT"
16630   "{rep\;movsq|rep movsq}"
16631   [(set_attr "type" "str")
16632    (set_attr "prefix_rep" "1")
16633    (set_attr "memory" "both")
16634    (set_attr "mode" "DI")])
16636 (define_insn "*rep_movsi"
16637   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16638    (set (match_operand:SI 0 "register_operand" "=D") 
16639         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16640                             (const_int 2))
16641                  (match_operand:SI 3 "register_operand" "0")))
16642    (set (match_operand:SI 1 "register_operand" "=S") 
16643         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16644                  (match_operand:SI 4 "register_operand" "1")))
16645    (set (mem:BLK (match_dup 3))
16646         (mem:BLK (match_dup 4)))
16647    (use (match_dup 5))
16648    (use (reg:SI DIRFLAG_REG))]
16649   "!TARGET_64BIT"
16650   "{rep\;movsl|rep movsd}"
16651   [(set_attr "type" "str")
16652    (set_attr "prefix_rep" "1")
16653    (set_attr "memory" "both")
16654    (set_attr "mode" "SI")])
16656 (define_insn "*rep_movsi_rex64"
16657   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16658    (set (match_operand:DI 0 "register_operand" "=D") 
16659         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16660                             (const_int 2))
16661                  (match_operand:DI 3 "register_operand" "0")))
16662    (set (match_operand:DI 1 "register_operand" "=S") 
16663         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16664                  (match_operand:DI 4 "register_operand" "1")))
16665    (set (mem:BLK (match_dup 3))
16666         (mem:BLK (match_dup 4)))
16667    (use (match_dup 5))
16668    (use (reg:SI DIRFLAG_REG))]
16669   "TARGET_64BIT"
16670   "{rep\;movsl|rep movsd}"
16671   [(set_attr "type" "str")
16672    (set_attr "prefix_rep" "1")
16673    (set_attr "memory" "both")
16674    (set_attr "mode" "SI")])
16676 (define_insn "*rep_movqi"
16677   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16678    (set (match_operand:SI 0 "register_operand" "=D") 
16679         (plus:SI (match_operand:SI 3 "register_operand" "0")
16680                  (match_operand:SI 5 "register_operand" "2")))
16681    (set (match_operand:SI 1 "register_operand" "=S") 
16682         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16683    (set (mem:BLK (match_dup 3))
16684         (mem:BLK (match_dup 4)))
16685    (use (match_dup 5))
16686    (use (reg:SI DIRFLAG_REG))]
16687   "!TARGET_64BIT"
16688   "{rep\;movsb|rep movsb}"
16689   [(set_attr "type" "str")
16690    (set_attr "prefix_rep" "1")
16691    (set_attr "memory" "both")
16692    (set_attr "mode" "SI")])
16694 (define_insn "*rep_movqi_rex64"
16695   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16696    (set (match_operand:DI 0 "register_operand" "=D") 
16697         (plus:DI (match_operand:DI 3 "register_operand" "0")
16698                  (match_operand:DI 5 "register_operand" "2")))
16699    (set (match_operand:DI 1 "register_operand" "=S") 
16700         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16701    (set (mem:BLK (match_dup 3))
16702         (mem:BLK (match_dup 4)))
16703    (use (match_dup 5))
16704    (use (reg:SI DIRFLAG_REG))]
16705   "TARGET_64BIT"
16706   "{rep\;movsb|rep movsb}"
16707   [(set_attr "type" "str")
16708    (set_attr "prefix_rep" "1")
16709    (set_attr "memory" "both")
16710    (set_attr "mode" "SI")])
16712 (define_expand "clrmemsi"
16713    [(use (match_operand:BLK 0 "memory_operand" ""))
16714     (use (match_operand:SI 1 "nonmemory_operand" ""))
16715     (use (match_operand 2 "const_int_operand" ""))]
16716   ""
16718  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16719    DONE;
16720  else
16721    FAIL;
16724 (define_expand "clrmemdi"
16725    [(use (match_operand:BLK 0 "memory_operand" ""))
16726     (use (match_operand:DI 1 "nonmemory_operand" ""))
16727     (use (match_operand 2 "const_int_operand" ""))]
16728   "TARGET_64BIT"
16730  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16731    DONE;
16732  else
16733    FAIL;
16736 ;; Most CPUs don't like single string operations
16737 ;; Handle this case here to simplify previous expander.
16739 (define_expand "strset"
16740   [(set (match_operand 1 "memory_operand" "")
16741         (match_operand 2 "register_operand" ""))
16742    (parallel [(set (match_operand 0 "register_operand" "")
16743                    (match_dup 3))
16744               (clobber (reg:CC FLAGS_REG))])]
16745   ""
16747   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16748     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16750   /* If .md ever supports :P for Pmode, this can be directly
16751      in the pattern above.  */
16752   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16753                               GEN_INT (GET_MODE_SIZE (GET_MODE
16754                                                       (operands[2]))));
16755   if (TARGET_SINGLE_STRINGOP || optimize_size)
16756     {
16757       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16758                                       operands[3]));
16759       DONE;
16760     }
16763 (define_expand "strset_singleop"
16764   [(parallel [(set (match_operand 1 "memory_operand" "")
16765                    (match_operand 2 "register_operand" ""))
16766               (set (match_operand 0 "register_operand" "")
16767                    (match_operand 3 "" ""))
16768               (use (reg:SI DIRFLAG_REG))])]
16769   "TARGET_SINGLE_STRINGOP || optimize_size"
16770   "")
16772 (define_insn "*strsetdi_rex_1"
16773   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16774         (match_operand:SI 2 "register_operand" "a"))
16775    (set (match_operand:DI 0 "register_operand" "=D")
16776         (plus:DI (match_dup 1)
16777                  (const_int 8)))
16778    (use (reg:SI DIRFLAG_REG))]
16779   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16780   "stosq"
16781   [(set_attr "type" "str")
16782    (set_attr "memory" "store")
16783    (set_attr "mode" "DI")])
16785 (define_insn "*strsetsi_1"
16786   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16787         (match_operand:SI 2 "register_operand" "a"))
16788    (set (match_operand:SI 0 "register_operand" "=D")
16789         (plus:SI (match_dup 1)
16790                  (const_int 4)))
16791    (use (reg:SI DIRFLAG_REG))]
16792   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16793   "{stosl|stosd}"
16794   [(set_attr "type" "str")
16795    (set_attr "memory" "store")
16796    (set_attr "mode" "SI")])
16798 (define_insn "*strsetsi_rex_1"
16799   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16800         (match_operand:SI 2 "register_operand" "a"))
16801    (set (match_operand:DI 0 "register_operand" "=D")
16802         (plus:DI (match_dup 1)
16803                  (const_int 4)))
16804    (use (reg:SI DIRFLAG_REG))]
16805   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16806   "{stosl|stosd}"
16807   [(set_attr "type" "str")
16808    (set_attr "memory" "store")
16809    (set_attr "mode" "SI")])
16811 (define_insn "*strsethi_1"
16812   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16813         (match_operand:HI 2 "register_operand" "a"))
16814    (set (match_operand:SI 0 "register_operand" "=D")
16815         (plus:SI (match_dup 1)
16816                  (const_int 2)))
16817    (use (reg:SI DIRFLAG_REG))]
16818   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16819   "stosw"
16820   [(set_attr "type" "str")
16821    (set_attr "memory" "store")
16822    (set_attr "mode" "HI")])
16824 (define_insn "*strsethi_rex_1"
16825   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16826         (match_operand:HI 2 "register_operand" "a"))
16827    (set (match_operand:DI 0 "register_operand" "=D")
16828         (plus:DI (match_dup 1)
16829                  (const_int 2)))
16830    (use (reg:SI DIRFLAG_REG))]
16831   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16832   "stosw"
16833   [(set_attr "type" "str")
16834    (set_attr "memory" "store")
16835    (set_attr "mode" "HI")])
16837 (define_insn "*strsetqi_1"
16838   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16839         (match_operand:QI 2 "register_operand" "a"))
16840    (set (match_operand:SI 0 "register_operand" "=D")
16841         (plus:SI (match_dup 1)
16842                  (const_int 1)))
16843    (use (reg:SI DIRFLAG_REG))]
16844   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16845   "stosb"
16846   [(set_attr "type" "str")
16847    (set_attr "memory" "store")
16848    (set_attr "mode" "QI")])
16850 (define_insn "*strsetqi_rex_1"
16851   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16852         (match_operand:QI 2 "register_operand" "a"))
16853    (set (match_operand:DI 0 "register_operand" "=D")
16854         (plus:DI (match_dup 1)
16855                  (const_int 1)))
16856    (use (reg:SI DIRFLAG_REG))]
16857   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16858   "stosb"
16859   [(set_attr "type" "str")
16860    (set_attr "memory" "store")
16861    (set_attr "mode" "QI")])
16863 (define_expand "rep_stos"
16864   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16865               (set (match_operand 0 "register_operand" "")
16866                    (match_operand 4 "" ""))
16867               (set (match_operand 2 "memory_operand" "") (const_int 0))
16868               (use (match_operand 3 "register_operand" ""))
16869               (use (match_dup 1))
16870               (use (reg:SI DIRFLAG_REG))])]
16871   ""
16872   "")
16874 (define_insn "*rep_stosdi_rex64"
16875   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16876    (set (match_operand:DI 0 "register_operand" "=D") 
16877         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16878                             (const_int 3))
16879                  (match_operand:DI 3 "register_operand" "0")))
16880    (set (mem:BLK (match_dup 3))
16881         (const_int 0))
16882    (use (match_operand:DI 2 "register_operand" "a"))
16883    (use (match_dup 4))
16884    (use (reg:SI DIRFLAG_REG))]
16885   "TARGET_64BIT"
16886   "{rep\;stosq|rep stosq}"
16887   [(set_attr "type" "str")
16888    (set_attr "prefix_rep" "1")
16889    (set_attr "memory" "store")
16890    (set_attr "mode" "DI")])
16892 (define_insn "*rep_stossi"
16893   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16894    (set (match_operand:SI 0 "register_operand" "=D") 
16895         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16896                             (const_int 2))
16897                  (match_operand:SI 3 "register_operand" "0")))
16898    (set (mem:BLK (match_dup 3))
16899         (const_int 0))
16900    (use (match_operand:SI 2 "register_operand" "a"))
16901    (use (match_dup 4))
16902    (use (reg:SI DIRFLAG_REG))]
16903   "!TARGET_64BIT"
16904   "{rep\;stosl|rep stosd}"
16905   [(set_attr "type" "str")
16906    (set_attr "prefix_rep" "1")
16907    (set_attr "memory" "store")
16908    (set_attr "mode" "SI")])
16910 (define_insn "*rep_stossi_rex64"
16911   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16912    (set (match_operand:DI 0 "register_operand" "=D") 
16913         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16914                             (const_int 2))
16915                  (match_operand:DI 3 "register_operand" "0")))
16916    (set (mem:BLK (match_dup 3))
16917         (const_int 0))
16918    (use (match_operand:SI 2 "register_operand" "a"))
16919    (use (match_dup 4))
16920    (use (reg:SI DIRFLAG_REG))]
16921   "TARGET_64BIT"
16922   "{rep\;stosl|rep stosd}"
16923   [(set_attr "type" "str")
16924    (set_attr "prefix_rep" "1")
16925    (set_attr "memory" "store")
16926    (set_attr "mode" "SI")])
16928 (define_insn "*rep_stosqi"
16929   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16930    (set (match_operand:SI 0 "register_operand" "=D") 
16931         (plus:SI (match_operand:SI 3 "register_operand" "0")
16932                  (match_operand:SI 4 "register_operand" "1")))
16933    (set (mem:BLK (match_dup 3))
16934         (const_int 0))
16935    (use (match_operand:QI 2 "register_operand" "a"))
16936    (use (match_dup 4))
16937    (use (reg:SI DIRFLAG_REG))]
16938   "!TARGET_64BIT"
16939   "{rep\;stosb|rep stosb}"
16940   [(set_attr "type" "str")
16941    (set_attr "prefix_rep" "1")
16942    (set_attr "memory" "store")
16943    (set_attr "mode" "QI")])
16945 (define_insn "*rep_stosqi_rex64"
16946   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16947    (set (match_operand:DI 0 "register_operand" "=D") 
16948         (plus:DI (match_operand:DI 3 "register_operand" "0")
16949                  (match_operand:DI 4 "register_operand" "1")))
16950    (set (mem:BLK (match_dup 3))
16951         (const_int 0))
16952    (use (match_operand:QI 2 "register_operand" "a"))
16953    (use (match_dup 4))
16954    (use (reg:SI DIRFLAG_REG))]
16955   "TARGET_64BIT"
16956   "{rep\;stosb|rep stosb}"
16957   [(set_attr "type" "str")
16958    (set_attr "prefix_rep" "1")
16959    (set_attr "memory" "store")
16960    (set_attr "mode" "QI")])
16962 (define_expand "cmpstrsi"
16963   [(set (match_operand:SI 0 "register_operand" "")
16964         (compare:SI (match_operand:BLK 1 "general_operand" "")
16965                     (match_operand:BLK 2 "general_operand" "")))
16966    (use (match_operand 3 "general_operand" ""))
16967    (use (match_operand 4 "immediate_operand" ""))]
16968   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16970   rtx addr1, addr2, out, outlow, count, countreg, align;
16972   /* Can't use this if the user has appropriated esi or edi.  */
16973   if (global_regs[4] || global_regs[5])
16974     FAIL;
16976   out = operands[0];
16977   if (GET_CODE (out) != REG)
16978     out = gen_reg_rtx (SImode);
16980   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16981   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16982   if (addr1 != XEXP (operands[1], 0))
16983     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16984   if (addr2 != XEXP (operands[2], 0))
16985     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16987   count = operands[3];
16988   countreg = ix86_zero_extend_to_Pmode (count);
16990   /* %%% Iff we are testing strict equality, we can use known alignment
16991      to good advantage.  This may be possible with combine, particularly
16992      once cc0 is dead.  */
16993   align = operands[4];
16995   emit_insn (gen_cld ());
16996   if (GET_CODE (count) == CONST_INT)
16997     {
16998       if (INTVAL (count) == 0)
16999         {
17000           emit_move_insn (operands[0], const0_rtx);
17001           DONE;
17002         }
17003       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17004                                     operands[1], operands[2]));
17005     }
17006   else
17007     {
17008       if (TARGET_64BIT)
17009         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17010       else
17011         emit_insn (gen_cmpsi_1 (countreg, countreg));
17012       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17013                                  operands[1], operands[2]));
17014     }
17016   outlow = gen_lowpart (QImode, out);
17017   emit_insn (gen_cmpintqi (outlow));
17018   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17020   if (operands[0] != out)
17021     emit_move_insn (operands[0], out);
17023   DONE;
17026 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17028 (define_expand "cmpintqi"
17029   [(set (match_dup 1)
17030         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17031    (set (match_dup 2)
17032         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17033    (parallel [(set (match_operand:QI 0 "register_operand" "")
17034                    (minus:QI (match_dup 1)
17035                              (match_dup 2)))
17036               (clobber (reg:CC FLAGS_REG))])]
17037   ""
17038   "operands[1] = gen_reg_rtx (QImode);
17039    operands[2] = gen_reg_rtx (QImode);")
17041 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17042 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17044 (define_expand "cmpstrqi_nz_1"
17045   [(parallel [(set (reg:CC FLAGS_REG)
17046                    (compare:CC (match_operand 4 "memory_operand" "")
17047                                (match_operand 5 "memory_operand" "")))
17048               (use (match_operand 2 "register_operand" ""))
17049               (use (match_operand:SI 3 "immediate_operand" ""))
17050               (use (reg:SI DIRFLAG_REG))
17051               (clobber (match_operand 0 "register_operand" ""))
17052               (clobber (match_operand 1 "register_operand" ""))
17053               (clobber (match_dup 2))])]
17054   ""
17055   "")
17057 (define_insn "*cmpstrqi_nz_1"
17058   [(set (reg:CC FLAGS_REG)
17059         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17060                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17061    (use (match_operand:SI 6 "register_operand" "2"))
17062    (use (match_operand:SI 3 "immediate_operand" "i"))
17063    (use (reg:SI DIRFLAG_REG))
17064    (clobber (match_operand:SI 0 "register_operand" "=S"))
17065    (clobber (match_operand:SI 1 "register_operand" "=D"))
17066    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17067   "!TARGET_64BIT"
17068   "repz{\;| }cmpsb"
17069   [(set_attr "type" "str")
17070    (set_attr "mode" "QI")
17071    (set_attr "prefix_rep" "1")])
17073 (define_insn "*cmpstrqi_nz_rex_1"
17074   [(set (reg:CC FLAGS_REG)
17075         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17076                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17077    (use (match_operand:DI 6 "register_operand" "2"))
17078    (use (match_operand:SI 3 "immediate_operand" "i"))
17079    (use (reg:SI DIRFLAG_REG))
17080    (clobber (match_operand:DI 0 "register_operand" "=S"))
17081    (clobber (match_operand:DI 1 "register_operand" "=D"))
17082    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17083   "TARGET_64BIT"
17084   "repz{\;| }cmpsb"
17085   [(set_attr "type" "str")
17086    (set_attr "mode" "QI")
17087    (set_attr "prefix_rep" "1")])
17089 ;; The same, but the count is not known to not be zero.
17091 (define_expand "cmpstrqi_1"
17092   [(parallel [(set (reg:CC FLAGS_REG)
17093                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17094                                      (const_int 0))
17095                   (compare:CC (match_operand 4 "memory_operand" "")
17096                               (match_operand 5 "memory_operand" ""))
17097                   (const_int 0)))
17098               (use (match_operand:SI 3 "immediate_operand" ""))
17099               (use (reg:CC FLAGS_REG))
17100               (use (reg:SI DIRFLAG_REG))
17101               (clobber (match_operand 0 "register_operand" ""))
17102               (clobber (match_operand 1 "register_operand" ""))
17103               (clobber (match_dup 2))])]
17104   ""
17105   "")
17107 (define_insn "*cmpstrqi_1"
17108   [(set (reg:CC FLAGS_REG)
17109         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17110                              (const_int 0))
17111           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17112                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17113           (const_int 0)))
17114    (use (match_operand:SI 3 "immediate_operand" "i"))
17115    (use (reg:CC FLAGS_REG))
17116    (use (reg:SI DIRFLAG_REG))
17117    (clobber (match_operand:SI 0 "register_operand" "=S"))
17118    (clobber (match_operand:SI 1 "register_operand" "=D"))
17119    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17120   "!TARGET_64BIT"
17121   "repz{\;| }cmpsb"
17122   [(set_attr "type" "str")
17123    (set_attr "mode" "QI")
17124    (set_attr "prefix_rep" "1")])
17126 (define_insn "*cmpstrqi_rex_1"
17127   [(set (reg:CC FLAGS_REG)
17128         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17129                              (const_int 0))
17130           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17131                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17132           (const_int 0)))
17133    (use (match_operand:SI 3 "immediate_operand" "i"))
17134    (use (reg:CC FLAGS_REG))
17135    (use (reg:SI DIRFLAG_REG))
17136    (clobber (match_operand:DI 0 "register_operand" "=S"))
17137    (clobber (match_operand:DI 1 "register_operand" "=D"))
17138    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17139   "TARGET_64BIT"
17140   "repz{\;| }cmpsb"
17141   [(set_attr "type" "str")
17142    (set_attr "mode" "QI")
17143    (set_attr "prefix_rep" "1")])
17145 (define_expand "strlensi"
17146   [(set (match_operand:SI 0 "register_operand" "")
17147         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17148                     (match_operand:QI 2 "immediate_operand" "")
17149                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17150   ""
17152  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17153    DONE;
17154  else
17155    FAIL;
17158 (define_expand "strlendi"
17159   [(set (match_operand:DI 0 "register_operand" "")
17160         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17161                     (match_operand:QI 2 "immediate_operand" "")
17162                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17163   ""
17165  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17166    DONE;
17167  else
17168    FAIL;
17171 (define_expand "strlenqi_1"
17172   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17173               (use (reg:SI DIRFLAG_REG))
17174               (clobber (match_operand 1 "register_operand" ""))
17175               (clobber (reg:CC FLAGS_REG))])]
17176   ""
17177   "")
17179 (define_insn "*strlenqi_1"
17180   [(set (match_operand:SI 0 "register_operand" "=&c")
17181         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17182                     (match_operand:QI 2 "register_operand" "a")
17183                     (match_operand:SI 3 "immediate_operand" "i")
17184                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17185    (use (reg:SI DIRFLAG_REG))
17186    (clobber (match_operand:SI 1 "register_operand" "=D"))
17187    (clobber (reg:CC FLAGS_REG))]
17188   "!TARGET_64BIT"
17189   "repnz{\;| }scasb"
17190   [(set_attr "type" "str")
17191    (set_attr "mode" "QI")
17192    (set_attr "prefix_rep" "1")])
17194 (define_insn "*strlenqi_rex_1"
17195   [(set (match_operand:DI 0 "register_operand" "=&c")
17196         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17197                     (match_operand:QI 2 "register_operand" "a")
17198                     (match_operand:DI 3 "immediate_operand" "i")
17199                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17200    (use (reg:SI DIRFLAG_REG))
17201    (clobber (match_operand:DI 1 "register_operand" "=D"))
17202    (clobber (reg:CC FLAGS_REG))]
17203   "TARGET_64BIT"
17204   "repnz{\;| }scasb"
17205   [(set_attr "type" "str")
17206    (set_attr "mode" "QI")
17207    (set_attr "prefix_rep" "1")])
17209 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17210 ;; handled in combine, but it is not currently up to the task.
17211 ;; When used for their truth value, the cmpstr* expanders generate
17212 ;; code like this:
17214 ;;   repz cmpsb
17215 ;;   seta       %al
17216 ;;   setb       %dl
17217 ;;   cmpb       %al, %dl
17218 ;;   jcc        label
17220 ;; The intermediate three instructions are unnecessary.
17222 ;; This one handles cmpstr*_nz_1...
17223 (define_peephole2
17224   [(parallel[
17225      (set (reg:CC FLAGS_REG)
17226           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17227                       (mem:BLK (match_operand 5 "register_operand" ""))))
17228      (use (match_operand 6 "register_operand" ""))
17229      (use (match_operand:SI 3 "immediate_operand" ""))
17230      (use (reg:SI DIRFLAG_REG))
17231      (clobber (match_operand 0 "register_operand" ""))
17232      (clobber (match_operand 1 "register_operand" ""))
17233      (clobber (match_operand 2 "register_operand" ""))])
17234    (set (match_operand:QI 7 "register_operand" "")
17235         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17236    (set (match_operand:QI 8 "register_operand" "")
17237         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17238    (set (reg 17)
17239         (compare (match_dup 7) (match_dup 8)))
17240   ]
17241   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17242   [(parallel[
17243      (set (reg:CC FLAGS_REG)
17244           (compare:CC (mem:BLK (match_dup 4))
17245                       (mem:BLK (match_dup 5))))
17246      (use (match_dup 6))
17247      (use (match_dup 3))
17248      (use (reg:SI DIRFLAG_REG))
17249      (clobber (match_dup 0))
17250      (clobber (match_dup 1))
17251      (clobber (match_dup 2))])]
17252   "")
17254 ;; ...and this one handles cmpstr*_1.
17255 (define_peephole2
17256   [(parallel[
17257      (set (reg:CC FLAGS_REG)
17258           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17259                                (const_int 0))
17260             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17261                         (mem:BLK (match_operand 5 "register_operand" "")))
17262             (const_int 0)))
17263      (use (match_operand:SI 3 "immediate_operand" ""))
17264      (use (reg:CC FLAGS_REG))
17265      (use (reg:SI DIRFLAG_REG))
17266      (clobber (match_operand 0 "register_operand" ""))
17267      (clobber (match_operand 1 "register_operand" ""))
17268      (clobber (match_operand 2 "register_operand" ""))])
17269    (set (match_operand:QI 7 "register_operand" "")
17270         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17271    (set (match_operand:QI 8 "register_operand" "")
17272         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17273    (set (reg 17)
17274         (compare (match_dup 7) (match_dup 8)))
17275   ]
17276   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17277   [(parallel[
17278      (set (reg:CC FLAGS_REG)
17279           (if_then_else:CC (ne (match_dup 6)
17280                                (const_int 0))
17281             (compare:CC (mem:BLK (match_dup 4))
17282                         (mem:BLK (match_dup 5)))
17283             (const_int 0)))
17284      (use (match_dup 3))
17285      (use (reg:CC FLAGS_REG))
17286      (use (reg:SI DIRFLAG_REG))
17287      (clobber (match_dup 0))
17288      (clobber (match_dup 1))
17289      (clobber (match_dup 2))])]
17290   "")
17294 ;; Conditional move instructions.
17296 (define_expand "movdicc"
17297   [(set (match_operand:DI 0 "register_operand" "")
17298         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17299                          (match_operand:DI 2 "general_operand" "")
17300                          (match_operand:DI 3 "general_operand" "")))]
17301   "TARGET_64BIT"
17302   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17304 (define_insn "x86_movdicc_0_m1_rex64"
17305   [(set (match_operand:DI 0 "register_operand" "=r")
17306         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17307           (const_int -1)
17308           (const_int 0)))
17309    (clobber (reg:CC FLAGS_REG))]
17310   "TARGET_64BIT"
17311   "sbb{q}\t%0, %0"
17312   ; Since we don't have the proper number of operands for an alu insn,
17313   ; fill in all the blanks.
17314   [(set_attr "type" "alu")
17315    (set_attr "pent_pair" "pu")
17316    (set_attr "memory" "none")
17317    (set_attr "imm_disp" "false")
17318    (set_attr "mode" "DI")
17319    (set_attr "length_immediate" "0")])
17321 (define_insn "movdicc_c_rex64"
17322   [(set (match_operand:DI 0 "register_operand" "=r,r")
17323         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17324                                 [(reg 17) (const_int 0)])
17325                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17326                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17327   "TARGET_64BIT && TARGET_CMOVE
17328    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17329   "@
17330    cmov%O2%C1\t{%2, %0|%0, %2}
17331    cmov%O2%c1\t{%3, %0|%0, %3}"
17332   [(set_attr "type" "icmov")
17333    (set_attr "mode" "DI")])
17335 (define_expand "movsicc"
17336   [(set (match_operand:SI 0 "register_operand" "")
17337         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17338                          (match_operand:SI 2 "general_operand" "")
17339                          (match_operand:SI 3 "general_operand" "")))]
17340   ""
17341   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17343 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17344 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17345 ;; So just document what we're doing explicitly.
17347 (define_insn "x86_movsicc_0_m1"
17348   [(set (match_operand:SI 0 "register_operand" "=r")
17349         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17350           (const_int -1)
17351           (const_int 0)))
17352    (clobber (reg:CC FLAGS_REG))]
17353   ""
17354   "sbb{l}\t%0, %0"
17355   ; Since we don't have the proper number of operands for an alu insn,
17356   ; fill in all the blanks.
17357   [(set_attr "type" "alu")
17358    (set_attr "pent_pair" "pu")
17359    (set_attr "memory" "none")
17360    (set_attr "imm_disp" "false")
17361    (set_attr "mode" "SI")
17362    (set_attr "length_immediate" "0")])
17364 (define_insn "*movsicc_noc"
17365   [(set (match_operand:SI 0 "register_operand" "=r,r")
17366         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17367                                 [(reg 17) (const_int 0)])
17368                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17369                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17370   "TARGET_CMOVE
17371    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17372   "@
17373    cmov%O2%C1\t{%2, %0|%0, %2}
17374    cmov%O2%c1\t{%3, %0|%0, %3}"
17375   [(set_attr "type" "icmov")
17376    (set_attr "mode" "SI")])
17378 (define_expand "movhicc"
17379   [(set (match_operand:HI 0 "register_operand" "")
17380         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17381                          (match_operand:HI 2 "general_operand" "")
17382                          (match_operand:HI 3 "general_operand" "")))]
17383   "TARGET_HIMODE_MATH"
17384   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17386 (define_insn "*movhicc_noc"
17387   [(set (match_operand:HI 0 "register_operand" "=r,r")
17388         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17389                                 [(reg 17) (const_int 0)])
17390                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17391                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17392   "TARGET_CMOVE
17393    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17394   "@
17395    cmov%O2%C1\t{%2, %0|%0, %2}
17396    cmov%O2%c1\t{%3, %0|%0, %3}"
17397   [(set_attr "type" "icmov")
17398    (set_attr "mode" "HI")])
17400 (define_expand "movqicc"
17401   [(set (match_operand:QI 0 "register_operand" "")
17402         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17403                          (match_operand:QI 2 "general_operand" "")
17404                          (match_operand:QI 3 "general_operand" "")))]
17405   "TARGET_QIMODE_MATH"
17406   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17408 (define_insn_and_split "*movqicc_noc"
17409   [(set (match_operand:QI 0 "register_operand" "=r,r")
17410         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17411                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17412                       (match_operand:QI 2 "register_operand" "r,0")
17413                       (match_operand:QI 3 "register_operand" "0,r")))]
17414   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17415   "#"
17416   "&& reload_completed"
17417   [(set (match_dup 0)
17418         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17419                       (match_dup 2)
17420                       (match_dup 3)))]
17421   "operands[0] = gen_lowpart (SImode, operands[0]);
17422    operands[2] = gen_lowpart (SImode, operands[2]);
17423    operands[3] = gen_lowpart (SImode, operands[3]);"
17424   [(set_attr "type" "icmov")
17425    (set_attr "mode" "SI")])
17427 (define_expand "movsfcc"
17428   [(set (match_operand:SF 0 "register_operand" "")
17429         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17430                          (match_operand:SF 2 "register_operand" "")
17431                          (match_operand:SF 3 "register_operand" "")))]
17432   "TARGET_CMOVE"
17433   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17435 (define_insn "*movsfcc_1"
17436   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17437         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17438                                 [(reg 17) (const_int 0)])
17439                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17440                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17441   "TARGET_CMOVE
17442    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17443   "@
17444    fcmov%F1\t{%2, %0|%0, %2}
17445    fcmov%f1\t{%3, %0|%0, %3}
17446    cmov%O2%C1\t{%2, %0|%0, %2}
17447    cmov%O2%c1\t{%3, %0|%0, %3}"
17448   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17449    (set_attr "mode" "SF,SF,SI,SI")])
17451 (define_expand "movdfcc"
17452   [(set (match_operand:DF 0 "register_operand" "")
17453         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17454                          (match_operand:DF 2 "register_operand" "")
17455                          (match_operand:DF 3 "register_operand" "")))]
17456   "TARGET_CMOVE"
17457   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17459 (define_insn "*movdfcc_1"
17460   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17461         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17462                                 [(reg 17) (const_int 0)])
17463                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17464                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17465   "!TARGET_64BIT && TARGET_CMOVE
17466    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17467   "@
17468    fcmov%F1\t{%2, %0|%0, %2}
17469    fcmov%f1\t{%3, %0|%0, %3}
17470    #
17471    #"
17472   [(set_attr "type" "fcmov,fcmov,multi,multi")
17473    (set_attr "mode" "DF")])
17475 (define_insn "*movdfcc_1_rex64"
17476   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17477         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17478                                 [(reg 17) (const_int 0)])
17479                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17480                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17481   "TARGET_64BIT && TARGET_CMOVE
17482    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17483   "@
17484    fcmov%F1\t{%2, %0|%0, %2}
17485    fcmov%f1\t{%3, %0|%0, %3}
17486    cmov%O2%C1\t{%2, %0|%0, %2}
17487    cmov%O2%c1\t{%3, %0|%0, %3}"
17488   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17489    (set_attr "mode" "DF")])
17491 (define_split
17492   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17493         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17494                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17495                       (match_operand:DF 2 "nonimmediate_operand" "")
17496                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17497   "!TARGET_64BIT && reload_completed"
17498   [(set (match_dup 2)
17499         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17500                       (match_dup 5)
17501                       (match_dup 7)))
17502    (set (match_dup 3)
17503         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17504                       (match_dup 6)
17505                       (match_dup 8)))]
17506   "split_di (operands+2, 1, operands+5, operands+6);
17507    split_di (operands+3, 1, operands+7, operands+8);
17508    split_di (operands, 1, operands+2, operands+3);")
17510 (define_expand "movxfcc"
17511   [(set (match_operand:XF 0 "register_operand" "")
17512         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17513                          (match_operand:XF 2 "register_operand" "")
17514                          (match_operand:XF 3 "register_operand" "")))]
17515   "TARGET_CMOVE"
17516   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17518 (define_insn "*movxfcc_1"
17519   [(set (match_operand:XF 0 "register_operand" "=f,f")
17520         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17521                                 [(reg 17) (const_int 0)])
17522                       (match_operand:XF 2 "register_operand" "f,0")
17523                       (match_operand:XF 3 "register_operand" "0,f")))]
17524   "TARGET_CMOVE"
17525   "@
17526    fcmov%F1\t{%2, %0|%0, %2}
17527    fcmov%f1\t{%3, %0|%0, %3}"
17528   [(set_attr "type" "fcmov")
17529    (set_attr "mode" "XF")])
17531 (define_expand "minsf3"
17532   [(parallel [
17533      (set (match_operand:SF 0 "register_operand" "")
17534           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17535                                (match_operand:SF 2 "nonimmediate_operand" ""))
17536                            (match_dup 1)
17537                            (match_dup 2)))
17538      (clobber (reg:CC FLAGS_REG))])]
17539   "TARGET_SSE"
17540   "")
17542 (define_insn "*minsf"
17543   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17544         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17545                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17546                          (match_dup 1)
17547                          (match_dup 2)))
17548    (clobber (reg:CC FLAGS_REG))]
17549   "TARGET_SSE && TARGET_IEEE_FP"
17550   "#")
17552 (define_insn "*minsf_nonieee"
17553   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17554         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17555                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17556                          (match_dup 1)
17557                          (match_dup 2)))
17558    (clobber (reg:CC FLAGS_REG))]
17559   "TARGET_SSE && !TARGET_IEEE_FP
17560    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17561   "#")
17563 (define_split
17564   [(set (match_operand:SF 0 "register_operand" "")
17565         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17566                              (match_operand:SF 2 "nonimmediate_operand" ""))
17567                          (match_operand:SF 3 "register_operand" "")
17568                          (match_operand:SF 4 "nonimmediate_operand" "")))
17569    (clobber (reg:CC FLAGS_REG))]
17570   "SSE_REG_P (operands[0]) && reload_completed
17571    && ((operands_match_p (operands[1], operands[3])
17572         && operands_match_p (operands[2], operands[4]))
17573        || (operands_match_p (operands[1], operands[4])
17574            && operands_match_p (operands[2], operands[3])))"
17575   [(set (match_dup 0)
17576         (if_then_else:SF (lt (match_dup 1)
17577                              (match_dup 2))
17578                          (match_dup 1)
17579                          (match_dup 2)))])
17581 ;; Conditional addition patterns
17582 (define_expand "addqicc"
17583   [(match_operand:QI 0 "register_operand" "")
17584    (match_operand 1 "comparison_operator" "")
17585    (match_operand:QI 2 "register_operand" "")
17586    (match_operand:QI 3 "const_int_operand" "")]
17587   ""
17588   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17590 (define_expand "addhicc"
17591   [(match_operand:HI 0 "register_operand" "")
17592    (match_operand 1 "comparison_operator" "")
17593    (match_operand:HI 2 "register_operand" "")
17594    (match_operand:HI 3 "const_int_operand" "")]
17595   ""
17596   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17598 (define_expand "addsicc"
17599   [(match_operand:SI 0 "register_operand" "")
17600    (match_operand 1 "comparison_operator" "")
17601    (match_operand:SI 2 "register_operand" "")
17602    (match_operand:SI 3 "const_int_operand" "")]
17603   ""
17604   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17606 (define_expand "adddicc"
17607   [(match_operand:DI 0 "register_operand" "")
17608    (match_operand 1 "comparison_operator" "")
17609    (match_operand:DI 2 "register_operand" "")
17610    (match_operand:DI 3 "const_int_operand" "")]
17611   "TARGET_64BIT"
17612   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17614 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17616 (define_split
17617   [(set (match_operand:SF 0 "fp_register_operand" "")
17618         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17619                              (match_operand:SF 2 "register_operand" ""))
17620                          (match_operand:SF 3 "register_operand" "")
17621                          (match_operand:SF 4 "register_operand" "")))
17622    (clobber (reg:CC FLAGS_REG))]
17623   "reload_completed
17624    && ((operands_match_p (operands[1], operands[3])
17625         && operands_match_p (operands[2], operands[4]))
17626        || (operands_match_p (operands[1], operands[4])
17627            && operands_match_p (operands[2], operands[3])))"
17628   [(set (reg:CCFP FLAGS_REG)
17629         (compare:CCFP (match_dup 2)
17630                       (match_dup 1)))
17631    (set (match_dup 0)
17632         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17633                          (match_dup 1)
17634                          (match_dup 2)))])
17636 (define_insn "*minsf_sse"
17637   [(set (match_operand:SF 0 "register_operand" "=x")
17638         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17639                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17640                          (match_dup 1)
17641                          (match_dup 2)))]
17642   "TARGET_SSE && reload_completed"
17643   "minss\t{%2, %0|%0, %2}"
17644   [(set_attr "type" "sse")
17645    (set_attr "mode" "SF")])
17647 (define_expand "mindf3"
17648   [(parallel [
17649      (set (match_operand:DF 0 "register_operand" "")
17650           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17651                                (match_operand:DF 2 "nonimmediate_operand" ""))
17652                            (match_dup 1)
17653                            (match_dup 2)))
17654      (clobber (reg:CC FLAGS_REG))])]
17655   "TARGET_SSE2 && TARGET_SSE_MATH"
17656   "#")
17658 (define_insn "*mindf"
17659   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17660         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17661                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17662                          (match_dup 1)
17663                          (match_dup 2)))
17664    (clobber (reg:CC FLAGS_REG))]
17665   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17666   "#")
17668 (define_insn "*mindf_nonieee"
17669   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17670         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17671                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17672                          (match_dup 1)
17673                          (match_dup 2)))
17674    (clobber (reg:CC FLAGS_REG))]
17675   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17676    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17677   "#")
17679 (define_split
17680   [(set (match_operand:DF 0 "register_operand" "")
17681         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17682                              (match_operand:DF 2 "nonimmediate_operand" ""))
17683                          (match_operand:DF 3 "register_operand" "")
17684                          (match_operand:DF 4 "nonimmediate_operand" "")))
17685    (clobber (reg:CC FLAGS_REG))]
17686   "SSE_REG_P (operands[0]) && reload_completed
17687    && ((operands_match_p (operands[1], operands[3])
17688         && operands_match_p (operands[2], operands[4]))
17689        || (operands_match_p (operands[1], operands[4])
17690            && operands_match_p (operands[2], operands[3])))"
17691   [(set (match_dup 0)
17692         (if_then_else:DF (lt (match_dup 1)
17693                              (match_dup 2))
17694                          (match_dup 1)
17695                          (match_dup 2)))])
17697 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17698 (define_split
17699   [(set (match_operand:DF 0 "fp_register_operand" "")
17700         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17701                              (match_operand:DF 2 "register_operand" ""))
17702                          (match_operand:DF 3 "register_operand" "")
17703                          (match_operand:DF 4 "register_operand" "")))
17704    (clobber (reg:CC FLAGS_REG))]
17705   "reload_completed
17706    && ((operands_match_p (operands[1], operands[3])
17707         && operands_match_p (operands[2], operands[4]))
17708        || (operands_match_p (operands[1], operands[4])
17709            && operands_match_p (operands[2], operands[3])))"
17710   [(set (reg:CCFP FLAGS_REG)
17711         (compare:CCFP (match_dup 2)
17712                       (match_dup 1)))
17713    (set (match_dup 0)
17714         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17715                          (match_dup 1)
17716                          (match_dup 2)))])
17718 (define_insn "*mindf_sse"
17719   [(set (match_operand:DF 0 "register_operand" "=Y")
17720         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17721                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17722                          (match_dup 1)
17723                          (match_dup 2)))]
17724   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17725   "minsd\t{%2, %0|%0, %2}"
17726   [(set_attr "type" "sse")
17727    (set_attr "mode" "DF")])
17729 (define_expand "maxsf3"
17730   [(parallel [
17731      (set (match_operand:SF 0 "register_operand" "")
17732           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17733                                (match_operand:SF 2 "nonimmediate_operand" ""))
17734                            (match_dup 1)
17735                            (match_dup 2)))
17736      (clobber (reg:CC FLAGS_REG))])]
17737   "TARGET_SSE"
17738   "#")
17740 (define_insn "*maxsf"
17741   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17742         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17743                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17744                          (match_dup 1)
17745                          (match_dup 2)))
17746    (clobber (reg:CC FLAGS_REG))]
17747   "TARGET_SSE && TARGET_IEEE_FP"
17748   "#")
17750 (define_insn "*maxsf_nonieee"
17751   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17752         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17753                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17754                          (match_dup 1)
17755                          (match_dup 2)))
17756    (clobber (reg:CC FLAGS_REG))]
17757   "TARGET_SSE && !TARGET_IEEE_FP
17758    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17759   "#")
17761 (define_split
17762   [(set (match_operand:SF 0 "register_operand" "")
17763         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17764                              (match_operand:SF 2 "nonimmediate_operand" ""))
17765                          (match_operand:SF 3 "register_operand" "")
17766                          (match_operand:SF 4 "nonimmediate_operand" "")))
17767    (clobber (reg:CC FLAGS_REG))]
17768   "SSE_REG_P (operands[0]) && reload_completed
17769    && ((operands_match_p (operands[1], operands[3])
17770         && operands_match_p (operands[2], operands[4]))
17771        || (operands_match_p (operands[1], operands[4])
17772            && operands_match_p (operands[2], operands[3])))"
17773   [(set (match_dup 0)
17774         (if_then_else:SF (gt (match_dup 1)
17775                              (match_dup 2))
17776                          (match_dup 1)
17777                          (match_dup 2)))])
17779 (define_split
17780   [(set (match_operand:SF 0 "fp_register_operand" "")
17781         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17782                              (match_operand:SF 2 "register_operand" ""))
17783                          (match_operand:SF 3 "register_operand" "")
17784                          (match_operand:SF 4 "register_operand" "")))
17785    (clobber (reg:CC FLAGS_REG))]
17786   "reload_completed
17787    && ((operands_match_p (operands[1], operands[3])
17788         && operands_match_p (operands[2], operands[4]))
17789        || (operands_match_p (operands[1], operands[4])
17790            && operands_match_p (operands[2], operands[3])))"
17791   [(set (reg:CCFP FLAGS_REG)
17792         (compare:CCFP (match_dup 1)
17793                       (match_dup 2)))
17794    (set (match_dup 0)
17795         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17796                          (match_dup 1)
17797                          (match_dup 2)))])
17799 (define_insn "*maxsf_sse"
17800   [(set (match_operand:SF 0 "register_operand" "=x")
17801         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17802                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17803                          (match_dup 1)
17804                          (match_dup 2)))]
17805   "TARGET_SSE && reload_completed"
17806   "maxss\t{%2, %0|%0, %2}"
17807   [(set_attr "type" "sse")
17808    (set_attr "mode" "SF")])
17810 (define_expand "maxdf3"
17811   [(parallel [
17812      (set (match_operand:DF 0 "register_operand" "")
17813           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17814                                (match_operand:DF 2 "nonimmediate_operand" ""))
17815                            (match_dup 1)
17816                            (match_dup 2)))
17817      (clobber (reg:CC FLAGS_REG))])]
17818   "TARGET_SSE2 && TARGET_SSE_MATH"
17819   "#")
17821 (define_insn "*maxdf"
17822   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17823         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17824                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17825                          (match_dup 1)
17826                          (match_dup 2)))
17827    (clobber (reg:CC FLAGS_REG))]
17828   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17829   "#")
17831 (define_insn "*maxdf_nonieee"
17832   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17833         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17834                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17835                          (match_dup 1)
17836                          (match_dup 2)))
17837    (clobber (reg:CC FLAGS_REG))]
17838   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17839    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17840   "#")
17842 (define_split
17843   [(set (match_operand:DF 0 "register_operand" "")
17844         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17845                              (match_operand:DF 2 "nonimmediate_operand" ""))
17846                          (match_operand:DF 3 "register_operand" "")
17847                          (match_operand:DF 4 "nonimmediate_operand" "")))
17848    (clobber (reg:CC FLAGS_REG))]
17849   "SSE_REG_P (operands[0]) && reload_completed
17850    && ((operands_match_p (operands[1], operands[3])
17851         && operands_match_p (operands[2], operands[4]))
17852        || (operands_match_p (operands[1], operands[4])
17853            && operands_match_p (operands[2], operands[3])))"
17854   [(set (match_dup 0)
17855         (if_then_else:DF (gt (match_dup 1)
17856                              (match_dup 2))
17857                          (match_dup 1)
17858                          (match_dup 2)))])
17860 (define_split
17861   [(set (match_operand:DF 0 "fp_register_operand" "")
17862         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17863                              (match_operand:DF 2 "register_operand" ""))
17864                          (match_operand:DF 3 "register_operand" "")
17865                          (match_operand:DF 4 "register_operand" "")))
17866    (clobber (reg:CC FLAGS_REG))]
17867   "reload_completed
17868    && ((operands_match_p (operands[1], operands[3])
17869         && operands_match_p (operands[2], operands[4]))
17870        || (operands_match_p (operands[1], operands[4])
17871            && operands_match_p (operands[2], operands[3])))"
17872   [(set (reg:CCFP FLAGS_REG)
17873         (compare:CCFP (match_dup 1)
17874                       (match_dup 2)))
17875    (set (match_dup 0)
17876         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17877                          (match_dup 1)
17878                          (match_dup 2)))])
17880 (define_insn "*maxdf_sse"
17881   [(set (match_operand:DF 0 "register_operand" "=Y")
17882         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17883                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17884                          (match_dup 1)
17885                          (match_dup 2)))]
17886   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17887   "maxsd\t{%2, %0|%0, %2}"
17888   [(set_attr "type" "sse")
17889    (set_attr "mode" "DF")])
17891 ;; Misc patterns (?)
17893 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17894 ;; Otherwise there will be nothing to keep
17895 ;; 
17896 ;; [(set (reg ebp) (reg esp))]
17897 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17898 ;;  (clobber (eflags)]
17899 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17901 ;; in proper program order.
17902 (define_insn "pro_epilogue_adjust_stack_1"
17903   [(set (match_operand:SI 0 "register_operand" "=r,r")
17904         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17905                  (match_operand:SI 2 "immediate_operand" "i,i")))
17906    (clobber (reg:CC FLAGS_REG))
17907    (clobber (mem:BLK (scratch)))]
17908   "!TARGET_64BIT"
17910   switch (get_attr_type (insn))
17911     {
17912     case TYPE_IMOV:
17913       return "mov{l}\t{%1, %0|%0, %1}";
17915     case TYPE_ALU:
17916       if (GET_CODE (operands[2]) == CONST_INT
17917           && (INTVAL (operands[2]) == 128
17918               || (INTVAL (operands[2]) < 0
17919                   && INTVAL (operands[2]) != -128)))
17920         {
17921           operands[2] = GEN_INT (-INTVAL (operands[2]));
17922           return "sub{l}\t{%2, %0|%0, %2}";
17923         }
17924       return "add{l}\t{%2, %0|%0, %2}";
17926     case TYPE_LEA:
17927       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17928       return "lea{l}\t{%a2, %0|%0, %a2}";
17930     default:
17931       abort ();
17932     }
17934   [(set (attr "type")
17935         (cond [(eq_attr "alternative" "0")
17936                  (const_string "alu")
17937                (match_operand:SI 2 "const0_operand" "")
17938                  (const_string "imov")
17939               ]
17940               (const_string "lea")))
17941    (set_attr "mode" "SI")])
17943 (define_insn "pro_epilogue_adjust_stack_rex64"
17944   [(set (match_operand:DI 0 "register_operand" "=r,r")
17945         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17946                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17947    (clobber (reg:CC FLAGS_REG))
17948    (clobber (mem:BLK (scratch)))]
17949   "TARGET_64BIT"
17951   switch (get_attr_type (insn))
17952     {
17953     case TYPE_IMOV:
17954       return "mov{q}\t{%1, %0|%0, %1}";
17956     case TYPE_ALU:
17957       if (GET_CODE (operands[2]) == CONST_INT
17958           /* Avoid overflows.  */
17959           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17960           && (INTVAL (operands[2]) == 128
17961               || (INTVAL (operands[2]) < 0
17962                   && INTVAL (operands[2]) != -128)))
17963         {
17964           operands[2] = GEN_INT (-INTVAL (operands[2]));
17965           return "sub{q}\t{%2, %0|%0, %2}";
17966         }
17967       return "add{q}\t{%2, %0|%0, %2}";
17969     case TYPE_LEA:
17970       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17971       return "lea{q}\t{%a2, %0|%0, %a2}";
17973     default:
17974       abort ();
17975     }
17977   [(set (attr "type")
17978         (cond [(eq_attr "alternative" "0")
17979                  (const_string "alu")
17980                (match_operand:DI 2 "const0_operand" "")
17981                  (const_string "imov")
17982               ]
17983               (const_string "lea")))
17984    (set_attr "mode" "DI")])
17986 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17987   [(set (match_operand:DI 0 "register_operand" "=r,r")
17988         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17989                  (match_operand:DI 3 "immediate_operand" "i,i")))
17990    (use (match_operand:DI 2 "register_operand" "r,r"))
17991    (clobber (reg:CC FLAGS_REG))
17992    (clobber (mem:BLK (scratch)))]
17993   "TARGET_64BIT"
17995   switch (get_attr_type (insn))
17996     {
17997     case TYPE_ALU:
17998       return "add{q}\t{%2, %0|%0, %2}";
18000     case TYPE_LEA:
18001       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18002       return "lea{q}\t{%a2, %0|%0, %a2}";
18004     default:
18005       abort ();
18006     }
18008   [(set_attr "type" "alu,lea")
18009    (set_attr "mode" "DI")])
18011 ;; Placeholder for the conditional moves.  This one is split either to SSE
18012 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18013 ;; fact is that compares supported by the cmp??ss instructions are exactly
18014 ;; swapped of those supported by cmove sequence.
18015 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18016 ;; supported by i387 comparisons and we do need to emit two conditional moves
18017 ;; in tandem.
18019 (define_insn "sse_movsfcc"
18020   [(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")
18021         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18022                         [(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")
18023                          (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")])
18024                       (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")
18025                       (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")))
18026    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18027    (clobber (reg:CC FLAGS_REG))]
18028   "TARGET_SSE
18029    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18030    /* Avoid combine from being smart and converting min/max
18031       instruction patterns into conditional moves.  */
18032    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18033         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18034        || !rtx_equal_p (operands[4], operands[2])
18035        || !rtx_equal_p (operands[5], operands[3]))
18036    && (!TARGET_IEEE_FP
18037        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18038   "#")
18040 (define_insn "sse_movsfcc_eq"
18041   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18042         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18043                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18044                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18045                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18046    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18047    (clobber (reg:CC FLAGS_REG))]
18048   "TARGET_SSE
18049    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18050   "#")
18052 (define_insn "sse_movdfcc"
18053   [(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")
18054         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18055                         [(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")
18056                          (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")])
18057                       (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")
18058                       (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")))
18059    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18060    (clobber (reg:CC FLAGS_REG))]
18061   "TARGET_SSE2
18062    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18063    /* Avoid combine from being smart and converting min/max
18064       instruction patterns into conditional moves.  */
18065    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18066         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18067        || !rtx_equal_p (operands[4], operands[2])
18068        || !rtx_equal_p (operands[5], operands[3]))
18069    && (!TARGET_IEEE_FP
18070        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18071   "#")
18073 (define_insn "sse_movdfcc_eq"
18074   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18075         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18076                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18077                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18078                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18079    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18080    (clobber (reg:CC FLAGS_REG))]
18081   "TARGET_SSE
18082    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18083   "#")
18085 ;; For non-sse moves just expand the usual cmove sequence.
18086 (define_split
18087   [(set (match_operand 0 "register_operand" "")
18088         (if_then_else (match_operator 1 "comparison_operator"
18089                         [(match_operand 4 "nonimmediate_operand" "")
18090                          (match_operand 5 "register_operand" "")])
18091                       (match_operand 2 "nonimmediate_operand" "")
18092                       (match_operand 3 "nonimmediate_operand" "")))
18093    (clobber (match_operand 6 "" ""))
18094    (clobber (reg:CC FLAGS_REG))]
18095   "!SSE_REG_P (operands[0]) && reload_completed
18096    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18097   [(const_int 0)]
18099    ix86_compare_op0 = operands[5];
18100    ix86_compare_op1 = operands[4];
18101    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18102                                  VOIDmode, operands[5], operands[4]);
18103    ix86_expand_fp_movcc (operands);
18104    DONE;
18107 ;; Split SSE based conditional move into sequence:
18108 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18109 ;; and   op2, op0   -  zero op2 if comparison was false
18110 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18111 ;; or    op2, op0   -  get the nonzero one into the result.
18112 (define_split
18113   [(set (match_operand:SF 0 "register_operand" "")
18114         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18115                         [(match_operand:SF 4 "register_operand" "")
18116                          (match_operand:SF 5 "nonimmediate_operand" "")])
18117                       (match_operand:SF 2 "register_operand" "")
18118                       (match_operand:SF 3 "register_operand" "")))
18119    (clobber (match_operand 6 "" ""))
18120    (clobber (reg:CC FLAGS_REG))]
18121   "SSE_REG_P (operands[0]) && reload_completed"
18122   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18123    (set (match_dup 2) (and:V4SF (match_dup 2)
18124                                 (match_dup 8)))
18125    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18126                                           (match_dup 3)))
18127    (set (match_dup 0) (ior:V4SF (match_dup 6)
18128                                 (match_dup 7)))]
18130   /* If op2 == op3, op3 would be clobbered before it is used.  */
18131   if (operands_match_p (operands[2], operands[3]))
18132     {
18133       emit_move_insn (operands[0], operands[2]);
18134       DONE;
18135     }
18137   PUT_MODE (operands[1], GET_MODE (operands[0]));
18138   if (operands_match_p (operands[0], operands[4]))
18139     operands[6] = operands[4], operands[7] = operands[2];
18140   else
18141     operands[6] = operands[2], operands[7] = operands[4];
18142   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18143   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18144   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18145   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18146   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18147   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18150 (define_split
18151   [(set (match_operand:DF 0 "register_operand" "")
18152         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18153                         [(match_operand:DF 4 "register_operand" "")
18154                          (match_operand:DF 5 "nonimmediate_operand" "")])
18155                       (match_operand:DF 2 "register_operand" "")
18156                       (match_operand:DF 3 "register_operand" "")))
18157    (clobber (match_operand 6 "" ""))
18158    (clobber (reg:CC FLAGS_REG))]
18159   "SSE_REG_P (operands[0]) && reload_completed"
18160   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18161    (set (match_dup 2) (and:V2DF (match_dup 2)
18162                                 (match_dup 8)))
18163    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18164                                           (match_dup 3)))
18165    (set (match_dup 0) (ior:V2DF (match_dup 6)
18166                                 (match_dup 7)))]
18168   if (GET_MODE (operands[2]) == DFmode
18169       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18170     {
18171       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18172       emit_insn (gen_sse2_unpcklpd (op, op, op));
18173       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18174       emit_insn (gen_sse2_unpcklpd (op, op, op));
18175     }
18177   /* If op2 == op3, op3 would be clobbered before it is used.  */
18178   if (operands_match_p (operands[2], operands[3]))
18179     {
18180       emit_move_insn (operands[0], operands[2]);
18181       DONE;
18182     }
18184   PUT_MODE (operands[1], GET_MODE (operands[0]));
18185   if (operands_match_p (operands[0], operands[4]))
18186     operands[6] = operands[4], operands[7] = operands[2];
18187   else
18188     operands[6] = operands[2], operands[7] = operands[4];
18189   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18190   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18191   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18192   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18193   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18194   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18197 ;; Special case of conditional move we can handle effectively.
18198 ;; Do not brother with the integer/floating point case, since these are
18199 ;; bot considerably slower, unlike in the generic case.
18200 (define_insn "*sse_movsfcc_const0_1"
18201   [(set (match_operand:SF 0 "register_operand" "=&x")
18202         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18203                         [(match_operand:SF 4 "register_operand" "0")
18204                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18205                       (match_operand:SF 2 "register_operand" "x")
18206                       (match_operand:SF 3 "const0_operand" "X")))]
18207   "TARGET_SSE"
18208   "#")
18210 (define_insn "*sse_movsfcc_const0_2"
18211   [(set (match_operand:SF 0 "register_operand" "=&x")
18212         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18213                         [(match_operand:SF 4 "register_operand" "0")
18214                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18215                       (match_operand:SF 2 "const0_operand" "X")
18216                       (match_operand:SF 3 "register_operand" "x")))]
18217   "TARGET_SSE"
18218   "#")
18220 (define_insn "*sse_movsfcc_const0_3"
18221   [(set (match_operand:SF 0 "register_operand" "=&x")
18222         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18223                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18224                          (match_operand:SF 5 "register_operand" "0")])
18225                       (match_operand:SF 2 "register_operand" "x")
18226                       (match_operand:SF 3 "const0_operand" "X")))]
18227   "TARGET_SSE"
18228   "#")
18230 (define_insn "*sse_movsfcc_const0_4"
18231   [(set (match_operand:SF 0 "register_operand" "=&x")
18232         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18233                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18234                          (match_operand:SF 5 "register_operand" "0")])
18235                       (match_operand:SF 2 "const0_operand" "X")
18236                       (match_operand:SF 3 "register_operand" "x")))]
18237   "TARGET_SSE"
18238   "#")
18240 (define_insn "*sse_movdfcc_const0_1"
18241   [(set (match_operand:DF 0 "register_operand" "=&Y")
18242         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18243                         [(match_operand:DF 4 "register_operand" "0")
18244                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18245                       (match_operand:DF 2 "register_operand" "Y")
18246                       (match_operand:DF 3 "const0_operand" "X")))]
18247   "TARGET_SSE2"
18248   "#")
18250 (define_insn "*sse_movdfcc_const0_2"
18251   [(set (match_operand:DF 0 "register_operand" "=&Y")
18252         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18253                         [(match_operand:DF 4 "register_operand" "0")
18254                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18255                       (match_operand:DF 2 "const0_operand" "X")
18256                       (match_operand:DF 3 "register_operand" "Y")))]
18257   "TARGET_SSE2"
18258   "#")
18260 (define_insn "*sse_movdfcc_const0_3"
18261   [(set (match_operand:DF 0 "register_operand" "=&Y")
18262         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18263                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18264                          (match_operand:DF 5 "register_operand" "0")])
18265                       (match_operand:DF 2 "register_operand" "Y")
18266                       (match_operand:DF 3 "const0_operand" "X")))]
18267   "TARGET_SSE2"
18268   "#")
18270 (define_insn "*sse_movdfcc_const0_4"
18271   [(set (match_operand:DF 0 "register_operand" "=&Y")
18272         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18273                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18274                          (match_operand:DF 5 "register_operand" "0")])
18275                       (match_operand:DF 2 "const0_operand" "X")
18276                       (match_operand:DF 3 "register_operand" "Y")))]
18277   "TARGET_SSE2"
18278   "#")
18280 (define_split
18281   [(set (match_operand:SF 0 "register_operand" "")
18282         (if_then_else (match_operator 1 "comparison_operator"
18283                         [(match_operand:SF 4 "nonimmediate_operand" "")
18284                          (match_operand:SF 5 "nonimmediate_operand" "")])
18285                       (match_operand:SF 2 "nonmemory_operand" "")
18286                       (match_operand:SF 3 "nonmemory_operand" "")))]
18287   "SSE_REG_P (operands[0]) && reload_completed
18288    && (const0_operand (operands[2], GET_MODE (operands[0]))
18289        || const0_operand (operands[3], GET_MODE (operands[0])))"
18290   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18291    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18293   PUT_MODE (operands[1], GET_MODE (operands[0]));
18294   if (!sse_comparison_operator (operands[1], VOIDmode)
18295       || !rtx_equal_p (operands[0], operands[4]))
18296     {
18297       rtx tmp = operands[5];
18298       operands[5] = operands[4];
18299       operands[4] = tmp;
18300       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18301     }
18302   if (!rtx_equal_p (operands[0], operands[4]))
18303     abort ();
18304   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18305   if (const0_operand (operands[2], GET_MODE (operands[2])))
18306     {
18307       operands[7] = operands[3];
18308       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18309     }
18310   else
18311     {
18312       operands[7] = operands[2];
18313       operands[6] = operands[8];
18314     }
18315   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18318 (define_split
18319   [(set (match_operand:DF 0 "register_operand" "")
18320         (if_then_else (match_operator 1 "comparison_operator"
18321                         [(match_operand:DF 4 "nonimmediate_operand" "")
18322                          (match_operand:DF 5 "nonimmediate_operand" "")])
18323                       (match_operand:DF 2 "nonmemory_operand" "")
18324                       (match_operand:DF 3 "nonmemory_operand" "")))]
18325   "SSE_REG_P (operands[0]) && reload_completed
18326    && (const0_operand (operands[2], GET_MODE (operands[0]))
18327        || const0_operand (operands[3], GET_MODE (operands[0])))"
18328   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18329    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18331   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18332       && GET_MODE (operands[2]) == DFmode)
18333     {
18334       if (REG_P (operands[2]))
18335         {
18336           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18337           emit_insn (gen_sse2_unpcklpd (op, op, op));
18338         }
18339       if (REG_P (operands[3]))
18340         {
18341           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18342           emit_insn (gen_sse2_unpcklpd (op, op, op));
18343         }
18344     }
18345   PUT_MODE (operands[1], GET_MODE (operands[0]));
18346   if (!sse_comparison_operator (operands[1], VOIDmode)
18347       || !rtx_equal_p (operands[0], operands[4]))
18348     {
18349       rtx tmp = operands[5];
18350       operands[5] = operands[4];
18351       operands[4] = tmp;
18352       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18353     }
18354   if (!rtx_equal_p (operands[0], operands[4]))
18355     abort ();
18356   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18357   if (const0_operand (operands[2], GET_MODE (operands[2])))
18358     {
18359       operands[7] = operands[3];
18360       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18361     }
18362   else
18363     {
18364       operands[7] = operands[2];
18365       operands[6] = operands[8];
18366     }
18367   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18370 (define_expand "allocate_stack_worker"
18371   [(match_operand:SI 0 "register_operand" "")]
18372   "TARGET_STACK_PROBE"
18374   if (reload_completed)
18375     {
18376       if (TARGET_64BIT)
18377         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18378       else
18379         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18380     }
18381   else
18382     {
18383       if (TARGET_64BIT)
18384         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18385       else
18386         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18387     }
18388   DONE;
18391 (define_insn "allocate_stack_worker_1"
18392   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18393     UNSPECV_STACK_PROBE)
18394    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18395    (clobber (match_scratch:SI 1 "=0"))
18396    (clobber (reg:CC FLAGS_REG))]
18397   "!TARGET_64BIT && TARGET_STACK_PROBE"
18398   "call\t__alloca"
18399   [(set_attr "type" "multi")
18400    (set_attr "length" "5")])
18402 (define_expand "allocate_stack_worker_postreload"
18403   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18404                                     UNSPECV_STACK_PROBE)
18405               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18406               (clobber (match_dup 0))
18407               (clobber (reg:CC FLAGS_REG))])]
18408   ""
18409   "")
18411 (define_insn "allocate_stack_worker_rex64"
18412   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18413     UNSPECV_STACK_PROBE)
18414    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18415    (clobber (match_scratch:DI 1 "=0"))
18416    (clobber (reg:CC FLAGS_REG))]
18417   "TARGET_64BIT && TARGET_STACK_PROBE"
18418   "call\t__alloca"
18419   [(set_attr "type" "multi")
18420    (set_attr "length" "5")])
18422 (define_expand "allocate_stack_worker_rex64_postreload"
18423   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18424                                     UNSPECV_STACK_PROBE)
18425               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18426               (clobber (match_dup 0))
18427               (clobber (reg:CC FLAGS_REG))])]
18428   ""
18429   "")
18431 (define_expand "allocate_stack"
18432   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18433                    (minus:SI (reg:SI SP_REG)
18434                              (match_operand:SI 1 "general_operand" "")))
18435               (clobber (reg:CC FLAGS_REG))])
18436    (parallel [(set (reg:SI SP_REG)
18437                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18438               (clobber (reg:CC FLAGS_REG))])]
18439   "TARGET_STACK_PROBE"
18441 #ifdef CHECK_STACK_LIMIT
18442   if (GET_CODE (operands[1]) == CONST_INT
18443       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18444     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18445                            operands[1]));
18446   else 
18447 #endif
18448     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18449                                                             operands[1])));
18451   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18452   DONE;
18455 (define_expand "builtin_setjmp_receiver"
18456   [(label_ref (match_operand 0 "" ""))]
18457   "!TARGET_64BIT && flag_pic"
18459   emit_insn (gen_set_got (pic_offset_table_rtx));
18460   DONE;
18463 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18465 (define_split
18466   [(set (match_operand 0 "register_operand" "")
18467         (match_operator 3 "promotable_binary_operator"
18468            [(match_operand 1 "register_operand" "")
18469             (match_operand 2 "aligned_operand" "")]))
18470    (clobber (reg:CC FLAGS_REG))]
18471   "! TARGET_PARTIAL_REG_STALL && reload_completed
18472    && ((GET_MODE (operands[0]) == HImode 
18473         && ((!optimize_size && !TARGET_FAST_PREFIX)
18474             || GET_CODE (operands[2]) != CONST_INT
18475             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18476        || (GET_MODE (operands[0]) == QImode 
18477            && (TARGET_PROMOTE_QImode || optimize_size)))"
18478   [(parallel [(set (match_dup 0)
18479                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18480               (clobber (reg:CC FLAGS_REG))])]
18481   "operands[0] = gen_lowpart (SImode, operands[0]);
18482    operands[1] = gen_lowpart (SImode, operands[1]);
18483    if (GET_CODE (operands[3]) != ASHIFT)
18484      operands[2] = gen_lowpart (SImode, operands[2]);
18485    PUT_MODE (operands[3], SImode);")
18487 ; Promote the QImode tests, as i386 has encoding of the AND
18488 ; instruction with 32-bit sign-extended immediate and thus the
18489 ; instruction size is unchanged, except in the %eax case for
18490 ; which it is increased by one byte, hence the ! optimize_size.
18491 (define_split
18492   [(set (reg 17)
18493         (compare (and (match_operand 1 "aligned_operand" "")
18494                       (match_operand 2 "const_int_operand" ""))
18495                  (const_int 0)))
18496    (set (match_operand 0 "register_operand" "")
18497         (and (match_dup 1) (match_dup 2)))]
18498   "! TARGET_PARTIAL_REG_STALL && reload_completed
18499    /* Ensure that the operand will remain sign-extended immediate.  */
18500    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18501    && ! optimize_size
18502    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18503        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18504   [(parallel [(set (reg:CCNO FLAGS_REG)
18505                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18506                                  (const_int 0)))
18507               (set (match_dup 0)
18508                    (and:SI (match_dup 1) (match_dup 2)))])]
18509   "operands[2]
18510      = gen_int_mode (INTVAL (operands[2])
18511                      & GET_MODE_MASK (GET_MODE (operands[0])),
18512                      SImode);
18513    operands[0] = gen_lowpart (SImode, operands[0]);
18514    operands[1] = gen_lowpart (SImode, operands[1]);")
18516 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18517 ; the TEST instruction with 32-bit sign-extended immediate and thus
18518 ; the instruction size would at least double, which is not what we
18519 ; want even with ! optimize_size.
18520 (define_split
18521   [(set (reg 17)
18522         (compare (and (match_operand:HI 0 "aligned_operand" "")
18523                       (match_operand:HI 1 "const_int_operand" ""))
18524                  (const_int 0)))]
18525   "! TARGET_PARTIAL_REG_STALL && reload_completed
18526    /* Ensure that the operand will remain sign-extended immediate.  */
18527    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18528    && ! TARGET_FAST_PREFIX
18529    && ! optimize_size"
18530   [(set (reg:CCNO FLAGS_REG)
18531         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18532                       (const_int 0)))]
18533   "operands[1]
18534      = gen_int_mode (INTVAL (operands[1])
18535                      & GET_MODE_MASK (GET_MODE (operands[0])),
18536                      SImode);
18537    operands[0] = gen_lowpart (SImode, operands[0]);")
18539 (define_split
18540   [(set (match_operand 0 "register_operand" "")
18541         (neg (match_operand 1 "register_operand" "")))
18542    (clobber (reg:CC FLAGS_REG))]
18543   "! TARGET_PARTIAL_REG_STALL && reload_completed
18544    && (GET_MODE (operands[0]) == HImode
18545        || (GET_MODE (operands[0]) == QImode 
18546            && (TARGET_PROMOTE_QImode || optimize_size)))"
18547   [(parallel [(set (match_dup 0)
18548                    (neg:SI (match_dup 1)))
18549               (clobber (reg:CC FLAGS_REG))])]
18550   "operands[0] = gen_lowpart (SImode, operands[0]);
18551    operands[1] = gen_lowpart (SImode, operands[1]);")
18553 (define_split
18554   [(set (match_operand 0 "register_operand" "")
18555         (not (match_operand 1 "register_operand" "")))]
18556   "! TARGET_PARTIAL_REG_STALL && reload_completed
18557    && (GET_MODE (operands[0]) == HImode
18558        || (GET_MODE (operands[0]) == QImode 
18559            && (TARGET_PROMOTE_QImode || optimize_size)))"
18560   [(set (match_dup 0)
18561         (not:SI (match_dup 1)))]
18562   "operands[0] = gen_lowpart (SImode, operands[0]);
18563    operands[1] = gen_lowpart (SImode, operands[1]);")
18565 (define_split 
18566   [(set (match_operand 0 "register_operand" "")
18567         (if_then_else (match_operator 1 "comparison_operator" 
18568                                 [(reg 17) (const_int 0)])
18569                       (match_operand 2 "register_operand" "")
18570                       (match_operand 3 "register_operand" "")))]
18571   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18572    && (GET_MODE (operands[0]) == HImode
18573        || (GET_MODE (operands[0]) == QImode 
18574            && (TARGET_PROMOTE_QImode || optimize_size)))"
18575   [(set (match_dup 0)
18576         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18577   "operands[0] = gen_lowpart (SImode, operands[0]);
18578    operands[2] = gen_lowpart (SImode, operands[2]);
18579    operands[3] = gen_lowpart (SImode, operands[3]);")
18580                         
18582 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18583 ;; transform a complex memory operation into two memory to register operations.
18585 ;; Don't push memory operands
18586 (define_peephole2
18587   [(set (match_operand:SI 0 "push_operand" "")
18588         (match_operand:SI 1 "memory_operand" ""))
18589    (match_scratch:SI 2 "r")]
18590   "! optimize_size && ! TARGET_PUSH_MEMORY"
18591   [(set (match_dup 2) (match_dup 1))
18592    (set (match_dup 0) (match_dup 2))]
18593   "")
18595 (define_peephole2
18596   [(set (match_operand:DI 0 "push_operand" "")
18597         (match_operand:DI 1 "memory_operand" ""))
18598    (match_scratch:DI 2 "r")]
18599   "! optimize_size && ! TARGET_PUSH_MEMORY"
18600   [(set (match_dup 2) (match_dup 1))
18601    (set (match_dup 0) (match_dup 2))]
18602   "")
18604 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18605 ;; SImode pushes.
18606 (define_peephole2
18607   [(set (match_operand:SF 0 "push_operand" "")
18608         (match_operand:SF 1 "memory_operand" ""))
18609    (match_scratch:SF 2 "r")]
18610   "! optimize_size && ! TARGET_PUSH_MEMORY"
18611   [(set (match_dup 2) (match_dup 1))
18612    (set (match_dup 0) (match_dup 2))]
18613   "")
18615 (define_peephole2
18616   [(set (match_operand:HI 0 "push_operand" "")
18617         (match_operand:HI 1 "memory_operand" ""))
18618    (match_scratch:HI 2 "r")]
18619   "! optimize_size && ! TARGET_PUSH_MEMORY"
18620   [(set (match_dup 2) (match_dup 1))
18621    (set (match_dup 0) (match_dup 2))]
18622   "")
18624 (define_peephole2
18625   [(set (match_operand:QI 0 "push_operand" "")
18626         (match_operand:QI 1 "memory_operand" ""))
18627    (match_scratch:QI 2 "q")]
18628   "! optimize_size && ! TARGET_PUSH_MEMORY"
18629   [(set (match_dup 2) (match_dup 1))
18630    (set (match_dup 0) (match_dup 2))]
18631   "")
18633 ;; Don't move an immediate directly to memory when the instruction
18634 ;; gets too big.
18635 (define_peephole2
18636   [(match_scratch:SI 1 "r")
18637    (set (match_operand:SI 0 "memory_operand" "")
18638         (const_int 0))]
18639   "! optimize_size
18640    && ! TARGET_USE_MOV0
18641    && TARGET_SPLIT_LONG_MOVES
18642    && get_attr_length (insn) >= ix86_cost->large_insn
18643    && peep2_regno_dead_p (0, FLAGS_REG)"
18644   [(parallel [(set (match_dup 1) (const_int 0))
18645               (clobber (reg:CC FLAGS_REG))])
18646    (set (match_dup 0) (match_dup 1))]
18647   "")
18649 (define_peephole2
18650   [(match_scratch:HI 1 "r")
18651    (set (match_operand:HI 0 "memory_operand" "")
18652         (const_int 0))]
18653   "! optimize_size
18654    && ! TARGET_USE_MOV0
18655    && TARGET_SPLIT_LONG_MOVES
18656    && get_attr_length (insn) >= ix86_cost->large_insn
18657    && peep2_regno_dead_p (0, FLAGS_REG)"
18658   [(parallel [(set (match_dup 2) (const_int 0))
18659               (clobber (reg:CC FLAGS_REG))])
18660    (set (match_dup 0) (match_dup 1))]
18661   "operands[2] = gen_lowpart (SImode, operands[1]);")
18663 (define_peephole2
18664   [(match_scratch:QI 1 "q")
18665    (set (match_operand:QI 0 "memory_operand" "")
18666         (const_int 0))]
18667   "! optimize_size
18668    && ! TARGET_USE_MOV0
18669    && TARGET_SPLIT_LONG_MOVES
18670    && get_attr_length (insn) >= ix86_cost->large_insn
18671    && peep2_regno_dead_p (0, FLAGS_REG)"
18672   [(parallel [(set (match_dup 2) (const_int 0))
18673               (clobber (reg:CC FLAGS_REG))])
18674    (set (match_dup 0) (match_dup 1))]
18675   "operands[2] = gen_lowpart (SImode, operands[1]);")
18677 (define_peephole2
18678   [(match_scratch:SI 2 "r")
18679    (set (match_operand:SI 0 "memory_operand" "")
18680         (match_operand:SI 1 "immediate_operand" ""))]
18681   "! optimize_size
18682    && get_attr_length (insn) >= ix86_cost->large_insn
18683    && TARGET_SPLIT_LONG_MOVES"
18684   [(set (match_dup 2) (match_dup 1))
18685    (set (match_dup 0) (match_dup 2))]
18686   "")
18688 (define_peephole2
18689   [(match_scratch:HI 2 "r")
18690    (set (match_operand:HI 0 "memory_operand" "")
18691         (match_operand:HI 1 "immediate_operand" ""))]
18692   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18693   && TARGET_SPLIT_LONG_MOVES"
18694   [(set (match_dup 2) (match_dup 1))
18695    (set (match_dup 0) (match_dup 2))]
18696   "")
18698 (define_peephole2
18699   [(match_scratch:QI 2 "q")
18700    (set (match_operand:QI 0 "memory_operand" "")
18701         (match_operand:QI 1 "immediate_operand" ""))]
18702   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18703   && TARGET_SPLIT_LONG_MOVES"
18704   [(set (match_dup 2) (match_dup 1))
18705    (set (match_dup 0) (match_dup 2))]
18706   "")
18708 ;; Don't compare memory with zero, load and use a test instead.
18709 (define_peephole2
18710   [(set (reg 17)
18711         (compare (match_operand:SI 0 "memory_operand" "")
18712                  (const_int 0)))
18713    (match_scratch:SI 3 "r")]
18714   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18715   [(set (match_dup 3) (match_dup 0))
18716    (set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
18717   "")
18719 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18720 ;; Don't split NOTs with a displacement operand, because resulting XOR
18721 ;; will not be pairable anyway.
18723 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18724 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18725 ;; so this split helps here as well.
18727 ;; Note: Can't do this as a regular split because we can't get proper
18728 ;; lifetime information then.
18730 (define_peephole2
18731   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18732         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18733   "!optimize_size
18734    && peep2_regno_dead_p (0, FLAGS_REG)
18735    && ((TARGET_PENTIUM 
18736         && (GET_CODE (operands[0]) != MEM
18737             || !memory_displacement_operand (operands[0], SImode)))
18738        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18739   [(parallel [(set (match_dup 0)
18740                    (xor:SI (match_dup 1) (const_int -1)))
18741               (clobber (reg:CC FLAGS_REG))])]
18742   "")
18744 (define_peephole2
18745   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18746         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18747   "!optimize_size
18748    && peep2_regno_dead_p (0, FLAGS_REG)
18749    && ((TARGET_PENTIUM 
18750         && (GET_CODE (operands[0]) != MEM
18751             || !memory_displacement_operand (operands[0], HImode)))
18752        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18753   [(parallel [(set (match_dup 0)
18754                    (xor:HI (match_dup 1) (const_int -1)))
18755               (clobber (reg:CC FLAGS_REG))])]
18756   "")
18758 (define_peephole2
18759   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18760         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18761   "!optimize_size
18762    && peep2_regno_dead_p (0, FLAGS_REG)
18763    && ((TARGET_PENTIUM 
18764         && (GET_CODE (operands[0]) != MEM
18765             || !memory_displacement_operand (operands[0], QImode)))
18766        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18767   [(parallel [(set (match_dup 0)
18768                    (xor:QI (match_dup 1) (const_int -1)))
18769               (clobber (reg:CC FLAGS_REG))])]
18770   "")
18772 ;; Non pairable "test imm, reg" instructions can be translated to
18773 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18774 ;; byte opcode instead of two, have a short form for byte operands),
18775 ;; so do it for other CPUs as well.  Given that the value was dead,
18776 ;; this should not create any new dependencies.  Pass on the sub-word
18777 ;; versions if we're concerned about partial register stalls.
18779 (define_peephole2
18780   [(set (reg 17)
18781         (compare (and:SI (match_operand:SI 0 "register_operand" "")
18782                          (match_operand:SI 1 "immediate_operand" ""))
18783                  (const_int 0)))]
18784   "ix86_match_ccmode (insn, CCNOmode)
18785    && (true_regnum (operands[0]) != 0
18786        || (GET_CODE (operands[1]) == CONST_INT
18787            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18788    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18789   [(parallel
18790      [(set (reg:CCNO FLAGS_REG)
18791            (compare:CCNO (and:SI (match_dup 0)
18792                                  (match_dup 1))
18793                          (const_int 0)))
18794       (set (match_dup 0)
18795            (and:SI (match_dup 0) (match_dup 1)))])]
18796   "")
18798 ;; We don't need to handle HImode case, because it will be promoted to SImode
18799 ;; on ! TARGET_PARTIAL_REG_STALL
18801 (define_peephole2
18802   [(set (reg 17)
18803         (compare (and:QI (match_operand:QI 0 "register_operand" "")
18804                          (match_operand:QI 1 "immediate_operand" ""))
18805                  (const_int 0)))]
18806   "! TARGET_PARTIAL_REG_STALL
18807    && ix86_match_ccmode (insn, CCNOmode)
18808    && true_regnum (operands[0]) != 0
18809    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18810   [(parallel
18811      [(set (reg:CCNO FLAGS_REG)
18812            (compare:CCNO (and:QI (match_dup 0)
18813                                  (match_dup 1))
18814                          (const_int 0)))
18815       (set (match_dup 0)
18816            (and:QI (match_dup 0) (match_dup 1)))])]
18817   "")
18819 (define_peephole2
18820   [(set (reg 17)
18821         (compare
18822           (and:SI
18823             (zero_extract:SI
18824               (match_operand 0 "ext_register_operand" "")
18825               (const_int 8)
18826               (const_int 8))
18827             (match_operand 1 "const_int_operand" ""))
18828           (const_int 0)))]
18829   "! TARGET_PARTIAL_REG_STALL
18830    && ix86_match_ccmode (insn, CCNOmode)
18831    && true_regnum (operands[0]) != 0
18832    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18833   [(parallel [(set (reg:CCNO FLAGS_REG)
18834                    (compare:CCNO
18835                        (and:SI
18836                          (zero_extract:SI
18837                          (match_dup 0)
18838                          (const_int 8)
18839                          (const_int 8))
18840                         (match_dup 1))
18841                    (const_int 0)))
18842               (set (zero_extract:SI (match_dup 0)
18843                                     (const_int 8)
18844                                     (const_int 8))
18845                    (and:SI 
18846                      (zero_extract:SI
18847                        (match_dup 0)
18848                        (const_int 8)
18849                        (const_int 8))
18850                      (match_dup 1)))])]
18851   "")
18853 ;; Don't do logical operations with memory inputs.
18854 (define_peephole2
18855   [(match_scratch:SI 2 "r")
18856    (parallel [(set (match_operand:SI 0 "register_operand" "")
18857                    (match_operator:SI 3 "arith_or_logical_operator"
18858                      [(match_dup 0)
18859                       (match_operand:SI 1 "memory_operand" "")]))
18860               (clobber (reg:CC FLAGS_REG))])]
18861   "! optimize_size && ! TARGET_READ_MODIFY"
18862   [(set (match_dup 2) (match_dup 1))
18863    (parallel [(set (match_dup 0)
18864                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18865               (clobber (reg:CC FLAGS_REG))])]
18866   "")
18868 (define_peephole2
18869   [(match_scratch:SI 2 "r")
18870    (parallel [(set (match_operand:SI 0 "register_operand" "")
18871                    (match_operator:SI 3 "arith_or_logical_operator"
18872                      [(match_operand:SI 1 "memory_operand" "")
18873                       (match_dup 0)]))
18874               (clobber (reg:CC FLAGS_REG))])]
18875   "! optimize_size && ! TARGET_READ_MODIFY"
18876   [(set (match_dup 2) (match_dup 1))
18877    (parallel [(set (match_dup 0)
18878                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18879               (clobber (reg:CC FLAGS_REG))])]
18880   "")
18882 ; Don't do logical operations with memory outputs
18884 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18885 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18886 ; the same decoder scheduling characteristics as the original.
18888 (define_peephole2
18889   [(match_scratch:SI 2 "r")
18890    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18891                    (match_operator:SI 3 "arith_or_logical_operator"
18892                      [(match_dup 0)
18893                       (match_operand:SI 1 "nonmemory_operand" "")]))
18894               (clobber (reg:CC FLAGS_REG))])]
18895   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18896   [(set (match_dup 2) (match_dup 0))
18897    (parallel [(set (match_dup 2)
18898                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18899               (clobber (reg:CC FLAGS_REG))])
18900    (set (match_dup 0) (match_dup 2))]
18901   "")
18903 (define_peephole2
18904   [(match_scratch:SI 2 "r")
18905    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18906                    (match_operator:SI 3 "arith_or_logical_operator"
18907                      [(match_operand:SI 1 "nonmemory_operand" "")
18908                       (match_dup 0)]))
18909               (clobber (reg:CC FLAGS_REG))])]
18910   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18911   [(set (match_dup 2) (match_dup 0))
18912    (parallel [(set (match_dup 2)
18913                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18914               (clobber (reg:CC FLAGS_REG))])
18915    (set (match_dup 0) (match_dup 2))]
18916   "")
18918 ;; Attempt to always use XOR for zeroing registers.
18919 (define_peephole2
18920   [(set (match_operand 0 "register_operand" "")
18921         (const_int 0))]
18922   "(GET_MODE (operands[0]) == QImode
18923     || GET_MODE (operands[0]) == HImode
18924     || GET_MODE (operands[0]) == SImode
18925     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18926    && (! TARGET_USE_MOV0 || optimize_size)
18927    && peep2_regno_dead_p (0, FLAGS_REG)"
18928   [(parallel [(set (match_dup 0) (const_int 0))
18929               (clobber (reg:CC FLAGS_REG))])]
18930   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18931                               operands[0]);")
18933 (define_peephole2
18934   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18935         (const_int 0))]
18936   "(GET_MODE (operands[0]) == QImode
18937     || GET_MODE (operands[0]) == HImode)
18938    && (! TARGET_USE_MOV0 || optimize_size)
18939    && peep2_regno_dead_p (0, FLAGS_REG)"
18940   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18941               (clobber (reg:CC FLAGS_REG))])])
18943 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18944 (define_peephole2
18945   [(set (match_operand 0 "register_operand" "")
18946         (const_int -1))]
18947   "(GET_MODE (operands[0]) == HImode
18948     || GET_MODE (operands[0]) == SImode 
18949     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18950    && (optimize_size || TARGET_PENTIUM)
18951    && peep2_regno_dead_p (0, FLAGS_REG)"
18952   [(parallel [(set (match_dup 0) (const_int -1))
18953               (clobber (reg:CC FLAGS_REG))])]
18954   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18955                               operands[0]);")
18957 ;; Attempt to convert simple leas to adds. These can be created by
18958 ;; move expanders.
18959 (define_peephole2
18960   [(set (match_operand:SI 0 "register_operand" "")
18961         (plus:SI (match_dup 0)
18962                  (match_operand:SI 1 "nonmemory_operand" "")))]
18963   "peep2_regno_dead_p (0, FLAGS_REG)"
18964   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18965               (clobber (reg:CC FLAGS_REG))])]
18966   "")
18968 (define_peephole2
18969   [(set (match_operand:SI 0 "register_operand" "")
18970         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18971                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18972   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18973   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18974               (clobber (reg:CC FLAGS_REG))])]
18975   "operands[2] = gen_lowpart (SImode, operands[2]);")
18977 (define_peephole2
18978   [(set (match_operand:DI 0 "register_operand" "")
18979         (plus:DI (match_dup 0)
18980                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18981   "peep2_regno_dead_p (0, FLAGS_REG)"
18982   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18983               (clobber (reg:CC FLAGS_REG))])]
18984   "")
18986 (define_peephole2
18987   [(set (match_operand:SI 0 "register_operand" "")
18988         (mult:SI (match_dup 0)
18989                  (match_operand:SI 1 "const_int_operand" "")))]
18990   "exact_log2 (INTVAL (operands[1])) >= 0
18991    && peep2_regno_dead_p (0, FLAGS_REG)"
18992   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18993               (clobber (reg:CC FLAGS_REG))])]
18994   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18996 (define_peephole2
18997   [(set (match_operand:DI 0 "register_operand" "")
18998         (mult:DI (match_dup 0)
18999                  (match_operand:DI 1 "const_int_operand" "")))]
19000   "exact_log2 (INTVAL (operands[1])) >= 0
19001    && peep2_regno_dead_p (0, FLAGS_REG)"
19002   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19003               (clobber (reg:CC FLAGS_REG))])]
19004   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19006 (define_peephole2
19007   [(set (match_operand:SI 0 "register_operand" "")
19008         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19009                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19010   "exact_log2 (INTVAL (operands[2])) >= 0
19011    && REGNO (operands[0]) == REGNO (operands[1])
19012    && peep2_regno_dead_p (0, FLAGS_REG)"
19013   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19014               (clobber (reg:CC FLAGS_REG))])]
19015   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19017 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19018 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19019 ;; many CPUs it is also faster, since special hardware to avoid esp
19020 ;; dependencies is present.
19022 ;; While some of these conversions may be done using splitters, we use peepholes
19023 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19025 ;; Convert prologue esp subtractions to push.
19026 ;; We need register to push.  In order to keep verify_flow_info happy we have
19027 ;; two choices
19028 ;; - use scratch and clobber it in order to avoid dependencies
19029 ;; - use already live register
19030 ;; We can't use the second way right now, since there is no reliable way how to
19031 ;; verify that given register is live.  First choice will also most likely in
19032 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19033 ;; call clobbered registers are dead.  We may want to use base pointer as an
19034 ;; alternative when no register is available later.
19036 (define_peephole2
19037   [(match_scratch:SI 0 "r")
19038    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19039               (clobber (reg:CC FLAGS_REG))
19040               (clobber (mem:BLK (scratch)))])]
19041   "optimize_size || !TARGET_SUB_ESP_4"
19042   [(clobber (match_dup 0))
19043    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19044               (clobber (mem:BLK (scratch)))])])
19046 (define_peephole2
19047   [(match_scratch:SI 0 "r")
19048    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19049               (clobber (reg:CC FLAGS_REG))
19050               (clobber (mem:BLK (scratch)))])]
19051   "optimize_size || !TARGET_SUB_ESP_8"
19052   [(clobber (match_dup 0))
19053    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19054    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19055               (clobber (mem:BLK (scratch)))])])
19057 ;; Convert esp subtractions to push.
19058 (define_peephole2
19059   [(match_scratch:SI 0 "r")
19060    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19061               (clobber (reg:CC FLAGS_REG))])]
19062   "optimize_size || !TARGET_SUB_ESP_4"
19063   [(clobber (match_dup 0))
19064    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19066 (define_peephole2
19067   [(match_scratch:SI 0 "r")
19068    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19069               (clobber (reg:CC FLAGS_REG))])]
19070   "optimize_size || !TARGET_SUB_ESP_8"
19071   [(clobber (match_dup 0))
19072    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19073    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19075 ;; Convert epilogue deallocator to pop.
19076 (define_peephole2
19077   [(match_scratch:SI 0 "r")
19078    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19079               (clobber (reg:CC FLAGS_REG))
19080               (clobber (mem:BLK (scratch)))])]
19081   "optimize_size || !TARGET_ADD_ESP_4"
19082   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19083               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19084               (clobber (mem:BLK (scratch)))])]
19085   "")
19087 ;; Two pops case is tricky, since pop causes dependency on destination register.
19088 ;; We use two registers if available.
19089 (define_peephole2
19090   [(match_scratch:SI 0 "r")
19091    (match_scratch:SI 1 "r")
19092    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19093               (clobber (reg:CC FLAGS_REG))
19094               (clobber (mem:BLK (scratch)))])]
19095   "optimize_size || !TARGET_ADD_ESP_8"
19096   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19097               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19098               (clobber (mem:BLK (scratch)))])
19099    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19100               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19101   "")
19103 (define_peephole2
19104   [(match_scratch:SI 0 "r")
19105    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19106               (clobber (reg:CC FLAGS_REG))
19107               (clobber (mem:BLK (scratch)))])]
19108   "optimize_size"
19109   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19110               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19111               (clobber (mem:BLK (scratch)))])
19112    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19113               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19114   "")
19116 ;; Convert esp additions to pop.
19117 (define_peephole2
19118   [(match_scratch:SI 0 "r")
19119    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19120               (clobber (reg:CC FLAGS_REG))])]
19121   ""
19122   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19123               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19124   "")
19126 ;; Two pops case is tricky, since pop causes dependency on destination register.
19127 ;; We use two registers if available.
19128 (define_peephole2
19129   [(match_scratch:SI 0 "r")
19130    (match_scratch:SI 1 "r")
19131    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19132               (clobber (reg:CC FLAGS_REG))])]
19133   ""
19134   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19135               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19136    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19137               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19138   "")
19140 (define_peephole2
19141   [(match_scratch:SI 0 "r")
19142    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19143               (clobber (reg:CC FLAGS_REG))])]
19144   "optimize_size"
19145   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19146               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19147    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19148               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19149   "")
19151 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19152 ;; required and register dies.
19153 (define_peephole2
19154   [(set (reg 17)
19155         (compare (match_operand:SI 0 "register_operand" "")
19156                  (match_operand:SI 1 "incdec_operand" "")))]
19157   "ix86_match_ccmode (insn, CCGCmode)
19158    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19159   [(parallel [(set (reg:CCGC FLAGS_REG)
19160                    (compare:CCGC (match_dup 0)
19161                                  (match_dup 1)))
19162               (clobber (match_dup 0))])]
19163   "")
19165 (define_peephole2
19166   [(set (reg 17)
19167         (compare (match_operand:HI 0 "register_operand" "")
19168                  (match_operand:HI 1 "incdec_operand" "")))]
19169   "ix86_match_ccmode (insn, CCGCmode)
19170    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19171   [(parallel [(set (reg:CCGC FLAGS_REG)
19172                    (compare:CCGC (match_dup 0)
19173                                  (match_dup 1)))
19174               (clobber (match_dup 0))])]
19175   "")
19177 (define_peephole2
19178   [(set (reg 17)
19179         (compare (match_operand:QI 0 "register_operand" "")
19180                  (match_operand:QI 1 "incdec_operand" "")))]
19181   "ix86_match_ccmode (insn, CCGCmode)
19182    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19183   [(parallel [(set (reg:CCGC FLAGS_REG)
19184                    (compare:CCGC (match_dup 0)
19185                                  (match_dup 1)))
19186               (clobber (match_dup 0))])]
19187   "")
19189 ;; Convert compares with 128 to shorter add -128
19190 (define_peephole2
19191   [(set (reg 17)
19192         (compare (match_operand:SI 0 "register_operand" "")
19193                  (const_int 128)))]
19194   "ix86_match_ccmode (insn, CCGCmode)
19195    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19196   [(parallel [(set (reg:CCGC FLAGS_REG)
19197                    (compare:CCGC (match_dup 0)
19198                                  (const_int 128)))
19199               (clobber (match_dup 0))])]
19200   "")
19202 (define_peephole2
19203   [(set (reg 17)
19204         (compare (match_operand:HI 0 "register_operand" "")
19205                  (const_int 128)))]
19206   "ix86_match_ccmode (insn, CCGCmode)
19207    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19208   [(parallel [(set (reg:CCGC FLAGS_REG)
19209                    (compare:CCGC (match_dup 0)
19210                                  (const_int 128)))
19211               (clobber (match_dup 0))])]
19212   "")
19214 (define_peephole2
19215   [(match_scratch:DI 0 "r")
19216    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19217               (clobber (reg:CC FLAGS_REG))
19218               (clobber (mem:BLK (scratch)))])]
19219   "optimize_size || !TARGET_SUB_ESP_4"
19220   [(clobber (match_dup 0))
19221    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19222               (clobber (mem:BLK (scratch)))])])
19224 (define_peephole2
19225   [(match_scratch:DI 0 "r")
19226    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19227               (clobber (reg:CC FLAGS_REG))
19228               (clobber (mem:BLK (scratch)))])]
19229   "optimize_size || !TARGET_SUB_ESP_8"
19230   [(clobber (match_dup 0))
19231    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19232    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19233               (clobber (mem:BLK (scratch)))])])
19235 ;; Convert esp subtractions to push.
19236 (define_peephole2
19237   [(match_scratch:DI 0 "r")
19238    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19239               (clobber (reg:CC FLAGS_REG))])]
19240   "optimize_size || !TARGET_SUB_ESP_4"
19241   [(clobber (match_dup 0))
19242    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19244 (define_peephole2
19245   [(match_scratch:DI 0 "r")
19246    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19247               (clobber (reg:CC FLAGS_REG))])]
19248   "optimize_size || !TARGET_SUB_ESP_8"
19249   [(clobber (match_dup 0))
19250    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19251    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19253 ;; Convert epilogue deallocator to pop.
19254 (define_peephole2
19255   [(match_scratch:DI 0 "r")
19256    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19257               (clobber (reg:CC FLAGS_REG))
19258               (clobber (mem:BLK (scratch)))])]
19259   "optimize_size || !TARGET_ADD_ESP_4"
19260   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19261               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19262               (clobber (mem:BLK (scratch)))])]
19263   "")
19265 ;; Two pops case is tricky, since pop causes dependency on destination register.
19266 ;; We use two registers if available.
19267 (define_peephole2
19268   [(match_scratch:DI 0 "r")
19269    (match_scratch:DI 1 "r")
19270    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19271               (clobber (reg:CC FLAGS_REG))
19272               (clobber (mem:BLK (scratch)))])]
19273   "optimize_size || !TARGET_ADD_ESP_8"
19274   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19275               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19276               (clobber (mem:BLK (scratch)))])
19277    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19278               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19279   "")
19281 (define_peephole2
19282   [(match_scratch:DI 0 "r")
19283    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19284               (clobber (reg:CC FLAGS_REG))
19285               (clobber (mem:BLK (scratch)))])]
19286   "optimize_size"
19287   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19288               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19289               (clobber (mem:BLK (scratch)))])
19290    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19291               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19292   "")
19294 ;; Convert esp additions to pop.
19295 (define_peephole2
19296   [(match_scratch:DI 0 "r")
19297    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19298               (clobber (reg:CC FLAGS_REG))])]
19299   ""
19300   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19301               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19302   "")
19304 ;; Two pops case is tricky, since pop causes dependency on destination register.
19305 ;; We use two registers if available.
19306 (define_peephole2
19307   [(match_scratch:DI 0 "r")
19308    (match_scratch:DI 1 "r")
19309    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19310               (clobber (reg:CC FLAGS_REG))])]
19311   ""
19312   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19313               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19314    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19315               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19316   "")
19318 (define_peephole2
19319   [(match_scratch:DI 0 "r")
19320    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19321               (clobber (reg:CC FLAGS_REG))])]
19322   "optimize_size"
19323   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19324               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19325    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19326               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19327   "")
19329 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19330 ;; imul $32bit_imm, reg, reg is direct decoded.
19331 (define_peephole2
19332   [(match_scratch:DI 3 "r")
19333    (parallel [(set (match_operand:DI 0 "register_operand" "")
19334                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19335                             (match_operand:DI 2 "immediate_operand" "")))
19336               (clobber (reg:CC FLAGS_REG))])]
19337   "TARGET_K8 && !optimize_size
19338    && (GET_CODE (operands[2]) != CONST_INT
19339        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19340   [(set (match_dup 3) (match_dup 1))
19341    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19342               (clobber (reg:CC FLAGS_REG))])]
19345 (define_peephole2
19346   [(match_scratch:SI 3 "r")
19347    (parallel [(set (match_operand:SI 0 "register_operand" "")
19348                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19349                             (match_operand:SI 2 "immediate_operand" "")))
19350               (clobber (reg:CC FLAGS_REG))])]
19351   "TARGET_K8 && !optimize_size
19352    && (GET_CODE (operands[2]) != CONST_INT
19353        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19354   [(set (match_dup 3) (match_dup 1))
19355    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19356               (clobber (reg:CC FLAGS_REG))])]
19359 (define_peephole2
19360   [(match_scratch:SI 3 "r")
19361    (parallel [(set (match_operand:DI 0 "register_operand" "")
19362                    (zero_extend:DI
19363                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19364                               (match_operand:SI 2 "immediate_operand" ""))))
19365               (clobber (reg:CC FLAGS_REG))])]
19366   "TARGET_K8 && !optimize_size
19367    && (GET_CODE (operands[2]) != CONST_INT
19368        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19369   [(set (match_dup 3) (match_dup 1))
19370    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19371               (clobber (reg:CC FLAGS_REG))])]
19374 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19375 ;; Convert it into imul reg, reg
19376 ;; It would be better to force assembler to encode instruction using long
19377 ;; immediate, but there is apparently no way to do so.
19378 (define_peephole2
19379   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19380                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19381                             (match_operand:DI 2 "const_int_operand" "")))
19382               (clobber (reg:CC FLAGS_REG))])
19383    (match_scratch:DI 3 "r")]
19384   "TARGET_K8 && !optimize_size
19385    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19386   [(set (match_dup 3) (match_dup 2))
19387    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19388               (clobber (reg:CC FLAGS_REG))])]
19390   if (!rtx_equal_p (operands[0], operands[1]))
19391     emit_move_insn (operands[0], operands[1]);
19394 (define_peephole2
19395   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19396                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19397                             (match_operand:SI 2 "const_int_operand" "")))
19398               (clobber (reg:CC FLAGS_REG))])
19399    (match_scratch:SI 3 "r")]
19400   "TARGET_K8 && !optimize_size
19401    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19402   [(set (match_dup 3) (match_dup 2))
19403    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19404               (clobber (reg:CC FLAGS_REG))])]
19406   if (!rtx_equal_p (operands[0], operands[1]))
19407     emit_move_insn (operands[0], operands[1]);
19410 (define_peephole2
19411   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19412                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19413                             (match_operand:HI 2 "immediate_operand" "")))
19414               (clobber (reg:CC FLAGS_REG))])
19415    (match_scratch:HI 3 "r")]
19416   "TARGET_K8 && !optimize_size"
19417   [(set (match_dup 3) (match_dup 2))
19418    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19419               (clobber (reg:CC FLAGS_REG))])]
19421   if (!rtx_equal_p (operands[0], operands[1]))
19422     emit_move_insn (operands[0], operands[1]);
19425 ;; Call-value patterns last so that the wildcard operand does not
19426 ;; disrupt insn-recog's switch tables.
19428 (define_insn "*call_value_pop_0"
19429   [(set (match_operand 0 "" "")
19430         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19431               (match_operand:SI 2 "" "")))
19432    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19433                             (match_operand:SI 3 "immediate_operand" "")))]
19434   "!TARGET_64BIT"
19436   if (SIBLING_CALL_P (insn))
19437     return "jmp\t%P1";
19438   else
19439     return "call\t%P1";
19441   [(set_attr "type" "callv")])
19443 (define_insn "*call_value_pop_1"
19444   [(set (match_operand 0 "" "")
19445         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19446               (match_operand:SI 2 "" "")))
19447    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19448                             (match_operand:SI 3 "immediate_operand" "i")))]
19449   "!TARGET_64BIT"
19451   if (constant_call_address_operand (operands[1], QImode))
19452     {
19453       if (SIBLING_CALL_P (insn))
19454         return "jmp\t%P1";
19455       else
19456         return "call\t%P1";
19457     }
19458   if (SIBLING_CALL_P (insn))
19459     return "jmp\t%A1";
19460   else
19461     return "call\t%A1";
19463   [(set_attr "type" "callv")])
19465 (define_insn "*call_value_0"
19466   [(set (match_operand 0 "" "")
19467         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19468               (match_operand:SI 2 "" "")))]
19469   "!TARGET_64BIT"
19471   if (SIBLING_CALL_P (insn))
19472     return "jmp\t%P1";
19473   else
19474     return "call\t%P1";
19476   [(set_attr "type" "callv")])
19478 (define_insn "*call_value_0_rex64"
19479   [(set (match_operand 0 "" "")
19480         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19481               (match_operand:DI 2 "const_int_operand" "")))]
19482   "TARGET_64BIT"
19484   if (SIBLING_CALL_P (insn))
19485     return "jmp\t%P1";
19486   else
19487     return "call\t%P1";
19489   [(set_attr "type" "callv")])
19491 (define_insn "*call_value_1"
19492   [(set (match_operand 0 "" "")
19493         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19494               (match_operand:SI 2 "" "")))]
19495   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19497   if (constant_call_address_operand (operands[1], QImode))
19498     return "call\t%P1";
19499   return "call\t%*%1";
19501   [(set_attr "type" "callv")])
19503 (define_insn "*sibcall_value_1"
19504   [(set (match_operand 0 "" "")
19505         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19506               (match_operand:SI 2 "" "")))]
19507   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19509   if (constant_call_address_operand (operands[1], QImode))
19510     return "jmp\t%P1";
19511   return "jmp\t%*%1";
19513   [(set_attr "type" "callv")])
19515 (define_insn "*call_value_1_rex64"
19516   [(set (match_operand 0 "" "")
19517         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19518               (match_operand:DI 2 "" "")))]
19519   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19521   if (constant_call_address_operand (operands[1], QImode))
19522     return "call\t%P1";
19523   return "call\t%A1";
19525   [(set_attr "type" "callv")])
19527 (define_insn "*sibcall_value_1_rex64"
19528   [(set (match_operand 0 "" "")
19529         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19530               (match_operand:DI 2 "" "")))]
19531   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19532   "jmp\t%P1"
19533   [(set_attr "type" "callv")])
19535 (define_insn "*sibcall_value_1_rex64_v"
19536   [(set (match_operand 0 "" "")
19537         (call (mem:QI (reg:DI 40))
19538               (match_operand:DI 1 "" "")))]
19539   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19540   "jmp\t*%%r11"
19541   [(set_attr "type" "callv")])
19543 (define_insn "trap"
19544   [(trap_if (const_int 1) (const_int 5))]
19545   ""
19546   "int\t$5")
19548 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19549 ;;; for the sake of bounds checking.  By emitting bounds checks as
19550 ;;; conditional traps rather than as conditional jumps around
19551 ;;; unconditional traps we avoid introducing spurious basic-block
19552 ;;; boundaries and facilitate elimination of redundant checks.  In
19553 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19554 ;;; interrupt 5.
19555 ;;; 
19556 ;;; FIXME: Static branch prediction rules for ix86 are such that
19557 ;;; forward conditional branches predict as untaken.  As implemented
19558 ;;; below, pseudo conditional traps violate that rule.  We should use
19559 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19560 ;;; section loaded at the end of the text segment and branch forward
19561 ;;; there on bounds-failure, and then jump back immediately (in case
19562 ;;; the system chooses to ignore bounds violations, or to report
19563 ;;; violations and continue execution).
19565 (define_expand "conditional_trap"
19566   [(trap_if (match_operator 0 "comparison_operator"
19567              [(match_dup 2) (const_int 0)])
19568             (match_operand 1 "const_int_operand" ""))]
19569   ""
19571   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19572                               ix86_expand_compare (GET_CODE (operands[0]),
19573                                                    NULL, NULL),
19574                               operands[1]));
19575   DONE;
19578 (define_insn "*conditional_trap_1"
19579   [(trap_if (match_operator 0 "comparison_operator"
19580              [(reg 17) (const_int 0)])
19581             (match_operand 1 "const_int_operand" ""))]
19582   ""
19584   operands[2] = gen_label_rtx ();
19585   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19586   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19587                              CODE_LABEL_NUMBER (operands[2]));
19588   RET;
19591         ;; Pentium III SIMD instructions.
19593 ;; Moves for SSE/MMX regs.
19595 (define_insn "movv4sf_internal"
19596   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19597         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19598   "TARGET_SSE"
19599   "@
19600     xorps\t%0, %0
19601     movaps\t{%1, %0|%0, %1}
19602     movaps\t{%1, %0|%0, %1}"
19603   [(set_attr "type" "ssemov")
19604    (set_attr "mode" "V4SF")])
19606 (define_split
19607   [(set (match_operand:V4SF 0 "register_operand" "")
19608         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19609   "TARGET_SSE"
19610   [(set (match_dup 0)
19611         (vec_merge:V4SF
19612          (vec_duplicate:V4SF (match_dup 1))
19613          (match_dup 2)
19614          (const_int 1)))]
19616   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19617   operands[2] = CONST0_RTX (V4SFmode);
19620 (define_insn "movv4si_internal"
19621   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19622         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19623   "TARGET_SSE"
19625   switch (which_alternative)
19626     {
19627     case 0:
19628       if (get_attr_mode (insn) == MODE_V4SF)
19629         return "xorps\t%0, %0";
19630       else
19631         return "pxor\t%0, %0";
19632     case 1:
19633     case 2:
19634       if (get_attr_mode (insn) == MODE_V4SF)
19635         return "movaps\t{%1, %0|%0, %1}";
19636       else
19637         return "movdqa\t{%1, %0|%0, %1}";
19638     default:
19639       abort ();
19640     }
19642   [(set_attr "type" "ssemov")
19643    (set (attr "mode")
19644         (cond [(eq_attr "alternative" "0,1")
19645                  (if_then_else
19646                    (ne (symbol_ref "optimize_size")
19647                        (const_int 0))
19648                    (const_string "V4SF")
19649                    (const_string "TI"))
19650                (eq_attr "alternative" "2")
19651                  (if_then_else
19652                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19653                             (const_int 0))
19654                         (ne (symbol_ref "optimize_size")
19655                             (const_int 0)))
19656                    (const_string "V4SF")
19657                    (const_string "TI"))]
19658                (const_string "TI")))])
19660 (define_insn "movv2di_internal"
19661   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19662         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19663   "TARGET_SSE"
19665   switch (which_alternative)
19666     {
19667     case 0:
19668       if (get_attr_mode (insn) == MODE_V4SF)
19669         return "xorps\t%0, %0";
19670       else
19671         return "pxor\t%0, %0";
19672     case 1:
19673     case 2:
19674       if (get_attr_mode (insn) == MODE_V4SF)
19675         return "movaps\t{%1, %0|%0, %1}";
19676       else
19677         return "movdqa\t{%1, %0|%0, %1}";
19678     default:
19679       abort ();
19680     }
19682   [(set_attr "type" "ssemov")
19683    (set (attr "mode")
19684         (cond [(eq_attr "alternative" "0,1")
19685                  (if_then_else
19686                    (ne (symbol_ref "optimize_size")
19687                        (const_int 0))
19688                    (const_string "V4SF")
19689                    (const_string "TI"))
19690                (eq_attr "alternative" "2")
19691                  (if_then_else
19692                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19693                             (const_int 0))
19694                         (ne (symbol_ref "optimize_size")
19695                             (const_int 0)))
19696                    (const_string "V4SF")
19697                    (const_string "TI"))]
19698                (const_string "TI")))])
19700 (define_split
19701   [(set (match_operand:V2DF 0 "register_operand" "")
19702         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19703   "TARGET_SSE2"
19704   [(set (match_dup 0)
19705         (vec_merge:V2DF
19706          (vec_duplicate:V2DF (match_dup 1))
19707          (match_dup 2)
19708          (const_int 1)))]
19710   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19711   operands[2] = CONST0_RTX (V2DFmode);
19714 (define_insn "movv8qi_internal"
19715   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19716         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19717   "TARGET_MMX
19718    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19719   "@
19720     pxor\t%0, %0
19721     movq\t{%1, %0|%0, %1}
19722     movq\t{%1, %0|%0, %1}
19723     movdq2q\t{%1, %0|%0, %1}
19724     movq2dq\t{%1, %0|%0, %1}
19725     movq\t{%1, %0|%0, %1}
19726     movq\t{%1, %0|%0, %1}"
19727   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19728    (set_attr "mode" "DI")])
19730 (define_insn "movv4hi_internal"
19731   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19732         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19733   "TARGET_MMX
19734    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19735   "@
19736     pxor\t%0, %0
19737     movq\t{%1, %0|%0, %1}
19738     movq\t{%1, %0|%0, %1}
19739     movdq2q\t{%1, %0|%0, %1}
19740     movq2dq\t{%1, %0|%0, %1}
19741     movq\t{%1, %0|%0, %1}
19742     movq\t{%1, %0|%0, %1}"
19743   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19744    (set_attr "mode" "DI")])
19746 (define_insn "*movv2si_internal"
19747   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19748         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19749   "TARGET_MMX
19750    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19751   "@
19752     pxor\t%0, %0
19753     movq\t{%1, %0|%0, %1}
19754     movq\t{%1, %0|%0, %1}
19755     movdq2q\t{%1, %0|%0, %1}
19756     movq2dq\t{%1, %0|%0, %1}
19757     movq\t{%1, %0|%0, %1}
19758     movq\t{%1, %0|%0, %1}"
19759   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19760    (set_attr "mode" "DI")])
19762 (define_insn "movv2sf_internal"
19763   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
19764         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
19765   "TARGET_3DNOW
19766    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19767   "@
19768     pxor\t%0, %0
19769     movq\t{%1, %0|%0, %1}
19770     movq\t{%1, %0|%0, %1}
19771     movdq2q\t{%1, %0|%0, %1}
19772     movq2dq\t{%1, %0|%0, %1}
19773     movlps\t{%1, %0|%0, %1}
19774     movlps\t{%1, %0|%0, %1}"
19775   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19776    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
19778 (define_expand "movti"
19779   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19780         (match_operand:TI 1 "nonimmediate_operand" ""))]
19781   "TARGET_SSE || TARGET_64BIT"
19783   if (TARGET_64BIT)
19784     ix86_expand_move (TImode, operands);
19785   else
19786     ix86_expand_vector_move (TImode, operands);
19787   DONE;
19790 (define_expand "movtf"
19791   [(set (match_operand:TF 0 "nonimmediate_operand" "")
19792         (match_operand:TF 1 "nonimmediate_operand" ""))]
19793   "TARGET_64BIT"
19795   if (TARGET_64BIT)
19796     ix86_expand_move (TFmode, operands);
19797   else
19798     ix86_expand_vector_move (TFmode, operands);
19799   DONE;
19802 (define_insn "movv2df_internal"
19803   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19804         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19805   "TARGET_SSE2
19806    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19808   switch (which_alternative)
19809     {
19810     case 0:
19811       if (get_attr_mode (insn) == MODE_V4SF)
19812         return "xorps\t%0, %0";
19813       else
19814         return "xorpd\t%0, %0";
19815     case 1:
19816     case 2:
19817       if (get_attr_mode (insn) == MODE_V4SF)
19818         return "movaps\t{%1, %0|%0, %1}";
19819       else
19820         return "movapd\t{%1, %0|%0, %1}";
19821     default:
19822       abort ();
19823     }
19825   [(set_attr "type" "ssemov")
19826    (set (attr "mode")
19827         (cond [(eq_attr "alternative" "0,1")
19828                  (if_then_else
19829                    (ne (symbol_ref "optimize_size")
19830                        (const_int 0))
19831                    (const_string "V4SF")
19832                    (const_string "V2DF"))
19833                (eq_attr "alternative" "2")
19834                  (if_then_else
19835                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19836                             (const_int 0))
19837                         (ne (symbol_ref "optimize_size")
19838                             (const_int 0)))
19839                    (const_string "V4SF")
19840                    (const_string "V2DF"))]
19841                (const_string "V2DF")))])
19843 (define_insn "movv8hi_internal"
19844   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19845         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19846   "TARGET_SSE2
19847    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19849   switch (which_alternative)
19850     {
19851     case 0:
19852       if (get_attr_mode (insn) == MODE_V4SF)
19853         return "xorps\t%0, %0";
19854       else
19855         return "pxor\t%0, %0";
19856     case 1:
19857     case 2:
19858       if (get_attr_mode (insn) == MODE_V4SF)
19859         return "movaps\t{%1, %0|%0, %1}";
19860       else
19861         return "movdqa\t{%1, %0|%0, %1}";
19862     default:
19863       abort ();
19864     }
19866   [(set_attr "type" "ssemov")
19867    (set (attr "mode")
19868         (cond [(eq_attr "alternative" "0,1")
19869                  (if_then_else
19870                    (ne (symbol_ref "optimize_size")
19871                        (const_int 0))
19872                    (const_string "V4SF")
19873                    (const_string "TI"))
19874                (eq_attr "alternative" "2")
19875                  (if_then_else
19876                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19877                             (const_int 0))
19878                         (ne (symbol_ref "optimize_size")
19879                             (const_int 0)))
19880                    (const_string "V4SF")
19881                    (const_string "TI"))]
19882                (const_string "TI")))])
19884 (define_insn "movv16qi_internal"
19885   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19886         (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19887   "TARGET_SSE2
19888    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19890   switch (which_alternative)
19891     {
19892     case 0:
19893       if (get_attr_mode (insn) == MODE_V4SF)
19894         return "xorps\t%0, %0";
19895       else
19896         return "pxor\t%0, %0";
19897     case 1:
19898     case 2:
19899       if (get_attr_mode (insn) == MODE_V4SF)
19900         return "movaps\t{%1, %0|%0, %1}";
19901       else
19902         return "movdqa\t{%1, %0|%0, %1}";
19903     default:
19904       abort ();
19905     }
19907   [(set_attr "type" "ssemov")
19908    (set (attr "mode")
19909         (cond [(eq_attr "alternative" "0,1")
19910                  (if_then_else
19911                    (ne (symbol_ref "optimize_size")
19912                        (const_int 0))
19913                    (const_string "V4SF")
19914                    (const_string "TI"))
19915                (eq_attr "alternative" "2")
19916                  (if_then_else
19917                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19918                             (const_int 0))
19919                         (ne (symbol_ref "optimize_size")
19920                             (const_int 0)))
19921                    (const_string "V4SF")
19922                    (const_string "TI"))]
19923                (const_string "TI")))])
19925 (define_expand "movv2df"
19926   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19927         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19928   "TARGET_SSE2"
19930   ix86_expand_vector_move (V2DFmode, operands);
19931   DONE;
19934 (define_expand "movv8hi"
19935   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19936         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19937   "TARGET_SSE2"
19939   ix86_expand_vector_move (V8HImode, operands);
19940   DONE;
19943 (define_expand "movv16qi"
19944   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19945         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19946   "TARGET_SSE2"
19948   ix86_expand_vector_move (V16QImode, operands);
19949   DONE;
19952 (define_expand "movv4sf"
19953   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19954         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19955   "TARGET_SSE"
19957   ix86_expand_vector_move (V4SFmode, operands);
19958   DONE;
19961 (define_expand "movv4si"
19962   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19963         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19964   "TARGET_SSE"
19966   ix86_expand_vector_move (V4SImode, operands);
19967   DONE;
19970 (define_expand "movv2di"
19971   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19972         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19973   "TARGET_SSE"
19975   ix86_expand_vector_move (V2DImode, operands);
19976   DONE;
19979 (define_expand "movv2si"
19980   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19981         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19982   "TARGET_MMX"
19984   ix86_expand_vector_move (V2SImode, operands);
19985   DONE;
19988 (define_expand "movv4hi"
19989   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19990         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19991   "TARGET_MMX"
19993   ix86_expand_vector_move (V4HImode, operands);
19994   DONE;
19997 (define_expand "movv8qi"
19998   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19999         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20000   "TARGET_MMX"
20002   ix86_expand_vector_move (V8QImode, operands);
20003   DONE;
20006 (define_expand "movv2sf"
20007   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20008         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20009    "TARGET_3DNOW"
20011   ix86_expand_vector_move (V2SFmode, operands);
20012   DONE;
20015 (define_insn "*pushti"
20016   [(set (match_operand:TI 0 "push_operand" "=<")
20017         (match_operand:TI 1 "register_operand" "x"))]
20018   "TARGET_SSE"
20019   "#")
20021 (define_insn "*pushv2df"
20022   [(set (match_operand:V2DF 0 "push_operand" "=<")
20023         (match_operand:V2DF 1 "register_operand" "x"))]
20024   "TARGET_SSE"
20025   "#")
20027 (define_insn "*pushv2di"
20028   [(set (match_operand:V2DI 0 "push_operand" "=<")
20029         (match_operand:V2DI 1 "register_operand" "x"))]
20030   "TARGET_SSE2"
20031   "#")
20033 (define_insn "*pushv8hi"
20034   [(set (match_operand:V8HI 0 "push_operand" "=<")
20035         (match_operand:V8HI 1 "register_operand" "x"))]
20036   "TARGET_SSE2"
20037   "#")
20039 (define_insn "*pushv16qi"
20040   [(set (match_operand:V16QI 0 "push_operand" "=<")
20041         (match_operand:V16QI 1 "register_operand" "x"))]
20042   "TARGET_SSE2"
20043   "#")
20045 (define_insn "*pushv4sf"
20046   [(set (match_operand:V4SF 0 "push_operand" "=<")
20047         (match_operand:V4SF 1 "register_operand" "x"))]
20048   "TARGET_SSE"
20049   "#")
20051 (define_insn "*pushv4si"
20052   [(set (match_operand:V4SI 0 "push_operand" "=<")
20053         (match_operand:V4SI 1 "register_operand" "x"))]
20054   "TARGET_SSE2"
20055   "#")
20057 (define_insn "*pushv2si"
20058   [(set (match_operand:V2SI 0 "push_operand" "=<")
20059         (match_operand:V2SI 1 "register_operand" "y"))]
20060   "TARGET_MMX"
20061   "#")
20063 (define_insn "*pushv4hi"
20064   [(set (match_operand:V4HI 0 "push_operand" "=<")
20065         (match_operand:V4HI 1 "register_operand" "y"))]
20066   "TARGET_MMX"
20067   "#")
20069 (define_insn "*pushv8qi"
20070   [(set (match_operand:V8QI 0 "push_operand" "=<")
20071         (match_operand:V8QI 1 "register_operand" "y"))]
20072   "TARGET_MMX"
20073   "#")
20075 (define_insn "*pushv2sf"
20076   [(set (match_operand:V2SF 0 "push_operand" "=<")
20077         (match_operand:V2SF 1 "register_operand" "y"))]
20078   "TARGET_3DNOW"
20079   "#")
20081 (define_split
20082   [(set (match_operand 0 "push_operand" "")
20083         (match_operand 1 "register_operand" ""))]
20084   "!TARGET_64BIT && reload_completed
20085    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20086   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20087    (set (match_dup 2) (match_dup 1))]
20088   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20089                                  stack_pointer_rtx);
20090    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20092 (define_split
20093   [(set (match_operand 0 "push_operand" "")
20094         (match_operand 1 "register_operand" ""))]
20095   "TARGET_64BIT && reload_completed
20096    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20097   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20098    (set (match_dup 2) (match_dup 1))]
20099   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20100                                  stack_pointer_rtx);
20101    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20104 (define_insn "movti_internal"
20105   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20106         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20107   "TARGET_SSE && !TARGET_64BIT
20108    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20110   switch (which_alternative)
20111     {
20112     case 0:
20113       if (get_attr_mode (insn) == MODE_V4SF)
20114         return "xorps\t%0, %0";
20115       else
20116         return "pxor\t%0, %0";
20117     case 1:
20118     case 2:
20119       if (get_attr_mode (insn) == MODE_V4SF)
20120         return "movaps\t{%1, %0|%0, %1}";
20121       else
20122         return "movdqa\t{%1, %0|%0, %1}";
20123     default:
20124       abort ();
20125     }
20127   [(set_attr "type" "ssemov,ssemov,ssemov")
20128    (set (attr "mode")
20129         (cond [(eq_attr "alternative" "0,1")
20130                  (if_then_else
20131                    (ne (symbol_ref "optimize_size")
20132                        (const_int 0))
20133                    (const_string "V4SF")
20134                    (const_string "TI"))
20135                (eq_attr "alternative" "2")
20136                  (if_then_else
20137                    (ne (symbol_ref "optimize_size")
20138                        (const_int 0))
20139                    (const_string "V4SF")
20140                    (const_string "TI"))]
20141                (const_string "TI")))])
20143 (define_insn "*movti_rex64"
20144   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20145         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20146   "TARGET_64BIT
20147    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20149   switch (which_alternative)
20150     {
20151     case 0:
20152     case 1:
20153       return "#";
20154     case 2:
20155       if (get_attr_mode (insn) == MODE_V4SF)
20156         return "xorps\t%0, %0";
20157       else
20158         return "pxor\t%0, %0";
20159     case 3:
20160     case 4:
20161       if (get_attr_mode (insn) == MODE_V4SF)
20162         return "movaps\t{%1, %0|%0, %1}";
20163       else
20164         return "movdqa\t{%1, %0|%0, %1}";
20165     default:
20166       abort ();
20167     }
20169   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20170    (set (attr "mode")
20171         (cond [(eq_attr "alternative" "2,3")
20172                  (if_then_else
20173                    (ne (symbol_ref "optimize_size")
20174                        (const_int 0))
20175                    (const_string "V4SF")
20176                    (const_string "TI"))
20177                (eq_attr "alternative" "4")
20178                  (if_then_else
20179                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20180                             (const_int 0))
20181                         (ne (symbol_ref "optimize_size")
20182                             (const_int 0)))
20183                    (const_string "V4SF")
20184                    (const_string "TI"))]
20185                (const_string "DI")))])
20187 (define_insn "*movtf_rex64"
20188   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20189         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20190   "TARGET_64BIT
20191    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20193   switch (which_alternative)
20194     {
20195     case 0:
20196     case 1:
20197       return "#";
20198     case 2:
20199       if (get_attr_mode (insn) == MODE_V4SF)
20200         return "xorps\t%0, %0";
20201       else
20202         return "pxor\t%0, %0";
20203     case 3:
20204     case 4:
20205       if (get_attr_mode (insn) == MODE_V4SF)
20206         return "movaps\t{%1, %0|%0, %1}";
20207       else
20208         return "movdqa\t{%1, %0|%0, %1}";
20209     default:
20210       abort ();
20211     }
20213   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20214    (set (attr "mode")
20215         (cond [(eq_attr "alternative" "2,3")
20216                  (if_then_else
20217                    (ne (symbol_ref "optimize_size")
20218                        (const_int 0))
20219                    (const_string "V4SF")
20220                    (const_string "TI"))
20221                (eq_attr "alternative" "4")
20222                  (if_then_else
20223                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20224                             (const_int 0))
20225                         (ne (symbol_ref "optimize_size")
20226                             (const_int 0)))
20227                    (const_string "V4SF")
20228                    (const_string "TI"))]
20229                (const_string "DI")))])
20231 (define_split
20232   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20233         (match_operand:TI 1 "general_operand" ""))]
20234   "reload_completed && !SSE_REG_P (operands[0])
20235    && !SSE_REG_P (operands[1])"
20236   [(const_int 0)]
20237   "ix86_split_long_move (operands); DONE;")
20239 (define_split
20240   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20241         (match_operand:TF 1 "general_operand" ""))]
20242   "reload_completed && !SSE_REG_P (operands[0])
20243    && !SSE_REG_P (operands[1])"
20244   [(const_int 0)]
20245   "ix86_split_long_move (operands); DONE;")
20247 ;; These two patterns are useful for specifying exactly whether to use
20248 ;; movaps or movups
20249 (define_expand "sse_movaps"
20250   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20251         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20252                      UNSPEC_MOVA))]
20253   "TARGET_SSE"
20255   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20256     {
20257       rtx tmp = gen_reg_rtx (V4SFmode);
20258       emit_insn (gen_sse_movaps (tmp, operands[1]));
20259       emit_move_insn (operands[0], tmp);
20260       DONE;
20261     }
20264 (define_insn "*sse_movaps_1"
20265   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20266         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20267                      UNSPEC_MOVA))]
20268   "TARGET_SSE
20269    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20270   "movaps\t{%1, %0|%0, %1}"
20271   [(set_attr "type" "ssemov,ssemov")
20272    (set_attr "mode" "V4SF")])
20274 (define_expand "sse_movups"
20275   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20276         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20277                      UNSPEC_MOVU))]
20278   "TARGET_SSE"
20280   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20281     {
20282       rtx tmp = gen_reg_rtx (V4SFmode);
20283       emit_insn (gen_sse_movups (tmp, operands[1]));
20284       emit_move_insn (operands[0], tmp);
20285       DONE;
20286     }
20289 (define_insn "*sse_movups_1"
20290   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20291         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20292                      UNSPEC_MOVU))]
20293   "TARGET_SSE
20294    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20295   "movups\t{%1, %0|%0, %1}"
20296   [(set_attr "type" "ssecvt,ssecvt")
20297    (set_attr "mode" "V4SF")])
20299 ;; SSE Strange Moves.
20301 (define_insn "sse_movmskps"
20302   [(set (match_operand:SI 0 "register_operand" "=r")
20303         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20304                    UNSPEC_MOVMSK))]
20305   "TARGET_SSE"
20306   "movmskps\t{%1, %0|%0, %1}"
20307   [(set_attr "type" "ssecvt")
20308    (set_attr "mode" "V4SF")])
20310 (define_insn "mmx_pmovmskb"
20311   [(set (match_operand:SI 0 "register_operand" "=r")
20312         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20313                    UNSPEC_MOVMSK))]
20314   "TARGET_SSE || TARGET_3DNOW_A"
20315   "pmovmskb\t{%1, %0|%0, %1}"
20316   [(set_attr "type" "ssecvt")
20317    (set_attr "mode" "V4SF")])
20320 (define_insn "mmx_maskmovq"
20321   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20322         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20323                       (match_operand:V8QI 2 "register_operand" "y")]
20324                      UNSPEC_MASKMOV))]
20325   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20326   ;; @@@ check ordering of operands in intel/nonintel syntax
20327   "maskmovq\t{%2, %1|%1, %2}"
20328   [(set_attr "type" "mmxcvt")
20329    (set_attr "mode" "DI")])
20331 (define_insn "mmx_maskmovq_rex"
20332   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20333         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20334                       (match_operand:V8QI 2 "register_operand" "y")]
20335                      UNSPEC_MASKMOV))]
20336   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20337   ;; @@@ check ordering of operands in intel/nonintel syntax
20338   "maskmovq\t{%2, %1|%1, %2}"
20339   [(set_attr "type" "mmxcvt")
20340    (set_attr "mode" "DI")])
20342 (define_insn "sse_movntv4sf"
20343   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20344         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20345                      UNSPEC_MOVNT))]
20346   "TARGET_SSE"
20347   "movntps\t{%1, %0|%0, %1}"
20348   [(set_attr "type" "ssemov")
20349    (set_attr "mode" "V4SF")])
20351 (define_insn "sse_movntdi"
20352   [(set (match_operand:DI 0 "memory_operand" "=m")
20353         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20354                    UNSPEC_MOVNT))]
20355   "TARGET_SSE || TARGET_3DNOW_A"
20356   "movntq\t{%1, %0|%0, %1}"
20357   [(set_attr "type" "mmxmov")
20358    (set_attr "mode" "DI")])
20360 (define_insn "sse_movhlps"
20361   [(set (match_operand:V4SF 0 "register_operand" "=x")
20362         (vec_merge:V4SF
20363          (match_operand:V4SF 1 "register_operand" "0")
20364          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20365                           (parallel [(const_int 2)
20366                                      (const_int 3)
20367                                      (const_int 0)
20368                                      (const_int 1)]))
20369          (const_int 3)))]
20370   "TARGET_SSE"
20371   "movhlps\t{%2, %0|%0, %2}"
20372   [(set_attr "type" "ssecvt")
20373    (set_attr "mode" "V4SF")])
20375 (define_insn "sse_movlhps"
20376   [(set (match_operand:V4SF 0 "register_operand" "=x")
20377         (vec_merge:V4SF
20378          (match_operand:V4SF 1 "register_operand" "0")
20379          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20380                           (parallel [(const_int 2)
20381                                      (const_int 3)
20382                                      (const_int 0)
20383                                      (const_int 1)]))
20384          (const_int 12)))]
20385   "TARGET_SSE"
20386   "movlhps\t{%2, %0|%0, %2}"
20387   [(set_attr "type" "ssecvt")
20388    (set_attr "mode" "V4SF")])
20390 (define_insn "sse_movhps"
20391   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20392         (vec_merge:V4SF
20393          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20394          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20395          (const_int 12)))]
20396   "TARGET_SSE
20397    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20398   "movhps\t{%2, %0|%0, %2}"
20399   [(set_attr "type" "ssecvt")
20400    (set_attr "mode" "V4SF")])
20402 (define_insn "sse_movlps"
20403   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20404         (vec_merge:V4SF
20405          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20406          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20407          (const_int 3)))]
20408   "TARGET_SSE
20409    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20410   "movlps\t{%2, %0|%0, %2}"
20411   [(set_attr "type" "ssecvt")
20412    (set_attr "mode" "V4SF")])
20414 (define_expand "sse_loadss"
20415   [(match_operand:V4SF 0 "register_operand" "")
20416    (match_operand:SF 1 "memory_operand" "")]
20417   "TARGET_SSE"
20419   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20420                                CONST0_RTX (V4SFmode)));
20421   DONE;
20424 (define_insn "sse_loadss_1"
20425   [(set (match_operand:V4SF 0 "register_operand" "=x")
20426         (vec_merge:V4SF
20427          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20428          (match_operand:V4SF 2 "const0_operand" "X")
20429          (const_int 1)))]
20430   "TARGET_SSE"
20431   "movss\t{%1, %0|%0, %1}"
20432   [(set_attr "type" "ssemov")
20433    (set_attr "mode" "SF")])
20435 (define_insn "sse_movss"
20436   [(set (match_operand:V4SF 0 "register_operand" "=x")
20437         (vec_merge:V4SF
20438          (match_operand:V4SF 1 "register_operand" "0")
20439          (match_operand:V4SF 2 "register_operand" "x")
20440          (const_int 1)))]
20441   "TARGET_SSE"
20442   "movss\t{%2, %0|%0, %2}"
20443   [(set_attr "type" "ssemov")
20444    (set_attr "mode" "SF")])
20446 (define_insn "sse_storess"
20447   [(set (match_operand:SF 0 "memory_operand" "=m")
20448         (vec_select:SF
20449          (match_operand:V4SF 1 "register_operand" "x")
20450          (parallel [(const_int 0)])))]
20451   "TARGET_SSE"
20452   "movss\t{%1, %0|%0, %1}"
20453   [(set_attr "type" "ssemov")
20454    (set_attr "mode" "SF")])
20456 (define_insn "sse_shufps"
20457   [(set (match_operand:V4SF 0 "register_operand" "=x")
20458         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20459                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20460                       (match_operand:SI 3 "immediate_operand" "i")]
20461                      UNSPEC_SHUFFLE))]
20462   "TARGET_SSE"
20463   ;; @@@ check operand order for intel/nonintel syntax
20464   "shufps\t{%3, %2, %0|%0, %2, %3}"
20465   [(set_attr "type" "ssecvt")
20466    (set_attr "mode" "V4SF")])
20469 ;; SSE arithmetic
20471 (define_insn "addv4sf3"
20472   [(set (match_operand:V4SF 0 "register_operand" "=x")
20473         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20474                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20475   "TARGET_SSE"
20476   "addps\t{%2, %0|%0, %2}"
20477   [(set_attr "type" "sseadd")
20478    (set_attr "mode" "V4SF")])
20480 (define_insn "vmaddv4sf3"
20481   [(set (match_operand:V4SF 0 "register_operand" "=x")
20482         (vec_merge:V4SF
20483          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20484                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20485          (match_dup 1)
20486          (const_int 1)))]
20487   "TARGET_SSE"
20488   "addss\t{%2, %0|%0, %2}"
20489   [(set_attr "type" "sseadd")
20490    (set_attr "mode" "SF")])
20492 (define_insn "subv4sf3"
20493   [(set (match_operand:V4SF 0 "register_operand" "=x")
20494         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20495                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20496   "TARGET_SSE"
20497   "subps\t{%2, %0|%0, %2}"
20498   [(set_attr "type" "sseadd")
20499    (set_attr "mode" "V4SF")])
20501 (define_insn "vmsubv4sf3"
20502   [(set (match_operand:V4SF 0 "register_operand" "=x")
20503         (vec_merge:V4SF
20504          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20505                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20506          (match_dup 1)
20507          (const_int 1)))]
20508   "TARGET_SSE"
20509   "subss\t{%2, %0|%0, %2}"
20510   [(set_attr "type" "sseadd")
20511    (set_attr "mode" "SF")])
20513 ;; ??? Should probably be done by generic code instead.
20514 (define_expand "negv4sf2"
20515   [(set (match_operand:V4SF 0 "register_operand" "")
20516         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20517                   (match_dup 2)))]
20518   "TARGET_SSE"
20520   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20521   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20522   operands[2] = force_reg (V4SFmode, vm0);
20525 (define_insn "mulv4sf3"
20526   [(set (match_operand:V4SF 0 "register_operand" "=x")
20527         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20528                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20529   "TARGET_SSE"
20530   "mulps\t{%2, %0|%0, %2}"
20531   [(set_attr "type" "ssemul")
20532    (set_attr "mode" "V4SF")])
20534 (define_insn "vmmulv4sf3"
20535   [(set (match_operand:V4SF 0 "register_operand" "=x")
20536         (vec_merge:V4SF
20537          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20538                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20539          (match_dup 1)
20540          (const_int 1)))]
20541   "TARGET_SSE"
20542   "mulss\t{%2, %0|%0, %2}"
20543   [(set_attr "type" "ssemul")
20544    (set_attr "mode" "SF")])
20546 (define_insn "divv4sf3"
20547   [(set (match_operand:V4SF 0 "register_operand" "=x")
20548         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20549                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20550   "TARGET_SSE"
20551   "divps\t{%2, %0|%0, %2}"
20552   [(set_attr "type" "ssediv")
20553    (set_attr "mode" "V4SF")])
20555 (define_insn "vmdivv4sf3"
20556   [(set (match_operand:V4SF 0 "register_operand" "=x")
20557         (vec_merge:V4SF
20558          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20559                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20560          (match_dup 1)
20561          (const_int 1)))]
20562   "TARGET_SSE"
20563   "divss\t{%2, %0|%0, %2}"
20564   [(set_attr "type" "ssediv")
20565    (set_attr "mode" "SF")])
20568 ;; SSE square root/reciprocal
20570 (define_insn "rcpv4sf2"
20571   [(set (match_operand:V4SF 0 "register_operand" "=x")
20572         (unspec:V4SF
20573          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20574   "TARGET_SSE"
20575   "rcpps\t{%1, %0|%0, %1}"
20576   [(set_attr "type" "sse")
20577    (set_attr "mode" "V4SF")])
20579 (define_insn "vmrcpv4sf2"
20580   [(set (match_operand:V4SF 0 "register_operand" "=x")
20581         (vec_merge:V4SF
20582          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20583                       UNSPEC_RCP)
20584          (match_operand:V4SF 2 "register_operand" "0")
20585          (const_int 1)))]
20586   "TARGET_SSE"
20587   "rcpss\t{%1, %0|%0, %1}"
20588   [(set_attr "type" "sse")
20589    (set_attr "mode" "SF")])
20591 (define_insn "rsqrtv4sf2"
20592   [(set (match_operand:V4SF 0 "register_operand" "=x")
20593         (unspec:V4SF
20594          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20595   "TARGET_SSE"
20596   "rsqrtps\t{%1, %0|%0, %1}"
20597   [(set_attr "type" "sse")
20598    (set_attr "mode" "V4SF")])
20600 (define_insn "vmrsqrtv4sf2"
20601   [(set (match_operand:V4SF 0 "register_operand" "=x")
20602         (vec_merge:V4SF
20603          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20604                       UNSPEC_RSQRT)
20605          (match_operand:V4SF 2 "register_operand" "0")
20606          (const_int 1)))]
20607   "TARGET_SSE"
20608   "rsqrtss\t{%1, %0|%0, %1}"
20609   [(set_attr "type" "sse")
20610    (set_attr "mode" "SF")])
20612 (define_insn "sqrtv4sf2"
20613   [(set (match_operand:V4SF 0 "register_operand" "=x")
20614         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20615   "TARGET_SSE"
20616   "sqrtps\t{%1, %0|%0, %1}"
20617   [(set_attr "type" "sse")
20618    (set_attr "mode" "V4SF")])
20620 (define_insn "vmsqrtv4sf2"
20621   [(set (match_operand:V4SF 0 "register_operand" "=x")
20622         (vec_merge:V4SF
20623          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20624          (match_operand:V4SF 2 "register_operand" "0")
20625          (const_int 1)))]
20626   "TARGET_SSE"
20627   "sqrtss\t{%1, %0|%0, %1}"
20628   [(set_attr "type" "sse")
20629    (set_attr "mode" "SF")])
20631 ;; SSE logical operations.
20633 ;; SSE defines logical operations on floating point values.  This brings
20634 ;; interesting challenge to RTL representation where logicals are only valid
20635 ;; on integral types.  We deal with this by representing the floating point
20636 ;; logical as logical on arguments casted to TImode as this is what hardware
20637 ;; really does.  Unfortunately hardware requires the type information to be
20638 ;; present and thus we must avoid subregs from being simplified and eliminated
20639 ;; in later compilation phases.
20641 ;; We have following variants from each instruction:
20642 ;; sse_andsf3 - the operation taking V4SF vector operands
20643 ;;              and doing TImode cast on them
20644 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20645 ;;                      TImode, since backend insist on eliminating casts
20646 ;;                      on memory operands
20647 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20648 ;;                   We can not accept memory operand here as instruction reads
20649 ;;                   whole scalar.  This is generated only post reload by GCC
20650 ;;                   scalar float operations that expands to logicals (fabs)
20651 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20652 ;;                   memory operand.  Eventually combine can be able
20653 ;;                   to synthesize these using splitter.
20654 ;; sse2_anddf3, *sse2_anddf3_memory
20655 ;;              
20656 ;; 
20657 ;; These are not called andti3 etc. because we really really don't want
20658 ;; the compiler to widen DImode ands to TImode ands and then try to move
20659 ;; into DImode subregs of SSE registers, and them together, and move out
20660 ;; of DImode subregs again!
20661 ;; SSE1 single precision floating point logical operation
20662 (define_expand "sse_andv4sf3"
20663   [(set (match_operand:V4SF 0 "register_operand" "")
20664         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20665                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20666   "TARGET_SSE"
20667   "")
20669 (define_insn "*sse_andv4sf3"
20670   [(set (match_operand:V4SF 0 "register_operand" "=x")
20671         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20672                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20673   "TARGET_SSE
20674    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20675   "andps\t{%2, %0|%0, %2}"
20676   [(set_attr "type" "sselog")
20677    (set_attr "mode" "V4SF")])
20679 (define_expand "sse_nandv4sf3"
20680   [(set (match_operand:V4SF 0 "register_operand" "")
20681         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20682                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20683   "TARGET_SSE"
20684   "")
20686 (define_insn "*sse_nandv4sf3"
20687   [(set (match_operand:V4SF 0 "register_operand" "=x")
20688         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20689                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20690   "TARGET_SSE"
20691   "andnps\t{%2, %0|%0, %2}"
20692   [(set_attr "type" "sselog")
20693    (set_attr "mode" "V4SF")])
20695 (define_expand "sse_iorv4sf3"
20696   [(set (match_operand:V4SF 0 "register_operand" "")
20697         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20698                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20699   "TARGET_SSE"
20700   "")
20702 (define_insn "*sse_iorv4sf3"
20703   [(set (match_operand:V4SF 0 "register_operand" "=x")
20704         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20705                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20706   "TARGET_SSE
20707    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20708   "orps\t{%2, %0|%0, %2}"
20709   [(set_attr "type" "sselog")
20710    (set_attr "mode" "V4SF")])
20712 (define_expand "sse_xorv4sf3"
20713   [(set (match_operand:V4SF 0 "register_operand" "")
20714         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20715                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20716   "TARGET_SSE"
20717   "")
20719 (define_insn "*sse_xorv4sf3"
20720   [(set (match_operand:V4SF 0 "register_operand" "=x")
20721         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20722                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20723   "TARGET_SSE
20724    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20725   "xorps\t{%2, %0|%0, %2}"
20726   [(set_attr "type" "sselog")
20727    (set_attr "mode" "V4SF")])
20729 ;; SSE2 double precision floating point logical operation
20731 (define_expand "sse2_andv2df3"
20732   [(set (match_operand:V2DF 0 "register_operand" "")
20733         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20734                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20735   "TARGET_SSE2"
20736   "")
20738 (define_insn "*sse2_andv2df3"
20739   [(set (match_operand:V2DF 0 "register_operand" "=x")
20740         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20741                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20742   "TARGET_SSE2
20743    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20744   "andpd\t{%2, %0|%0, %2}"
20745   [(set_attr "type" "sselog")
20746    (set_attr "mode" "V2DF")])
20748 (define_expand "sse2_nandv2df3"
20749   [(set (match_operand:V2DF 0 "register_operand" "")
20750         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20751                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20752   "TARGET_SSE2"
20753   "")
20755 (define_insn "*sse2_nandv2df3"
20756   [(set (match_operand:V2DF 0 "register_operand" "=x")
20757         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20758                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20759   "TARGET_SSE2"
20760   "andnpd\t{%2, %0|%0, %2}"
20761   [(set_attr "type" "sselog")
20762    (set_attr "mode" "V2DF")])
20764 (define_expand "sse2_iorv2df3"
20765   [(set (match_operand:V2DF 0 "register_operand" "")
20766         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20767                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20768   "TARGET_SSE2"
20769   "")
20771 (define_insn "*sse2_iorv2df3"
20772   [(set (match_operand:V2DF 0 "register_operand" "=x")
20773         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20774                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20775   "TARGET_SSE2
20776    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20777   "orpd\t{%2, %0|%0, %2}"
20778   [(set_attr "type" "sselog")
20779    (set_attr "mode" "V2DF")])
20781 (define_expand "sse2_xorv2df3"
20782   [(set (match_operand:V2DF 0 "register_operand" "")
20783         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20784                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20785   "TARGET_SSE2"
20786   "")
20788 (define_insn "*sse2_xorv2df3"
20789   [(set (match_operand:V2DF 0 "register_operand" "=x")
20790         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20791                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20792   "TARGET_SSE2
20793    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20794   "xorpd\t{%2, %0|%0, %2}"
20795   [(set_attr "type" "sselog")
20796    (set_attr "mode" "V2DF")])
20798 ;; SSE2 integral logicals.  These patterns must always come after floating
20799 ;; point ones since we don't want compiler to use integer opcodes on floating
20800 ;; point SSE values to avoid matching of subregs in the match_operand.
20801 (define_insn "*sse2_andti3"
20802   [(set (match_operand:TI 0 "register_operand" "=x")
20803         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20804                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20805   "TARGET_SSE2
20806    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20807   "pand\t{%2, %0|%0, %2}"
20808   [(set_attr "type" "sselog")
20809    (set_attr "mode" "TI")])
20811 (define_insn "sse2_andv2di3"
20812   [(set (match_operand:V2DI 0 "register_operand" "=x")
20813         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20814                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20815   "TARGET_SSE2
20816    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20817   "pand\t{%2, %0|%0, %2}"
20818   [(set_attr "type" "sselog")
20819    (set_attr "mode" "TI")])
20821 (define_insn "*sse2_nandti3"
20822   [(set (match_operand:TI 0 "register_operand" "=x")
20823         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20824                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20825   "TARGET_SSE2"
20826   "pandn\t{%2, %0|%0, %2}"
20827   [(set_attr "type" "sselog")
20828    (set_attr "mode" "TI")])
20830 (define_insn "sse2_nandv2di3"
20831   [(set (match_operand:V2DI 0 "register_operand" "=x")
20832         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20833                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20834   "TARGET_SSE2
20835    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20836   "pandn\t{%2, %0|%0, %2}"
20837   [(set_attr "type" "sselog")
20838    (set_attr "mode" "TI")])
20840 (define_insn "*sse2_iorti3"
20841   [(set (match_operand:TI 0 "register_operand" "=x")
20842         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20843                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20844   "TARGET_SSE2
20845    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20846   "por\t{%2, %0|%0, %2}"
20847   [(set_attr "type" "sselog")
20848    (set_attr "mode" "TI")])
20850 (define_insn "sse2_iorv2di3"
20851   [(set (match_operand:V2DI 0 "register_operand" "=x")
20852         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20853                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20854   "TARGET_SSE2
20855    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20856   "por\t{%2, %0|%0, %2}"
20857   [(set_attr "type" "sselog")
20858    (set_attr "mode" "TI")])
20860 (define_insn "*sse2_xorti3"
20861   [(set (match_operand:TI 0 "register_operand" "=x")
20862         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20863                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20864   "TARGET_SSE2
20865    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20866   "pxor\t{%2, %0|%0, %2}"
20867   [(set_attr "type" "sselog")
20868    (set_attr "mode" "TI")])
20870 (define_insn "sse2_xorv2di3"
20871   [(set (match_operand:V2DI 0 "register_operand" "=x")
20872         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20873                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20874   "TARGET_SSE2
20875    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20876   "pxor\t{%2, %0|%0, %2}"
20877   [(set_attr "type" "sselog")
20878    (set_attr "mode" "TI")])
20880 ;; Use xor, but don't show input operands so they aren't live before
20881 ;; this insn.
20882 (define_insn "sse_clrv4sf"
20883   [(set (match_operand:V4SF 0 "register_operand" "=x")
20884         (match_operand:V4SF 1 "const0_operand" "X"))]
20885   "TARGET_SSE"
20887   if (get_attr_mode (insn) == MODE_TI)
20888     return "pxor\t{%0, %0|%0, %0}";
20889   else
20890     return "xorps\t{%0, %0|%0, %0}";
20892   [(set_attr "type" "sselog")
20893    (set_attr "memory" "none")
20894    (set (attr "mode")
20895         (if_then_else
20896            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20897                          (const_int 0))
20898                      (ne (symbol_ref "TARGET_SSE2")
20899                          (const_int 0)))
20900                 (eq (symbol_ref "optimize_size")
20901                     (const_int 0)))
20902          (const_string "TI")
20903          (const_string "V4SF")))])
20905 ;; Use xor, but don't show input operands so they aren't live before
20906 ;; this insn.
20907 (define_insn "sse_clrv2df"
20908   [(set (match_operand:V2DF 0 "register_operand" "=x")
20909         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20910   "TARGET_SSE2"
20911   "xorpd\t{%0, %0|%0, %0}"
20912   [(set_attr "type" "sselog")
20913    (set_attr "memory" "none")
20914    (set_attr "mode" "V4SF")])
20916 ;; SSE mask-generating compares
20918 (define_insn "maskcmpv4sf3"
20919   [(set (match_operand:V4SI 0 "register_operand" "=x")
20920         (match_operator:V4SI 3 "sse_comparison_operator"
20921                 [(match_operand:V4SF 1 "register_operand" "0")
20922                  (match_operand:V4SF 2 "register_operand" "x")]))]
20923   "TARGET_SSE"
20924   "cmp%D3ps\t{%2, %0|%0, %2}"
20925   [(set_attr "type" "ssecmp")
20926    (set_attr "mode" "V4SF")])
20928 (define_insn "maskncmpv4sf3"
20929   [(set (match_operand:V4SI 0 "register_operand" "=x")
20930         (not:V4SI
20931          (match_operator:V4SI 3 "sse_comparison_operator"
20932                 [(match_operand:V4SF 1 "register_operand" "0")
20933                  (match_operand:V4SF 2 "register_operand" "x")])))]
20934   "TARGET_SSE"
20936   if (GET_CODE (operands[3]) == UNORDERED)
20937     return "cmpordps\t{%2, %0|%0, %2}";
20938   else
20939     return "cmpn%D3ps\t{%2, %0|%0, %2}";
20941   [(set_attr "type" "ssecmp")
20942    (set_attr "mode" "V4SF")])
20944 (define_insn "vmmaskcmpv4sf3"
20945   [(set (match_operand:V4SI 0 "register_operand" "=x")
20946         (vec_merge:V4SI
20947          (match_operator:V4SI 3 "sse_comparison_operator"
20948                 [(match_operand:V4SF 1 "register_operand" "0")
20949                  (match_operand:V4SF 2 "register_operand" "x")])
20950          (subreg:V4SI (match_dup 1) 0)
20951          (const_int 1)))]
20952   "TARGET_SSE"
20953   "cmp%D3ss\t{%2, %0|%0, %2}"
20954   [(set_attr "type" "ssecmp")
20955    (set_attr "mode" "SF")])
20957 (define_insn "vmmaskncmpv4sf3"
20958   [(set (match_operand:V4SI 0 "register_operand" "=x")
20959         (vec_merge:V4SI
20960          (not:V4SI
20961           (match_operator:V4SI 3 "sse_comparison_operator"
20962                 [(match_operand:V4SF 1 "register_operand" "0")
20963                  (match_operand:V4SF 2 "register_operand" "x")]))
20964          (subreg:V4SI (match_dup 1) 0)
20965          (const_int 1)))]
20966   "TARGET_SSE"
20968   if (GET_CODE (operands[3]) == UNORDERED)
20969     return "cmpordss\t{%2, %0|%0, %2}";
20970   else
20971     return "cmpn%D3ss\t{%2, %0|%0, %2}";
20973   [(set_attr "type" "ssecmp")
20974    (set_attr "mode" "SF")])
20976 (define_insn "sse_comi"
20977   [(set (reg:CCFP FLAGS_REG)
20978         (compare:CCFP (vec_select:SF
20979                        (match_operand:V4SF 0 "register_operand" "x")
20980                        (parallel [(const_int 0)]))
20981                       (vec_select:SF
20982                        (match_operand:V4SF 1 "register_operand" "x")
20983                        (parallel [(const_int 0)]))))]
20984   "TARGET_SSE"
20985   "comiss\t{%1, %0|%0, %1}"
20986   [(set_attr "type" "ssecomi")
20987    (set_attr "mode" "SF")])
20989 (define_insn "sse_ucomi"
20990   [(set (reg:CCFPU FLAGS_REG)
20991         (compare:CCFPU (vec_select:SF
20992                         (match_operand:V4SF 0 "register_operand" "x")
20993                         (parallel [(const_int 0)]))
20994                        (vec_select:SF
20995                         (match_operand:V4SF 1 "register_operand" "x")
20996                         (parallel [(const_int 0)]))))]
20997   "TARGET_SSE"
20998   "ucomiss\t{%1, %0|%0, %1}"
20999   [(set_attr "type" "ssecomi")
21000    (set_attr "mode" "SF")])
21003 ;; SSE unpack
21005 (define_insn "sse_unpckhps"
21006   [(set (match_operand:V4SF 0 "register_operand" "=x")
21007         (vec_merge:V4SF
21008          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21009                           (parallel [(const_int 2)
21010                                      (const_int 0)
21011                                      (const_int 3)
21012                                      (const_int 1)]))
21013          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21014                           (parallel [(const_int 0)
21015                                      (const_int 2)
21016                                      (const_int 1)
21017                                      (const_int 3)]))
21018          (const_int 5)))]
21019   "TARGET_SSE"
21020   "unpckhps\t{%2, %0|%0, %2}"
21021   [(set_attr "type" "ssecvt")
21022    (set_attr "mode" "V4SF")])
21024 (define_insn "sse_unpcklps"
21025   [(set (match_operand:V4SF 0 "register_operand" "=x")
21026         (vec_merge:V4SF
21027          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21028                           (parallel [(const_int 0)
21029                                      (const_int 2)
21030                                      (const_int 1)
21031                                      (const_int 3)]))
21032          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21033                           (parallel [(const_int 2)
21034                                      (const_int 0)
21035                                      (const_int 3)
21036                                      (const_int 1)]))
21037          (const_int 5)))]
21038   "TARGET_SSE"
21039   "unpcklps\t{%2, %0|%0, %2}"
21040   [(set_attr "type" "ssecvt")
21041    (set_attr "mode" "V4SF")])
21044 ;; SSE min/max
21046 (define_insn "smaxv4sf3"
21047   [(set (match_operand:V4SF 0 "register_operand" "=x")
21048         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21049                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21050   "TARGET_SSE"
21051   "maxps\t{%2, %0|%0, %2}"
21052   [(set_attr "type" "sse")
21053    (set_attr "mode" "V4SF")])
21055 (define_insn "vmsmaxv4sf3"
21056   [(set (match_operand:V4SF 0 "register_operand" "=x")
21057         (vec_merge:V4SF
21058          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21059                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21060          (match_dup 1)
21061          (const_int 1)))]
21062   "TARGET_SSE"
21063   "maxss\t{%2, %0|%0, %2}"
21064   [(set_attr "type" "sse")
21065    (set_attr "mode" "SF")])
21067 (define_insn "sminv4sf3"
21068   [(set (match_operand:V4SF 0 "register_operand" "=x")
21069         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21070                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21071   "TARGET_SSE"
21072   "minps\t{%2, %0|%0, %2}"
21073   [(set_attr "type" "sse")
21074    (set_attr "mode" "V4SF")])
21076 (define_insn "vmsminv4sf3"
21077   [(set (match_operand:V4SF 0 "register_operand" "=x")
21078         (vec_merge:V4SF
21079          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21080                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21081          (match_dup 1)
21082          (const_int 1)))]
21083   "TARGET_SSE"
21084   "minss\t{%2, %0|%0, %2}"
21085   [(set_attr "type" "sse")
21086    (set_attr "mode" "SF")])
21088 ;; SSE <-> integer/MMX conversions
21090 (define_insn "cvtpi2ps"
21091   [(set (match_operand:V4SF 0 "register_operand" "=x")
21092         (vec_merge:V4SF
21093          (match_operand:V4SF 1 "register_operand" "0")
21094          (vec_duplicate:V4SF
21095           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21096          (const_int 12)))]
21097   "TARGET_SSE"
21098   "cvtpi2ps\t{%2, %0|%0, %2}"
21099   [(set_attr "type" "ssecvt")
21100    (set_attr "mode" "V4SF")])
21102 (define_insn "cvtps2pi"
21103   [(set (match_operand:V2SI 0 "register_operand" "=y")
21104         (vec_select:V2SI
21105          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21106          (parallel [(const_int 0) (const_int 1)])))]
21107   "TARGET_SSE"
21108   "cvtps2pi\t{%1, %0|%0, %1}"
21109   [(set_attr "type" "ssecvt")
21110    (set_attr "mode" "V4SF")])
21112 (define_insn "cvttps2pi"
21113   [(set (match_operand:V2SI 0 "register_operand" "=y")
21114         (vec_select:V2SI
21115          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21116                       UNSPEC_FIX)
21117          (parallel [(const_int 0) (const_int 1)])))]
21118   "TARGET_SSE"
21119   "cvttps2pi\t{%1, %0|%0, %1}"
21120   [(set_attr "type" "ssecvt")
21121    (set_attr "mode" "SF")])
21123 (define_insn "cvtsi2ss"
21124   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21125         (vec_merge:V4SF
21126          (match_operand:V4SF 1 "register_operand" "0,0")
21127          (vec_duplicate:V4SF
21128           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21129          (const_int 14)))]
21130   "TARGET_SSE"
21131   "cvtsi2ss\t{%2, %0|%0, %2}"
21132   [(set_attr "type" "sseicvt")
21133    (set_attr "athlon_decode" "vector,double")
21134    (set_attr "mode" "SF")])
21136 (define_insn "cvtsi2ssq"
21137   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21138         (vec_merge:V4SF
21139          (match_operand:V4SF 1 "register_operand" "0,0")
21140          (vec_duplicate:V4SF
21141           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21142          (const_int 14)))]
21143   "TARGET_SSE && TARGET_64BIT"
21144   "cvtsi2ssq\t{%2, %0|%0, %2}"
21145   [(set_attr "type" "sseicvt")
21146    (set_attr "athlon_decode" "vector,double")
21147    (set_attr "mode" "SF")])
21149 (define_insn "cvtss2si"
21150   [(set (match_operand:SI 0 "register_operand" "=r,r")
21151         (vec_select:SI
21152          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21153          (parallel [(const_int 0)])))]
21154   "TARGET_SSE"
21155   "cvtss2si\t{%1, %0|%0, %1}"
21156   [(set_attr "type" "sseicvt")
21157    (set_attr "athlon_decode" "double,vector")
21158    (set_attr "mode" "SI")])
21160 (define_insn "cvtss2siq"
21161   [(set (match_operand:DI 0 "register_operand" "=r,r")
21162         (vec_select:DI
21163          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21164          (parallel [(const_int 0)])))]
21165   "TARGET_SSE"
21166   "cvtss2siq\t{%1, %0|%0, %1}"
21167   [(set_attr "type" "sseicvt")
21168    (set_attr "athlon_decode" "double,vector")
21169    (set_attr "mode" "DI")])
21171 (define_insn "cvttss2si"
21172   [(set (match_operand:SI 0 "register_operand" "=r,r")
21173         (vec_select:SI
21174          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21175                       UNSPEC_FIX)
21176          (parallel [(const_int 0)])))]
21177   "TARGET_SSE"
21178   "cvttss2si\t{%1, %0|%0, %1}"
21179   [(set_attr "type" "sseicvt")
21180    (set_attr "mode" "SF")
21181    (set_attr "athlon_decode" "double,vector")])
21183 (define_insn "cvttss2siq"
21184   [(set (match_operand:DI 0 "register_operand" "=r,r")
21185         (vec_select:DI
21186          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21187                       UNSPEC_FIX)
21188          (parallel [(const_int 0)])))]
21189   "TARGET_SSE && TARGET_64BIT"
21190   "cvttss2siq\t{%1, %0|%0, %1}"
21191   [(set_attr "type" "sseicvt")
21192    (set_attr "mode" "SF")
21193    (set_attr "athlon_decode" "double,vector")])
21196 ;; MMX insns
21198 ;; MMX arithmetic
21200 (define_insn "addv8qi3"
21201   [(set (match_operand:V8QI 0 "register_operand" "=y")
21202         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21203                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21204   "TARGET_MMX"
21205   "paddb\t{%2, %0|%0, %2}"
21206   [(set_attr "type" "mmxadd")
21207    (set_attr "mode" "DI")])
21209 (define_insn "addv4hi3"
21210   [(set (match_operand:V4HI 0 "register_operand" "=y")
21211         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21212                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21213   "TARGET_MMX"
21214   "paddw\t{%2, %0|%0, %2}"
21215   [(set_attr "type" "mmxadd")
21216    (set_attr "mode" "DI")])
21218 (define_insn "addv2si3"
21219   [(set (match_operand:V2SI 0 "register_operand" "=y")
21220         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21221                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21222   "TARGET_MMX"
21223   "paddd\t{%2, %0|%0, %2}"
21224   [(set_attr "type" "mmxadd")
21225    (set_attr "mode" "DI")])
21227 (define_insn "mmx_adddi3"
21228   [(set (match_operand:DI 0 "register_operand" "=y")
21229         (unspec:DI
21230          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21231                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21232          UNSPEC_NOP))]
21233   "TARGET_MMX"
21234   "paddq\t{%2, %0|%0, %2}"
21235   [(set_attr "type" "mmxadd")
21236    (set_attr "mode" "DI")])
21238 (define_insn "ssaddv8qi3"
21239   [(set (match_operand:V8QI 0 "register_operand" "=y")
21240         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21241                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21242   "TARGET_MMX"
21243   "paddsb\t{%2, %0|%0, %2}"
21244   [(set_attr "type" "mmxadd")
21245    (set_attr "mode" "DI")])
21247 (define_insn "ssaddv4hi3"
21248   [(set (match_operand:V4HI 0 "register_operand" "=y")
21249         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21250                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21251   "TARGET_MMX"
21252   "paddsw\t{%2, %0|%0, %2}"
21253   [(set_attr "type" "mmxadd")
21254    (set_attr "mode" "DI")])
21256 (define_insn "usaddv8qi3"
21257   [(set (match_operand:V8QI 0 "register_operand" "=y")
21258         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21259                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21260   "TARGET_MMX"
21261   "paddusb\t{%2, %0|%0, %2}"
21262   [(set_attr "type" "mmxadd")
21263    (set_attr "mode" "DI")])
21265 (define_insn "usaddv4hi3"
21266   [(set (match_operand:V4HI 0 "register_operand" "=y")
21267         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21268                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21269   "TARGET_MMX"
21270   "paddusw\t{%2, %0|%0, %2}"
21271   [(set_attr "type" "mmxadd")
21272    (set_attr "mode" "DI")])
21274 (define_insn "subv8qi3"
21275   [(set (match_operand:V8QI 0 "register_operand" "=y")
21276         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21277                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21278   "TARGET_MMX"
21279   "psubb\t{%2, %0|%0, %2}"
21280   [(set_attr "type" "mmxadd")
21281    (set_attr "mode" "DI")])
21283 (define_insn "subv4hi3"
21284   [(set (match_operand:V4HI 0 "register_operand" "=y")
21285         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21286                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21287   "TARGET_MMX"
21288   "psubw\t{%2, %0|%0, %2}"
21289   [(set_attr "type" "mmxadd")
21290    (set_attr "mode" "DI")])
21292 (define_insn "subv2si3"
21293   [(set (match_operand:V2SI 0 "register_operand" "=y")
21294         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21295                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21296   "TARGET_MMX"
21297   "psubd\t{%2, %0|%0, %2}"
21298   [(set_attr "type" "mmxadd")
21299    (set_attr "mode" "DI")])
21301 (define_insn "mmx_subdi3"
21302   [(set (match_operand:DI 0 "register_operand" "=y")
21303         (unspec:DI
21304          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21305                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21306          UNSPEC_NOP))]
21307   "TARGET_MMX"
21308   "psubq\t{%2, %0|%0, %2}"
21309   [(set_attr "type" "mmxadd")
21310    (set_attr "mode" "DI")])
21312 (define_insn "sssubv8qi3"
21313   [(set (match_operand:V8QI 0 "register_operand" "=y")
21314         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21315                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21316   "TARGET_MMX"
21317   "psubsb\t{%2, %0|%0, %2}"
21318   [(set_attr "type" "mmxadd")
21319    (set_attr "mode" "DI")])
21321 (define_insn "sssubv4hi3"
21322   [(set (match_operand:V4HI 0 "register_operand" "=y")
21323         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21324                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21325   "TARGET_MMX"
21326   "psubsw\t{%2, %0|%0, %2}"
21327   [(set_attr "type" "mmxadd")
21328    (set_attr "mode" "DI")])
21330 (define_insn "ussubv8qi3"
21331   [(set (match_operand:V8QI 0 "register_operand" "=y")
21332         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21333                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21334   "TARGET_MMX"
21335   "psubusb\t{%2, %0|%0, %2}"
21336   [(set_attr "type" "mmxadd")
21337    (set_attr "mode" "DI")])
21339 (define_insn "ussubv4hi3"
21340   [(set (match_operand:V4HI 0 "register_operand" "=y")
21341         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21342                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21343   "TARGET_MMX"
21344   "psubusw\t{%2, %0|%0, %2}"
21345   [(set_attr "type" "mmxadd")
21346    (set_attr "mode" "DI")])
21348 (define_insn "mulv4hi3"
21349   [(set (match_operand:V4HI 0 "register_operand" "=y")
21350         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21351                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21352   "TARGET_MMX"
21353   "pmullw\t{%2, %0|%0, %2}"
21354   [(set_attr "type" "mmxmul")
21355    (set_attr "mode" "DI")])
21357 (define_insn "smulv4hi3_highpart"
21358   [(set (match_operand:V4HI 0 "register_operand" "=y")
21359         (truncate:V4HI
21360          (lshiftrt:V4SI
21361           (mult:V4SI (sign_extend:V4SI
21362                       (match_operand:V4HI 1 "register_operand" "0"))
21363                      (sign_extend:V4SI
21364                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21365           (const_int 16))))]
21366   "TARGET_MMX"
21367   "pmulhw\t{%2, %0|%0, %2}"
21368   [(set_attr "type" "mmxmul")
21369    (set_attr "mode" "DI")])
21371 (define_insn "umulv4hi3_highpart"
21372   [(set (match_operand:V4HI 0 "register_operand" "=y")
21373         (truncate:V4HI
21374          (lshiftrt:V4SI
21375           (mult:V4SI (zero_extend:V4SI
21376                       (match_operand:V4HI 1 "register_operand" "0"))
21377                      (zero_extend:V4SI
21378                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21379           (const_int 16))))]
21380   "TARGET_SSE || TARGET_3DNOW_A"
21381   "pmulhuw\t{%2, %0|%0, %2}"
21382   [(set_attr "type" "mmxmul")
21383    (set_attr "mode" "DI")])
21385 (define_insn "mmx_pmaddwd"
21386   [(set (match_operand:V2SI 0 "register_operand" "=y")
21387         (plus:V2SI
21388          (mult:V2SI
21389           (sign_extend:V2SI
21390            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21391                             (parallel [(const_int 0) (const_int 2)])))
21392           (sign_extend:V2SI
21393            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21394                             (parallel [(const_int 0) (const_int 2)]))))
21395          (mult:V2SI
21396           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21397                                              (parallel [(const_int 1)
21398                                                         (const_int 3)])))
21399           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21400                                              (parallel [(const_int 1)
21401                                                         (const_int 3)]))))))]
21402   "TARGET_MMX"
21403   "pmaddwd\t{%2, %0|%0, %2}"
21404   [(set_attr "type" "mmxmul")
21405    (set_attr "mode" "DI")])
21408 ;; MMX logical operations
21409 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21410 ;; normal code that also wants to use the FPU from getting broken.
21411 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21412 (define_insn "mmx_iordi3"
21413   [(set (match_operand:DI 0 "register_operand" "=y")
21414         (unspec:DI
21415          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21416                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21417          UNSPEC_NOP))]
21418   "TARGET_MMX"
21419   "por\t{%2, %0|%0, %2}"
21420   [(set_attr "type" "mmxadd")
21421    (set_attr "mode" "DI")])
21423 (define_insn "mmx_xordi3"
21424   [(set (match_operand:DI 0 "register_operand" "=y")
21425         (unspec:DI
21426          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21427                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21428          UNSPEC_NOP))]
21429   "TARGET_MMX"
21430   "pxor\t{%2, %0|%0, %2}"
21431   [(set_attr "type" "mmxadd")
21432    (set_attr "mode" "DI")
21433    (set_attr "memory" "none")])
21435 ;; Same as pxor, but don't show input operands so that we don't think
21436 ;; they are live.
21437 (define_insn "mmx_clrdi"
21438   [(set (match_operand:DI 0 "register_operand" "=y")
21439         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21440   "TARGET_MMX"
21441   "pxor\t{%0, %0|%0, %0}"
21442   [(set_attr "type" "mmxadd")
21443    (set_attr "mode" "DI")
21444    (set_attr "memory" "none")])
21446 (define_insn "mmx_anddi3"
21447   [(set (match_operand:DI 0 "register_operand" "=y")
21448         (unspec:DI
21449          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21450                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21451          UNSPEC_NOP))]
21452   "TARGET_MMX"
21453   "pand\t{%2, %0|%0, %2}"
21454   [(set_attr "type" "mmxadd")
21455    (set_attr "mode" "DI")])
21457 (define_insn "mmx_nanddi3"
21458   [(set (match_operand:DI 0 "register_operand" "=y")
21459         (unspec:DI
21460          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21461                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21462          UNSPEC_NOP))]
21463   "TARGET_MMX"
21464   "pandn\t{%2, %0|%0, %2}"
21465   [(set_attr "type" "mmxadd")
21466    (set_attr "mode" "DI")])
21469 ;; MMX unsigned averages/sum of absolute differences
21471 (define_insn "mmx_uavgv8qi3"
21472   [(set (match_operand:V8QI 0 "register_operand" "=y")
21473         (ashiftrt:V8QI
21474          (plus:V8QI (plus:V8QI
21475                      (match_operand:V8QI 1 "register_operand" "0")
21476                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21477                     (const_vector:V8QI [(const_int 1)
21478                                         (const_int 1)
21479                                         (const_int 1)
21480                                         (const_int 1)
21481                                         (const_int 1)
21482                                         (const_int 1)
21483                                         (const_int 1)
21484                                         (const_int 1)]))
21485          (const_int 1)))]
21486   "TARGET_SSE || TARGET_3DNOW_A"
21487   "pavgb\t{%2, %0|%0, %2}"
21488   [(set_attr "type" "mmxshft")
21489    (set_attr "mode" "DI")])
21491 (define_insn "mmx_uavgv4hi3"
21492   [(set (match_operand:V4HI 0 "register_operand" "=y")
21493         (ashiftrt:V4HI
21494          (plus:V4HI (plus:V4HI
21495                      (match_operand:V4HI 1 "register_operand" "0")
21496                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21497                     (const_vector:V4HI [(const_int 1)
21498                                         (const_int 1)
21499                                         (const_int 1)
21500                                         (const_int 1)]))
21501          (const_int 1)))]
21502   "TARGET_SSE || TARGET_3DNOW_A"
21503   "pavgw\t{%2, %0|%0, %2}"
21504   [(set_attr "type" "mmxshft")
21505    (set_attr "mode" "DI")])
21507 (define_insn "mmx_psadbw"
21508   [(set (match_operand:DI 0 "register_operand" "=y")
21509         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21510                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21511                    UNSPEC_PSADBW))]
21512   "TARGET_SSE || TARGET_3DNOW_A"
21513   "psadbw\t{%2, %0|%0, %2}"
21514   [(set_attr "type" "mmxshft")
21515    (set_attr "mode" "DI")])
21518 ;; MMX insert/extract/shuffle
21520 (define_insn "mmx_pinsrw"
21521   [(set (match_operand:V4HI 0 "register_operand" "=y")
21522         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21523                         (vec_duplicate:V4HI
21524                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21525                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21526   "TARGET_SSE || TARGET_3DNOW_A"
21527   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21528   [(set_attr "type" "mmxcvt")
21529    (set_attr "mode" "DI")])
21531 (define_insn "mmx_pextrw"
21532   [(set (match_operand:SI 0 "register_operand" "=r")
21533         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21534                                        (parallel
21535                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21536   "TARGET_SSE || TARGET_3DNOW_A"
21537   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21538   [(set_attr "type" "mmxcvt")
21539    (set_attr "mode" "DI")])
21541 (define_insn "mmx_pshufw"
21542   [(set (match_operand:V4HI 0 "register_operand" "=y")
21543         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21544                       (match_operand:SI 2 "immediate_operand" "i")]
21545                      UNSPEC_SHUFFLE))]
21546   "TARGET_SSE || TARGET_3DNOW_A"
21547   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21548   [(set_attr "type" "mmxcvt")
21549    (set_attr "mode" "DI")])
21552 ;; MMX mask-generating comparisons
21554 (define_insn "eqv8qi3"
21555   [(set (match_operand:V8QI 0 "register_operand" "=y")
21556         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21557                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21558   "TARGET_MMX"
21559   "pcmpeqb\t{%2, %0|%0, %2}"
21560   [(set_attr "type" "mmxcmp")
21561    (set_attr "mode" "DI")])
21563 (define_insn "eqv4hi3"
21564   [(set (match_operand:V4HI 0 "register_operand" "=y")
21565         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21566                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21567   "TARGET_MMX"
21568   "pcmpeqw\t{%2, %0|%0, %2}"
21569   [(set_attr "type" "mmxcmp")
21570    (set_attr "mode" "DI")])
21572 (define_insn "eqv2si3"
21573   [(set (match_operand:V2SI 0 "register_operand" "=y")
21574         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21575                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21576   "TARGET_MMX"
21577   "pcmpeqd\t{%2, %0|%0, %2}"
21578   [(set_attr "type" "mmxcmp")
21579    (set_attr "mode" "DI")])
21581 (define_insn "gtv8qi3"
21582   [(set (match_operand:V8QI 0 "register_operand" "=y")
21583         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21584                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21585   "TARGET_MMX"
21586   "pcmpgtb\t{%2, %0|%0, %2}"
21587   [(set_attr "type" "mmxcmp")
21588    (set_attr "mode" "DI")])
21590 (define_insn "gtv4hi3"
21591   [(set (match_operand:V4HI 0 "register_operand" "=y")
21592         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21593                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21594   "TARGET_MMX"
21595   "pcmpgtw\t{%2, %0|%0, %2}"
21596   [(set_attr "type" "mmxcmp")
21597    (set_attr "mode" "DI")])
21599 (define_insn "gtv2si3"
21600   [(set (match_operand:V2SI 0 "register_operand" "=y")
21601         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21602                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21603   "TARGET_MMX"
21604   "pcmpgtd\t{%2, %0|%0, %2}"
21605   [(set_attr "type" "mmxcmp")
21606    (set_attr "mode" "DI")])
21609 ;; MMX max/min insns
21611 (define_insn "umaxv8qi3"
21612   [(set (match_operand:V8QI 0 "register_operand" "=y")
21613         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21614                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21615   "TARGET_SSE || TARGET_3DNOW_A"
21616   "pmaxub\t{%2, %0|%0, %2}"
21617   [(set_attr "type" "mmxadd")
21618    (set_attr "mode" "DI")])
21620 (define_insn "smaxv4hi3"
21621   [(set (match_operand:V4HI 0 "register_operand" "=y")
21622         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21623                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21624   "TARGET_SSE || TARGET_3DNOW_A"
21625   "pmaxsw\t{%2, %0|%0, %2}"
21626   [(set_attr "type" "mmxadd")
21627    (set_attr "mode" "DI")])
21629 (define_insn "uminv8qi3"
21630   [(set (match_operand:V8QI 0 "register_operand" "=y")
21631         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21632                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21633   "TARGET_SSE || TARGET_3DNOW_A"
21634   "pminub\t{%2, %0|%0, %2}"
21635   [(set_attr "type" "mmxadd")
21636    (set_attr "mode" "DI")])
21638 (define_insn "sminv4hi3"
21639   [(set (match_operand:V4HI 0 "register_operand" "=y")
21640         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21641                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21642   "TARGET_SSE || TARGET_3DNOW_A"
21643   "pminsw\t{%2, %0|%0, %2}"
21644   [(set_attr "type" "mmxadd")
21645    (set_attr "mode" "DI")])
21648 ;; MMX shifts
21650 (define_insn "ashrv4hi3"
21651   [(set (match_operand:V4HI 0 "register_operand" "=y")
21652         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21653                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21654   "TARGET_MMX"
21655   "psraw\t{%2, %0|%0, %2}"
21656   [(set_attr "type" "mmxshft")
21657    (set_attr "mode" "DI")])
21659 (define_insn "ashrv2si3"
21660   [(set (match_operand:V2SI 0 "register_operand" "=y")
21661         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21662                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21663   "TARGET_MMX"
21664   "psrad\t{%2, %0|%0, %2}"
21665   [(set_attr "type" "mmxshft")
21666    (set_attr "mode" "DI")])
21668 (define_insn "lshrv4hi3"
21669   [(set (match_operand:V4HI 0 "register_operand" "=y")
21670         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21671                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21672   "TARGET_MMX"
21673   "psrlw\t{%2, %0|%0, %2}"
21674   [(set_attr "type" "mmxshft")
21675    (set_attr "mode" "DI")])
21677 (define_insn "lshrv2si3"
21678   [(set (match_operand:V2SI 0 "register_operand" "=y")
21679         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21680                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21681   "TARGET_MMX"
21682   "psrld\t{%2, %0|%0, %2}"
21683   [(set_attr "type" "mmxshft")
21684    (set_attr "mode" "DI")])
21686 ;; See logical MMX insns.
21687 (define_insn "mmx_lshrdi3"
21688   [(set (match_operand:DI 0 "register_operand" "=y")
21689         (unspec:DI
21690           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21691                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21692           UNSPEC_NOP))]
21693   "TARGET_MMX"
21694   "psrlq\t{%2, %0|%0, %2}"
21695   [(set_attr "type" "mmxshft")
21696    (set_attr "mode" "DI")])
21698 (define_insn "ashlv4hi3"
21699   [(set (match_operand:V4HI 0 "register_operand" "=y")
21700         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21701                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21702   "TARGET_MMX"
21703   "psllw\t{%2, %0|%0, %2}"
21704   [(set_attr "type" "mmxshft")
21705    (set_attr "mode" "DI")])
21707 (define_insn "ashlv2si3"
21708   [(set (match_operand:V2SI 0 "register_operand" "=y")
21709         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21710                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21711   "TARGET_MMX"
21712   "pslld\t{%2, %0|%0, %2}"
21713   [(set_attr "type" "mmxshft")
21714    (set_attr "mode" "DI")])
21716 ;; See logical MMX insns.
21717 (define_insn "mmx_ashldi3"
21718   [(set (match_operand:DI 0 "register_operand" "=y")
21719         (unspec:DI
21720          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21721                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21722          UNSPEC_NOP))]
21723   "TARGET_MMX"
21724   "psllq\t{%2, %0|%0, %2}"
21725   [(set_attr "type" "mmxshft")
21726    (set_attr "mode" "DI")])
21729 ;; MMX pack/unpack insns.
21731 (define_insn "mmx_packsswb"
21732   [(set (match_operand:V8QI 0 "register_operand" "=y")
21733         (vec_concat:V8QI
21734          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21735          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21736   "TARGET_MMX"
21737   "packsswb\t{%2, %0|%0, %2}"
21738   [(set_attr "type" "mmxshft")
21739    (set_attr "mode" "DI")])
21741 (define_insn "mmx_packssdw"
21742   [(set (match_operand:V4HI 0 "register_operand" "=y")
21743         (vec_concat:V4HI
21744          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21745          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21746   "TARGET_MMX"
21747   "packssdw\t{%2, %0|%0, %2}"
21748   [(set_attr "type" "mmxshft")
21749    (set_attr "mode" "DI")])
21751 (define_insn "mmx_packuswb"
21752   [(set (match_operand:V8QI 0 "register_operand" "=y")
21753         (vec_concat:V8QI
21754          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21755          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21756   "TARGET_MMX"
21757   "packuswb\t{%2, %0|%0, %2}"
21758   [(set_attr "type" "mmxshft")
21759    (set_attr "mode" "DI")])
21761 (define_insn "mmx_punpckhbw"
21762   [(set (match_operand:V8QI 0 "register_operand" "=y")
21763         (vec_merge:V8QI
21764          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21765                           (parallel [(const_int 4)
21766                                      (const_int 0)
21767                                      (const_int 5)
21768                                      (const_int 1)
21769                                      (const_int 6)
21770                                      (const_int 2)
21771                                      (const_int 7)
21772                                      (const_int 3)]))
21773          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21774                           (parallel [(const_int 0)
21775                                      (const_int 4)
21776                                      (const_int 1)
21777                                      (const_int 5)
21778                                      (const_int 2)
21779                                      (const_int 6)
21780                                      (const_int 3)
21781                                      (const_int 7)]))
21782          (const_int 85)))]
21783   "TARGET_MMX"
21784   "punpckhbw\t{%2, %0|%0, %2}"
21785   [(set_attr "type" "mmxcvt")
21786    (set_attr "mode" "DI")])
21788 (define_insn "mmx_punpckhwd"
21789   [(set (match_operand:V4HI 0 "register_operand" "=y")
21790         (vec_merge:V4HI
21791          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21792                           (parallel [(const_int 0)
21793                                      (const_int 2)
21794                                      (const_int 1)
21795                                      (const_int 3)]))
21796          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21797                           (parallel [(const_int 2)
21798                                      (const_int 0)
21799                                      (const_int 3)
21800                                      (const_int 1)]))
21801          (const_int 5)))]
21802   "TARGET_MMX"
21803   "punpckhwd\t{%2, %0|%0, %2}"
21804   [(set_attr "type" "mmxcvt")
21805    (set_attr "mode" "DI")])
21807 (define_insn "mmx_punpckhdq"
21808   [(set (match_operand:V2SI 0 "register_operand" "=y")
21809         (vec_merge:V2SI
21810          (match_operand:V2SI 1 "register_operand" "0")
21811          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21812                           (parallel [(const_int 1)
21813                                      (const_int 0)]))
21814          (const_int 1)))]
21815   "TARGET_MMX"
21816   "punpckhdq\t{%2, %0|%0, %2}"
21817   [(set_attr "type" "mmxcvt")
21818    (set_attr "mode" "DI")])
21820 (define_insn "mmx_punpcklbw"
21821   [(set (match_operand:V8QI 0 "register_operand" "=y")
21822         (vec_merge:V8QI
21823          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21824                           (parallel [(const_int 0)
21825                                      (const_int 4)
21826                                      (const_int 1)
21827                                      (const_int 5)
21828                                      (const_int 2)
21829                                      (const_int 6)
21830                                      (const_int 3)
21831                                      (const_int 7)]))
21832          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21833                           (parallel [(const_int 4)
21834                                      (const_int 0)
21835                                      (const_int 5)
21836                                      (const_int 1)
21837                                      (const_int 6)
21838                                      (const_int 2)
21839                                      (const_int 7)
21840                                      (const_int 3)]))
21841          (const_int 85)))]
21842   "TARGET_MMX"
21843   "punpcklbw\t{%2, %0|%0, %2}"
21844   [(set_attr "type" "mmxcvt")
21845    (set_attr "mode" "DI")])
21847 (define_insn "mmx_punpcklwd"
21848   [(set (match_operand:V4HI 0 "register_operand" "=y")
21849         (vec_merge:V4HI
21850          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21851                           (parallel [(const_int 2)
21852                                      (const_int 0)
21853                                      (const_int 3)
21854                                      (const_int 1)]))
21855          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21856                           (parallel [(const_int 0)
21857                                      (const_int 2)
21858                                      (const_int 1)
21859                                      (const_int 3)]))
21860          (const_int 5)))]
21861   "TARGET_MMX"
21862   "punpcklwd\t{%2, %0|%0, %2}"
21863   [(set_attr "type" "mmxcvt")
21864    (set_attr "mode" "DI")])
21866 (define_insn "mmx_punpckldq"
21867   [(set (match_operand:V2SI 0 "register_operand" "=y")
21868         (vec_merge:V2SI
21869          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21870                            (parallel [(const_int 1)
21871                                       (const_int 0)]))
21872          (match_operand:V2SI 2 "register_operand" "y")
21873          (const_int 1)))]
21874   "TARGET_MMX"
21875   "punpckldq\t{%2, %0|%0, %2}"
21876   [(set_attr "type" "mmxcvt")
21877    (set_attr "mode" "DI")])
21880 ;; Miscellaneous stuff
21882 (define_insn "emms"
21883   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21884    (clobber (reg:XF 8))
21885    (clobber (reg:XF 9))
21886    (clobber (reg:XF 10))
21887    (clobber (reg:XF 11))
21888    (clobber (reg:XF 12))
21889    (clobber (reg:XF 13))
21890    (clobber (reg:XF 14))
21891    (clobber (reg:XF 15))
21892    (clobber (reg:DI 29))
21893    (clobber (reg:DI 30))
21894    (clobber (reg:DI 31))
21895    (clobber (reg:DI 32))
21896    (clobber (reg:DI 33))
21897    (clobber (reg:DI 34))
21898    (clobber (reg:DI 35))
21899    (clobber (reg:DI 36))]
21900   "TARGET_MMX"
21901   "emms"
21902   [(set_attr "type" "mmx")
21903    (set_attr "memory" "unknown")])
21905 (define_insn "ldmxcsr"
21906   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21907                     UNSPECV_LDMXCSR)]
21908   "TARGET_SSE"
21909   "ldmxcsr\t%0"
21910   [(set_attr "type" "sse")
21911    (set_attr "memory" "load")])
21913 (define_insn "stmxcsr"
21914   [(set (match_operand:SI 0 "memory_operand" "=m")
21915         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21916   "TARGET_SSE"
21917   "stmxcsr\t%0"
21918   [(set_attr "type" "sse")
21919    (set_attr "memory" "store")])
21921 (define_expand "sfence"
21922   [(set (match_dup 0)
21923         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21924   "TARGET_SSE || TARGET_3DNOW_A"
21926   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21927   MEM_VOLATILE_P (operands[0]) = 1;
21930 (define_insn "*sfence_insn"
21931   [(set (match_operand:BLK 0 "" "")
21932         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21933   "TARGET_SSE || TARGET_3DNOW_A"
21934   "sfence"
21935   [(set_attr "type" "sse")
21936    (set_attr "memory" "unknown")])
21938 (define_expand "sse_prologue_save"
21939   [(parallel [(set (match_operand:BLK 0 "" "")
21940                    (unspec:BLK [(reg:DI 21)
21941                                 (reg:DI 22)
21942                                 (reg:DI 23)
21943                                 (reg:DI 24)
21944                                 (reg:DI 25)
21945                                 (reg:DI 26)
21946                                 (reg:DI 27)
21947                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21948               (use (match_operand:DI 1 "register_operand" ""))
21949               (use (match_operand:DI 2 "immediate_operand" ""))
21950               (use (label_ref:DI (match_operand 3 "" "")))])]
21951   "TARGET_64BIT"
21952   "")
21954 (define_insn "*sse_prologue_save_insn"
21955   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21956                           (match_operand:DI 4 "const_int_operand" "n")))
21957         (unspec:BLK [(reg:DI 21)
21958                      (reg:DI 22)
21959                      (reg:DI 23)
21960                      (reg:DI 24)
21961                      (reg:DI 25)
21962                      (reg:DI 26)
21963                      (reg:DI 27)
21964                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21965    (use (match_operand:DI 1 "register_operand" "r"))
21966    (use (match_operand:DI 2 "const_int_operand" "i"))
21967    (use (label_ref:DI (match_operand 3 "" "X")))]
21968   "TARGET_64BIT
21969    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21970    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21971   "*
21973   int i;
21974   operands[0] = gen_rtx_MEM (Pmode,
21975                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21976   output_asm_insn (\"jmp\\t%A1\", operands);
21977   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21978     {
21979       operands[4] = adjust_address (operands[0], DImode, i*16);
21980       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21981       PUT_MODE (operands[4], TImode);
21982       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21983         output_asm_insn (\"rex\", operands);
21984       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21985     }
21986   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21987                              CODE_LABEL_NUMBER (operands[3]));
21988   RET;
21990   "
21991   [(set_attr "type" "other")
21992    (set_attr "length_immediate" "0")
21993    (set_attr "length_address" "0")
21994    (set_attr "length" "135")
21995    (set_attr "memory" "store")
21996    (set_attr "modrm" "0")
21997    (set_attr "mode" "DI")])
21999 ;; 3Dnow! instructions
22001 (define_insn "addv2sf3"
22002   [(set (match_operand:V2SF 0 "register_operand" "=y")
22003         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22004                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22005   "TARGET_3DNOW"
22006   "pfadd\\t{%2, %0|%0, %2}"
22007   [(set_attr "type" "mmxadd")
22008    (set_attr "mode" "V2SF")])
22010 (define_insn "subv2sf3"
22011   [(set (match_operand:V2SF 0 "register_operand" "=y")
22012         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22013                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22014   "TARGET_3DNOW"
22015   "pfsub\\t{%2, %0|%0, %2}"
22016   [(set_attr "type" "mmxadd")
22017    (set_attr "mode" "V2SF")])
22019 (define_insn "subrv2sf3"
22020   [(set (match_operand:V2SF 0 "register_operand" "=y")
22021         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22022                     (match_operand:V2SF 1 "register_operand" "0")))]
22023   "TARGET_3DNOW"
22024   "pfsubr\\t{%2, %0|%0, %2}"
22025   [(set_attr "type" "mmxadd")
22026    (set_attr "mode" "V2SF")])
22028 (define_insn "gtv2sf3"
22029   [(set (match_operand:V2SI 0 "register_operand" "=y")
22030         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22031                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22032  "TARGET_3DNOW"
22033   "pfcmpgt\\t{%2, %0|%0, %2}"
22034   [(set_attr "type" "mmxcmp")
22035    (set_attr "mode" "V2SF")])
22037 (define_insn "gev2sf3"
22038   [(set (match_operand:V2SI 0 "register_operand" "=y")
22039         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22040                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22041   "TARGET_3DNOW"
22042   "pfcmpge\\t{%2, %0|%0, %2}"
22043   [(set_attr "type" "mmxcmp")
22044    (set_attr "mode" "V2SF")])
22046 (define_insn "eqv2sf3"
22047   [(set (match_operand:V2SI 0 "register_operand" "=y")
22048         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22049                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22050   "TARGET_3DNOW"
22051   "pfcmpeq\\t{%2, %0|%0, %2}"
22052   [(set_attr "type" "mmxcmp")
22053    (set_attr "mode" "V2SF")])
22055 (define_insn "pfmaxv2sf3"
22056   [(set (match_operand:V2SF 0 "register_operand" "=y")
22057         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22058                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22059   "TARGET_3DNOW"
22060   "pfmax\\t{%2, %0|%0, %2}"
22061   [(set_attr "type" "mmxadd")
22062    (set_attr "mode" "V2SF")])
22064 (define_insn "pfminv2sf3"
22065   [(set (match_operand:V2SF 0 "register_operand" "=y")
22066         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22067                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22068   "TARGET_3DNOW"
22069   "pfmin\\t{%2, %0|%0, %2}"
22070   [(set_attr "type" "mmxadd")
22071    (set_attr "mode" "V2SF")])
22073 (define_insn "mulv2sf3"
22074   [(set (match_operand:V2SF 0 "register_operand" "=y")
22075         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22076                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22077   "TARGET_3DNOW"
22078   "pfmul\\t{%2, %0|%0, %2}"
22079   [(set_attr "type" "mmxmul")
22080    (set_attr "mode" "V2SF")])
22082 (define_insn "femms"
22083   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22084    (clobber (reg:XF 8))
22085    (clobber (reg:XF 9))
22086    (clobber (reg:XF 10))
22087    (clobber (reg:XF 11))
22088    (clobber (reg:XF 12))
22089    (clobber (reg:XF 13))
22090    (clobber (reg:XF 14))
22091    (clobber (reg:XF 15))
22092    (clobber (reg:DI 29))
22093    (clobber (reg:DI 30))
22094    (clobber (reg:DI 31))
22095    (clobber (reg:DI 32))
22096    (clobber (reg:DI 33))
22097    (clobber (reg:DI 34))
22098    (clobber (reg:DI 35))
22099    (clobber (reg:DI 36))]
22100   "TARGET_3DNOW"
22101   "femms"
22102   [(set_attr "type" "mmx")
22103    (set_attr "memory" "none")]) 
22105 (define_insn "pf2id"
22106   [(set (match_operand:V2SI 0 "register_operand" "=y")
22107         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22108   "TARGET_3DNOW"
22109   "pf2id\\t{%1, %0|%0, %1}"
22110   [(set_attr "type" "mmxcvt")
22111    (set_attr "mode" "V2SF")])
22113 (define_insn "pf2iw"
22114   [(set (match_operand:V2SI 0 "register_operand" "=y")
22115         (sign_extend:V2SI
22116            (ss_truncate:V2HI
22117               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22118   "TARGET_3DNOW_A"
22119   "pf2iw\\t{%1, %0|%0, %1}"
22120   [(set_attr "type" "mmxcvt")
22121    (set_attr "mode" "V2SF")])
22123 (define_insn "pfacc"
22124   [(set (match_operand:V2SF 0 "register_operand" "=y")
22125         (vec_concat:V2SF
22126            (plus:SF
22127               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22128                              (parallel [(const_int  0)]))
22129               (vec_select:SF (match_dup 1)
22130                              (parallel [(const_int 1)])))
22131            (plus:SF
22132               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22133                              (parallel [(const_int  0)]))
22134               (vec_select:SF (match_dup 2)
22135                              (parallel [(const_int 1)])))))]
22136   "TARGET_3DNOW"
22137   "pfacc\\t{%2, %0|%0, %2}"
22138   [(set_attr "type" "mmxadd")
22139    (set_attr "mode" "V2SF")])
22141 (define_insn "pfnacc"
22142   [(set (match_operand:V2SF 0 "register_operand" "=y")
22143         (vec_concat:V2SF
22144            (minus:SF
22145               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22146                              (parallel [(const_int 0)]))
22147               (vec_select:SF (match_dup 1)
22148                              (parallel [(const_int 1)])))
22149            (minus:SF
22150               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22151                              (parallel [(const_int  0)]))
22152               (vec_select:SF (match_dup 2)
22153                              (parallel [(const_int 1)])))))]
22154   "TARGET_3DNOW_A"
22155   "pfnacc\\t{%2, %0|%0, %2}"
22156   [(set_attr "type" "mmxadd")
22157    (set_attr "mode" "V2SF")])
22159 (define_insn "pfpnacc"
22160   [(set (match_operand:V2SF 0 "register_operand" "=y")
22161         (vec_concat:V2SF
22162            (minus:SF
22163               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22164                              (parallel [(const_int 0)]))
22165               (vec_select:SF (match_dup 1)
22166                              (parallel [(const_int 1)])))
22167            (plus:SF
22168               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22169                              (parallel [(const_int 0)]))
22170               (vec_select:SF (match_dup 2)
22171                              (parallel [(const_int 1)])))))]
22172   "TARGET_3DNOW_A"
22173   "pfpnacc\\t{%2, %0|%0, %2}"
22174   [(set_attr "type" "mmxadd")
22175    (set_attr "mode" "V2SF")])
22177 (define_insn "pi2fw"
22178   [(set (match_operand:V2SF 0 "register_operand" "=y")
22179         (float:V2SF
22180            (vec_concat:V2SI
22181               (sign_extend:SI
22182                  (truncate:HI
22183                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22184                                    (parallel [(const_int 0)]))))
22185               (sign_extend:SI
22186                  (truncate:HI
22187                     (vec_select:SI (match_dup 1)
22188                                    (parallel [(const_int  1)])))))))]
22189   "TARGET_3DNOW_A"
22190   "pi2fw\\t{%1, %0|%0, %1}"
22191   [(set_attr "type" "mmxcvt")
22192    (set_attr "mode" "V2SF")])
22194 (define_insn "floatv2si2"
22195   [(set (match_operand:V2SF 0 "register_operand" "=y")
22196         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22197   "TARGET_3DNOW"
22198   "pi2fd\\t{%1, %0|%0, %1}"
22199   [(set_attr "type" "mmxcvt")
22200    (set_attr "mode" "V2SF")])
22202 ;; This insn is identical to pavgb in operation, but the opcode is
22203 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22205 (define_insn "pavgusb"
22206  [(set (match_operand:V8QI 0 "register_operand" "=y")
22207        (unspec:V8QI
22208           [(match_operand:V8QI 1 "register_operand" "0")
22209            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22210           UNSPEC_PAVGUSB))]
22211   "TARGET_3DNOW"
22212   "pavgusb\\t{%2, %0|%0, %2}"
22213   [(set_attr "type" "mmxshft")
22214    (set_attr "mode" "TI")])
22216 ;; 3DNow reciprocal and sqrt
22218 (define_insn "pfrcpv2sf2"
22219   [(set (match_operand:V2SF 0 "register_operand" "=y")
22220         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22221         UNSPEC_PFRCP))]
22222   "TARGET_3DNOW"
22223   "pfrcp\\t{%1, %0|%0, %1}"
22224   [(set_attr "type" "mmx")
22225    (set_attr "mode" "TI")])
22227 (define_insn "pfrcpit1v2sf3"
22228   [(set (match_operand:V2SF 0 "register_operand" "=y")
22229         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22230                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22231                      UNSPEC_PFRCPIT1))]
22232   "TARGET_3DNOW"
22233   "pfrcpit1\\t{%2, %0|%0, %2}"
22234   [(set_attr "type" "mmx")
22235    (set_attr "mode" "TI")])
22237 (define_insn "pfrcpit2v2sf3"
22238   [(set (match_operand:V2SF 0 "register_operand" "=y")
22239         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22240                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22241                      UNSPEC_PFRCPIT2))]
22242   "TARGET_3DNOW"
22243   "pfrcpit2\\t{%2, %0|%0, %2}"
22244   [(set_attr "type" "mmx")
22245    (set_attr "mode" "TI")])
22247 (define_insn "pfrsqrtv2sf2"
22248   [(set (match_operand:V2SF 0 "register_operand" "=y")
22249         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22250                      UNSPEC_PFRSQRT))]
22251   "TARGET_3DNOW"
22252   "pfrsqrt\\t{%1, %0|%0, %1}"
22253   [(set_attr "type" "mmx")
22254    (set_attr "mode" "TI")])
22255                 
22256 (define_insn "pfrsqit1v2sf3"
22257   [(set (match_operand:V2SF 0 "register_operand" "=y")
22258         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22259                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22260                      UNSPEC_PFRSQIT1))]
22261   "TARGET_3DNOW"
22262   "pfrsqit1\\t{%2, %0|%0, %2}"
22263   [(set_attr "type" "mmx")
22264    (set_attr "mode" "TI")])
22266 (define_insn "pmulhrwv4hi3"
22267   [(set (match_operand:V4HI 0 "register_operand" "=y")
22268         (truncate:V4HI
22269            (lshiftrt:V4SI
22270               (plus:V4SI
22271                  (mult:V4SI
22272                     (sign_extend:V4SI
22273                        (match_operand:V4HI 1 "register_operand" "0"))
22274                     (sign_extend:V4SI
22275                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22276                  (const_vector:V4SI [(const_int 32768)
22277                                      (const_int 32768)
22278                                      (const_int 32768)
22279                                      (const_int 32768)]))
22280               (const_int 16))))]
22281   "TARGET_3DNOW"
22282   "pmulhrw\\t{%2, %0|%0, %2}"
22283   [(set_attr "type" "mmxmul")
22284    (set_attr "mode" "TI")])
22286 (define_insn "pswapdv2si2"
22287   [(set (match_operand:V2SI 0 "register_operand" "=y")
22288         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22289                          (parallel [(const_int 1) (const_int 0)])))]
22290   "TARGET_3DNOW_A"
22291   "pswapd\\t{%1, %0|%0, %1}"
22292   [(set_attr "type" "mmxcvt")
22293    (set_attr "mode" "TI")])
22295 (define_insn "pswapdv2sf2"
22296   [(set (match_operand:V2SF 0 "register_operand" "=y")
22297         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22298                          (parallel [(const_int 1) (const_int 0)])))]
22299   "TARGET_3DNOW_A"
22300   "pswapd\\t{%1, %0|%0, %1}"
22301   [(set_attr "type" "mmxcvt")
22302    (set_attr "mode" "TI")])
22304 (define_expand "prefetch"
22305   [(prefetch (match_operand 0 "address_operand" "")
22306              (match_operand:SI 1 "const_int_operand" "")
22307              (match_operand:SI 2 "const_int_operand" ""))]
22308   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22310   int rw = INTVAL (operands[1]);
22311   int locality = INTVAL (operands[2]);
22313   if (rw != 0 && rw != 1)
22314     abort ();
22315   if (locality < 0 || locality > 3)
22316     abort ();
22317   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22318     abort ();
22320   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22321      suported by SSE counterpart or the SSE prefetch is not available
22322      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22323      of locality.  */
22324   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22325     operands[2] = GEN_INT (3);
22326   else
22327     operands[1] = const0_rtx;
22330 (define_insn "*prefetch_sse"
22331   [(prefetch (match_operand:SI 0 "address_operand" "p")
22332              (const_int 0)
22333              (match_operand:SI 1 "const_int_operand" ""))]
22334   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22336   static const char * const patterns[4] = {
22337    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22338   };
22340   int locality = INTVAL (operands[1]);
22341   if (locality < 0 || locality > 3)
22342     abort ();
22344   return patterns[locality];  
22346   [(set_attr "type" "sse")
22347    (set_attr "memory" "none")])
22349 (define_insn "*prefetch_sse_rex"
22350   [(prefetch (match_operand:DI 0 "address_operand" "p")
22351              (const_int 0)
22352              (match_operand:SI 1 "const_int_operand" ""))]
22353   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22355   static const char * const patterns[4] = {
22356    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22357   };
22359   int locality = INTVAL (operands[1]);
22360   if (locality < 0 || locality > 3)
22361     abort ();
22363   return patterns[locality];  
22365   [(set_attr "type" "sse")
22366    (set_attr "memory" "none")])
22368 (define_insn "*prefetch_3dnow"
22369   [(prefetch (match_operand:SI 0 "address_operand" "p")
22370              (match_operand:SI 1 "const_int_operand" "n")
22371              (const_int 3))]
22372   "TARGET_3DNOW && !TARGET_64BIT"
22374   if (INTVAL (operands[1]) == 0)
22375     return "prefetch\t%a0";
22376   else
22377     return "prefetchw\t%a0";
22379   [(set_attr "type" "mmx")
22380    (set_attr "memory" "none")])
22382 (define_insn "*prefetch_3dnow_rex"
22383   [(prefetch (match_operand:DI 0 "address_operand" "p")
22384              (match_operand:SI 1 "const_int_operand" "n")
22385              (const_int 3))]
22386   "TARGET_3DNOW && TARGET_64BIT"
22388   if (INTVAL (operands[1]) == 0)
22389     return "prefetch\t%a0";
22390   else
22391     return "prefetchw\t%a0";
22393   [(set_attr "type" "mmx")
22394    (set_attr "memory" "none")])
22396 ;; SSE2 support
22398 (define_insn "addv2df3"
22399   [(set (match_operand:V2DF 0 "register_operand" "=x")
22400         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22401                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22402   "TARGET_SSE2"
22403   "addpd\t{%2, %0|%0, %2}"
22404   [(set_attr "type" "sseadd")
22405    (set_attr "mode" "V2DF")])
22407 (define_insn "vmaddv2df3"
22408   [(set (match_operand:V2DF 0 "register_operand" "=x")
22409         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22410                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22411                         (match_dup 1)
22412                         (const_int 1)))]
22413   "TARGET_SSE2"
22414   "addsd\t{%2, %0|%0, %2}"
22415   [(set_attr "type" "sseadd")
22416    (set_attr "mode" "DF")])
22418 (define_insn "subv2df3"
22419   [(set (match_operand:V2DF 0 "register_operand" "=x")
22420         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22421                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22422   "TARGET_SSE2"
22423   "subpd\t{%2, %0|%0, %2}"
22424   [(set_attr "type" "sseadd")
22425    (set_attr "mode" "V2DF")])
22427 (define_insn "vmsubv2df3"
22428   [(set (match_operand:V2DF 0 "register_operand" "=x")
22429         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22430                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22431                         (match_dup 1)
22432                         (const_int 1)))]
22433   "TARGET_SSE2"
22434   "subsd\t{%2, %0|%0, %2}"
22435   [(set_attr "type" "sseadd")
22436    (set_attr "mode" "DF")])
22438 (define_insn "mulv2df3"
22439   [(set (match_operand:V2DF 0 "register_operand" "=x")
22440         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22441                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22442   "TARGET_SSE2"
22443   "mulpd\t{%2, %0|%0, %2}"
22444   [(set_attr "type" "ssemul")
22445    (set_attr "mode" "V2DF")])
22447 (define_insn "vmmulv2df3"
22448   [(set (match_operand:V2DF 0 "register_operand" "=x")
22449         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22450                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22451                         (match_dup 1)
22452                         (const_int 1)))]
22453   "TARGET_SSE2"
22454   "mulsd\t{%2, %0|%0, %2}"
22455   [(set_attr "type" "ssemul")
22456    (set_attr "mode" "DF")])
22458 (define_insn "divv2df3"
22459   [(set (match_operand:V2DF 0 "register_operand" "=x")
22460         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22461                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22462   "TARGET_SSE2"
22463   "divpd\t{%2, %0|%0, %2}"
22464   [(set_attr "type" "ssediv")
22465    (set_attr "mode" "V2DF")])
22467 (define_insn "vmdivv2df3"
22468   [(set (match_operand:V2DF 0 "register_operand" "=x")
22469         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22470                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22471                         (match_dup 1)
22472                         (const_int 1)))]
22473   "TARGET_SSE2"
22474   "divsd\t{%2, %0|%0, %2}"
22475   [(set_attr "type" "ssediv")
22476    (set_attr "mode" "DF")])
22478 ;; SSE min/max
22480 (define_insn "smaxv2df3"
22481   [(set (match_operand:V2DF 0 "register_operand" "=x")
22482         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22483                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22484   "TARGET_SSE2"
22485   "maxpd\t{%2, %0|%0, %2}"
22486   [(set_attr "type" "sseadd")
22487    (set_attr "mode" "V2DF")])
22489 (define_insn "vmsmaxv2df3"
22490   [(set (match_operand:V2DF 0 "register_operand" "=x")
22491         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22492                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22493                         (match_dup 1)
22494                         (const_int 1)))]
22495   "TARGET_SSE2"
22496   "maxsd\t{%2, %0|%0, %2}"
22497   [(set_attr "type" "sseadd")
22498    (set_attr "mode" "DF")])
22500 (define_insn "sminv2df3"
22501   [(set (match_operand:V2DF 0 "register_operand" "=x")
22502         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22503                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22504   "TARGET_SSE2"
22505   "minpd\t{%2, %0|%0, %2}"
22506   [(set_attr "type" "sseadd")
22507    (set_attr "mode" "V2DF")])
22509 (define_insn "vmsminv2df3"
22510   [(set (match_operand:V2DF 0 "register_operand" "=x")
22511         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22512                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22513                         (match_dup 1)
22514                         (const_int 1)))]
22515   "TARGET_SSE2"
22516   "minsd\t{%2, %0|%0, %2}"
22517   [(set_attr "type" "sseadd")
22518    (set_attr "mode" "DF")])
22519 ;; SSE2 square root.  There doesn't appear to be an extension for the
22520 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22522 (define_insn "sqrtv2df2"
22523   [(set (match_operand:V2DF 0 "register_operand" "=x")
22524         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22525   "TARGET_SSE2"
22526   "sqrtpd\t{%1, %0|%0, %1}"
22527   [(set_attr "type" "sse")
22528    (set_attr "mode" "V2DF")])
22530 (define_insn "vmsqrtv2df2"
22531   [(set (match_operand:V2DF 0 "register_operand" "=x")
22532         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22533                         (match_operand:V2DF 2 "register_operand" "0")
22534                         (const_int 1)))]
22535   "TARGET_SSE2"
22536   "sqrtsd\t{%1, %0|%0, %1}"
22537   [(set_attr "type" "sse")
22538    (set_attr "mode" "SF")])
22540 ;; SSE mask-generating compares
22542 (define_insn "maskcmpv2df3"
22543   [(set (match_operand:V2DI 0 "register_operand" "=x")
22544         (match_operator:V2DI 3 "sse_comparison_operator"
22545                              [(match_operand:V2DF 1 "register_operand" "0")
22546                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22547   "TARGET_SSE2"
22548   "cmp%D3pd\t{%2, %0|%0, %2}"
22549   [(set_attr "type" "ssecmp")
22550    (set_attr "mode" "V2DF")])
22552 (define_insn "maskncmpv2df3"
22553   [(set (match_operand:V2DI 0 "register_operand" "=x")
22554         (not:V2DI
22555          (match_operator:V2DI 3 "sse_comparison_operator"
22556                               [(match_operand:V2DF 1 "register_operand" "0")
22557                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22558   "TARGET_SSE2"
22560   if (GET_CODE (operands[3]) == UNORDERED)
22561     return "cmpordps\t{%2, %0|%0, %2}";
22562   else
22563     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22565   [(set_attr "type" "ssecmp")
22566    (set_attr "mode" "V2DF")])
22568 (define_insn "vmmaskcmpv2df3"
22569   [(set (match_operand:V2DI 0 "register_operand" "=x")
22570         (vec_merge:V2DI
22571          (match_operator:V2DI 3 "sse_comparison_operator"
22572                               [(match_operand:V2DF 1 "register_operand" "0")
22573                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22574          (subreg:V2DI (match_dup 1) 0)
22575          (const_int 1)))]
22576   "TARGET_SSE2"
22577   "cmp%D3sd\t{%2, %0|%0, %2}"
22578   [(set_attr "type" "ssecmp")
22579    (set_attr "mode" "DF")])
22581 (define_insn "vmmaskncmpv2df3"
22582   [(set (match_operand:V2DI 0 "register_operand" "=x")
22583         (vec_merge:V2DI
22584          (not:V2DI
22585           (match_operator:V2DI 3 "sse_comparison_operator"
22586                                [(match_operand:V2DF 1 "register_operand" "0")
22587                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22588          (subreg:V2DI (match_dup 1) 0)
22589          (const_int 1)))]
22590   "TARGET_SSE2"
22592   if (GET_CODE (operands[3]) == UNORDERED)
22593     return "cmpordsd\t{%2, %0|%0, %2}";
22594   else
22595     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22597   [(set_attr "type" "ssecmp")
22598    (set_attr "mode" "DF")])
22600 (define_insn "sse2_comi"
22601   [(set (reg:CCFP FLAGS_REG)
22602         (compare:CCFP (vec_select:DF
22603                        (match_operand:V2DF 0 "register_operand" "x")
22604                        (parallel [(const_int 0)]))
22605                       (vec_select:DF
22606                        (match_operand:V2DF 1 "register_operand" "x")
22607                        (parallel [(const_int 0)]))))]
22608   "TARGET_SSE2"
22609   "comisd\t{%1, %0|%0, %1}"
22610   [(set_attr "type" "ssecomi")
22611    (set_attr "mode" "DF")])
22613 (define_insn "sse2_ucomi"
22614   [(set (reg:CCFPU FLAGS_REG)
22615         (compare:CCFPU (vec_select:DF
22616                          (match_operand:V2DF 0 "register_operand" "x")
22617                          (parallel [(const_int 0)]))
22618                         (vec_select:DF
22619                          (match_operand:V2DF 1 "register_operand" "x")
22620                          (parallel [(const_int 0)]))))]
22621   "TARGET_SSE2"
22622   "ucomisd\t{%1, %0|%0, %1}"
22623   [(set_attr "type" "ssecomi")
22624    (set_attr "mode" "DF")])
22626 ;; SSE Strange Moves.
22628 (define_insn "sse2_movmskpd"
22629   [(set (match_operand:SI 0 "register_operand" "=r")
22630         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22631                    UNSPEC_MOVMSK))]
22632   "TARGET_SSE2"
22633   "movmskpd\t{%1, %0|%0, %1}"
22634   [(set_attr "type" "ssecvt")
22635    (set_attr "mode" "V2DF")])
22637 (define_insn "sse2_pmovmskb"
22638   [(set (match_operand:SI 0 "register_operand" "=r")
22639         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22640                    UNSPEC_MOVMSK))]
22641   "TARGET_SSE2"
22642   "pmovmskb\t{%1, %0|%0, %1}"
22643   [(set_attr "type" "ssecvt")
22644    (set_attr "mode" "V2DF")])
22646 (define_insn "sse2_maskmovdqu"
22647   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22648         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22649                        (match_operand:V16QI 2 "register_operand" "x")]
22650                       UNSPEC_MASKMOV))]
22651   "TARGET_SSE2"
22652   ;; @@@ check ordering of operands in intel/nonintel syntax
22653   "maskmovdqu\t{%2, %1|%1, %2}"
22654   [(set_attr "type" "ssecvt")
22655    (set_attr "mode" "TI")])
22657 (define_insn "sse2_maskmovdqu_rex64"
22658   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22659         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22660                        (match_operand:V16QI 2 "register_operand" "x")]
22661                       UNSPEC_MASKMOV))]
22662   "TARGET_SSE2"
22663   ;; @@@ check ordering of operands in intel/nonintel syntax
22664   "maskmovdqu\t{%2, %1|%1, %2}"
22665   [(set_attr "type" "ssecvt")
22666    (set_attr "mode" "TI")])
22668 (define_insn "sse2_movntv2df"
22669   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22670         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22671                      UNSPEC_MOVNT))]
22672   "TARGET_SSE2"
22673   "movntpd\t{%1, %0|%0, %1}"
22674   [(set_attr "type" "ssecvt")
22675    (set_attr "mode" "V2DF")])
22677 (define_insn "sse2_movntv2di"
22678   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22679         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22680                      UNSPEC_MOVNT))]
22681   "TARGET_SSE2"
22682   "movntdq\t{%1, %0|%0, %1}"
22683   [(set_attr "type" "ssecvt")
22684    (set_attr "mode" "TI")])
22686 (define_insn "sse2_movntsi"
22687   [(set (match_operand:SI 0 "memory_operand" "=m")
22688         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22689                    UNSPEC_MOVNT))]
22690   "TARGET_SSE2"
22691   "movnti\t{%1, %0|%0, %1}"
22692   [(set_attr "type" "ssecvt")
22693    (set_attr "mode" "V2DF")])
22695 ;; SSE <-> integer/MMX conversions
22697 ;; Conversions between SI and SF
22699 (define_insn "cvtdq2ps"
22700   [(set (match_operand:V4SF 0 "register_operand" "=x")
22701         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22702   "TARGET_SSE2"
22703   "cvtdq2ps\t{%1, %0|%0, %1}"
22704   [(set_attr "type" "ssecvt")
22705    (set_attr "mode" "V2DF")])
22707 (define_insn "cvtps2dq"
22708   [(set (match_operand:V4SI 0 "register_operand" "=x")
22709         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22710   "TARGET_SSE2"
22711   "cvtps2dq\t{%1, %0|%0, %1}"
22712   [(set_attr "type" "ssecvt")
22713    (set_attr "mode" "TI")])
22715 (define_insn "cvttps2dq"
22716   [(set (match_operand:V4SI 0 "register_operand" "=x")
22717         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22718                      UNSPEC_FIX))]
22719   "TARGET_SSE2"
22720   "cvttps2dq\t{%1, %0|%0, %1}"
22721   [(set_attr "type" "ssecvt")
22722    (set_attr "mode" "TI")])
22724 ;; Conversions between SI and DF
22726 (define_insn "cvtdq2pd"
22727   [(set (match_operand:V2DF 0 "register_operand" "=x")
22728         (float:V2DF (vec_select:V2SI
22729                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22730                      (parallel
22731                       [(const_int 0)
22732                        (const_int 1)]))))]
22733   "TARGET_SSE2"
22734   "cvtdq2pd\t{%1, %0|%0, %1}"
22735   [(set_attr "type" "ssecvt")
22736    (set_attr "mode" "V2DF")])
22738 (define_insn "cvtpd2dq"
22739   [(set (match_operand:V4SI 0 "register_operand" "=x")
22740         (vec_concat:V4SI
22741          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22742          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22743   "TARGET_SSE2"
22744   "cvtpd2dq\t{%1, %0|%0, %1}"
22745   [(set_attr "type" "ssecvt")
22746    (set_attr "mode" "TI")])
22748 (define_insn "cvttpd2dq"
22749   [(set (match_operand:V4SI 0 "register_operand" "=x")
22750         (vec_concat:V4SI
22751          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22752                       UNSPEC_FIX)
22753          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22754   "TARGET_SSE2"
22755   "cvttpd2dq\t{%1, %0|%0, %1}"
22756   [(set_attr "type" "ssecvt")
22757    (set_attr "mode" "TI")])
22759 (define_insn "cvtpd2pi"
22760   [(set (match_operand:V2SI 0 "register_operand" "=y")
22761         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22762   "TARGET_SSE2"
22763   "cvtpd2pi\t{%1, %0|%0, %1}"
22764   [(set_attr "type" "ssecvt")
22765    (set_attr "mode" "TI")])
22767 (define_insn "cvttpd2pi"
22768   [(set (match_operand:V2SI 0 "register_operand" "=y")
22769         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22770                      UNSPEC_FIX))]
22771   "TARGET_SSE2"
22772   "cvttpd2pi\t{%1, %0|%0, %1}"
22773   [(set_attr "type" "ssecvt")
22774    (set_attr "mode" "TI")])
22776 (define_insn "cvtpi2pd"
22777   [(set (match_operand:V2DF 0 "register_operand" "=x")
22778         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22779   "TARGET_SSE2"
22780   "cvtpi2pd\t{%1, %0|%0, %1}"
22781   [(set_attr "type" "ssecvt")
22782    (set_attr "mode" "TI")])
22784 ;; Conversions between SI and DF
22786 (define_insn "cvtsd2si"
22787   [(set (match_operand:SI 0 "register_operand" "=r,r")
22788         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22789                                (parallel [(const_int 0)]))))]
22790   "TARGET_SSE2"
22791   "cvtsd2si\t{%1, %0|%0, %1}"
22792   [(set_attr "type" "sseicvt")
22793    (set_attr "athlon_decode" "double,vector")
22794    (set_attr "mode" "SI")])
22796 (define_insn "cvtsd2siq"
22797   [(set (match_operand:DI 0 "register_operand" "=r,r")
22798         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22799                                (parallel [(const_int 0)]))))]
22800   "TARGET_SSE2 && TARGET_64BIT"
22801   "cvtsd2siq\t{%1, %0|%0, %1}"
22802   [(set_attr "type" "sseicvt")
22803    (set_attr "athlon_decode" "double,vector")
22804    (set_attr "mode" "DI")])
22806 (define_insn "cvttsd2si"
22807   [(set (match_operand:SI 0 "register_operand" "=r,r")
22808         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22809                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22810   "TARGET_SSE2"
22811   "cvttsd2si\t{%1, %0|%0, %1}"
22812   [(set_attr "type" "sseicvt")
22813    (set_attr "mode" "SI")
22814    (set_attr "athlon_decode" "double,vector")])
22816 (define_insn "cvttsd2siq"
22817   [(set (match_operand:DI 0 "register_operand" "=r,r")
22818         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22819                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22820   "TARGET_SSE2 && TARGET_64BIT"
22821   "cvttsd2siq\t{%1, %0|%0, %1}"
22822   [(set_attr "type" "sseicvt")
22823    (set_attr "mode" "DI")
22824    (set_attr "athlon_decode" "double,vector")])
22826 (define_insn "cvtsi2sd"
22827   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22828         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22829                         (vec_duplicate:V2DF
22830                           (float:DF
22831                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22832                         (const_int 2)))]
22833   "TARGET_SSE2"
22834   "cvtsi2sd\t{%2, %0|%0, %2}"
22835   [(set_attr "type" "sseicvt")
22836    (set_attr "mode" "DF")
22837    (set_attr "athlon_decode" "double,direct")])
22839 (define_insn "cvtsi2sdq"
22840   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22841         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22842                         (vec_duplicate:V2DF
22843                           (float:DF
22844                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22845                         (const_int 2)))]
22846   "TARGET_SSE2 && TARGET_64BIT"
22847   "cvtsi2sdq\t{%2, %0|%0, %2}"
22848   [(set_attr "type" "sseicvt")
22849    (set_attr "mode" "DF")
22850    (set_attr "athlon_decode" "double,direct")])
22852 ;; Conversions between SF and DF
22854 (define_insn "cvtsd2ss"
22855   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22856         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22857                         (vec_duplicate:V4SF
22858                           (float_truncate:V2SF
22859                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22860                         (const_int 14)))]
22861   "TARGET_SSE2"
22862   "cvtsd2ss\t{%2, %0|%0, %2}"
22863   [(set_attr "type" "ssecvt")
22864    (set_attr "athlon_decode" "vector,double")
22865    (set_attr "mode" "SF")])
22867 (define_insn "cvtss2sd"
22868   [(set (match_operand:V2DF 0 "register_operand" "=x")
22869         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22870                         (float_extend:V2DF
22871                           (vec_select:V2SF
22872                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22873                             (parallel [(const_int 0)
22874                                        (const_int 1)])))
22875                         (const_int 2)))]
22876   "TARGET_SSE2"
22877   "cvtss2sd\t{%2, %0|%0, %2}"
22878   [(set_attr "type" "ssecvt")
22879    (set_attr "mode" "DF")])
22881 (define_insn "cvtpd2ps"
22882   [(set (match_operand:V4SF 0 "register_operand" "=x")
22883         (subreg:V4SF
22884           (vec_concat:V4SI
22885             (subreg:V2SI (float_truncate:V2SF
22886                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22887             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22888   "TARGET_SSE2"
22889   "cvtpd2ps\t{%1, %0|%0, %1}"
22890   [(set_attr "type" "ssecvt")
22891    (set_attr "mode" "V4SF")])
22893 (define_insn "cvtps2pd"
22894   [(set (match_operand:V2DF 0 "register_operand" "=x")
22895         (float_extend:V2DF
22896           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22897                            (parallel [(const_int 0)
22898                                       (const_int 1)]))))]
22899   "TARGET_SSE2"
22900   "cvtps2pd\t{%1, %0|%0, %1}"
22901   [(set_attr "type" "ssecvt")
22902    (set_attr "mode" "V2DF")])
22904 ;; SSE2 variants of MMX insns
22906 ;; MMX arithmetic
22908 (define_insn "addv16qi3"
22909   [(set (match_operand:V16QI 0 "register_operand" "=x")
22910         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22911                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22912   "TARGET_SSE2"
22913   "paddb\t{%2, %0|%0, %2}"
22914   [(set_attr "type" "sseiadd")
22915    (set_attr "mode" "TI")])
22917 (define_insn "addv8hi3"
22918   [(set (match_operand:V8HI 0 "register_operand" "=x")
22919         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22920                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22921   "TARGET_SSE2"
22922   "paddw\t{%2, %0|%0, %2}"
22923   [(set_attr "type" "sseiadd")
22924    (set_attr "mode" "TI")])
22926 (define_insn "addv4si3"
22927   [(set (match_operand:V4SI 0 "register_operand" "=x")
22928         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22929                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22930   "TARGET_SSE2"
22931   "paddd\t{%2, %0|%0, %2}"
22932   [(set_attr "type" "sseiadd")
22933    (set_attr "mode" "TI")])
22935 (define_insn "addv2di3"
22936   [(set (match_operand:V2DI 0 "register_operand" "=x")
22937         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22938                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22939   "TARGET_SSE2"
22940   "paddq\t{%2, %0|%0, %2}"
22941   [(set_attr "type" "sseiadd")
22942    (set_attr "mode" "TI")])
22944 (define_insn "ssaddv16qi3"
22945   [(set (match_operand:V16QI 0 "register_operand" "=x")
22946         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22947                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22948   "TARGET_SSE2"
22949   "paddsb\t{%2, %0|%0, %2}"
22950   [(set_attr "type" "sseiadd")
22951    (set_attr "mode" "TI")])
22953 (define_insn "ssaddv8hi3"
22954   [(set (match_operand:V8HI 0 "register_operand" "=x")
22955         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22956                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22957   "TARGET_SSE2"
22958   "paddsw\t{%2, %0|%0, %2}"
22959   [(set_attr "type" "sseiadd")
22960    (set_attr "mode" "TI")])
22962 (define_insn "usaddv16qi3"
22963   [(set (match_operand:V16QI 0 "register_operand" "=x")
22964         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22965                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22966   "TARGET_SSE2"
22967   "paddusb\t{%2, %0|%0, %2}"
22968   [(set_attr "type" "sseiadd")
22969    (set_attr "mode" "TI")])
22971 (define_insn "usaddv8hi3"
22972   [(set (match_operand:V8HI 0 "register_operand" "=x")
22973         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22974                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22975   "TARGET_SSE2"
22976   "paddusw\t{%2, %0|%0, %2}"
22977   [(set_attr "type" "sseiadd")
22978    (set_attr "mode" "TI")])
22980 (define_insn "subv16qi3"
22981   [(set (match_operand:V16QI 0 "register_operand" "=x")
22982         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22983                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22984   "TARGET_SSE2"
22985   "psubb\t{%2, %0|%0, %2}"
22986   [(set_attr "type" "sseiadd")
22987    (set_attr "mode" "TI")])
22989 (define_insn "subv8hi3"
22990   [(set (match_operand:V8HI 0 "register_operand" "=x")
22991         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22992                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22993   "TARGET_SSE2"
22994   "psubw\t{%2, %0|%0, %2}"
22995   [(set_attr "type" "sseiadd")
22996    (set_attr "mode" "TI")])
22998 (define_insn "subv4si3"
22999   [(set (match_operand:V4SI 0 "register_operand" "=x")
23000         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23001                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23002   "TARGET_SSE2"
23003   "psubd\t{%2, %0|%0, %2}"
23004   [(set_attr "type" "sseiadd")
23005    (set_attr "mode" "TI")])
23007 (define_insn "subv2di3"
23008   [(set (match_operand:V2DI 0 "register_operand" "=x")
23009         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23010                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23011   "TARGET_SSE2"
23012   "psubq\t{%2, %0|%0, %2}"
23013   [(set_attr "type" "sseiadd")
23014    (set_attr "mode" "TI")])
23016 (define_insn "sssubv16qi3"
23017   [(set (match_operand:V16QI 0 "register_operand" "=x")
23018         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23019                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23020   "TARGET_SSE2"
23021   "psubsb\t{%2, %0|%0, %2}"
23022   [(set_attr "type" "sseiadd")
23023    (set_attr "mode" "TI")])
23025 (define_insn "sssubv8hi3"
23026   [(set (match_operand:V8HI 0 "register_operand" "=x")
23027         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23028                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23029   "TARGET_SSE2"
23030   "psubsw\t{%2, %0|%0, %2}"
23031   [(set_attr "type" "sseiadd")
23032    (set_attr "mode" "TI")])
23034 (define_insn "ussubv16qi3"
23035   [(set (match_operand:V16QI 0 "register_operand" "=x")
23036         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23037                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23038   "TARGET_SSE2"
23039   "psubusb\t{%2, %0|%0, %2}"
23040   [(set_attr "type" "sseiadd")
23041    (set_attr "mode" "TI")])
23043 (define_insn "ussubv8hi3"
23044   [(set (match_operand:V8HI 0 "register_operand" "=x")
23045         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23046                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23047   "TARGET_SSE2"
23048   "psubusw\t{%2, %0|%0, %2}"
23049   [(set_attr "type" "sseiadd")
23050    (set_attr "mode" "TI")])
23052 (define_insn "mulv8hi3"
23053   [(set (match_operand:V8HI 0 "register_operand" "=x")
23054         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23055                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23056   "TARGET_SSE2"
23057   "pmullw\t{%2, %0|%0, %2}"
23058   [(set_attr "type" "sseimul")
23059    (set_attr "mode" "TI")])
23061 (define_insn "smulv8hi3_highpart"
23062   [(set (match_operand:V8HI 0 "register_operand" "=x")
23063         (truncate:V8HI
23064          (lshiftrt:V8SI
23065           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23066                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23067           (const_int 16))))]
23068   "TARGET_SSE2"
23069   "pmulhw\t{%2, %0|%0, %2}"
23070   [(set_attr "type" "sseimul")
23071    (set_attr "mode" "TI")])
23073 (define_insn "umulv8hi3_highpart"
23074   [(set (match_operand:V8HI 0 "register_operand" "=x")
23075         (truncate:V8HI
23076          (lshiftrt:V8SI
23077           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23078                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23079           (const_int 16))))]
23080   "TARGET_SSE2"
23081   "pmulhuw\t{%2, %0|%0, %2}"
23082   [(set_attr "type" "sseimul")
23083    (set_attr "mode" "TI")])
23085 (define_insn "sse2_umulsidi3"
23086   [(set (match_operand:DI 0 "register_operand" "=y")
23087         (mult:DI (zero_extend:DI (vec_select:SI
23088                                   (match_operand:V2SI 1 "register_operand" "0")
23089                                   (parallel [(const_int 0)])))
23090                  (zero_extend:DI (vec_select:SI
23091                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23092                                   (parallel [(const_int 0)])))))]
23093   "TARGET_SSE2"
23094   "pmuludq\t{%2, %0|%0, %2}"
23095   [(set_attr "type" "mmxmul")
23096    (set_attr "mode" "DI")])
23098 (define_insn "sse2_umulv2siv2di3"
23099   [(set (match_operand:V2DI 0 "register_operand" "=x")
23100         (mult:V2DI (zero_extend:V2DI
23101                      (vec_select:V2SI
23102                        (match_operand:V4SI 1 "register_operand" "0")
23103                        (parallel [(const_int 0) (const_int 2)])))
23104                    (zero_extend:V2DI
23105                      (vec_select:V2SI
23106                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23107                        (parallel [(const_int 0) (const_int 2)])))))]
23108   "TARGET_SSE2"
23109   "pmuludq\t{%2, %0|%0, %2}"
23110   [(set_attr "type" "sseimul")
23111    (set_attr "mode" "TI")])
23113 (define_insn "sse2_pmaddwd"
23114   [(set (match_operand:V4SI 0 "register_operand" "=x")
23115         (plus:V4SI
23116          (mult:V4SI
23117           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23118                                              (parallel [(const_int 0)
23119                                                         (const_int 2)
23120                                                         (const_int 4)
23121                                                         (const_int 6)])))
23122           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23123                                              (parallel [(const_int 0)
23124                                                         (const_int 2)
23125                                                         (const_int 4)
23126                                                         (const_int 6)]))))
23127          (mult:V4SI
23128           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23129                                              (parallel [(const_int 1)
23130                                                         (const_int 3)
23131                                                         (const_int 5)
23132                                                         (const_int 7)])))
23133           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23134                                              (parallel [(const_int 1)
23135                                                         (const_int 3)
23136                                                         (const_int 5)
23137                                                         (const_int 7)]))))))]
23138   "TARGET_SSE2"
23139   "pmaddwd\t{%2, %0|%0, %2}"
23140   [(set_attr "type" "sseiadd")
23141    (set_attr "mode" "TI")])
23143 ;; Same as pxor, but don't show input operands so that we don't think
23144 ;; they are live.
23145 (define_insn "sse2_clrti"
23146   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23147   "TARGET_SSE2"
23149   if (get_attr_mode (insn) == MODE_TI)
23150     return "pxor\t%0, %0";
23151   else
23152     return "xorps\t%0, %0";
23154   [(set_attr "type" "ssemov")
23155    (set_attr "memory" "none")
23156    (set (attr "mode")
23157               (if_then_else
23158                 (ne (symbol_ref "optimize_size")
23159                     (const_int 0))
23160                 (const_string "V4SF")
23161                 (const_string "TI")))])
23163 ;; MMX unsigned averages/sum of absolute differences
23165 (define_insn "sse2_uavgv16qi3"
23166   [(set (match_operand:V16QI 0 "register_operand" "=x")
23167         (ashiftrt:V16QI
23168          (plus:V16QI (plus:V16QI
23169                      (match_operand:V16QI 1 "register_operand" "0")
23170                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23171                      (const_vector:V16QI [(const_int 1) (const_int 1)
23172                                           (const_int 1) (const_int 1)
23173                                           (const_int 1) (const_int 1)
23174                                           (const_int 1) (const_int 1)
23175                                           (const_int 1) (const_int 1)
23176                                           (const_int 1) (const_int 1)
23177                                           (const_int 1) (const_int 1)
23178                                           (const_int 1) (const_int 1)]))
23179          (const_int 1)))]
23180   "TARGET_SSE2"
23181   "pavgb\t{%2, %0|%0, %2}"
23182   [(set_attr "type" "sseiadd")
23183    (set_attr "mode" "TI")])
23185 (define_insn "sse2_uavgv8hi3"
23186   [(set (match_operand:V8HI 0 "register_operand" "=x")
23187         (ashiftrt:V8HI
23188          (plus:V8HI (plus:V8HI
23189                      (match_operand:V8HI 1 "register_operand" "0")
23190                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23191                     (const_vector:V8HI [(const_int 1) (const_int 1)
23192                                         (const_int 1) (const_int 1)
23193                                         (const_int 1) (const_int 1)
23194                                         (const_int 1) (const_int 1)]))
23195          (const_int 1)))]
23196   "TARGET_SSE2"
23197   "pavgw\t{%2, %0|%0, %2}"
23198   [(set_attr "type" "sseiadd")
23199    (set_attr "mode" "TI")])
23201 ;; @@@ this isn't the right representation.
23202 (define_insn "sse2_psadbw"
23203   [(set (match_operand:V2DI 0 "register_operand" "=x")
23204         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23205                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23206                      UNSPEC_PSADBW))]
23207   "TARGET_SSE2"
23208   "psadbw\t{%2, %0|%0, %2}"
23209   [(set_attr "type" "sseiadd")
23210    (set_attr "mode" "TI")])
23213 ;; MMX insert/extract/shuffle
23215 (define_insn "sse2_pinsrw"
23216   [(set (match_operand:V8HI 0 "register_operand" "=x")
23217         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23218                         (vec_duplicate:V8HI
23219                          (truncate:HI
23220                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23221                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23222   "TARGET_SSE2"
23223   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23224   [(set_attr "type" "ssecvt")
23225    (set_attr "mode" "TI")])
23227 (define_insn "sse2_pextrw"
23228   [(set (match_operand:SI 0 "register_operand" "=r")
23229         (zero_extend:SI
23230           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23231                          (parallel
23232                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23233   "TARGET_SSE2"
23234   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23235   [(set_attr "type" "ssecvt")
23236    (set_attr "mode" "TI")])
23238 (define_insn "sse2_pshufd"
23239   [(set (match_operand:V4SI 0 "register_operand" "=x")
23240         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23241                       (match_operand:SI 2 "immediate_operand" "i")]
23242                      UNSPEC_SHUFFLE))]
23243   "TARGET_SSE2"
23244   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23245   [(set_attr "type" "ssecvt")
23246    (set_attr "mode" "TI")])
23248 (define_insn "sse2_pshuflw"
23249   [(set (match_operand:V8HI 0 "register_operand" "=x")
23250         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23251                       (match_operand:SI 2 "immediate_operand" "i")]
23252                      UNSPEC_PSHUFLW))]
23253   "TARGET_SSE2"
23254   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23255   [(set_attr "type" "ssecvt")
23256    (set_attr "mode" "TI")])
23258 (define_insn "sse2_pshufhw"
23259   [(set (match_operand:V8HI 0 "register_operand" "=x")
23260         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23261                       (match_operand:SI 2 "immediate_operand" "i")]
23262                      UNSPEC_PSHUFHW))]
23263   "TARGET_SSE2"
23264   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23265   [(set_attr "type" "ssecvt")
23266    (set_attr "mode" "TI")])
23268 ;; MMX mask-generating comparisons
23270 (define_insn "eqv16qi3"
23271   [(set (match_operand:V16QI 0 "register_operand" "=x")
23272         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23273                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23274   "TARGET_SSE2"
23275   "pcmpeqb\t{%2, %0|%0, %2}"
23276   [(set_attr "type" "ssecmp")
23277    (set_attr "mode" "TI")])
23279 (define_insn "eqv8hi3"
23280   [(set (match_operand:V8HI 0 "register_operand" "=x")
23281         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23282                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23283   "TARGET_SSE2"
23284   "pcmpeqw\t{%2, %0|%0, %2}"
23285   [(set_attr "type" "ssecmp")
23286    (set_attr "mode" "TI")])
23288 (define_insn "eqv4si3"
23289   [(set (match_operand:V4SI 0 "register_operand" "=x")
23290         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23291                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23292   "TARGET_SSE2"
23293   "pcmpeqd\t{%2, %0|%0, %2}"
23294   [(set_attr "type" "ssecmp")
23295    (set_attr "mode" "TI")])
23297 (define_insn "gtv16qi3"
23298   [(set (match_operand:V16QI 0 "register_operand" "=x")
23299         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23300                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23301   "TARGET_SSE2"
23302   "pcmpgtb\t{%2, %0|%0, %2}"
23303   [(set_attr "type" "ssecmp")
23304    (set_attr "mode" "TI")])
23306 (define_insn "gtv8hi3"
23307   [(set (match_operand:V8HI 0 "register_operand" "=x")
23308         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23309                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23310   "TARGET_SSE2"
23311   "pcmpgtw\t{%2, %0|%0, %2}"
23312   [(set_attr "type" "ssecmp")
23313    (set_attr "mode" "TI")])
23315 (define_insn "gtv4si3"
23316   [(set (match_operand:V4SI 0 "register_operand" "=x")
23317         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23318                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23319   "TARGET_SSE2"
23320   "pcmpgtd\t{%2, %0|%0, %2}"
23321   [(set_attr "type" "ssecmp")
23322    (set_attr "mode" "TI")])
23325 ;; MMX max/min insns
23327 (define_insn "umaxv16qi3"
23328   [(set (match_operand:V16QI 0 "register_operand" "=x")
23329         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23330                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23331   "TARGET_SSE2"
23332   "pmaxub\t{%2, %0|%0, %2}"
23333   [(set_attr "type" "sseiadd")
23334    (set_attr "mode" "TI")])
23336 (define_insn "smaxv8hi3"
23337   [(set (match_operand:V8HI 0 "register_operand" "=x")
23338         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23339                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23340   "TARGET_SSE2"
23341   "pmaxsw\t{%2, %0|%0, %2}"
23342   [(set_attr "type" "sseiadd")
23343    (set_attr "mode" "TI")])
23345 (define_insn "uminv16qi3"
23346   [(set (match_operand:V16QI 0 "register_operand" "=x")
23347         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23348                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23349   "TARGET_SSE2"
23350   "pminub\t{%2, %0|%0, %2}"
23351   [(set_attr "type" "sseiadd")
23352    (set_attr "mode" "TI")])
23354 (define_insn "sminv8hi3"
23355   [(set (match_operand:V8HI 0 "register_operand" "=x")
23356         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23357                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23358   "TARGET_SSE2"
23359   "pminsw\t{%2, %0|%0, %2}"
23360   [(set_attr "type" "sseiadd")
23361    (set_attr "mode" "TI")])
23364 ;; MMX shifts
23366 (define_insn "ashrv8hi3"
23367   [(set (match_operand:V8HI 0 "register_operand" "=x")
23368         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23369                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23370   "TARGET_SSE2"
23371   "psraw\t{%2, %0|%0, %2}"
23372   [(set_attr "type" "sseishft")
23373    (set_attr "mode" "TI")])
23375 (define_insn "ashrv4si3"
23376   [(set (match_operand:V4SI 0 "register_operand" "=x")
23377         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23378                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23379   "TARGET_SSE2"
23380   "psrad\t{%2, %0|%0, %2}"
23381   [(set_attr "type" "sseishft")
23382    (set_attr "mode" "TI")])
23384 (define_insn "lshrv8hi3"
23385   [(set (match_operand:V8HI 0 "register_operand" "=x")
23386         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23387                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23388   "TARGET_SSE2"
23389   "psrlw\t{%2, %0|%0, %2}"
23390   [(set_attr "type" "sseishft")
23391    (set_attr "mode" "TI")])
23393 (define_insn "lshrv4si3"
23394   [(set (match_operand:V4SI 0 "register_operand" "=x")
23395         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23396                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23397   "TARGET_SSE2"
23398   "psrld\t{%2, %0|%0, %2}"
23399   [(set_attr "type" "sseishft")
23400    (set_attr "mode" "TI")])
23402 (define_insn "lshrv2di3"
23403   [(set (match_operand:V2DI 0 "register_operand" "=x")
23404         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23405                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23406   "TARGET_SSE2"
23407   "psrlq\t{%2, %0|%0, %2}"
23408   [(set_attr "type" "sseishft")
23409    (set_attr "mode" "TI")])
23411 (define_insn "ashlv8hi3"
23412   [(set (match_operand:V8HI 0 "register_operand" "=x")
23413         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23414                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23415   "TARGET_SSE2"
23416   "psllw\t{%2, %0|%0, %2}"
23417   [(set_attr "type" "sseishft")
23418    (set_attr "mode" "TI")])
23420 (define_insn "ashlv4si3"
23421   [(set (match_operand:V4SI 0 "register_operand" "=x")
23422         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23423                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23424   "TARGET_SSE2"
23425   "pslld\t{%2, %0|%0, %2}"
23426   [(set_attr "type" "sseishft")
23427    (set_attr "mode" "TI")])
23429 (define_insn "ashlv2di3"
23430   [(set (match_operand:V2DI 0 "register_operand" "=x")
23431         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23432                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23433   "TARGET_SSE2"
23434   "psllq\t{%2, %0|%0, %2}"
23435   [(set_attr "type" "sseishft")
23436    (set_attr "mode" "TI")])
23438 (define_insn "ashrv8hi3_ti"
23439   [(set (match_operand:V8HI 0 "register_operand" "=x")
23440         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23441                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23442   "TARGET_SSE2"
23443   "psraw\t{%2, %0|%0, %2}"
23444   [(set_attr "type" "sseishft")
23445    (set_attr "mode" "TI")])
23447 (define_insn "ashrv4si3_ti"
23448   [(set (match_operand:V4SI 0 "register_operand" "=x")
23449         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23450                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23451   "TARGET_SSE2"
23452   "psrad\t{%2, %0|%0, %2}"
23453   [(set_attr "type" "sseishft")
23454    (set_attr "mode" "TI")])
23456 (define_insn "lshrv8hi3_ti"
23457   [(set (match_operand:V8HI 0 "register_operand" "=x")
23458         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23459                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23460   "TARGET_SSE2"
23461   "psrlw\t{%2, %0|%0, %2}"
23462   [(set_attr "type" "sseishft")
23463    (set_attr "mode" "TI")])
23465 (define_insn "lshrv4si3_ti"
23466   [(set (match_operand:V4SI 0 "register_operand" "=x")
23467         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23468                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23469   "TARGET_SSE2"
23470   "psrld\t{%2, %0|%0, %2}"
23471   [(set_attr "type" "sseishft")
23472    (set_attr "mode" "TI")])
23474 (define_insn "lshrv2di3_ti"
23475   [(set (match_operand:V2DI 0 "register_operand" "=x")
23476         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23477                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23478   "TARGET_SSE2"
23479   "psrlq\t{%2, %0|%0, %2}"
23480   [(set_attr "type" "sseishft")
23481    (set_attr "mode" "TI")])
23483 (define_insn "ashlv8hi3_ti"
23484   [(set (match_operand:V8HI 0 "register_operand" "=x")
23485         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23486                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23487   "TARGET_SSE2"
23488   "psllw\t{%2, %0|%0, %2}"
23489   [(set_attr "type" "sseishft")
23490    (set_attr "mode" "TI")])
23492 (define_insn "ashlv4si3_ti"
23493   [(set (match_operand:V4SI 0 "register_operand" "=x")
23494         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23495                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23496   "TARGET_SSE2"
23497   "pslld\t{%2, %0|%0, %2}"
23498   [(set_attr "type" "sseishft")
23499    (set_attr "mode" "TI")])
23501 (define_insn "ashlv2di3_ti"
23502   [(set (match_operand:V2DI 0 "register_operand" "=x")
23503         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23504                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23505   "TARGET_SSE2"
23506   "psllq\t{%2, %0|%0, %2}"
23507   [(set_attr "type" "sseishft")
23508    (set_attr "mode" "TI")])
23510 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23511 ;; we wouldn't need here it since we never generate TImode arithmetic.
23513 ;; There has to be some kind of prize for the weirdest new instruction...
23514 (define_insn "sse2_ashlti3"
23515   [(set (match_operand:TI 0 "register_operand" "=x")
23516         (unspec:TI
23517          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23518                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23519                                (const_int 8)))] UNSPEC_NOP))]
23520   "TARGET_SSE2"
23521   "pslldq\t{%2, %0|%0, %2}"
23522   [(set_attr "type" "sseishft")
23523    (set_attr "mode" "TI")])
23525 (define_insn "sse2_lshrti3"
23526   [(set (match_operand:TI 0 "register_operand" "=x")
23527         (unspec:TI
23528          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23529                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23530                                 (const_int 8)))] UNSPEC_NOP))]
23531   "TARGET_SSE2"
23532   "psrldq\t{%2, %0|%0, %2}"
23533   [(set_attr "type" "sseishft")
23534    (set_attr "mode" "TI")])
23536 ;; SSE unpack
23538 (define_insn "sse2_unpckhpd"
23539   [(set (match_operand:V2DF 0 "register_operand" "=x")
23540         (vec_concat:V2DF
23541          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23542                         (parallel [(const_int 1)]))
23543          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23544                         (parallel [(const_int 1)]))))]
23545   "TARGET_SSE2"
23546   "unpckhpd\t{%2, %0|%0, %2}"
23547   [(set_attr "type" "ssecvt")
23548    (set_attr "mode" "V2DF")])
23550 (define_insn "sse2_unpcklpd"
23551   [(set (match_operand:V2DF 0 "register_operand" "=x")
23552         (vec_concat:V2DF
23553          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23554                         (parallel [(const_int 0)]))
23555          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23556                         (parallel [(const_int 0)]))))]
23557   "TARGET_SSE2"
23558   "unpcklpd\t{%2, %0|%0, %2}"
23559   [(set_attr "type" "ssecvt")
23560    (set_attr "mode" "V2DF")])
23562 ;; MMX pack/unpack insns.
23564 (define_insn "sse2_packsswb"
23565   [(set (match_operand:V16QI 0 "register_operand" "=x")
23566         (vec_concat:V16QI
23567          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23568          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23569   "TARGET_SSE2"
23570   "packsswb\t{%2, %0|%0, %2}"
23571   [(set_attr "type" "ssecvt")
23572    (set_attr "mode" "TI")])
23574 (define_insn "sse2_packssdw"
23575   [(set (match_operand:V8HI 0 "register_operand" "=x")
23576         (vec_concat:V8HI
23577          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23578          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23579   "TARGET_SSE2"
23580   "packssdw\t{%2, %0|%0, %2}"
23581   [(set_attr "type" "ssecvt")
23582    (set_attr "mode" "TI")])
23584 (define_insn "sse2_packuswb"
23585   [(set (match_operand:V16QI 0 "register_operand" "=x")
23586         (vec_concat:V16QI
23587          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23588          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23589   "TARGET_SSE2"
23590   "packuswb\t{%2, %0|%0, %2}"
23591   [(set_attr "type" "ssecvt")
23592    (set_attr "mode" "TI")])
23594 (define_insn "sse2_punpckhbw"
23595   [(set (match_operand:V16QI 0 "register_operand" "=x")
23596         (vec_merge:V16QI
23597          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23598                            (parallel [(const_int 8) (const_int 0)
23599                                       (const_int 9) (const_int 1)
23600                                       (const_int 10) (const_int 2)
23601                                       (const_int 11) (const_int 3)
23602                                       (const_int 12) (const_int 4)
23603                                       (const_int 13) (const_int 5)
23604                                       (const_int 14) (const_int 6)
23605                                       (const_int 15) (const_int 7)]))
23606          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23607                            (parallel [(const_int 0) (const_int 8)
23608                                       (const_int 1) (const_int 9)
23609                                       (const_int 2) (const_int 10)
23610                                       (const_int 3) (const_int 11)
23611                                       (const_int 4) (const_int 12)
23612                                       (const_int 5) (const_int 13)
23613                                       (const_int 6) (const_int 14)
23614                                       (const_int 7) (const_int 15)]))
23615          (const_int 21845)))]
23616   "TARGET_SSE2"
23617   "punpckhbw\t{%2, %0|%0, %2}"
23618   [(set_attr "type" "ssecvt")
23619    (set_attr "mode" "TI")])
23621 (define_insn "sse2_punpckhwd"
23622   [(set (match_operand:V8HI 0 "register_operand" "=x")
23623         (vec_merge:V8HI
23624          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23625                           (parallel [(const_int 4) (const_int 0)
23626                                      (const_int 5) (const_int 1)
23627                                      (const_int 6) (const_int 2)
23628                                      (const_int 7) (const_int 3)]))
23629          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23630                           (parallel [(const_int 0) (const_int 4)
23631                                      (const_int 1) (const_int 5)
23632                                      (const_int 2) (const_int 6)
23633                                      (const_int 3) (const_int 7)]))
23634          (const_int 85)))]
23635   "TARGET_SSE2"
23636   "punpckhwd\t{%2, %0|%0, %2}"
23637   [(set_attr "type" "ssecvt")
23638    (set_attr "mode" "TI")])
23640 (define_insn "sse2_punpckhdq"
23641   [(set (match_operand:V4SI 0 "register_operand" "=x")
23642         (vec_merge:V4SI
23643          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23644                           (parallel [(const_int 2) (const_int 0)
23645                                      (const_int 3) (const_int 1)]))
23646          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23647                           (parallel [(const_int 0) (const_int 2)
23648                                      (const_int 1) (const_int 3)]))
23649          (const_int 5)))]
23650   "TARGET_SSE2"
23651   "punpckhdq\t{%2, %0|%0, %2}"
23652   [(set_attr "type" "ssecvt")
23653    (set_attr "mode" "TI")])
23655 (define_insn "sse2_punpcklbw"
23656   [(set (match_operand:V16QI 0 "register_operand" "=x")
23657         (vec_merge:V16QI
23658          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23659                            (parallel [(const_int 0) (const_int 8)
23660                                       (const_int 1) (const_int 9)
23661                                       (const_int 2) (const_int 10)
23662                                       (const_int 3) (const_int 11)
23663                                       (const_int 4) (const_int 12)
23664                                       (const_int 5) (const_int 13)
23665                                       (const_int 6) (const_int 14)
23666                                       (const_int 7) (const_int 15)]))
23667          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23668                            (parallel [(const_int 8) (const_int 0)
23669                                       (const_int 9) (const_int 1)
23670                                       (const_int 10) (const_int 2)
23671                                       (const_int 11) (const_int 3)
23672                                       (const_int 12) (const_int 4)
23673                                       (const_int 13) (const_int 5)
23674                                       (const_int 14) (const_int 6)
23675                                       (const_int 15) (const_int 7)]))
23676          (const_int 21845)))]
23677   "TARGET_SSE2"
23678   "punpcklbw\t{%2, %0|%0, %2}"
23679   [(set_attr "type" "ssecvt")
23680    (set_attr "mode" "TI")])
23682 (define_insn "sse2_punpcklwd"
23683   [(set (match_operand:V8HI 0 "register_operand" "=x")
23684         (vec_merge:V8HI
23685          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23686                           (parallel [(const_int 0) (const_int 4)
23687                                      (const_int 1) (const_int 5)
23688                                      (const_int 2) (const_int 6)
23689                                      (const_int 3) (const_int 7)]))
23690          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23691                           (parallel [(const_int 4) (const_int 0)
23692                                      (const_int 5) (const_int 1)
23693                                      (const_int 6) (const_int 2)
23694                                      (const_int 7) (const_int 3)]))
23695          (const_int 85)))]
23696   "TARGET_SSE2"
23697   "punpcklwd\t{%2, %0|%0, %2}"
23698   [(set_attr "type" "ssecvt")
23699    (set_attr "mode" "TI")])
23701 (define_insn "sse2_punpckldq"
23702   [(set (match_operand:V4SI 0 "register_operand" "=x")
23703         (vec_merge:V4SI
23704          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23705                           (parallel [(const_int 0) (const_int 2)
23706                                      (const_int 1) (const_int 3)]))
23707          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23708                           (parallel [(const_int 2) (const_int 0)
23709                                      (const_int 3) (const_int 1)]))
23710          (const_int 5)))]
23711   "TARGET_SSE2"
23712   "punpckldq\t{%2, %0|%0, %2}"
23713   [(set_attr "type" "ssecvt")
23714    (set_attr "mode" "TI")])
23716 (define_insn "sse2_punpcklqdq"
23717   [(set (match_operand:V2DI 0 "register_operand" "=x")
23718         (vec_merge:V2DI
23719          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23720                           (parallel [(const_int 1)
23721                                      (const_int 0)]))
23722          (match_operand:V2DI 1 "register_operand" "0")
23723          (const_int 1)))]
23724   "TARGET_SSE2"
23725   "punpcklqdq\t{%2, %0|%0, %2}"
23726   [(set_attr "type" "ssecvt")
23727    (set_attr "mode" "TI")])
23729 (define_insn "sse2_punpckhqdq"
23730   [(set (match_operand:V2DI 0 "register_operand" "=x")
23731         (vec_merge:V2DI
23732          (match_operand:V2DI 1 "register_operand" "0")
23733          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23734                           (parallel [(const_int 1)
23735                                      (const_int 0)]))
23736          (const_int 1)))]
23737   "TARGET_SSE2"
23738   "punpckhqdq\t{%2, %0|%0, %2}"
23739   [(set_attr "type" "ssecvt")
23740    (set_attr "mode" "TI")])
23742 ;; SSE2 moves
23744 (define_insn "sse2_movapd"
23745   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23746         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23747                      UNSPEC_MOVA))]
23748   "TARGET_SSE2
23749    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23750   "movapd\t{%1, %0|%0, %1}"
23751   [(set_attr "type" "ssemov")
23752    (set_attr "mode" "V2DF")])
23754 (define_insn "sse2_movupd"
23755   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23756         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23757                      UNSPEC_MOVU))]
23758   "TARGET_SSE2
23759    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23760   "movupd\t{%1, %0|%0, %1}"
23761   [(set_attr "type" "ssecvt")
23762    (set_attr "mode" "V2DF")])
23764 (define_insn "sse2_movdqa"
23765   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23766         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23767                        UNSPEC_MOVA))]
23768   "TARGET_SSE2
23769    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23770   "movdqa\t{%1, %0|%0, %1}"
23771   [(set_attr "type" "ssemov")
23772    (set_attr "mode" "TI")])
23774 (define_insn "sse2_movdqu"
23775   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23776         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23777                        UNSPEC_MOVU))]
23778   "TARGET_SSE2
23779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23780   "movdqu\t{%1, %0|%0, %1}"
23781   [(set_attr "type" "ssecvt")
23782    (set_attr "mode" "TI")])
23784 (define_insn "sse2_movdq2q"
23785   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23786         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23787                        (parallel [(const_int 0)])))]
23788   "TARGET_SSE2 && !TARGET_64BIT"
23789   "@
23790    movq\t{%1, %0|%0, %1}
23791    movdq2q\t{%1, %0|%0, %1}"
23792   [(set_attr "type" "ssecvt")
23793    (set_attr "mode" "TI")])
23795 (define_insn "sse2_movdq2q_rex64"
23796   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23797         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23798                        (parallel [(const_int 0)])))]
23799   "TARGET_SSE2 && TARGET_64BIT"
23800   "@
23801    movq\t{%1, %0|%0, %1}
23802    movdq2q\t{%1, %0|%0, %1}
23803    movd\t{%1, %0|%0, %1}"
23804   [(set_attr "type" "ssecvt")
23805    (set_attr "mode" "TI")])
23807 (define_insn "sse2_movq2dq"
23808   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23809         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23810                          (const_int 0)))]
23811   "TARGET_SSE2 && !TARGET_64BIT"
23812   "@
23813    movq\t{%1, %0|%0, %1}
23814    movq2dq\t{%1, %0|%0, %1}"
23815   [(set_attr "type" "ssecvt,ssemov")
23816    (set_attr "mode" "TI")])
23818 (define_insn "sse2_movq2dq_rex64"
23819   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23820         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23821                          (const_int 0)))]
23822   "TARGET_SSE2 && TARGET_64BIT"
23823   "@
23824    movq\t{%1, %0|%0, %1}
23825    movq2dq\t{%1, %0|%0, %1}
23826    movd\t{%1, %0|%0, %1}"
23827   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23828    (set_attr "mode" "TI")])
23830 (define_insn "sse2_movq"
23831   [(set (match_operand:V2DI 0 "register_operand" "=x")
23832         (vec_concat:V2DI (vec_select:DI
23833                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23834                           (parallel [(const_int 0)]))
23835                          (const_int 0)))]
23836   "TARGET_SSE2"
23837   "movq\t{%1, %0|%0, %1}"
23838   [(set_attr "type" "ssemov")
23839    (set_attr "mode" "TI")])
23841 (define_insn "sse2_loadd"
23842   [(set (match_operand:V4SI 0 "register_operand" "=x")
23843         (vec_merge:V4SI
23844          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23845          (const_vector:V4SI [(const_int 0)
23846                              (const_int 0)
23847                              (const_int 0)
23848                              (const_int 0)])
23849          (const_int 1)))]
23850   "TARGET_SSE2"
23851   "movd\t{%1, %0|%0, %1}"
23852   [(set_attr "type" "ssemov")
23853    (set_attr "mode" "TI")])
23855 (define_insn "sse2_stored"
23856   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23857         (vec_select:SI
23858          (match_operand:V4SI 1 "register_operand" "x")
23859          (parallel [(const_int 0)])))]
23860   "TARGET_SSE2"
23861   "movd\t{%1, %0|%0, %1}"
23862   [(set_attr "type" "ssemov")
23863    (set_attr "mode" "TI")])
23865 (define_insn "sse2_movhpd"
23866   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23867         (vec_merge:V2DF
23868          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23869          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23870          (const_int 2)))]
23871   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23872   "movhpd\t{%2, %0|%0, %2}"
23873   [(set_attr "type" "ssecvt")
23874    (set_attr "mode" "V2DF")])
23876 (define_expand "sse2_loadsd"
23877   [(match_operand:V2DF 0 "register_operand" "")
23878    (match_operand:DF 1 "memory_operand" "")]
23879   "TARGET_SSE2"
23881   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23882                                 CONST0_RTX (V2DFmode)));
23883   DONE;
23886 (define_insn "sse2_loadsd_1"
23887   [(set (match_operand:V2DF 0 "register_operand" "=x")
23888         (vec_merge:V2DF
23889          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23890          (match_operand:V2DF 2 "const0_operand" "X")
23891          (const_int 1)))]
23892   "TARGET_SSE2"
23893   "movsd\t{%1, %0|%0, %1}"
23894   [(set_attr "type" "ssecvt")
23895    (set_attr "mode" "DF")])
23897 (define_insn "sse2_movsd"
23898   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
23899         (vec_merge:V2DF
23900          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23901          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
23902          (const_int 1)))]
23903   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
23904   "@movsd\t{%2, %0|%0, %2}
23905     movlpd\t{%2, %0|%0, %2}
23906     movlpd\t{%2, %0|%0, %2}"
23907   [(set_attr "type" "ssecvt")
23908    (set_attr "mode" "DF,V2DF,V2DF")])
23910 (define_insn "sse2_storesd"
23911   [(set (match_operand:DF 0 "memory_operand" "=m")
23912         (vec_select:DF
23913          (match_operand:V2DF 1 "register_operand" "x")
23914          (parallel [(const_int 0)])))]
23915   "TARGET_SSE2"
23916   "movsd\t{%1, %0|%0, %1}"
23917   [(set_attr "type" "ssecvt")
23918    (set_attr "mode" "DF")])
23920 (define_insn "sse2_shufpd"
23921   [(set (match_operand:V2DF 0 "register_operand" "=x")
23922         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23923                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23924                       (match_operand:SI 3 "immediate_operand" "i")]
23925                      UNSPEC_SHUFFLE))]
23926   "TARGET_SSE2"
23927   ;; @@@ check operand order for intel/nonintel syntax
23928   "shufpd\t{%3, %2, %0|%0, %2, %3}"
23929   [(set_attr "type" "ssecvt")
23930    (set_attr "mode" "V2DF")])
23932 (define_insn "sse2_clflush"
23933   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23934                     UNSPECV_CLFLUSH)]
23935   "TARGET_SSE2"
23936   "clflush\t%a0"
23937   [(set_attr "type" "sse")
23938    (set_attr "memory" "unknown")])
23940 (define_expand "sse2_mfence"
23941   [(set (match_dup 0)
23942         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23943   "TARGET_SSE2"
23945   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23946   MEM_VOLATILE_P (operands[0]) = 1;
23949 (define_insn "*mfence_insn"
23950   [(set (match_operand:BLK 0 "" "")
23951         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23952   "TARGET_SSE2"
23953   "mfence"
23954   [(set_attr "type" "sse")
23955    (set_attr "memory" "unknown")])
23957 (define_expand "sse2_lfence"
23958   [(set (match_dup 0)
23959         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23960   "TARGET_SSE2"
23962   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23963   MEM_VOLATILE_P (operands[0]) = 1;
23966 (define_insn "*lfence_insn"
23967   [(set (match_operand:BLK 0 "" "")
23968         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23969   "TARGET_SSE2"
23970   "lfence"
23971   [(set_attr "type" "sse")
23972    (set_attr "memory" "unknown")])
23974 ;; SSE3
23976 (define_insn "mwait"
23977   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23978                      (match_operand:SI 1 "register_operand" "c")]
23979                     UNSPECV_MWAIT)]
23980   "TARGET_SSE3"
23981   "mwait\t%0, %1"
23982   [(set_attr "length" "3")])
23984 (define_insn "monitor"
23985   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23986                      (match_operand:SI 1 "register_operand" "c")
23987                      (match_operand:SI 2 "register_operand" "d")]
23988                     UNSPECV_MONITOR)]
23989   "TARGET_SSE3"
23990   "monitor\t%0, %1, %2"
23991   [(set_attr "length" "3")])
23993 ;; SSE3 arithmetic
23995 (define_insn "addsubv4sf3"
23996   [(set (match_operand:V4SF 0 "register_operand" "=x")
23997         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23998                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23999                      UNSPEC_ADDSUB))]
24000   "TARGET_SSE3"
24001   "addsubps\t{%2, %0|%0, %2}"
24002   [(set_attr "type" "sseadd")
24003    (set_attr "mode" "V4SF")])
24005 (define_insn "addsubv2df3"
24006   [(set (match_operand:V2DF 0 "register_operand" "=x")
24007         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24008                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24009                      UNSPEC_ADDSUB))]
24010   "TARGET_SSE3"
24011   "addsubpd\t{%2, %0|%0, %2}"
24012   [(set_attr "type" "sseadd")
24013    (set_attr "mode" "V2DF")])
24015 (define_insn "haddv4sf3"
24016   [(set (match_operand:V4SF 0 "register_operand" "=x")
24017         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24018                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24019                      UNSPEC_HADD))]
24020   "TARGET_SSE3"
24021   "haddps\t{%2, %0|%0, %2}"
24022   [(set_attr "type" "sseadd")
24023    (set_attr "mode" "V4SF")])
24025 (define_insn "haddv2df3"
24026   [(set (match_operand:V2DF 0 "register_operand" "=x")
24027         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24028                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24029                      UNSPEC_HADD))]
24030   "TARGET_SSE3"
24031   "haddpd\t{%2, %0|%0, %2}"
24032   [(set_attr "type" "sseadd")
24033    (set_attr "mode" "V2DF")])
24035 (define_insn "hsubv4sf3"
24036   [(set (match_operand:V4SF 0 "register_operand" "=x")
24037         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24038                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24039                      UNSPEC_HSUB))]
24040   "TARGET_SSE3"
24041   "hsubps\t{%2, %0|%0, %2}"
24042   [(set_attr "type" "sseadd")
24043    (set_attr "mode" "V4SF")])
24045 (define_insn "hsubv2df3"
24046   [(set (match_operand:V2DF 0 "register_operand" "=x")
24047         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24048                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24049                      UNSPEC_HSUB))]
24050   "TARGET_SSE3"
24051   "hsubpd\t{%2, %0|%0, %2}"
24052   [(set_attr "type" "sseadd")
24053    (set_attr "mode" "V2DF")])
24055 (define_insn "movshdup"
24056   [(set (match_operand:V4SF 0 "register_operand" "=x")
24057         (unspec:V4SF
24058          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24059   "TARGET_SSE3"
24060   "movshdup\t{%1, %0|%0, %1}"
24061   [(set_attr "type" "sse")
24062    (set_attr "mode" "V4SF")])
24064 (define_insn "movsldup"
24065   [(set (match_operand:V4SF 0 "register_operand" "=x")
24066         (unspec:V4SF
24067          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24068   "TARGET_SSE3"
24069   "movsldup\t{%1, %0|%0, %1}"
24070   [(set_attr "type" "sse")
24071    (set_attr "mode" "V4SF")])
24073 (define_insn "lddqu"
24074   [(set (match_operand:V16QI 0 "register_operand" "=x")
24075         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24076                        UNSPEC_LDQQU))]
24077   "TARGET_SSE3"
24078   "lddqu\t{%1, %0|%0, %1}"
24079   [(set_attr "type" "ssecvt")
24080    (set_attr "mode" "TI")])
24082 (define_insn "loadddup"
24083   [(set (match_operand:V2DF 0 "register_operand" "=x")
24084         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24085   "TARGET_SSE3"
24086   "movddup\t{%1, %0|%0, %1}"
24087   [(set_attr "type" "ssecvt")
24088    (set_attr "mode" "DF")])
24090 (define_insn "movddup"
24091   [(set (match_operand:V2DF 0 "register_operand" "=x")
24092         (vec_duplicate:V2DF
24093          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24094                         (parallel [(const_int 0)]))))]
24095   "TARGET_SSE3"
24096   "movddup\t{%1, %0|%0, %1}"
24097   [(set_attr "type" "ssecvt")
24098    (set_attr "mode" "DF")])