* alias.c, c-common.h, c-incpath.c, c-incpath.h, expr.c,
[official-gcc.git] / gcc / config / i386 / i386.md
blobf96fa9495a3c3d8c16dcd631c28060a54f2856fc
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
51 ;; UNSPEC usage:
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_FIX_NOTRUNC          31)
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    ; x87 Rounding
139    (UNSPEC_FRNDINT_FLOOR        96)
140    (UNSPEC_FRNDINT_CEIL         97)
141    (UNSPEC_FRNDINT_TRUNC        98)
142    (UNSPEC_FRNDINT_MASK_PM      99)
144    ; REP instruction
145    (UNSPEC_REP                  75)
147    (UNSPEC_EH_RETURN            76)
148   ])
150 (define_constants
151   [(UNSPECV_BLOCKAGE            0)
152    (UNSPECV_STACK_PROBE         10)
153    (UNSPECV_EMMS                31)
154    (UNSPECV_LDMXCSR             37)
155    (UNSPECV_STMXCSR             40)
156    (UNSPECV_FEMMS               46)
157    (UNSPECV_CLFLUSH             57)
158    (UNSPECV_ALIGN               68)
159    (UNSPECV_MONITOR             69)
160    (UNSPECV_MWAIT               70)
161   ])
163 ;; Registers by name.
164 (define_constants
165   [(BP_REG                       6)
166    (SP_REG                       7)
167    (FLAGS_REG                   17)
168    (FPSR_REG                    18)
169    (DIRFLAG_REG                 19)
170   ])
172 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
173 ;; from i386.c.
175 ;; In C guard expressions, put expressions which may be compile-time
176 ;; constants first.  This allows for better optimization.  For
177 ;; example, write "TARGET_64BIT && reload_completed", not
178 ;; "reload_completed && TARGET_64BIT".
181 ;; Processor type.  This attribute must exactly match the processor_type
182 ;; enumeration in i386.h.
183 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
184   (const (symbol_ref "ix86_tune")))
186 ;; A basic instruction type.  Refinements due to arguments to be
187 ;; provided in other attributes.
188 (define_attr "type"
189   "other,multi,
190    alu,alu1,negnot,imov,imovx,lea,
191    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
192    icmp,test,ibr,setcc,icmov,
193    push,pop,call,callv,leave,
194    str,cld,
195    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
196    sselog,sselog1,sseiadd,sseishft,sseimul,
197    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
198    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
199   (const_string "other"))
201 ;; Main data type used by the insn
202 (define_attr "mode"
203   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
204   (const_string "unknown"))
206 ;; The CPU unit operations uses.
207 (define_attr "unit" "integer,i387,sse,mmx,unknown"
208   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
209            (const_string "i387")
210          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
211                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
212            (const_string "sse")
213          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
214            (const_string "mmx")
215          (eq_attr "type" "other")
216            (const_string "unknown")]
217          (const_string "integer")))
219 ;; The (bounding maximum) length of an instruction immediate.
220 (define_attr "length_immediate" ""
221   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
222            (const_int 0)
223          (eq_attr "unit" "i387,sse,mmx")
224            (const_int 0)
225          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
226                           imul,icmp,push,pop")
227            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
228          (eq_attr "type" "imov,test")
229            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
230          (eq_attr "type" "call")
231            (if_then_else (match_operand 0 "constant_call_address_operand" "")
232              (const_int 4)
233              (const_int 0))
234          (eq_attr "type" "callv")
235            (if_then_else (match_operand 1 "constant_call_address_operand" "")
236              (const_int 4)
237              (const_int 0))
238          ;; We don't know the size before shorten_branches.  Expect
239          ;; the instruction to fit for better scheduling.
240          (eq_attr "type" "ibr")
241            (const_int 1)
242          ]
243          (symbol_ref "/* Update immediate_length and other attributes! */
244                       abort(),1")))
246 ;; The (bounding maximum) length of an instruction address.
247 (define_attr "length_address" ""
248   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
249            (const_int 0)
250          (and (eq_attr "type" "call")
251               (match_operand 0 "constant_call_address_operand" ""))
252              (const_int 0)
253          (and (eq_attr "type" "callv")
254               (match_operand 1 "constant_call_address_operand" ""))
255              (const_int 0)
256          ]
257          (symbol_ref "ix86_attr_length_address_default (insn)")))
259 ;; Set when length prefix is used.
260 (define_attr "prefix_data16" ""
261   (if_then_else (ior (eq_attr "mode" "HI")
262                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
263     (const_int 1)
264     (const_int 0)))
266 ;; Set when string REP prefix is used.
267 (define_attr "prefix_rep" "" 
268   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
269     (const_int 1)
270     (const_int 0)))
272 ;; Set when 0f opcode prefix is used.
273 (define_attr "prefix_0f" ""
274   (if_then_else 
275     (ior (eq_attr "type" "imovx,setcc,icmov")
276          (eq_attr "unit" "sse,mmx"))
277     (const_int 1)
278     (const_int 0)))
280 ;; Set when REX opcode prefix is used.
281 (define_attr "prefix_rex" ""
282   (cond [(and (eq_attr "mode" "DI")
283               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
284            (const_int 1)
285          (and (eq_attr "mode" "QI")
286               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
287                   (const_int 0)))
288            (const_int 1)
289          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
290              (const_int 0))
291            (const_int 1)
292         ]
293         (const_int 0)))
295 ;; Set when modrm byte is used.
296 (define_attr "modrm" ""
297   (cond [(eq_attr "type" "str,cld,leave")
298            (const_int 0)
299          (eq_attr "unit" "i387")
300            (const_int 0)
301          (and (eq_attr "type" "incdec")
302               (ior (match_operand:SI 1 "register_operand" "")
303                    (match_operand:HI 1 "register_operand" "")))
304            (const_int 0)
305          (and (eq_attr "type" "push")
306               (not (match_operand 1 "memory_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "pop")
309               (not (match_operand 0 "memory_operand" "")))
310            (const_int 0)
311          (and (eq_attr "type" "imov")
312               (and (match_operand 0 "register_operand" "")
313                    (match_operand 1 "immediate_operand" "")))
314            (const_int 0)
315          (and (eq_attr "type" "call")
316               (match_operand 0 "constant_call_address_operand" ""))
317              (const_int 0)
318          (and (eq_attr "type" "callv")
319               (match_operand 1 "constant_call_address_operand" ""))
320              (const_int 0)
321          ]
322          (const_int 1)))
324 ;; The (bounding maximum) length of an instruction in bytes.
325 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
326 ;; Later we may want to split them and compute proper length as for
327 ;; other insns.
328 (define_attr "length" ""
329   (cond [(eq_attr "type" "other,multi,fistp,frndint")
330            (const_int 16)
331          (eq_attr "type" "fcmp")
332            (const_int 4)
333          (eq_attr "unit" "i387")
334            (plus (const_int 2)
335                  (plus (attr "prefix_data16")
336                        (attr "length_address")))]
337          (plus (plus (attr "modrm")
338                      (plus (attr "prefix_0f")
339                            (plus (attr "prefix_rex")
340                                  (const_int 1))))
341                (plus (attr "prefix_rep")
342                      (plus (attr "prefix_data16")
343                            (plus (attr "length_immediate")
344                                  (attr "length_address")))))))
346 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
347 ;; `store' if there is a simple memory reference therein, or `unknown'
348 ;; if the instruction is complex.
350 (define_attr "memory" "none,load,store,both,unknown"
351   (cond [(eq_attr "type" "other,multi,str")
352            (const_string "unknown")
353          (eq_attr "type" "lea,fcmov,fpspc,cld")
354            (const_string "none")
355          (eq_attr "type" "fistp,leave")
356            (const_string "both")
357          (eq_attr "type" "frndint")
358            (const_string "load")
359          (eq_attr "type" "push")
360            (if_then_else (match_operand 1 "memory_operand" "")
361              (const_string "both")
362              (const_string "store"))
363          (eq_attr "type" "pop")
364            (if_then_else (match_operand 0 "memory_operand" "")
365              (const_string "both")
366              (const_string "load"))
367          (eq_attr "type" "setcc")
368            (if_then_else (match_operand 0 "memory_operand" "")
369              (const_string "store")
370              (const_string "none"))
371          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
372            (if_then_else (ior (match_operand 0 "memory_operand" "")
373                               (match_operand 1 "memory_operand" ""))
374              (const_string "load")
375              (const_string "none"))
376          (eq_attr "type" "ibr")
377            (if_then_else (match_operand 0 "memory_operand" "")
378              (const_string "load")
379              (const_string "none"))
380          (eq_attr "type" "call")
381            (if_then_else (match_operand 0 "constant_call_address_operand" "")
382              (const_string "none")
383              (const_string "load"))
384          (eq_attr "type" "callv")
385            (if_then_else (match_operand 1 "constant_call_address_operand" "")
386              (const_string "none")
387              (const_string "load"))
388          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
389               (match_operand 1 "memory_operand" ""))
390            (const_string "both")
391          (and (match_operand 0 "memory_operand" "")
392               (match_operand 1 "memory_operand" ""))
393            (const_string "both")
394          (match_operand 0 "memory_operand" "")
395            (const_string "store")
396          (match_operand 1 "memory_operand" "")
397            (const_string "load")
398          (and (eq_attr "type"
399                  "!alu1,negnot,ishift1,
400                    imov,imovx,icmp,test,
401                    fmov,fcmp,fsgn,
402                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
403                    mmx,mmxmov,mmxcmp,mmxcvt")
404               (match_operand 2 "memory_operand" ""))
405            (const_string "load")
406          (and (eq_attr "type" "icmov")
407               (match_operand 3 "memory_operand" ""))
408            (const_string "load")
409         ]
410         (const_string "none")))
412 ;; Indicates if an instruction has both an immediate and a displacement.
414 (define_attr "imm_disp" "false,true,unknown"
415   (cond [(eq_attr "type" "other,multi")
416            (const_string "unknown")
417          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
418               (and (match_operand 0 "memory_displacement_operand" "")
419                    (match_operand 1 "immediate_operand" "")))
420            (const_string "true")
421          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
422               (and (match_operand 0 "memory_displacement_operand" "")
423                    (match_operand 2 "immediate_operand" "")))
424            (const_string "true")
425         ]
426         (const_string "false")))
428 ;; Indicates if an FP operation has an integer source.
430 (define_attr "fp_int_src" "false,true"
431   (const_string "false"))
433 ;; Defines rounding mode of an FP operation.
435 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
436   (const_string "any"))
438 ;; Describe a user's asm statement.
439 (define_asm_attributes
440   [(set_attr "length" "128")
441    (set_attr "type" "multi")])
443 ;; Scheduling descriptions
445 (include "pentium.md")
446 (include "ppro.md")
447 (include "k6.md")
448 (include "athlon.md")
451 ;; Operand and operator predicates
453 (include "predicates.md")
456 ;; Compare instructions.
458 ;; All compare insns have expanders that save the operands away without
459 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
460 ;; after the cmp) will actually emit the cmpM.
462 (define_expand "cmpdi"
463   [(set (reg:CC FLAGS_REG)
464         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
465                     (match_operand:DI 1 "x86_64_general_operand" "")))]
466   ""
468   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
469     operands[0] = force_reg (DImode, operands[0]);
470   ix86_compare_op0 = operands[0];
471   ix86_compare_op1 = operands[1];
472   DONE;
475 (define_expand "cmpsi"
476   [(set (reg:CC FLAGS_REG)
477         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
478                     (match_operand:SI 1 "general_operand" "")))]
479   ""
481   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
482     operands[0] = force_reg (SImode, operands[0]);
483   ix86_compare_op0 = operands[0];
484   ix86_compare_op1 = operands[1];
485   DONE;
488 (define_expand "cmphi"
489   [(set (reg:CC FLAGS_REG)
490         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
491                     (match_operand:HI 1 "general_operand" "")))]
492   ""
494   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
495     operands[0] = force_reg (HImode, operands[0]);
496   ix86_compare_op0 = operands[0];
497   ix86_compare_op1 = operands[1];
498   DONE;
501 (define_expand "cmpqi"
502   [(set (reg:CC FLAGS_REG)
503         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
504                     (match_operand:QI 1 "general_operand" "")))]
505   "TARGET_QIMODE_MATH"
507   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
508     operands[0] = force_reg (QImode, operands[0]);
509   ix86_compare_op0 = operands[0];
510   ix86_compare_op1 = operands[1];
511   DONE;
514 (define_insn "cmpdi_ccno_1_rex64"
515   [(set (reg FLAGS_REG)
516         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
517                  (match_operand:DI 1 "const0_operand" "n,n")))]
518   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
519   "@
520    test{q}\t{%0, %0|%0, %0}
521    cmp{q}\t{%1, %0|%0, %1}"
522   [(set_attr "type" "test,icmp")
523    (set_attr "length_immediate" "0,1")
524    (set_attr "mode" "DI")])
526 (define_insn "*cmpdi_minus_1_rex64"
527   [(set (reg FLAGS_REG)
528         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
529                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
530                  (const_int 0)))]
531   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
532   "cmp{q}\t{%1, %0|%0, %1}"
533   [(set_attr "type" "icmp")
534    (set_attr "mode" "DI")])
536 (define_expand "cmpdi_1_rex64"
537   [(set (reg:CC FLAGS_REG)
538         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
539                     (match_operand:DI 1 "general_operand" "")))]
540   "TARGET_64BIT"
541   "")
543 (define_insn "cmpdi_1_insn_rex64"
544   [(set (reg FLAGS_REG)
545         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
546                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
547   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
548   "cmp{q}\t{%1, %0|%0, %1}"
549   [(set_attr "type" "icmp")
550    (set_attr "mode" "DI")])
553 (define_insn "*cmpsi_ccno_1"
554   [(set (reg FLAGS_REG)
555         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
556                  (match_operand:SI 1 "const0_operand" "n,n")))]
557   "ix86_match_ccmode (insn, CCNOmode)"
558   "@
559    test{l}\t{%0, %0|%0, %0}
560    cmp{l}\t{%1, %0|%0, %1}"
561   [(set_attr "type" "test,icmp")
562    (set_attr "length_immediate" "0,1")
563    (set_attr "mode" "SI")])
565 (define_insn "*cmpsi_minus_1"
566   [(set (reg FLAGS_REG)
567         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
568                            (match_operand:SI 1 "general_operand" "ri,mr"))
569                  (const_int 0)))]
570   "ix86_match_ccmode (insn, CCGOCmode)"
571   "cmp{l}\t{%1, %0|%0, %1}"
572   [(set_attr "type" "icmp")
573    (set_attr "mode" "SI")])
575 (define_expand "cmpsi_1"
576   [(set (reg:CC FLAGS_REG)
577         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
578                     (match_operand:SI 1 "general_operand" "ri,mr")))]
579   ""
580   "")
582 (define_insn "*cmpsi_1_insn"
583   [(set (reg FLAGS_REG)
584         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
585                  (match_operand:SI 1 "general_operand" "ri,mr")))]
586   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
587     && ix86_match_ccmode (insn, CCmode)"
588   "cmp{l}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "icmp")
590    (set_attr "mode" "SI")])
592 (define_insn "*cmphi_ccno_1"
593   [(set (reg FLAGS_REG)
594         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
595                  (match_operand:HI 1 "const0_operand" "n,n")))]
596   "ix86_match_ccmode (insn, CCNOmode)"
597   "@
598    test{w}\t{%0, %0|%0, %0}
599    cmp{w}\t{%1, %0|%0, %1}"
600   [(set_attr "type" "test,icmp")
601    (set_attr "length_immediate" "0,1")
602    (set_attr "mode" "HI")])
604 (define_insn "*cmphi_minus_1"
605   [(set (reg FLAGS_REG)
606         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
607                            (match_operand:HI 1 "general_operand" "ri,mr"))
608                  (const_int 0)))]
609   "ix86_match_ccmode (insn, CCGOCmode)"
610   "cmp{w}\t{%1, %0|%0, %1}"
611   [(set_attr "type" "icmp")
612    (set_attr "mode" "HI")])
614 (define_insn "*cmphi_1"
615   [(set (reg FLAGS_REG)
616         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
617                  (match_operand:HI 1 "general_operand" "ri,mr")))]
618   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619    && ix86_match_ccmode (insn, CCmode)"
620   "cmp{w}\t{%1, %0|%0, %1}"
621   [(set_attr "type" "icmp")
622    (set_attr "mode" "HI")])
624 (define_insn "*cmpqi_ccno_1"
625   [(set (reg FLAGS_REG)
626         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
627                  (match_operand:QI 1 "const0_operand" "n,n")))]
628   "ix86_match_ccmode (insn, CCNOmode)"
629   "@
630    test{b}\t{%0, %0|%0, %0}
631    cmp{b}\t{$0, %0|%0, 0}"
632   [(set_attr "type" "test,icmp")
633    (set_attr "length_immediate" "0,1")
634    (set_attr "mode" "QI")])
636 (define_insn "*cmpqi_1"
637   [(set (reg FLAGS_REG)
638         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
639                  (match_operand:QI 1 "general_operand" "qi,mq")))]
640   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
641     && ix86_match_ccmode (insn, CCmode)"
642   "cmp{b}\t{%1, %0|%0, %1}"
643   [(set_attr "type" "icmp")
644    (set_attr "mode" "QI")])
646 (define_insn "*cmpqi_minus_1"
647   [(set (reg FLAGS_REG)
648         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
649                            (match_operand:QI 1 "general_operand" "qi,mq"))
650                  (const_int 0)))]
651   "ix86_match_ccmode (insn, CCGOCmode)"
652   "cmp{b}\t{%1, %0|%0, %1}"
653   [(set_attr "type" "icmp")
654    (set_attr "mode" "QI")])
656 (define_insn "*cmpqi_ext_1"
657   [(set (reg FLAGS_REG)
658         (compare
659           (match_operand:QI 0 "general_operand" "Qm")
660           (subreg:QI
661             (zero_extract:SI
662               (match_operand 1 "ext_register_operand" "Q")
663               (const_int 8)
664               (const_int 8)) 0)))]
665   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
666   "cmp{b}\t{%h1, %0|%0, %h1}"
667   [(set_attr "type" "icmp")
668    (set_attr "mode" "QI")])
670 (define_insn "*cmpqi_ext_1_rex64"
671   [(set (reg FLAGS_REG)
672         (compare
673           (match_operand:QI 0 "register_operand" "Q")
674           (subreg:QI
675             (zero_extract:SI
676               (match_operand 1 "ext_register_operand" "Q")
677               (const_int 8)
678               (const_int 8)) 0)))]
679   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
680   "cmp{b}\t{%h1, %0|%0, %h1}"
681   [(set_attr "type" "icmp")
682    (set_attr "mode" "QI")])
684 (define_insn "*cmpqi_ext_2"
685   [(set (reg FLAGS_REG)
686         (compare
687           (subreg:QI
688             (zero_extract:SI
689               (match_operand 0 "ext_register_operand" "Q")
690               (const_int 8)
691               (const_int 8)) 0)
692           (match_operand:QI 1 "const0_operand" "n")))]
693   "ix86_match_ccmode (insn, CCNOmode)"
694   "test{b}\t%h0, %h0"
695   [(set_attr "type" "test")
696    (set_attr "length_immediate" "0")
697    (set_attr "mode" "QI")])
699 (define_expand "cmpqi_ext_3"
700   [(set (reg:CC FLAGS_REG)
701         (compare:CC
702           (subreg:QI
703             (zero_extract:SI
704               (match_operand 0 "ext_register_operand" "")
705               (const_int 8)
706               (const_int 8)) 0)
707           (match_operand:QI 1 "general_operand" "")))]
708   ""
709   "")
711 (define_insn "cmpqi_ext_3_insn"
712   [(set (reg FLAGS_REG)
713         (compare
714           (subreg:QI
715             (zero_extract:SI
716               (match_operand 0 "ext_register_operand" "Q")
717               (const_int 8)
718               (const_int 8)) 0)
719           (match_operand:QI 1 "general_operand" "Qmn")))]
720   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721   "cmp{b}\t{%1, %h0|%h0, %1}"
722   [(set_attr "type" "icmp")
723    (set_attr "mode" "QI")])
725 (define_insn "cmpqi_ext_3_insn_rex64"
726   [(set (reg FLAGS_REG)
727         (compare
728           (subreg:QI
729             (zero_extract:SI
730               (match_operand 0 "ext_register_operand" "Q")
731               (const_int 8)
732               (const_int 8)) 0)
733           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
734   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735   "cmp{b}\t{%1, %h0|%h0, %1}"
736   [(set_attr "type" "icmp")
737    (set_attr "mode" "QI")])
739 (define_insn "*cmpqi_ext_4"
740   [(set (reg FLAGS_REG)
741         (compare
742           (subreg:QI
743             (zero_extract:SI
744               (match_operand 0 "ext_register_operand" "Q")
745               (const_int 8)
746               (const_int 8)) 0)
747           (subreg:QI
748             (zero_extract:SI
749               (match_operand 1 "ext_register_operand" "Q")
750               (const_int 8)
751               (const_int 8)) 0)))]
752   "ix86_match_ccmode (insn, CCmode)"
753   "cmp{b}\t{%h1, %h0|%h0, %h1}"
754   [(set_attr "type" "icmp")
755    (set_attr "mode" "QI")])
757 ;; These implement float point compares.
758 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
759 ;; which would allow mix and match FP modes on the compares.  Which is what
760 ;; the old patterns did, but with many more of them.
762 (define_expand "cmpxf"
763   [(set (reg:CC FLAGS_REG)
764         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
765                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
766   "TARGET_80387"
768   ix86_compare_op0 = operands[0];
769   ix86_compare_op1 = operands[1];
770   DONE;
773 (define_expand "cmpdf"
774   [(set (reg:CC FLAGS_REG)
775         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
776                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
777   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
779   ix86_compare_op0 = operands[0];
780   ix86_compare_op1 = operands[1];
781   DONE;
784 (define_expand "cmpsf"
785   [(set (reg:CC FLAGS_REG)
786         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
787                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
788   "TARGET_80387 || TARGET_SSE_MATH"
790   ix86_compare_op0 = operands[0];
791   ix86_compare_op1 = operands[1];
792   DONE;
795 ;; FP compares, step 1:
796 ;; Set the FP condition codes.
798 ;; CCFPmode     compare with exceptions
799 ;; CCFPUmode    compare with no exceptions
801 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
802 ;; used to manage the reg stack popping would not be preserved.
804 (define_insn "*cmpfp_0_sf"
805   [(set (match_operand:HI 0 "register_operand" "=a")
806         (unspec:HI
807           [(compare:CCFP
808              (match_operand:SF 1 "register_operand" "f")
809              (match_operand:SF 2 "const0_operand" "X"))]
810         UNSPEC_FNSTSW))]
811   "TARGET_80387"
812   "* return output_fp_compare (insn, operands, 0, 0);"
813   [(set_attr "type" "multi")
814    (set_attr "mode" "SF")])
816 (define_insn "*cmpfp_0_df"
817   [(set (match_operand:HI 0 "register_operand" "=a")
818         (unspec:HI
819           [(compare:CCFP
820              (match_operand:DF 1 "register_operand" "f")
821              (match_operand:DF 2 "const0_operand" "X"))]
822         UNSPEC_FNSTSW))]
823   "TARGET_80387"
824   "* return output_fp_compare (insn, operands, 0, 0);"
825   [(set_attr "type" "multi")
826    (set_attr "mode" "DF")])
828 (define_insn "*cmpfp_0_xf"
829   [(set (match_operand:HI 0 "register_operand" "=a")
830         (unspec:HI
831           [(compare:CCFP
832              (match_operand:XF 1 "register_operand" "f")
833              (match_operand:XF 2 "const0_operand" "X"))]
834         UNSPEC_FNSTSW))]
835   "TARGET_80387"
836   "* return output_fp_compare (insn, operands, 0, 0);"
837   [(set_attr "type" "multi")
838    (set_attr "mode" "XF")])
840 (define_insn "*cmpfp_sf"
841   [(set (match_operand:HI 0 "register_operand" "=a")
842         (unspec:HI
843           [(compare:CCFP
844              (match_operand:SF 1 "register_operand" "f")
845              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
846           UNSPEC_FNSTSW))]
847   "TARGET_80387"
848   "* return output_fp_compare (insn, operands, 0, 0);"
849   [(set_attr "type" "multi")
850    (set_attr "mode" "SF")])
852 (define_insn "*cmpfp_df"
853   [(set (match_operand:HI 0 "register_operand" "=a")
854         (unspec:HI
855           [(compare:CCFP
856              (match_operand:DF 1 "register_operand" "f")
857              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
858           UNSPEC_FNSTSW))]
859   "TARGET_80387"
860   "* return output_fp_compare (insn, operands, 0, 0);"
861   [(set_attr "type" "multi")
862    (set_attr "mode" "DF")])
864 (define_insn "*cmpfp_xf"
865   [(set (match_operand:HI 0 "register_operand" "=a")
866         (unspec:HI
867           [(compare:CCFP
868              (match_operand:XF 1 "register_operand" "f")
869              (match_operand:XF 2 "register_operand" "f"))]
870           UNSPEC_FNSTSW))]
871   "TARGET_80387"
872   "* return output_fp_compare (insn, operands, 0, 0);"
873   [(set_attr "type" "multi")
874    (set_attr "mode" "XF")])
876 (define_insn "*cmpfp_u"
877   [(set (match_operand:HI 0 "register_operand" "=a")
878         (unspec:HI
879           [(compare:CCFPU
880              (match_operand 1 "register_operand" "f")
881              (match_operand 2 "register_operand" "f"))]
882           UNSPEC_FNSTSW))]
883   "TARGET_80387
884    && FLOAT_MODE_P (GET_MODE (operands[1]))
885    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
886   "* return output_fp_compare (insn, operands, 0, 1);"
887   [(set_attr "type" "multi")
888    (set (attr "mode")
889      (cond [(match_operand:SF 1 "" "")
890               (const_string "SF")
891             (match_operand:DF 1 "" "")
892               (const_string "DF")
893            ]
894            (const_string "XF")))])
896 (define_insn "*cmpfp_si"
897   [(set (match_operand:HI 0 "register_operand" "=a")
898         (unspec:HI
899           [(compare:CCFP
900              (match_operand 1 "register_operand" "f")
901              (match_operator 3 "float_operator"
902                [(match_operand:SI 2 "memory_operand" "m")]))]
903           UNSPEC_FNSTSW))]
904   "TARGET_80387 && TARGET_USE_FIOP
905    && FLOAT_MODE_P (GET_MODE (operands[1]))
906    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
907   "* return output_fp_compare (insn, operands, 0, 0);"
908   [(set_attr "type" "multi")
909    (set_attr "fp_int_src" "true")
910    (set_attr "mode" "SI")])
912 ;; FP compares, step 2
913 ;; Move the fpsw to ax.
915 (define_insn "x86_fnstsw_1"
916   [(set (match_operand:HI 0 "register_operand" "=a")
917         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
918   "TARGET_80387"
919   "fnstsw\t%0"
920   [(set_attr "length" "2")
921    (set_attr "mode" "SI")
922    (set_attr "unit" "i387")])
924 ;; FP compares, step 3
925 ;; Get ax into flags, general case.
927 (define_insn "x86_sahf_1"
928   [(set (reg:CC FLAGS_REG)
929         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
930   "!TARGET_64BIT"
931   "sahf"
932   [(set_attr "length" "1")
933    (set_attr "athlon_decode" "vector")
934    (set_attr "mode" "SI")])
936 ;; Pentium Pro can do steps 1 through 3 in one go.
938 (define_insn "*cmpfp_i_mixed"
939   [(set (reg:CCFP FLAGS_REG)
940         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
941                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
942   "TARGET_MIX_SSE_I387
943    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp,ssecomi")
947    (set (attr "mode")
948      (if_then_else (match_operand:SF 1 "" "")
949         (const_string "SF")
950         (const_string "DF")))
951    (set_attr "athlon_decode" "vector")])
953 (define_insn "*cmpfp_i_sse"
954   [(set (reg:CCFP FLAGS_REG)
955         (compare:CCFP (match_operand 0 "register_operand" "x")
956                       (match_operand 1 "nonimmediate_operand" "xm")))]
957   "TARGET_SSE_MATH
958    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
959    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
960   "* return output_fp_compare (insn, operands, 1, 0);"
961   [(set_attr "type" "ssecomi")
962    (set (attr "mode")
963      (if_then_else (match_operand:SF 1 "" "")
964         (const_string "SF")
965         (const_string "DF")))
966    (set_attr "athlon_decode" "vector")])
968 (define_insn "*cmpfp_i_i387"
969   [(set (reg:CCFP FLAGS_REG)
970         (compare:CCFP (match_operand 0 "register_operand" "f")
971                       (match_operand 1 "register_operand" "f")))]
972   "TARGET_80387 && TARGET_CMOVE
973    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
974    && FLOAT_MODE_P (GET_MODE (operands[0]))
975    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976   "* return output_fp_compare (insn, operands, 1, 0);"
977   [(set_attr "type" "fcmp")
978    (set (attr "mode")
979      (cond [(match_operand:SF 1 "" "")
980               (const_string "SF")
981             (match_operand:DF 1 "" "")
982               (const_string "DF")
983            ]
984            (const_string "XF")))
985    (set_attr "athlon_decode" "vector")])
987 (define_insn "*cmpfp_iu_mixed"
988   [(set (reg:CCFPU FLAGS_REG)
989         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
990                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
991   "TARGET_MIX_SSE_I387
992    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
993    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
994   "* return output_fp_compare (insn, operands, 1, 1);"
995   [(set_attr "type" "fcmp,ssecomi")
996    (set (attr "mode")
997      (if_then_else (match_operand:SF 1 "" "")
998         (const_string "SF")
999         (const_string "DF")))
1000    (set_attr "athlon_decode" "vector")])
1002 (define_insn "*cmpfp_iu_sse"
1003   [(set (reg:CCFPU FLAGS_REG)
1004         (compare:CCFPU (match_operand 0 "register_operand" "x")
1005                        (match_operand 1 "nonimmediate_operand" "xm")))]
1006   "TARGET_SSE_MATH
1007    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1008    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1009   "* return output_fp_compare (insn, operands, 1, 1);"
1010   [(set_attr "type" "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_iu_387"
1018   [(set (reg:CCFPU FLAGS_REG)
1019         (compare:CCFPU (match_operand 0 "register_operand" "f")
1020                        (match_operand 1 "register_operand" "f")))]
1021   "TARGET_80387 && TARGET_CMOVE
1022    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1023    && FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "fcmp")
1027    (set (attr "mode")
1028      (cond [(match_operand:SF 1 "" "")
1029               (const_string "SF")
1030             (match_operand:DF 1 "" "")
1031               (const_string "DF")
1032            ]
1033            (const_string "XF")))
1034    (set_attr "athlon_decode" "vector")])
1036 ;; Move instructions.
1038 ;; General case of fullword move.
1040 (define_expand "movsi"
1041   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1042         (match_operand:SI 1 "general_operand" ""))]
1043   ""
1044   "ix86_expand_move (SImode, operands); DONE;")
1046 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1047 ;; general_operand.
1049 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1050 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1051 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1052 ;; targets without our curiosities, and it is just as easy to represent
1053 ;; this differently.
1055 (define_insn "*pushsi2"
1056   [(set (match_operand:SI 0 "push_operand" "=<")
1057         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1058   "!TARGET_64BIT"
1059   "push{l}\t%1"
1060   [(set_attr "type" "push")
1061    (set_attr "mode" "SI")])
1063 ;; For 64BIT abi we always round up to 8 bytes.
1064 (define_insn "*pushsi2_rex64"
1065   [(set (match_operand:SI 0 "push_operand" "=X")
1066         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1067   "TARGET_64BIT"
1068   "push{q}\t%q1"
1069   [(set_attr "type" "push")
1070    (set_attr "mode" "SI")])
1072 (define_insn "*pushsi2_prologue"
1073   [(set (match_operand:SI 0 "push_operand" "=<")
1074         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1075    (clobber (mem:BLK (scratch)))]
1076   "!TARGET_64BIT"
1077   "push{l}\t%1"
1078   [(set_attr "type" "push")
1079    (set_attr "mode" "SI")])
1081 (define_insn "*popsi1_epilogue"
1082   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1083         (mem:SI (reg:SI SP_REG)))
1084    (set (reg:SI SP_REG)
1085         (plus:SI (reg:SI SP_REG) (const_int 4)))
1086    (clobber (mem:BLK (scratch)))]
1087   "!TARGET_64BIT"
1088   "pop{l}\t%0"
1089   [(set_attr "type" "pop")
1090    (set_attr "mode" "SI")])
1092 (define_insn "popsi1"
1093   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1094         (mem:SI (reg:SI SP_REG)))
1095    (set (reg:SI SP_REG)
1096         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1097   "!TARGET_64BIT"
1098   "pop{l}\t%0"
1099   [(set_attr "type" "pop")
1100    (set_attr "mode" "SI")])
1102 (define_insn "*movsi_xor"
1103   [(set (match_operand:SI 0 "register_operand" "=r")
1104         (match_operand:SI 1 "const0_operand" "i"))
1105    (clobber (reg:CC FLAGS_REG))]
1106   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1107   "xor{l}\t{%0, %0|%0, %0}"
1108   [(set_attr "type" "alu1")
1109    (set_attr "mode" "SI")
1110    (set_attr "length_immediate" "0")])
1112 (define_insn "*movsi_or"
1113   [(set (match_operand:SI 0 "register_operand" "=r")
1114         (match_operand:SI 1 "immediate_operand" "i"))
1115    (clobber (reg:CC FLAGS_REG))]
1116   "reload_completed
1117    && operands[1] == constm1_rtx
1118    && (TARGET_PENTIUM || optimize_size)"
1120   operands[1] = constm1_rtx;
1121   return "or{l}\t{%1, %0|%0, %1}";
1123   [(set_attr "type" "alu1")
1124    (set_attr "mode" "SI")
1125    (set_attr "length_immediate" "1")])
1127 (define_insn "*movsi_1"
1128   [(set (match_operand:SI 0 "nonimmediate_operand"
1129                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1130         (match_operand:SI 1 "general_operand"
1131                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1132   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1134   switch (get_attr_type (insn))
1135     {
1136     case TYPE_SSELOG1:
1137       if (get_attr_mode (insn) == MODE_TI)
1138         return "pxor\t%0, %0";
1139       return "xorps\t%0, %0";
1141     case TYPE_SSEMOV:
1142       switch (get_attr_mode (insn))
1143         {
1144         case MODE_TI:
1145           return "movdqa\t{%1, %0|%0, %1}";
1146         case MODE_V4SF:
1147           return "movaps\t{%1, %0|%0, %1}";
1148         case MODE_SI:
1149           return "movd\t{%1, %0|%0, %1}";
1150         case MODE_SF:
1151           return "movss\t{%1, %0|%0, %1}";
1152         default:
1153           gcc_unreachable ();
1154         }
1156     case TYPE_MMXADD:
1157       return "pxor\t%0, %0";
1159     case TYPE_MMXMOV:
1160       if (get_attr_mode (insn) == MODE_DI)
1161         return "movq\t{%1, %0|%0, %1}";
1162       return "movd\t{%1, %0|%0, %1}";
1164     case TYPE_LEA:
1165       return "lea{l}\t{%1, %0|%0, %1}";
1167     default:
1168       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1169         abort();
1170       return "mov{l}\t{%1, %0|%0, %1}";
1171     }
1173   [(set (attr "type")
1174      (cond [(eq_attr "alternative" "2")
1175               (const_string "mmxadd")
1176             (eq_attr "alternative" "3,4,5")
1177               (const_string "mmxmov")
1178             (eq_attr "alternative" "6")
1179               (const_string "sselog1")
1180             (eq_attr "alternative" "7,8,9,10,11")
1181               (const_string "ssemov")
1182             (and (ne (symbol_ref "flag_pic") (const_int 0))
1183                  (match_operand:SI 1 "symbolic_operand" ""))
1184               (const_string "lea")
1185            ]
1186            (const_string "imov")))
1187    (set (attr "mode")
1188      (cond [(eq_attr "alternative" "2,3")
1189               (const_string "DI")
1190             (eq_attr "alternative" "6,7")
1191               (if_then_else
1192                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1193                 (const_string "V4SF")
1194                 (const_string "TI"))
1195             (and (eq_attr "alternative" "8,9,10,11")
1196                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1197               (const_string "SF")
1198            ]
1199            (const_string "SI")))])
1201 ;; Stores and loads of ax to arbitrary constant address.
1202 ;; We fake an second form of instruction to force reload to load address
1203 ;; into register when rax is not available
1204 (define_insn "*movabssi_1_rex64"
1205   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1206         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1207   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1208   "@
1209    movabs{l}\t{%1, %P0|%P0, %1}
1210    mov{l}\t{%1, %a0|%a0, %1}"
1211   [(set_attr "type" "imov")
1212    (set_attr "modrm" "0,*")
1213    (set_attr "length_address" "8,0")
1214    (set_attr "length_immediate" "0,*")
1215    (set_attr "memory" "store")
1216    (set_attr "mode" "SI")])
1218 (define_insn "*movabssi_2_rex64"
1219   [(set (match_operand:SI 0 "register_operand" "=a,r")
1220         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1221   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1222   "@
1223    movabs{l}\t{%P1, %0|%0, %P1}
1224    mov{l}\t{%a1, %0|%0, %a1}"
1225   [(set_attr "type" "imov")
1226    (set_attr "modrm" "0,*")
1227    (set_attr "length_address" "8,0")
1228    (set_attr "length_immediate" "0")
1229    (set_attr "memory" "load")
1230    (set_attr "mode" "SI")])
1232 (define_insn "*swapsi"
1233   [(set (match_operand:SI 0 "register_operand" "+r")
1234         (match_operand:SI 1 "register_operand" "+r"))
1235    (set (match_dup 1)
1236         (match_dup 0))]
1237   ""
1238   "xchg{l}\t%1, %0"
1239   [(set_attr "type" "imov")
1240    (set_attr "mode" "SI")
1241    (set_attr "pent_pair" "np")
1242    (set_attr "athlon_decode" "vector")])
1244 (define_expand "movhi"
1245   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1246         (match_operand:HI 1 "general_operand" ""))]
1247   ""
1248   "ix86_expand_move (HImode, operands); DONE;")
1250 (define_insn "*pushhi2"
1251   [(set (match_operand:HI 0 "push_operand" "=<,<")
1252         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1253   "!TARGET_64BIT"
1254   "@
1255    push{w}\t{|WORD PTR }%1
1256    push{w}\t%1"
1257   [(set_attr "type" "push")
1258    (set_attr "mode" "HI")])
1260 ;; For 64BIT abi we always round up to 8 bytes.
1261 (define_insn "*pushhi2_rex64"
1262   [(set (match_operand:HI 0 "push_operand" "=X")
1263         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1264   "TARGET_64BIT"
1265   "push{q}\t%q1"
1266   [(set_attr "type" "push")
1267    (set_attr "mode" "QI")])
1269 (define_insn "*movhi_1"
1270   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1271         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1272   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1274   switch (get_attr_type (insn))
1275     {
1276     case TYPE_IMOVX:
1277       /* movzwl is faster than movw on p2 due to partial word stalls,
1278          though not as fast as an aligned movl.  */
1279       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1280     default:
1281       if (get_attr_mode (insn) == MODE_SI)
1282         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1283       else
1284         return "mov{w}\t{%1, %0|%0, %1}";
1285     }
1287   [(set (attr "type")
1288      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1289               (const_string "imov")
1290             (and (eq_attr "alternative" "0")
1291                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1292                           (const_int 0))
1293                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1294                           (const_int 0))))
1295               (const_string "imov")
1296             (and (eq_attr "alternative" "1,2")
1297                  (match_operand:HI 1 "aligned_operand" ""))
1298               (const_string "imov")
1299             (and (ne (symbol_ref "TARGET_MOVX")
1300                      (const_int 0))
1301                  (eq_attr "alternative" "0,2"))
1302               (const_string "imovx")
1303            ]
1304            (const_string "imov")))
1305     (set (attr "mode")
1306       (cond [(eq_attr "type" "imovx")
1307                (const_string "SI")
1308              (and (eq_attr "alternative" "1,2")
1309                   (match_operand:HI 1 "aligned_operand" ""))
1310                (const_string "SI")
1311              (and (eq_attr "alternative" "0")
1312                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1313                            (const_int 0))
1314                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1315                            (const_int 0))))
1316                (const_string "SI")
1317             ]
1318             (const_string "HI")))])
1320 ;; Stores and loads of ax to arbitrary constant address.
1321 ;; We fake an second form of instruction to force reload to load address
1322 ;; into register when rax is not available
1323 (define_insn "*movabshi_1_rex64"
1324   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1325         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1326   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1327   "@
1328    movabs{w}\t{%1, %P0|%P0, %1}
1329    mov{w}\t{%1, %a0|%a0, %1}"
1330   [(set_attr "type" "imov")
1331    (set_attr "modrm" "0,*")
1332    (set_attr "length_address" "8,0")
1333    (set_attr "length_immediate" "0,*")
1334    (set_attr "memory" "store")
1335    (set_attr "mode" "HI")])
1337 (define_insn "*movabshi_2_rex64"
1338   [(set (match_operand:HI 0 "register_operand" "=a,r")
1339         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1340   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1341   "@
1342    movabs{w}\t{%P1, %0|%0, %P1}
1343    mov{w}\t{%a1, %0|%0, %a1}"
1344   [(set_attr "type" "imov")
1345    (set_attr "modrm" "0,*")
1346    (set_attr "length_address" "8,0")
1347    (set_attr "length_immediate" "0")
1348    (set_attr "memory" "load")
1349    (set_attr "mode" "HI")])
1351 (define_insn "*swaphi_1"
1352   [(set (match_operand:HI 0 "register_operand" "+r")
1353         (match_operand:HI 1 "register_operand" "+r"))
1354    (set (match_dup 1)
1355         (match_dup 0))]
1356   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1357   "xchg{l}\t%k1, %k0"
1358   [(set_attr "type" "imov")
1359    (set_attr "mode" "SI")
1360    (set_attr "pent_pair" "np")
1361    (set_attr "athlon_decode" "vector")])
1363 (define_insn "*swaphi_2"
1364   [(set (match_operand:HI 0 "register_operand" "+r")
1365         (match_operand:HI 1 "register_operand" "+r"))
1366    (set (match_dup 1)
1367         (match_dup 0))]
1368   "TARGET_PARTIAL_REG_STALL"
1369   "xchg{w}\t%1, %0"
1370   [(set_attr "type" "imov")
1371    (set_attr "mode" "HI")
1372    (set_attr "pent_pair" "np")
1373    (set_attr "athlon_decode" "vector")])
1375 (define_expand "movstricthi"
1376   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1377         (match_operand:HI 1 "general_operand" ""))]
1378   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1380   /* Don't generate memory->memory moves, go through a register */
1381   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1382     operands[1] = force_reg (HImode, operands[1]);
1385 (define_insn "*movstricthi_1"
1386   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1387         (match_operand:HI 1 "general_operand" "rn,m"))]
1388   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1389    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1390   "mov{w}\t{%1, %0|%0, %1}"
1391   [(set_attr "type" "imov")
1392    (set_attr "mode" "HI")])
1394 (define_insn "*movstricthi_xor"
1395   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1396         (match_operand:HI 1 "const0_operand" "i"))
1397    (clobber (reg:CC FLAGS_REG))]
1398   "reload_completed
1399    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1400   "xor{w}\t{%0, %0|%0, %0}"
1401   [(set_attr "type" "alu1")
1402    (set_attr "mode" "HI")
1403    (set_attr "length_immediate" "0")])
1405 (define_expand "movqi"
1406   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1407         (match_operand:QI 1 "general_operand" ""))]
1408   ""
1409   "ix86_expand_move (QImode, operands); DONE;")
1411 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1412 ;; "push a byte".  But actually we use pushw, which has the effect
1413 ;; of rounding the amount pushed up to a halfword.
1415 (define_insn "*pushqi2"
1416   [(set (match_operand:QI 0 "push_operand" "=X,X")
1417         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1418   "!TARGET_64BIT"
1419   "@
1420    push{w}\t{|word ptr }%1
1421    push{w}\t%w1"
1422   [(set_attr "type" "push")
1423    (set_attr "mode" "HI")])
1425 ;; For 64BIT abi we always round up to 8 bytes.
1426 (define_insn "*pushqi2_rex64"
1427   [(set (match_operand:QI 0 "push_operand" "=X")
1428         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1429   "TARGET_64BIT"
1430   "push{q}\t%q1"
1431   [(set_attr "type" "push")
1432    (set_attr "mode" "QI")])
1434 ;; Situation is quite tricky about when to choose full sized (SImode) move
1435 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1436 ;; partial register dependency machines (such as AMD Athlon), where QImode
1437 ;; moves issue extra dependency and for partial register stalls machines
1438 ;; that don't use QImode patterns (and QImode move cause stall on the next
1439 ;; instruction).
1441 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1442 ;; register stall machines with, where we use QImode instructions, since
1443 ;; partial register stall can be caused there.  Then we use movzx.
1444 (define_insn "*movqi_1"
1445   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1446         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1447   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1449   switch (get_attr_type (insn))
1450     {
1451     case TYPE_IMOVX:
1452       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1453         abort ();
1454       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1455     default:
1456       if (get_attr_mode (insn) == MODE_SI)
1457         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1458       else
1459         return "mov{b}\t{%1, %0|%0, %1}";
1460     }
1462   [(set (attr "type")
1463      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1464               (const_string "imov")
1465             (and (eq_attr "alternative" "3")
1466                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1467                           (const_int 0))
1468                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1469                           (const_int 0))))
1470               (const_string "imov")
1471             (eq_attr "alternative" "3,5")
1472               (const_string "imovx")
1473             (and (ne (symbol_ref "TARGET_MOVX")
1474                      (const_int 0))
1475                  (eq_attr "alternative" "2"))
1476               (const_string "imovx")
1477            ]
1478            (const_string "imov")))
1479    (set (attr "mode")
1480       (cond [(eq_attr "alternative" "3,4,5")
1481                (const_string "SI")
1482              (eq_attr "alternative" "6")
1483                (const_string "QI")
1484              (eq_attr "type" "imovx")
1485                (const_string "SI")
1486              (and (eq_attr "type" "imov")
1487                   (and (eq_attr "alternative" "0,1")
1488                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1489                            (const_int 0))))
1490                (const_string "SI")
1491              ;; Avoid partial register stalls when not using QImode arithmetic
1492              (and (eq_attr "type" "imov")
1493                   (and (eq_attr "alternative" "0,1")
1494                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1495                                 (const_int 0))
1496                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1497                                 (const_int 0)))))
1498                (const_string "SI")
1499            ]
1500            (const_string "QI")))])
1502 (define_expand "reload_outqi"
1503   [(parallel [(match_operand:QI 0 "" "=m")
1504               (match_operand:QI 1 "register_operand" "r")
1505               (match_operand:QI 2 "register_operand" "=&q")])]
1506   ""
1508   rtx op0, op1, op2;
1509   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1511   if (reg_overlap_mentioned_p (op2, op0))
1512     abort ();
1513   if (! q_regs_operand (op1, QImode))
1514     {
1515       emit_insn (gen_movqi (op2, op1));
1516       op1 = op2;
1517     }
1518   emit_insn (gen_movqi (op0, op1));
1519   DONE;
1522 (define_insn "*swapqi_1"
1523   [(set (match_operand:QI 0 "register_operand" "+r")
1524         (match_operand:QI 1 "register_operand" "+r"))
1525    (set (match_dup 1)
1526         (match_dup 0))]
1527   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1528   "xchg{l}\t%k1, %k0"
1529   [(set_attr "type" "imov")
1530    (set_attr "mode" "SI")
1531    (set_attr "pent_pair" "np")
1532    (set_attr "athlon_decode" "vector")])
1534 (define_insn "*swapqi_2"
1535   [(set (match_operand:QI 0 "register_operand" "+q")
1536         (match_operand:QI 1 "register_operand" "+q"))
1537    (set (match_dup 1)
1538         (match_dup 0))]
1539   "TARGET_PARTIAL_REG_STALL"
1540   "xchg{b}\t%1, %0"
1541   [(set_attr "type" "imov")
1542    (set_attr "mode" "QI")
1543    (set_attr "pent_pair" "np")
1544    (set_attr "athlon_decode" "vector")])
1546 (define_expand "movstrictqi"
1547   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1548         (match_operand:QI 1 "general_operand" ""))]
1549   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1551   /* Don't generate memory->memory moves, go through a register.  */
1552   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1553     operands[1] = force_reg (QImode, operands[1]);
1556 (define_insn "*movstrictqi_1"
1557   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1558         (match_operand:QI 1 "general_operand" "*qn,m"))]
1559   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1560    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1561   "mov{b}\t{%1, %0|%0, %1}"
1562   [(set_attr "type" "imov")
1563    (set_attr "mode" "QI")])
1565 (define_insn "*movstrictqi_xor"
1566   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1567         (match_operand:QI 1 "const0_operand" "i"))
1568    (clobber (reg:CC FLAGS_REG))]
1569   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1570   "xor{b}\t{%0, %0|%0, %0}"
1571   [(set_attr "type" "alu1")
1572    (set_attr "mode" "QI")
1573    (set_attr "length_immediate" "0")])
1575 (define_insn "*movsi_extv_1"
1576   [(set (match_operand:SI 0 "register_operand" "=R")
1577         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1578                          (const_int 8)
1579                          (const_int 8)))]
1580   ""
1581   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1582   [(set_attr "type" "imovx")
1583    (set_attr "mode" "SI")])
1585 (define_insn "*movhi_extv_1"
1586   [(set (match_operand:HI 0 "register_operand" "=R")
1587         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1588                          (const_int 8)
1589                          (const_int 8)))]
1590   ""
1591   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1592   [(set_attr "type" "imovx")
1593    (set_attr "mode" "SI")])
1595 (define_insn "*movqi_extv_1"
1596   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1597         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1598                          (const_int 8)
1599                          (const_int 8)))]
1600   "!TARGET_64BIT"
1602   switch (get_attr_type (insn))
1603     {
1604     case TYPE_IMOVX:
1605       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1606     default:
1607       return "mov{b}\t{%h1, %0|%0, %h1}";
1608     }
1610   [(set (attr "type")
1611      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1612                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1613                              (ne (symbol_ref "TARGET_MOVX")
1614                                  (const_int 0))))
1615         (const_string "imovx")
1616         (const_string "imov")))
1617    (set (attr "mode")
1618      (if_then_else (eq_attr "type" "imovx")
1619         (const_string "SI")
1620         (const_string "QI")))])
1622 (define_insn "*movqi_extv_1_rex64"
1623   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1624         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1625                          (const_int 8)
1626                          (const_int 8)))]
1627   "TARGET_64BIT"
1629   switch (get_attr_type (insn))
1630     {
1631     case TYPE_IMOVX:
1632       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1633     default:
1634       return "mov{b}\t{%h1, %0|%0, %h1}";
1635     }
1637   [(set (attr "type")
1638      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1639                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1640                              (ne (symbol_ref "TARGET_MOVX")
1641                                  (const_int 0))))
1642         (const_string "imovx")
1643         (const_string "imov")))
1644    (set (attr "mode")
1645      (if_then_else (eq_attr "type" "imovx")
1646         (const_string "SI")
1647         (const_string "QI")))])
1649 ;; Stores and loads of ax to arbitrary constant address.
1650 ;; We fake an second form of instruction to force reload to load address
1651 ;; into register when rax is not available
1652 (define_insn "*movabsqi_1_rex64"
1653   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1654         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1655   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1656   "@
1657    movabs{b}\t{%1, %P0|%P0, %1}
1658    mov{b}\t{%1, %a0|%a0, %1}"
1659   [(set_attr "type" "imov")
1660    (set_attr "modrm" "0,*")
1661    (set_attr "length_address" "8,0")
1662    (set_attr "length_immediate" "0,*")
1663    (set_attr "memory" "store")
1664    (set_attr "mode" "QI")])
1666 (define_insn "*movabsqi_2_rex64"
1667   [(set (match_operand:QI 0 "register_operand" "=a,r")
1668         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1669   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1670   "@
1671    movabs{b}\t{%P1, %0|%0, %P1}
1672    mov{b}\t{%a1, %0|%0, %a1}"
1673   [(set_attr "type" "imov")
1674    (set_attr "modrm" "0,*")
1675    (set_attr "length_address" "8,0")
1676    (set_attr "length_immediate" "0")
1677    (set_attr "memory" "load")
1678    (set_attr "mode" "QI")])
1680 (define_insn "*movsi_extzv_1"
1681   [(set (match_operand:SI 0 "register_operand" "=R")
1682         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1683                          (const_int 8)
1684                          (const_int 8)))]
1685   ""
1686   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1687   [(set_attr "type" "imovx")
1688    (set_attr "mode" "SI")])
1690 (define_insn "*movqi_extzv_2"
1691   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1692         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1693                                     (const_int 8)
1694                                     (const_int 8)) 0))]
1695   "!TARGET_64BIT"
1697   switch (get_attr_type (insn))
1698     {
1699     case TYPE_IMOVX:
1700       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1701     default:
1702       return "mov{b}\t{%h1, %0|%0, %h1}";
1703     }
1705   [(set (attr "type")
1706      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1707                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1708                              (ne (symbol_ref "TARGET_MOVX")
1709                                  (const_int 0))))
1710         (const_string "imovx")
1711         (const_string "imov")))
1712    (set (attr "mode")
1713      (if_then_else (eq_attr "type" "imovx")
1714         (const_string "SI")
1715         (const_string "QI")))])
1717 (define_insn "*movqi_extzv_2_rex64"
1718   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1719         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1720                                     (const_int 8)
1721                                     (const_int 8)) 0))]
1722   "TARGET_64BIT"
1724   switch (get_attr_type (insn))
1725     {
1726     case TYPE_IMOVX:
1727       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1728     default:
1729       return "mov{b}\t{%h1, %0|%0, %h1}";
1730     }
1732   [(set (attr "type")
1733      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1734                         (ne (symbol_ref "TARGET_MOVX")
1735                             (const_int 0)))
1736         (const_string "imovx")
1737         (const_string "imov")))
1738    (set (attr "mode")
1739      (if_then_else (eq_attr "type" "imovx")
1740         (const_string "SI")
1741         (const_string "QI")))])
1743 (define_insn "movsi_insv_1"
1744   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1745                          (const_int 8)
1746                          (const_int 8))
1747         (match_operand:SI 1 "general_operand" "Qmn"))]
1748   "!TARGET_64BIT"
1749   "mov{b}\t{%b1, %h0|%h0, %b1}"
1750   [(set_attr "type" "imov")
1751    (set_attr "mode" "QI")])
1753 (define_insn "movdi_insv_1_rex64"
1754   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1755                          (const_int 8)
1756                          (const_int 8))
1757         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1758   "TARGET_64BIT"
1759   "mov{b}\t{%b1, %h0|%h0, %b1}"
1760   [(set_attr "type" "imov")
1761    (set_attr "mode" "QI")])
1763 (define_insn "*movqi_insv_2"
1764   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1765                          (const_int 8)
1766                          (const_int 8))
1767         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1768                      (const_int 8)))]
1769   ""
1770   "mov{b}\t{%h1, %h0|%h0, %h1}"
1771   [(set_attr "type" "imov")
1772    (set_attr "mode" "QI")])
1774 (define_expand "movdi"
1775   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1776         (match_operand:DI 1 "general_operand" ""))]
1777   ""
1778   "ix86_expand_move (DImode, operands); DONE;")
1780 (define_insn "*pushdi"
1781   [(set (match_operand:DI 0 "push_operand" "=<")
1782         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1783   "!TARGET_64BIT"
1784   "#")
1786 (define_insn "*pushdi2_rex64"
1787   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1788         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1789   "TARGET_64BIT"
1790   "@
1791    push{q}\t%1
1792    #"
1793   [(set_attr "type" "push,multi")
1794    (set_attr "mode" "DI")])
1796 ;; Convert impossible pushes of immediate to existing instructions.
1797 ;; First try to get scratch register and go through it.  In case this
1798 ;; fails, push sign extended lower part first and then overwrite
1799 ;; upper part by 32bit move.
1800 (define_peephole2
1801   [(match_scratch:DI 2 "r")
1802    (set (match_operand:DI 0 "push_operand" "")
1803         (match_operand:DI 1 "immediate_operand" ""))]
1804   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1805    && !x86_64_immediate_operand (operands[1], DImode)"
1806   [(set (match_dup 2) (match_dup 1))
1807    (set (match_dup 0) (match_dup 2))]
1808   "")
1810 ;; We need to define this as both peepholer and splitter for case
1811 ;; peephole2 pass is not run.
1812 ;; "&& 1" is needed to keep it from matching the previous pattern.
1813 (define_peephole2
1814   [(set (match_operand:DI 0 "push_operand" "")
1815         (match_operand:DI 1 "immediate_operand" ""))]
1816   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1817    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1818   [(set (match_dup 0) (match_dup 1))
1819    (set (match_dup 2) (match_dup 3))]
1820   "split_di (operands + 1, 1, operands + 2, operands + 3);
1821    operands[1] = gen_lowpart (DImode, operands[2]);
1822    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1823                                                     GEN_INT (4)));
1824   ")
1826 (define_split
1827   [(set (match_operand:DI 0 "push_operand" "")
1828         (match_operand:DI 1 "immediate_operand" ""))]
1829   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1830    && !symbolic_operand (operands[1], DImode)
1831    && !x86_64_immediate_operand (operands[1], DImode)"
1832   [(set (match_dup 0) (match_dup 1))
1833    (set (match_dup 2) (match_dup 3))]
1834   "split_di (operands + 1, 1, operands + 2, operands + 3);
1835    operands[1] = gen_lowpart (DImode, operands[2]);
1836    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1837                                                     GEN_INT (4)));
1838   ")
1840 (define_insn "*pushdi2_prologue_rex64"
1841   [(set (match_operand:DI 0 "push_operand" "=<")
1842         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1843    (clobber (mem:BLK (scratch)))]
1844   "TARGET_64BIT"
1845   "push{q}\t%1"
1846   [(set_attr "type" "push")
1847    (set_attr "mode" "DI")])
1849 (define_insn "*popdi1_epilogue_rex64"
1850   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1851         (mem:DI (reg:DI SP_REG)))
1852    (set (reg:DI SP_REG)
1853         (plus:DI (reg:DI SP_REG) (const_int 8)))
1854    (clobber (mem:BLK (scratch)))]
1855   "TARGET_64BIT"
1856   "pop{q}\t%0"
1857   [(set_attr "type" "pop")
1858    (set_attr "mode" "DI")])
1860 (define_insn "popdi1"
1861   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1862         (mem:DI (reg:DI SP_REG)))
1863    (set (reg:DI SP_REG)
1864         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1865   "TARGET_64BIT"
1866   "pop{q}\t%0"
1867   [(set_attr "type" "pop")
1868    (set_attr "mode" "DI")])
1870 (define_insn "*movdi_xor_rex64"
1871   [(set (match_operand:DI 0 "register_operand" "=r")
1872         (match_operand:DI 1 "const0_operand" "i"))
1873    (clobber (reg:CC FLAGS_REG))]
1874   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1875    && reload_completed"
1876   "xor{l}\t{%k0, %k0|%k0, %k0}"
1877   [(set_attr "type" "alu1")
1878    (set_attr "mode" "SI")
1879    (set_attr "length_immediate" "0")])
1881 (define_insn "*movdi_or_rex64"
1882   [(set (match_operand:DI 0 "register_operand" "=r")
1883         (match_operand:DI 1 "const_int_operand" "i"))
1884    (clobber (reg:CC FLAGS_REG))]
1885   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1886    && reload_completed
1887    && operands[1] == constm1_rtx"
1889   operands[1] = constm1_rtx;
1890   return "or{q}\t{%1, %0|%0, %1}";
1892   [(set_attr "type" "alu1")
1893    (set_attr "mode" "DI")
1894    (set_attr "length_immediate" "1")])
1896 (define_insn "*movdi_2"
1897   [(set (match_operand:DI 0 "nonimmediate_operand"
1898                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1899         (match_operand:DI 1 "general_operand"
1900                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1901   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1902   "@
1903    #
1904    #
1905    pxor\t%0, %0
1906    movq\t{%1, %0|%0, %1}
1907    movq\t{%1, %0|%0, %1}
1908    pxor\t%0, %0
1909    movq\t{%1, %0|%0, %1}
1910    movdqa\t{%1, %0|%0, %1}
1911    movq\t{%1, %0|%0, %1}
1912    xorps\t%0, %0
1913    movlps\t{%1, %0|%0, %1}
1914    movaps\t{%1, %0|%0, %1}
1915    movlps\t{%1, %0|%0, %1}"
1916   [(set_attr "type" "*,*,mmxadd,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1917    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1919 (define_split
1920   [(set (match_operand:DI 0 "push_operand" "")
1921         (match_operand:DI 1 "general_operand" ""))]
1922   "!TARGET_64BIT && reload_completed
1923    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1924   [(const_int 0)]
1925   "ix86_split_long_move (operands); DONE;")
1927 ;; %%% This multiword shite has got to go.
1928 (define_split
1929   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1930         (match_operand:DI 1 "general_operand" ""))]
1931   "!TARGET_64BIT && reload_completed
1932    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1933    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1934   [(const_int 0)]
1935   "ix86_split_long_move (operands); DONE;")
1937 (define_insn "*movdi_1_rex64"
1938   [(set (match_operand:DI 0 "nonimmediate_operand"
1939                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1940         (match_operand:DI 1 "general_operand"
1941                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1942   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1944   switch (get_attr_type (insn))
1945     {
1946     case TYPE_SSECVT:
1947       if (which_alternative == 13)
1948         return "movq2dq\t{%1, %0|%0, %1}";
1949       else
1950         return "movdq2q\t{%1, %0|%0, %1}";
1951     case TYPE_SSEMOV:
1952       if (get_attr_mode (insn) == MODE_TI)
1953           return "movdqa\t{%1, %0|%0, %1}";
1954       /* FALLTHRU */
1955     case TYPE_MMXMOV:
1956       /* Moves from and into integer register is done using movd opcode with
1957          REX prefix.  */
1958       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1959           return "movd\t{%1, %0|%0, %1}";
1960       return "movq\t{%1, %0|%0, %1}";
1961     case TYPE_SSELOG1:
1962     case TYPE_MMXADD:
1963       return "pxor\t%0, %0";
1964     case TYPE_MULTI:
1965       return "#";
1966     case TYPE_LEA:
1967       return "lea{q}\t{%a1, %0|%0, %a1}";
1968     default:
1969       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1970         abort ();
1971       if (get_attr_mode (insn) == MODE_SI)
1972         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1973       else if (which_alternative == 2)
1974         return "movabs{q}\t{%1, %0|%0, %1}";
1975       else
1976         return "mov{q}\t{%1, %0|%0, %1}";
1977     }
1979   [(set (attr "type")
1980      (cond [(eq_attr "alternative" "5")
1981               (const_string "mmxadd")
1982             (eq_attr "alternative" "6,7,8")
1983               (const_string "mmxmov")
1984             (eq_attr "alternative" "9")
1985               (const_string "sselog1")
1986             (eq_attr "alternative" "10,11,12")
1987               (const_string "ssemov")
1988             (eq_attr "alternative" "13,14")
1989               (const_string "ssecvt")
1990             (eq_attr "alternative" "4")
1991               (const_string "multi")
1992             (and (ne (symbol_ref "flag_pic") (const_int 0))
1993                  (match_operand:DI 1 "symbolic_operand" ""))
1994               (const_string "lea")
1995            ]
1996            (const_string "imov")))
1997    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
1998    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
1999    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2001 ;; Stores and loads of ax to arbitrary constant address.
2002 ;; We fake an second form of instruction to force reload to load address
2003 ;; into register when rax is not available
2004 (define_insn "*movabsdi_1_rex64"
2005   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2006         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2007   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2008   "@
2009    movabs{q}\t{%1, %P0|%P0, %1}
2010    mov{q}\t{%1, %a0|%a0, %1}"
2011   [(set_attr "type" "imov")
2012    (set_attr "modrm" "0,*")
2013    (set_attr "length_address" "8,0")
2014    (set_attr "length_immediate" "0,*")
2015    (set_attr "memory" "store")
2016    (set_attr "mode" "DI")])
2018 (define_insn "*movabsdi_2_rex64"
2019   [(set (match_operand:DI 0 "register_operand" "=a,r")
2020         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2021   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2022   "@
2023    movabs{q}\t{%P1, %0|%0, %P1}
2024    mov{q}\t{%a1, %0|%0, %a1}"
2025   [(set_attr "type" "imov")
2026    (set_attr "modrm" "0,*")
2027    (set_attr "length_address" "8,0")
2028    (set_attr "length_immediate" "0")
2029    (set_attr "memory" "load")
2030    (set_attr "mode" "DI")])
2032 ;; Convert impossible stores of immediate to existing instructions.
2033 ;; First try to get scratch register and go through it.  In case this
2034 ;; fails, move by 32bit parts.
2035 (define_peephole2
2036   [(match_scratch:DI 2 "r")
2037    (set (match_operand:DI 0 "memory_operand" "")
2038         (match_operand:DI 1 "immediate_operand" ""))]
2039   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2040    && !x86_64_immediate_operand (operands[1], DImode)"
2041   [(set (match_dup 2) (match_dup 1))
2042    (set (match_dup 0) (match_dup 2))]
2043   "")
2045 ;; We need to define this as both peepholer and splitter for case
2046 ;; peephole2 pass is not run.
2047 ;; "&& 1" is needed to keep it from matching the previous pattern.
2048 (define_peephole2
2049   [(set (match_operand:DI 0 "memory_operand" "")
2050         (match_operand:DI 1 "immediate_operand" ""))]
2051   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2052    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2053   [(set (match_dup 2) (match_dup 3))
2054    (set (match_dup 4) (match_dup 5))]
2055   "split_di (operands, 2, operands + 2, operands + 4);")
2057 (define_split
2058   [(set (match_operand:DI 0 "memory_operand" "")
2059         (match_operand:DI 1 "immediate_operand" ""))]
2060   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2061    && !symbolic_operand (operands[1], DImode)
2062    && !x86_64_immediate_operand (operands[1], DImode)"
2063   [(set (match_dup 2) (match_dup 3))
2064    (set (match_dup 4) (match_dup 5))]
2065   "split_di (operands, 2, operands + 2, operands + 4);")
2067 (define_insn "*swapdi_rex64"
2068   [(set (match_operand:DI 0 "register_operand" "+r")
2069         (match_operand:DI 1 "register_operand" "+r"))
2070    (set (match_dup 1)
2071         (match_dup 0))]
2072   "TARGET_64BIT"
2073   "xchg{q}\t%1, %0"
2074   [(set_attr "type" "imov")
2075    (set_attr "mode" "DI")
2076    (set_attr "pent_pair" "np")
2077    (set_attr "athlon_decode" "vector")])
2079 (define_expand "movti"
2080   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2081         (match_operand:TI 1 "nonimmediate_operand" ""))]
2082   "TARGET_SSE || TARGET_64BIT"
2084   if (TARGET_64BIT)
2085     ix86_expand_move (TImode, operands);
2086   else
2087     ix86_expand_vector_move (TImode, operands);
2088   DONE;
2091 (define_insn "*movti_internal"
2092   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2093         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2094   "TARGET_SSE && !TARGET_64BIT
2095    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2097   switch (which_alternative)
2098     {
2099     case 0:
2100       if (get_attr_mode (insn) == MODE_V4SF)
2101         return "xorps\t%0, %0";
2102       else
2103         return "pxor\t%0, %0";
2104     case 1:
2105     case 2:
2106       if (get_attr_mode (insn) == MODE_V4SF)
2107         return "movaps\t{%1, %0|%0, %1}";
2108       else
2109         return "movdqa\t{%1, %0|%0, %1}";
2110     default:
2111       abort ();
2112     }
2114   [(set_attr "type" "ssemov,ssemov,ssemov")
2115    (set (attr "mode")
2116         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2117                  (const_string "V4SF")
2119                (eq_attr "alternative" "0,1")
2120                  (if_then_else
2121                    (ne (symbol_ref "optimize_size")
2122                        (const_int 0))
2123                    (const_string "V4SF")
2124                    (const_string "TI"))
2125                (eq_attr "alternative" "2")
2126                  (if_then_else
2127                    (ne (symbol_ref "optimize_size")
2128                        (const_int 0))
2129                    (const_string "V4SF")
2130                    (const_string "TI"))]
2131                (const_string "TI")))])
2133 (define_insn "*movti_rex64"
2134   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2135         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2136   "TARGET_64BIT
2137    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2139   switch (which_alternative)
2140     {
2141     case 0:
2142     case 1:
2143       return "#";
2144     case 2:
2145       if (get_attr_mode (insn) == MODE_V4SF)
2146         return "xorps\t%0, %0";
2147       else
2148         return "pxor\t%0, %0";
2149     case 3:
2150     case 4:
2151       if (get_attr_mode (insn) == MODE_V4SF)
2152         return "movaps\t{%1, %0|%0, %1}";
2153       else
2154         return "movdqa\t{%1, %0|%0, %1}";
2155     default:
2156       abort ();
2157     }
2159   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2160    (set (attr "mode")
2161         (cond [(eq_attr "alternative" "2,3")
2162                  (if_then_else
2163                    (ne (symbol_ref "optimize_size")
2164                        (const_int 0))
2165                    (const_string "V4SF")
2166                    (const_string "TI"))
2167                (eq_attr "alternative" "4")
2168                  (if_then_else
2169                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2170                             (const_int 0))
2171                         (ne (symbol_ref "optimize_size")
2172                             (const_int 0)))
2173                    (const_string "V4SF")
2174                    (const_string "TI"))]
2175                (const_string "DI")))])
2177 (define_split
2178   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2179         (match_operand:TI 1 "general_operand" ""))]
2180   "reload_completed && !SSE_REG_P (operands[0])
2181    && !SSE_REG_P (operands[1])"
2182   [(const_int 0)]
2183   "ix86_split_long_move (operands); DONE;")
2185 (define_expand "movsf"
2186   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2187         (match_operand:SF 1 "general_operand" ""))]
2188   ""
2189   "ix86_expand_move (SFmode, operands); DONE;")
2191 (define_insn "*pushsf"
2192   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2193         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2194   "!TARGET_64BIT"
2196   switch (which_alternative)
2197     {
2198     case 1:
2199       return "push{l}\t%1";
2201     default:
2202       /* This insn should be already split before reg-stack.  */
2203       abort ();
2204     }
2206   [(set_attr "type" "multi,push,multi")
2207    (set_attr "mode" "SF,SI,SF")])
2209 (define_insn "*pushsf_rex64"
2210   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2211         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2212   "TARGET_64BIT"
2214   switch (which_alternative)
2215     {
2216     case 1:
2217       return "push{q}\t%q1";
2219     default:
2220       /* This insn should be already split before reg-stack.  */
2221       abort ();
2222     }
2224   [(set_attr "type" "multi,push,multi")
2225    (set_attr "mode" "SF,DI,SF")])
2227 (define_split
2228   [(set (match_operand:SF 0 "push_operand" "")
2229         (match_operand:SF 1 "memory_operand" ""))]
2230   "reload_completed
2231    && GET_CODE (operands[1]) == MEM
2232    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2233    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2234   [(set (match_dup 0)
2235         (match_dup 1))]
2236   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2239 ;; %%% Kill this when call knows how to work this out.
2240 (define_split
2241   [(set (match_operand:SF 0 "push_operand" "")
2242         (match_operand:SF 1 "any_fp_register_operand" ""))]
2243   "!TARGET_64BIT"
2244   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2245    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2247 (define_split
2248   [(set (match_operand:SF 0 "push_operand" "")
2249         (match_operand:SF 1 "any_fp_register_operand" ""))]
2250   "TARGET_64BIT"
2251   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2252    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2254 (define_insn "*movsf_1"
2255   [(set (match_operand:SF 0 "nonimmediate_operand"
2256           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2257         (match_operand:SF 1 "general_operand"
2258           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2259   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2260    && (reload_in_progress || reload_completed
2261        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2262        || GET_CODE (operands[1]) != CONST_DOUBLE
2263        || memory_operand (operands[0], SFmode))" 
2265   switch (which_alternative)
2266     {
2267     case 0:
2268       return output_387_reg_move (insn, operands);
2270     case 1:
2271       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2272         return "fstp%z0\t%y0";
2273       else
2274         return "fst%z0\t%y0";
2276     case 2:
2277       return standard_80387_constant_opcode (operands[1]);
2279     case 3:
2280     case 4:
2281       return "mov{l}\t{%1, %0|%0, %1}";
2282     case 5:
2283       if (get_attr_mode (insn) == MODE_TI)
2284         return "pxor\t%0, %0";
2285       else
2286         return "xorps\t%0, %0";
2287     case 6:
2288       if (get_attr_mode (insn) == MODE_V4SF)
2289         return "movaps\t{%1, %0|%0, %1}";
2290       else
2291         return "movss\t{%1, %0|%0, %1}";
2292     case 7:
2293     case 8:
2294       return "movss\t{%1, %0|%0, %1}";
2296     case 9:
2297     case 10:
2298       return "movd\t{%1, %0|%0, %1}";
2300     case 11:
2301       return "movq\t{%1, %0|%0, %1}";
2303     default:
2304       abort();
2305     }
2307   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2308    (set (attr "mode")
2309         (cond [(eq_attr "alternative" "3,4,9,10")
2310                  (const_string "SI")
2311                (eq_attr "alternative" "5")
2312                  (if_then_else
2313                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2314                                  (const_int 0))
2315                              (ne (symbol_ref "TARGET_SSE2")
2316                                  (const_int 0)))
2317                         (eq (symbol_ref "optimize_size")
2318                             (const_int 0)))
2319                    (const_string "TI")
2320                    (const_string "V4SF"))
2321                /* For architectures resolving dependencies on
2322                   whole SSE registers use APS move to break dependency
2323                   chains, otherwise use short move to avoid extra work. 
2325                   Do the same for architectures resolving dependencies on
2326                   the parts.  While in DF mode it is better to always handle
2327                   just register parts, the SF mode is different due to lack
2328                   of instructions to load just part of the register.  It is
2329                   better to maintain the whole registers in single format
2330                   to avoid problems on using packed logical operations.  */
2331                (eq_attr "alternative" "6")
2332                  (if_then_else
2333                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2334                             (const_int 0))
2335                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2336                             (const_int 0)))
2337                    (const_string "V4SF")
2338                    (const_string "SF"))
2339                (eq_attr "alternative" "11")
2340                  (const_string "DI")]
2341                (const_string "SF")))])
2343 (define_insn "*swapsf"
2344   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2345         (match_operand:SF 1 "fp_register_operand" "+f"))
2346    (set (match_dup 1)
2347         (match_dup 0))]
2348   "reload_completed || TARGET_80387"
2350   if (STACK_TOP_P (operands[0]))
2351     return "fxch\t%1";
2352   else
2353     return "fxch\t%0";
2355   [(set_attr "type" "fxch")
2356    (set_attr "mode" "SF")])
2358 (define_expand "movdf"
2359   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2360         (match_operand:DF 1 "general_operand" ""))]
2361   ""
2362   "ix86_expand_move (DFmode, operands); DONE;")
2364 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2365 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2366 ;; On the average, pushdf using integers can be still shorter.  Allow this
2367 ;; pattern for optimize_size too.
2369 (define_insn "*pushdf_nointeger"
2370   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2371         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2372   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2374   /* This insn should be already split before reg-stack.  */
2375   abort ();
2377   [(set_attr "type" "multi")
2378    (set_attr "mode" "DF,SI,SI,DF")])
2380 (define_insn "*pushdf_integer"
2381   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2382         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2383   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2385   /* This insn should be already split before reg-stack.  */
2386   abort ();
2388   [(set_attr "type" "multi")
2389    (set_attr "mode" "DF,SI,DF")])
2391 ;; %%% Kill this when call knows how to work this out.
2392 (define_split
2393   [(set (match_operand:DF 0 "push_operand" "")
2394         (match_operand:DF 1 "any_fp_register_operand" ""))]
2395   "!TARGET_64BIT && reload_completed"
2396   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2397    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2398   "")
2400 (define_split
2401   [(set (match_operand:DF 0 "push_operand" "")
2402         (match_operand:DF 1 "any_fp_register_operand" ""))]
2403   "TARGET_64BIT && reload_completed"
2404   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2405    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2406   "")
2408 (define_split
2409   [(set (match_operand:DF 0 "push_operand" "")
2410         (match_operand:DF 1 "general_operand" ""))]
2411   "reload_completed"
2412   [(const_int 0)]
2413   "ix86_split_long_move (operands); DONE;")
2415 ;; Moving is usually shorter when only FP registers are used. This separate
2416 ;; movdf pattern avoids the use of integer registers for FP operations
2417 ;; when optimizing for size.
2419 (define_insn "*movdf_nointeger"
2420   [(set (match_operand:DF 0 "nonimmediate_operand"
2421                         "=f#Y,m  ,f#Y,*r  ,o  ,Y#f*x,Y#f*x,Y#f*x  ,m    ")
2422         (match_operand:DF 1 "general_operand"
2423                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y#f*x,HmY#f*x,Y#f*x"))]
2424   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2425    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2426    && (reload_in_progress || reload_completed
2427        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2428        || GET_CODE (operands[1]) != CONST_DOUBLE
2429        || memory_operand (operands[0], DFmode))" 
2431   switch (which_alternative)
2432     {
2433     case 0:
2434       return output_387_reg_move (insn, operands);
2436     case 1:
2437       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2438         return "fstp%z0\t%y0";
2439       else
2440         return "fst%z0\t%y0";
2442     case 2:
2443       return standard_80387_constant_opcode (operands[1]);
2445     case 3:
2446     case 4:
2447       return "#";
2448     case 5:
2449       switch (get_attr_mode (insn))
2450         {
2451         case MODE_V4SF:
2452           return "xorps\t%0, %0";
2453         case MODE_V2DF:
2454           return "xorpd\t%0, %0";
2455         case MODE_TI:
2456           return "pxor\t%0, %0";
2457         default:
2458           abort ();
2459         }
2460     case 6:
2461     case 7:
2462     case 8:
2463       switch (get_attr_mode (insn))
2464         {
2465         case MODE_V4SF:
2466           return "movaps\t{%1, %0|%0, %1}";
2467         case MODE_V2DF:
2468           return "movapd\t{%1, %0|%0, %1}";
2469         case MODE_TI:
2470           return "movdqa\t{%1, %0|%0, %1}";
2471         case MODE_DI:
2472           return "movq\t{%1, %0|%0, %1}";
2473         case MODE_DF:
2474           return "movsd\t{%1, %0|%0, %1}";
2475         case MODE_V1DF:
2476           return "movlpd\t{%1, %0|%0, %1}";
2477         case MODE_V2SF:
2478           return "movlps\t{%1, %0|%0, %1}";
2479         default:
2480           abort ();
2481         }
2483     default:
2484       abort();
2485     }
2487   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2488    (set (attr "mode")
2489         (cond [(eq_attr "alternative" "0,1,2")
2490                  (const_string "DF")
2491                (eq_attr "alternative" "3,4")
2492                  (const_string "SI")
2494                /* For SSE1, we have many fewer alternatives.  */
2495                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2496                  (cond [(eq_attr "alternative" "5,6")
2497                           (const_string "V4SF")
2498                        ]
2499                    (const_string "V2SF"))
2501                /* xorps is one byte shorter.  */
2502                (eq_attr "alternative" "5")
2503                  (cond [(ne (symbol_ref "optimize_size")
2504                             (const_int 0))
2505                           (const_string "V4SF")
2506                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2507                             (const_int 0))
2508                           (const_string "TI")
2509                        ]
2510                        (const_string "V2DF"))
2512                /* For architectures resolving dependencies on
2513                   whole SSE registers use APD move to break dependency
2514                   chains, otherwise use short move to avoid extra work.
2516                   movaps encodes one byte shorter.  */
2517                (eq_attr "alternative" "6")
2518                  (cond
2519                    [(ne (symbol_ref "optimize_size")
2520                         (const_int 0))
2521                       (const_string "V4SF")
2522                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2523                         (const_int 0))
2524                       (const_string "V2DF")
2525                    ]
2526                    (const_string "DF"))
2527                /* For architectures resolving dependencies on register
2528                   parts we may avoid extra work to zero out upper part
2529                   of register.  */
2530                (eq_attr "alternative" "7")
2531                  (if_then_else
2532                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2533                        (const_int 0))
2534                    (const_string "V1DF")
2535                    (const_string "DF"))
2536               ]
2537               (const_string "DF")))])
2539 (define_insn "*movdf_integer"
2540   [(set (match_operand:DF 0 "nonimmediate_operand"
2541                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y#rf*x,Y#rf*x,Y#rf*x,m")
2542         (match_operand:DF 1 "general_operand"
2543                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y#rf*x,m     ,Y#rf*x"))]
2544   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2545    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2546    && (reload_in_progress || reload_completed
2547        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2548        || GET_CODE (operands[1]) != CONST_DOUBLE
2549        || memory_operand (operands[0], DFmode))" 
2551   switch (which_alternative)
2552     {
2553     case 0:
2554       return output_387_reg_move (insn, operands);
2556     case 1:
2557       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2558         return "fstp%z0\t%y0";
2559       else
2560         return "fst%z0\t%y0";
2562     case 2:
2563       return standard_80387_constant_opcode (operands[1]);
2565     case 3:
2566     case 4:
2567       return "#";
2569     case 5:
2570       switch (get_attr_mode (insn))
2571         {
2572         case MODE_V4SF:
2573           return "xorps\t%0, %0";
2574         case MODE_V2DF:
2575           return "xorpd\t%0, %0";
2576         case MODE_TI:
2577           return "pxor\t%0, %0";
2578         default:
2579           abort ();
2580         }
2581     case 6:
2582     case 7:
2583     case 8:
2584       switch (get_attr_mode (insn))
2585         {
2586         case MODE_V4SF:
2587           return "movaps\t{%1, %0|%0, %1}";
2588         case MODE_V2DF:
2589           return "movapd\t{%1, %0|%0, %1}";
2590         case MODE_TI:
2591           return "movdqa\t{%1, %0|%0, %1}";
2592         case MODE_DI:
2593           return "movq\t{%1, %0|%0, %1}";
2594         case MODE_DF:
2595           return "movsd\t{%1, %0|%0, %1}";
2596         case MODE_V1DF:
2597           return "movlpd\t{%1, %0|%0, %1}";
2598         case MODE_V2SF:
2599           return "movlps\t{%1, %0|%0, %1}";
2600         default:
2601           abort ();
2602         }
2604     default:
2605       abort();
2606     }
2608   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2609    (set (attr "mode")
2610         (cond [(eq_attr "alternative" "0,1,2")
2611                  (const_string "DF")
2612                (eq_attr "alternative" "3,4")
2613                  (const_string "SI")
2615                /* For SSE1, we have many fewer alternatives.  */
2616                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2617                  (cond [(eq_attr "alternative" "5,6")
2618                           (const_string "V4SF")
2619                        ]
2620                    (const_string "V2SF"))
2622                /* xorps is one byte shorter.  */
2623                (eq_attr "alternative" "5")
2624                  (cond [(ne (symbol_ref "optimize_size")
2625                             (const_int 0))
2626                           (const_string "V4SF")
2627                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2628                             (const_int 0))
2629                           (const_string "TI")
2630                        ]
2631                        (const_string "V2DF"))
2633                /* For architectures resolving dependencies on
2634                   whole SSE registers use APD move to break dependency
2635                   chains, otherwise use short move to avoid extra work.
2637                   movaps encodes one byte shorter.  */
2638                (eq_attr "alternative" "6")
2639                  (cond
2640                    [(ne (symbol_ref "optimize_size")
2641                         (const_int 0))
2642                       (const_string "V4SF")
2643                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2644                         (const_int 0))
2645                       (const_string "V2DF")
2646                    ]
2647                    (const_string "DF"))
2648                /* For architectures resolving dependencies on register
2649                   parts we may avoid extra work to zero out upper part
2650                   of register.  */
2651                (eq_attr "alternative" "7")
2652                  (if_then_else
2653                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2654                        (const_int 0))
2655                    (const_string "V1DF")
2656                    (const_string "DF"))
2657               ]
2658               (const_string "DF")))])
2660 (define_split
2661   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2662         (match_operand:DF 1 "general_operand" ""))]
2663   "reload_completed
2664    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2665    && ! (ANY_FP_REG_P (operands[0]) || 
2666          (GET_CODE (operands[0]) == SUBREG
2667           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2668    && ! (ANY_FP_REG_P (operands[1]) || 
2669          (GET_CODE (operands[1]) == SUBREG
2670           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2671   [(const_int 0)]
2672   "ix86_split_long_move (operands); DONE;")
2674 (define_insn "*swapdf"
2675   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2676         (match_operand:DF 1 "fp_register_operand" "+f"))
2677    (set (match_dup 1)
2678         (match_dup 0))]
2679   "reload_completed || TARGET_80387"
2681   if (STACK_TOP_P (operands[0]))
2682     return "fxch\t%1";
2683   else
2684     return "fxch\t%0";
2686   [(set_attr "type" "fxch")
2687    (set_attr "mode" "DF")])
2689 (define_expand "movxf"
2690   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2691         (match_operand:XF 1 "general_operand" ""))]
2692   ""
2693   "ix86_expand_move (XFmode, operands); DONE;")
2695 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2696 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2697 ;; Pushing using integer instructions is longer except for constants
2698 ;; and direct memory references.
2699 ;; (assuming that any given constant is pushed only once, but this ought to be
2700 ;;  handled elsewhere).
2702 (define_insn "*pushxf_nointeger"
2703   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2704         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2705   "optimize_size"
2707   /* This insn should be already split before reg-stack.  */
2708   abort ();
2710   [(set_attr "type" "multi")
2711    (set_attr "mode" "XF,SI,SI")])
2713 (define_insn "*pushxf_integer"
2714   [(set (match_operand:XF 0 "push_operand" "=<,<")
2715         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
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")])
2724 (define_split
2725   [(set (match_operand 0 "push_operand" "")
2726         (match_operand 1 "general_operand" ""))]
2727   "reload_completed
2728    && (GET_MODE (operands[0]) == XFmode
2729        || GET_MODE (operands[0]) == DFmode)
2730    && !ANY_FP_REG_P (operands[1])"
2731   [(const_int 0)]
2732   "ix86_split_long_move (operands); DONE;")
2734 (define_split
2735   [(set (match_operand:XF 0 "push_operand" "")
2736         (match_operand:XF 1 "any_fp_register_operand" ""))]
2737   "!TARGET_64BIT"
2738   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2739    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2740   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2742 (define_split
2743   [(set (match_operand:XF 0 "push_operand" "")
2744         (match_operand:XF 1 "any_fp_register_operand" ""))]
2745   "TARGET_64BIT"
2746   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2747    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2748   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2750 ;; Do not use integer registers when optimizing for size
2751 (define_insn "*movxf_nointeger"
2752   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2753         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2754   "optimize_size
2755    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2756    && (reload_in_progress || reload_completed
2757        || GET_CODE (operands[1]) != CONST_DOUBLE
2758        || memory_operand (operands[0], XFmode))" 
2760   switch (which_alternative)
2761     {
2762     case 0:
2763       return output_387_reg_move (insn, operands);
2765     case 1:
2766       /* There is no non-popping store to memory for XFmode.  So if
2767          we need one, follow the store with a load.  */
2768       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2769         return "fstp%z0\t%y0\;fld%z0\t%y0";
2770       else
2771         return "fstp%z0\t%y0";
2773     case 2:
2774       return standard_80387_constant_opcode (operands[1]);
2776     case 3: case 4:
2777       return "#";
2778     }
2779   abort();
2781   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2782    (set_attr "mode" "XF,XF,XF,SI,SI")])
2784 (define_insn "*movxf_integer"
2785   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2786         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2787   "!optimize_size
2788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789    && (reload_in_progress || reload_completed
2790        || GET_CODE (operands[1]) != CONST_DOUBLE
2791        || memory_operand (operands[0], XFmode))" 
2793   switch (which_alternative)
2794     {
2795     case 0:
2796       return output_387_reg_move (insn, operands);
2798     case 1:
2799       /* There is no non-popping store to memory for XFmode.  So if
2800          we need one, follow the store with a load.  */
2801       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2802         return "fstp%z0\t%y0\;fld%z0\t%y0";
2803       else
2804         return "fstp%z0\t%y0";
2806     case 2:
2807       return standard_80387_constant_opcode (operands[1]);
2809     case 3: case 4:
2810       return "#";
2811     }
2812   abort();
2814   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2815    (set_attr "mode" "XF,XF,XF,SI,SI")])
2817 (define_split
2818   [(set (match_operand 0 "nonimmediate_operand" "")
2819         (match_operand 1 "general_operand" ""))]
2820   "reload_completed
2821    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2822    && GET_MODE (operands[0]) == XFmode
2823    && ! (ANY_FP_REG_P (operands[0]) || 
2824          (GET_CODE (operands[0]) == SUBREG
2825           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2826    && ! (ANY_FP_REG_P (operands[1]) || 
2827          (GET_CODE (operands[1]) == SUBREG
2828           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2829   [(const_int 0)]
2830   "ix86_split_long_move (operands); DONE;")
2832 (define_split
2833   [(set (match_operand 0 "register_operand" "")
2834         (match_operand 1 "memory_operand" ""))]
2835   "reload_completed
2836    && GET_CODE (operands[1]) == MEM
2837    && (GET_MODE (operands[0]) == XFmode
2838        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2839    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2840    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2841   [(set (match_dup 0) (match_dup 1))]
2843   rtx c = get_pool_constant (XEXP (operands[1], 0));
2844   rtx r = operands[0];
2846   if (GET_CODE (r) == SUBREG)
2847     r = SUBREG_REG (r);
2849   if (SSE_REG_P (r))
2850     {
2851       if (!standard_sse_constant_p (c))
2852         FAIL;
2853     }
2854   else if (FP_REG_P (r))
2855     {
2856       if (!standard_80387_constant_p (c))
2857         FAIL;
2858     }
2859   else if (MMX_REG_P (r))
2860     FAIL;
2862   operands[1] = c;
2865 (define_insn "swapxf"
2866   [(set (match_operand:XF 0 "register_operand" "+f")
2867         (match_operand:XF 1 "register_operand" "+f"))
2868    (set (match_dup 1)
2869         (match_dup 0))]
2870   "TARGET_80387"
2872   if (STACK_TOP_P (operands[0]))
2873     return "fxch\t%1";
2874   else
2875     return "fxch\t%0";
2877   [(set_attr "type" "fxch")
2878    (set_attr "mode" "XF")])
2880 (define_expand "movtf"
2881   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2882         (match_operand:TF 1 "nonimmediate_operand" ""))]
2883   "TARGET_64BIT"
2885   ix86_expand_move (TFmode, operands);
2886   DONE;
2889 (define_insn "*movtf_internal"
2890   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2891         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2892   "TARGET_64BIT
2893    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2895   switch (which_alternative)
2896     {
2897     case 0:
2898     case 1:
2899       return "#";
2900     case 2:
2901       if (get_attr_mode (insn) == MODE_V4SF)
2902         return "xorps\t%0, %0";
2903       else
2904         return "pxor\t%0, %0";
2905     case 3:
2906     case 4:
2907       if (get_attr_mode (insn) == MODE_V4SF)
2908         return "movaps\t{%1, %0|%0, %1}";
2909       else
2910         return "movdqa\t{%1, %0|%0, %1}";
2911     default:
2912       abort ();
2913     }
2915   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2916    (set (attr "mode")
2917         (cond [(eq_attr "alternative" "2,3")
2918                  (if_then_else
2919                    (ne (symbol_ref "optimize_size")
2920                        (const_int 0))
2921                    (const_string "V4SF")
2922                    (const_string "TI"))
2923                (eq_attr "alternative" "4")
2924                  (if_then_else
2925                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2926                             (const_int 0))
2927                         (ne (symbol_ref "optimize_size")
2928                             (const_int 0)))
2929                    (const_string "V4SF")
2930                    (const_string "TI"))]
2931                (const_string "DI")))])
2933 (define_split
2934   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2935         (match_operand:TF 1 "general_operand" ""))]
2936   "reload_completed && !SSE_REG_P (operands[0])
2937    && !SSE_REG_P (operands[1])"
2938   [(const_int 0)]
2939   "ix86_split_long_move (operands); DONE;")
2941 ;; Zero extension instructions
2943 (define_expand "zero_extendhisi2"
2944   [(set (match_operand:SI 0 "register_operand" "")
2945      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2946   ""
2948   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2949     {
2950       operands[1] = force_reg (HImode, operands[1]);
2951       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2952       DONE;
2953     }
2956 (define_insn "zero_extendhisi2_and"
2957   [(set (match_operand:SI 0 "register_operand" "=r")
2958      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2959    (clobber (reg:CC FLAGS_REG))]
2960   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2961   "#"
2962   [(set_attr "type" "alu1")
2963    (set_attr "mode" "SI")])
2965 (define_split
2966   [(set (match_operand:SI 0 "register_operand" "")
2967         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2968    (clobber (reg:CC FLAGS_REG))]
2969   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2970   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2971               (clobber (reg:CC FLAGS_REG))])]
2972   "")
2974 (define_insn "*zero_extendhisi2_movzwl"
2975   [(set (match_operand:SI 0 "register_operand" "=r")
2976      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2977   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2978   "movz{wl|x}\t{%1, %0|%0, %1}"
2979   [(set_attr "type" "imovx")
2980    (set_attr "mode" "SI")])
2982 (define_expand "zero_extendqihi2"
2983   [(parallel
2984     [(set (match_operand:HI 0 "register_operand" "")
2985        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2986      (clobber (reg:CC FLAGS_REG))])]
2987   ""
2988   "")
2990 (define_insn "*zero_extendqihi2_and"
2991   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2992      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2993    (clobber (reg:CC FLAGS_REG))]
2994   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2995   "#"
2996   [(set_attr "type" "alu1")
2997    (set_attr "mode" "HI")])
2999 (define_insn "*zero_extendqihi2_movzbw_and"
3000   [(set (match_operand:HI 0 "register_operand" "=r,r")
3001      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3002    (clobber (reg:CC FLAGS_REG))]
3003   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3004   "#"
3005   [(set_attr "type" "imovx,alu1")
3006    (set_attr "mode" "HI")])
3008 (define_insn "*zero_extendqihi2_movzbw"
3009   [(set (match_operand:HI 0 "register_operand" "=r")
3010      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3011   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3012   "movz{bw|x}\t{%1, %0|%0, %1}"
3013   [(set_attr "type" "imovx")
3014    (set_attr "mode" "HI")])
3016 ;; For the movzbw case strip only the clobber
3017 (define_split
3018   [(set (match_operand:HI 0 "register_operand" "")
3019         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3020    (clobber (reg:CC FLAGS_REG))]
3021   "reload_completed 
3022    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3023    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3024   [(set (match_operand:HI 0 "register_operand" "")
3025         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3027 ;; When source and destination does not overlap, clear destination
3028 ;; first and then do the movb
3029 (define_split
3030   [(set (match_operand:HI 0 "register_operand" "")
3031         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3032    (clobber (reg:CC FLAGS_REG))]
3033   "reload_completed
3034    && ANY_QI_REG_P (operands[0])
3035    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3036    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3037   [(set (match_dup 0) (const_int 0))
3038    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3039   "operands[2] = gen_lowpart (QImode, operands[0]);")
3041 ;; Rest is handled by single and.
3042 (define_split
3043   [(set (match_operand:HI 0 "register_operand" "")
3044         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3045    (clobber (reg:CC FLAGS_REG))]
3046   "reload_completed
3047    && true_regnum (operands[0]) == true_regnum (operands[1])"
3048   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3049               (clobber (reg:CC FLAGS_REG))])]
3050   "")
3052 (define_expand "zero_extendqisi2"
3053   [(parallel
3054     [(set (match_operand:SI 0 "register_operand" "")
3055        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3056      (clobber (reg:CC FLAGS_REG))])]
3057   ""
3058   "")
3060 (define_insn "*zero_extendqisi2_and"
3061   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3062      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3063    (clobber (reg:CC FLAGS_REG))]
3064   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3065   "#"
3066   [(set_attr "type" "alu1")
3067    (set_attr "mode" "SI")])
3069 (define_insn "*zero_extendqisi2_movzbw_and"
3070   [(set (match_operand:SI 0 "register_operand" "=r,r")
3071      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3074   "#"
3075   [(set_attr "type" "imovx,alu1")
3076    (set_attr "mode" "SI")])
3078 (define_insn "*zero_extendqisi2_movzbw"
3079   [(set (match_operand:SI 0 "register_operand" "=r")
3080      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3081   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3082   "movz{bl|x}\t{%1, %0|%0, %1}"
3083   [(set_attr "type" "imovx")
3084    (set_attr "mode" "SI")])
3086 ;; For the movzbl case strip only the clobber
3087 (define_split
3088   [(set (match_operand:SI 0 "register_operand" "")
3089         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3090    (clobber (reg:CC FLAGS_REG))]
3091   "reload_completed 
3092    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3093    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3094   [(set (match_dup 0)
3095         (zero_extend:SI (match_dup 1)))])
3097 ;; When source and destination does not overlap, clear destination
3098 ;; first and then do the movb
3099 (define_split
3100   [(set (match_operand:SI 0 "register_operand" "")
3101         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3102    (clobber (reg:CC FLAGS_REG))]
3103   "reload_completed
3104    && ANY_QI_REG_P (operands[0])
3105    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3106    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3107    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3108   [(set (match_dup 0) (const_int 0))
3109    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3110   "operands[2] = gen_lowpart (QImode, operands[0]);")
3112 ;; Rest is handled by single and.
3113 (define_split
3114   [(set (match_operand:SI 0 "register_operand" "")
3115         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3116    (clobber (reg:CC FLAGS_REG))]
3117   "reload_completed
3118    && true_regnum (operands[0]) == true_regnum (operands[1])"
3119   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3120               (clobber (reg:CC FLAGS_REG))])]
3121   "")
3123 ;; %%% Kill me once multi-word ops are sane.
3124 (define_expand "zero_extendsidi2"
3125   [(set (match_operand:DI 0 "register_operand" "=r")
3126      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3127   ""
3128   "if (!TARGET_64BIT)
3129      {
3130        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3131        DONE;
3132      }
3133   ")
3135 (define_insn "zero_extendsidi2_32"
3136   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3137         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3138    (clobber (reg:CC FLAGS_REG))]
3139   "!TARGET_64BIT"
3140   "@
3141    #
3142    #
3143    #
3144    movd\t{%1, %0|%0, %1}
3145    movd\t{%1, %0|%0, %1}"
3146   [(set_attr "mode" "SI,SI,SI,DI,TI")
3147    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3149 (define_insn "zero_extendsidi2_rex64"
3150   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3151      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3152   "TARGET_64BIT"
3153   "@
3154    mov\t{%k1, %k0|%k0, %k1}
3155    #
3156    movd\t{%1, %0|%0, %1}
3157    movd\t{%1, %0|%0, %1}"
3158   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3159    (set_attr "mode" "SI,DI,SI,SI")])
3161 (define_split
3162   [(set (match_operand:DI 0 "memory_operand" "")
3163      (zero_extend:DI (match_dup 0)))]
3164   "TARGET_64BIT"
3165   [(set (match_dup 4) (const_int 0))]
3166   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3168 (define_split 
3169   [(set (match_operand:DI 0 "register_operand" "")
3170         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3171    (clobber (reg:CC FLAGS_REG))]
3172   "!TARGET_64BIT && reload_completed
3173    && true_regnum (operands[0]) == true_regnum (operands[1])"
3174   [(set (match_dup 4) (const_int 0))]
3175   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3177 (define_split 
3178   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3179         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3180    (clobber (reg:CC FLAGS_REG))]
3181   "!TARGET_64BIT && reload_completed
3182    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3183   [(set (match_dup 3) (match_dup 1))
3184    (set (match_dup 4) (const_int 0))]
3185   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3187 (define_insn "zero_extendhidi2"
3188   [(set (match_operand:DI 0 "register_operand" "=r,r")
3189      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3190   "TARGET_64BIT"
3191   "@
3192    movz{wl|x}\t{%1, %k0|%k0, %1}
3193    movz{wq|x}\t{%1, %0|%0, %1}"
3194   [(set_attr "type" "imovx")
3195    (set_attr "mode" "SI,DI")])
3197 (define_insn "zero_extendqidi2"
3198   [(set (match_operand:DI 0 "register_operand" "=r,r")
3199      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3200   "TARGET_64BIT"
3201   "@
3202    movz{bl|x}\t{%1, %k0|%k0, %1}
3203    movz{bq|x}\t{%1, %0|%0, %1}"
3204   [(set_attr "type" "imovx")
3205    (set_attr "mode" "SI,DI")])
3207 ;; Sign extension instructions
3209 (define_expand "extendsidi2"
3210   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3211                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3212               (clobber (reg:CC FLAGS_REG))
3213               (clobber (match_scratch:SI 2 ""))])]
3214   ""
3216   if (TARGET_64BIT)
3217     {
3218       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3219       DONE;
3220     }
3223 (define_insn "*extendsidi2_1"
3224   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3225         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3226    (clobber (reg:CC FLAGS_REG))
3227    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3228   "!TARGET_64BIT"
3229   "#")
3231 (define_insn "extendsidi2_rex64"
3232   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3233         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3234   "TARGET_64BIT"
3235   "@
3236    {cltq|cdqe}
3237    movs{lq|x}\t{%1,%0|%0, %1}"
3238   [(set_attr "type" "imovx")
3239    (set_attr "mode" "DI")
3240    (set_attr "prefix_0f" "0")
3241    (set_attr "modrm" "0,1")])
3243 (define_insn "extendhidi2"
3244   [(set (match_operand:DI 0 "register_operand" "=r")
3245         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3246   "TARGET_64BIT"
3247   "movs{wq|x}\t{%1,%0|%0, %1}"
3248   [(set_attr "type" "imovx")
3249    (set_attr "mode" "DI")])
3251 (define_insn "extendqidi2"
3252   [(set (match_operand:DI 0 "register_operand" "=r")
3253         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3254   "TARGET_64BIT"
3255   "movs{bq|x}\t{%1,%0|%0, %1}"
3256    [(set_attr "type" "imovx")
3257     (set_attr "mode" "DI")])
3259 ;; Extend to memory case when source register does die.
3260 (define_split 
3261   [(set (match_operand:DI 0 "memory_operand" "")
3262         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3263    (clobber (reg:CC FLAGS_REG))
3264    (clobber (match_operand:SI 2 "register_operand" ""))]
3265   "(reload_completed
3266     && dead_or_set_p (insn, operands[1])
3267     && !reg_mentioned_p (operands[1], operands[0]))"
3268   [(set (match_dup 3) (match_dup 1))
3269    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3270               (clobber (reg:CC FLAGS_REG))])
3271    (set (match_dup 4) (match_dup 1))]
3272   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3274 ;; Extend to memory case when source register does not die.
3275 (define_split 
3276   [(set (match_operand:DI 0 "memory_operand" "")
3277         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3278    (clobber (reg:CC FLAGS_REG))
3279    (clobber (match_operand:SI 2 "register_operand" ""))]
3280   "reload_completed"
3281   [(const_int 0)]
3283   split_di (&operands[0], 1, &operands[3], &operands[4]);
3285   emit_move_insn (operands[3], operands[1]);
3287   /* Generate a cltd if possible and doing so it profitable.  */
3288   if (true_regnum (operands[1]) == 0
3289       && true_regnum (operands[2]) == 1
3290       && (optimize_size || TARGET_USE_CLTD))
3291     {
3292       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3293     }
3294   else
3295     {
3296       emit_move_insn (operands[2], operands[1]);
3297       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3298     }
3299   emit_move_insn (operands[4], operands[2]);
3300   DONE;
3303 ;; Extend to register case.  Optimize case where source and destination
3304 ;; registers match and cases where we can use cltd.
3305 (define_split 
3306   [(set (match_operand:DI 0 "register_operand" "")
3307         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3308    (clobber (reg:CC FLAGS_REG))
3309    (clobber (match_scratch:SI 2 ""))]
3310   "reload_completed"
3311   [(const_int 0)]
3313   split_di (&operands[0], 1, &operands[3], &operands[4]);
3315   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3316     emit_move_insn (operands[3], operands[1]);
3318   /* Generate a cltd if possible and doing so it profitable.  */
3319   if (true_regnum (operands[3]) == 0
3320       && (optimize_size || TARGET_USE_CLTD))
3321     {
3322       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3323       DONE;
3324     }
3326   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3327     emit_move_insn (operands[4], operands[1]);
3329   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3330   DONE;
3333 (define_insn "extendhisi2"
3334   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3335         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3336   ""
3338   switch (get_attr_prefix_0f (insn))
3339     {
3340     case 0:
3341       return "{cwtl|cwde}";
3342     default:
3343       return "movs{wl|x}\t{%1,%0|%0, %1}";
3344     }
3346   [(set_attr "type" "imovx")
3347    (set_attr "mode" "SI")
3348    (set (attr "prefix_0f")
3349      ;; movsx is short decodable while cwtl is vector decoded.
3350      (if_then_else (and (eq_attr "cpu" "!k6")
3351                         (eq_attr "alternative" "0"))
3352         (const_string "0")
3353         (const_string "1")))
3354    (set (attr "modrm")
3355      (if_then_else (eq_attr "prefix_0f" "0")
3356         (const_string "0")
3357         (const_string "1")))])
3359 (define_insn "*extendhisi2_zext"
3360   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3361         (zero_extend:DI
3362           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3363   "TARGET_64BIT"
3365   switch (get_attr_prefix_0f (insn))
3366     {
3367     case 0:
3368       return "{cwtl|cwde}";
3369     default:
3370       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3371     }
3373   [(set_attr "type" "imovx")
3374    (set_attr "mode" "SI")
3375    (set (attr "prefix_0f")
3376      ;; movsx is short decodable while cwtl is vector decoded.
3377      (if_then_else (and (eq_attr "cpu" "!k6")
3378                         (eq_attr "alternative" "0"))
3379         (const_string "0")
3380         (const_string "1")))
3381    (set (attr "modrm")
3382      (if_then_else (eq_attr "prefix_0f" "0")
3383         (const_string "0")
3384         (const_string "1")))])
3386 (define_insn "extendqihi2"
3387   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3388         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3389   ""
3391   switch (get_attr_prefix_0f (insn))
3392     {
3393     case 0:
3394       return "{cbtw|cbw}";
3395     default:
3396       return "movs{bw|x}\t{%1,%0|%0, %1}";
3397     }
3399   [(set_attr "type" "imovx")
3400    (set_attr "mode" "HI")
3401    (set (attr "prefix_0f")
3402      ;; movsx is short decodable while cwtl is vector decoded.
3403      (if_then_else (and (eq_attr "cpu" "!k6")
3404                         (eq_attr "alternative" "0"))
3405         (const_string "0")
3406         (const_string "1")))
3407    (set (attr "modrm")
3408      (if_then_else (eq_attr "prefix_0f" "0")
3409         (const_string "0")
3410         (const_string "1")))])
3412 (define_insn "extendqisi2"
3413   [(set (match_operand:SI 0 "register_operand" "=r")
3414         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3415   ""
3416   "movs{bl|x}\t{%1,%0|%0, %1}"
3417    [(set_attr "type" "imovx")
3418     (set_attr "mode" "SI")])
3420 (define_insn "*extendqisi2_zext"
3421   [(set (match_operand:DI 0 "register_operand" "=r")
3422         (zero_extend:DI
3423           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3424   "TARGET_64BIT"
3425   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3426    [(set_attr "type" "imovx")
3427     (set_attr "mode" "SI")])
3429 ;; Conversions between float and double.
3431 ;; These are all no-ops in the model used for the 80387.  So just
3432 ;; emit moves.
3434 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3435 (define_insn "*dummy_extendsfdf2"
3436   [(set (match_operand:DF 0 "push_operand" "=<")
3437         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3438   "0"
3439   "#")
3441 (define_split
3442   [(set (match_operand:DF 0 "push_operand" "")
3443         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3444   "!TARGET_64BIT"
3445   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3446    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3448 (define_split
3449   [(set (match_operand:DF 0 "push_operand" "")
3450         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3451   "TARGET_64BIT"
3452   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3453    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3455 (define_insn "*dummy_extendsfxf2"
3456   [(set (match_operand:XF 0 "push_operand" "=<")
3457         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3458   "0"
3459   "#")
3461 (define_split
3462   [(set (match_operand:XF 0 "push_operand" "")
3463         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3464   ""
3465   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3466    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3467   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3469 (define_split
3470   [(set (match_operand:XF 0 "push_operand" "")
3471         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3472   "TARGET_64BIT"
3473   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3474    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3475   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3477 (define_split
3478   [(set (match_operand:XF 0 "push_operand" "")
3479         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3480   ""
3481   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3482    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3483   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3485 (define_split
3486   [(set (match_operand:XF 0 "push_operand" "")
3487         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3488   "TARGET_64BIT"
3489   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3490    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3491   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3493 (define_expand "extendsfdf2"
3494   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3495         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3496   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3498   /* ??? Needed for compress_float_constant since all fp constants
3499      are LEGITIMATE_CONSTANT_P.  */
3500   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3501     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3502   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3503     operands[1] = force_reg (SFmode, operands[1]);
3506 (define_insn "*extendsfdf2_mixed"
3507   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3508         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3509   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3510    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3512   switch (which_alternative)
3513     {
3514     case 0:
3515       return output_387_reg_move (insn, operands);
3517     case 1:
3518       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3519         return "fstp%z0\t%y0";
3520       else
3521         return "fst%z0\t%y0";
3523     case 2:
3524       return "cvtss2sd\t{%1, %0|%0, %1}";
3526     default:
3527       abort ();
3528     }
3530   [(set_attr "type" "fmov,fmov,ssecvt")
3531    (set_attr "mode" "SF,XF,DF")])
3533 (define_insn "*extendsfdf2_sse"
3534   [(set (match_operand:DF 0 "register_operand" "=Y")
3535         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3536   "TARGET_SSE2 && TARGET_SSE_MATH
3537    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3538   "cvtss2sd\t{%1, %0|%0, %1}"
3539   [(set_attr "type" "ssecvt")
3540    (set_attr "mode" "DF")])
3542 (define_insn "*extendsfdf2_i387"
3543   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3544         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3545   "TARGET_80387
3546    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3548   switch (which_alternative)
3549     {
3550     case 0:
3551       return output_387_reg_move (insn, operands);
3553     case 1:
3554       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3555         return "fstp%z0\t%y0";
3556       else
3557         return "fst%z0\t%y0";
3559     default:
3560       abort ();
3561     }
3563   [(set_attr "type" "fmov")
3564    (set_attr "mode" "SF,XF")])
3566 (define_expand "extendsfxf2"
3567   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3568         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3569   "TARGET_80387"
3571   /* ??? Needed for compress_float_constant since all fp constants
3572      are LEGITIMATE_CONSTANT_P.  */
3573   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3574     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3575   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3576     operands[1] = force_reg (SFmode, operands[1]);
3579 (define_insn "*extendsfxf2_i387"
3580   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3581         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3582   "TARGET_80387
3583    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3585   switch (which_alternative)
3586     {
3587     case 0:
3588       return output_387_reg_move (insn, operands);
3590     case 1:
3591       /* There is no non-popping store to memory for XFmode.  So if
3592          we need one, follow the store with a load.  */
3593       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3594         return "fstp%z0\t%y0";
3595       else
3596         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3598     default:
3599       abort ();
3600     }
3602   [(set_attr "type" "fmov")
3603    (set_attr "mode" "SF,XF")])
3605 (define_expand "extenddfxf2"
3606   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3607         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3608   "TARGET_80387"
3610   /* ??? Needed for compress_float_constant since all fp constants
3611      are LEGITIMATE_CONSTANT_P.  */
3612   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3613     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3614   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3615     operands[1] = force_reg (DFmode, operands[1]);
3618 (define_insn "*extenddfxf2_i387"
3619   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3620         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3621   "TARGET_80387
3622    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3624   switch (which_alternative)
3625     {
3626     case 0:
3627       return output_387_reg_move (insn, operands);
3629     case 1:
3630       /* There is no non-popping store to memory for XFmode.  So if
3631          we need one, follow the store with a load.  */
3632       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3633         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3634       else
3635         return "fstp%z0\t%y0";
3637     default:
3638       abort ();
3639     }
3641   [(set_attr "type" "fmov")
3642    (set_attr "mode" "DF,XF")])
3644 ;; %%% This seems bad bad news.
3645 ;; This cannot output into an f-reg because there is no way to be sure
3646 ;; of truncating in that case.  Otherwise this is just like a simple move
3647 ;; insn.  So we pretend we can output to a reg in order to get better
3648 ;; register preferencing, but we really use a stack slot.
3650 ;; Conversion from DFmode to SFmode.
3652 (define_expand "truncdfsf2"
3653   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3654         (float_truncate:SF
3655           (match_operand:DF 1 "nonimmediate_operand" "")))]
3656   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3658   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3659     operands[1] = force_reg (DFmode, operands[1]);
3661   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3662     ;
3663   else if (flag_unsafe_math_optimizations)
3664     ;
3665   else
3666     {
3667       rtx temp = assign_386_stack_local (SFmode, 0);
3668       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3669       DONE;
3670     }
3673 (define_expand "truncdfsf2_with_temp"
3674   [(parallel [(set (match_operand:SF 0 "" "")
3675                    (float_truncate:SF (match_operand:DF 1 "" "")))
3676               (clobber (match_operand:SF 2 "" ""))])]
3677   "")
3679 (define_insn "*truncdfsf_fast_mixed"
3680   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3681         (float_truncate:SF
3682           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3683   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3685   switch (which_alternative)
3686     {
3687     case 0:
3688       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689         return "fstp%z0\t%y0";
3690       else
3691         return "fst%z0\t%y0";
3692     case 1:
3693       return output_387_reg_move (insn, operands);
3694     case 2:
3695       return "cvtsd2ss\t{%1, %0|%0, %1}";
3696     default:
3697       abort ();
3698     }
3700   [(set_attr "type" "fmov,fmov,ssecvt")
3701    (set_attr "mode" "SF")])
3703 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3704 ;; because nothing we do here is unsafe.
3705 (define_insn "*truncdfsf_fast_sse"
3706   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3707         (float_truncate:SF
3708           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3709   "TARGET_SSE2 && TARGET_SSE_MATH"
3710   "cvtsd2ss\t{%1, %0|%0, %1}"
3711   [(set_attr "type" "ssecvt")
3712    (set_attr "mode" "SF")])
3714 (define_insn "*truncdfsf_fast_i387"
3715   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3716         (float_truncate:SF
3717           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3718   "TARGET_80387 && flag_unsafe_math_optimizations"
3719   "* return output_387_reg_move (insn, operands);"
3720   [(set_attr "type" "fmov")
3721    (set_attr "mode" "SF")])
3723 (define_insn "*truncdfsf_mixed"
3724   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3725         (float_truncate:SF
3726           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3727    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3728   "TARGET_MIX_SSE_I387"
3730   switch (which_alternative)
3731     {
3732     case 0:
3733       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3734         return "fstp%z0\t%y0";
3735       else
3736         return "fst%z0\t%y0";
3737     case 1:
3738       return "#";
3739     case 2:
3740       return "cvtsd2ss\t{%1, %0|%0, %1}";
3741     default:
3742       abort ();
3743     }
3745   [(set_attr "type" "fmov,multi,ssecvt")
3746    (set_attr "mode" "SF")])
3748 (define_insn "*truncdfsf_i387"
3749   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3750         (float_truncate:SF
3751           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3752    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3753   "TARGET_80387"
3755   switch (which_alternative)
3756     {
3757     case 0:
3758       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3759         return "fstp%z0\t%y0";
3760       else
3761         return "fst%z0\t%y0";
3762     case 1:
3763       return "#";
3764     default:
3765       abort ();
3766     }
3768   [(set_attr "type" "fmov,multi")
3769    (set_attr "mode" "SF")])
3771 (define_split
3772   [(set (match_operand:SF 0 "register_operand" "")
3773         (float_truncate:SF
3774          (match_operand:DF 1 "fp_register_operand" "")))
3775    (clobber (match_operand 2 "" ""))]
3776   "reload_completed"
3777   [(set (match_dup 2) (match_dup 1))
3778    (set (match_dup 0) (match_dup 2))]
3780   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3783 ;; Conversion from XFmode to SFmode.
3785 (define_expand "truncxfsf2"
3786   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3787                    (float_truncate:SF
3788                     (match_operand:XF 1 "register_operand" "")))
3789               (clobber (match_dup 2))])]
3790   "TARGET_80387"
3792   if (flag_unsafe_math_optimizations)
3793     {
3794       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3795       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3796       if (reg != operands[0])
3797         emit_move_insn (operands[0], reg);
3798       DONE;
3799     }
3800   else
3801     operands[2] = assign_386_stack_local (SFmode, 0);
3804 (define_insn "*truncxfsf2_mixed"
3805   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3806         (float_truncate:SF
3807          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3808    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3809   "TARGET_MIX_SSE_I387"
3811   switch (which_alternative)
3812     {
3813     case 0:
3814       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3815         return "fstp%z0\t%y0";
3816       else
3817         return "fst%z0\t%y0";
3818     default:
3819       abort();
3820     }
3822   [(set_attr "type" "fmov,multi,multi,multi")
3823    (set_attr "mode" "SF")])
3825 (define_insn "truncxfsf2_i387_noop"
3826   [(set (match_operand:SF 0 "register_operand" "=f")
3827         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3828   "TARGET_80387 && flag_unsafe_math_optimizations"
3830   return output_387_reg_move (insn, operands);
3832   [(set_attr "type" "fmov")
3833    (set_attr "mode" "SF")])
3835 (define_insn "*truncxfsf2_i387"
3836   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3837         (float_truncate:SF
3838          (match_operand:XF 1 "register_operand" "f,f,f")))
3839    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3840   "TARGET_80387"
3842   switch (which_alternative)
3843     {
3844     case 0:
3845       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3846         return "fstp%z0\t%y0";
3847       else
3848         return "fst%z0\t%y0";
3849     default:
3850       abort ();
3851     }
3853   [(set_attr "type" "fmov,multi,multi")
3854    (set_attr "mode" "SF")])
3856 (define_insn "*truncxfsf2_i387_1"
3857   [(set (match_operand:SF 0 "memory_operand" "=m")
3858         (float_truncate:SF
3859          (match_operand:XF 1 "register_operand" "f")))]
3860   "TARGET_80387"
3862   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3863     return "fstp%z0\t%y0";
3864   else
3865     return "fst%z0\t%y0";
3867   [(set_attr "type" "fmov")
3868    (set_attr "mode" "SF")])
3870 (define_split
3871   [(set (match_operand:SF 0 "register_operand" "")
3872         (float_truncate:SF
3873          (match_operand:XF 1 "register_operand" "")))
3874    (clobber (match_operand:SF 2 "memory_operand" ""))]
3875   "TARGET_80387 && reload_completed"
3876   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3877    (set (match_dup 0) (match_dup 2))]
3878   "")
3880 (define_split
3881   [(set (match_operand:SF 0 "memory_operand" "")
3882         (float_truncate:SF
3883          (match_operand:XF 1 "register_operand" "")))
3884    (clobber (match_operand:SF 2 "memory_operand" ""))]
3885   "TARGET_80387"
3886   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3887   "")
3889 ;; Conversion from XFmode to DFmode.
3891 (define_expand "truncxfdf2"
3892   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3893                    (float_truncate:DF
3894                     (match_operand:XF 1 "register_operand" "")))
3895               (clobber (match_dup 2))])]
3896   "TARGET_80387"
3898   if (flag_unsafe_math_optimizations)
3899     {
3900       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3901       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3902       if (reg != operands[0])
3903         emit_move_insn (operands[0], reg);
3904       DONE;
3905     }
3906   else
3907     operands[2] = assign_386_stack_local (DFmode, 0);
3910 (define_insn "*truncxfdf2_mixed"
3911   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3912         (float_truncate:DF
3913          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3914    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3915   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3917   switch (which_alternative)
3918     {
3919     case 0:
3920       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921         return "fstp%z0\t%y0";
3922       else
3923         return "fst%z0\t%y0";
3924     default:
3925       abort();
3926     }
3927   abort ();
3929   [(set_attr "type" "fmov,multi,multi,multi")
3930    (set_attr "mode" "DF")])
3932 (define_insn "truncxfdf2_i387_noop"
3933   [(set (match_operand:DF 0 "register_operand" "=f")
3934         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3935   "TARGET_80387 && flag_unsafe_math_optimizations"
3937   return output_387_reg_move (insn, operands);
3939   [(set_attr "type" "fmov")
3940    (set_attr "mode" "DF")])
3942 (define_insn "*truncxfdf2_i387"
3943   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3944         (float_truncate:DF
3945          (match_operand:XF 1 "register_operand" "f,f,f")))
3946    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3947   "TARGET_80387"
3949   switch (which_alternative)
3950     {
3951     case 0:
3952       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3953         return "fstp%z0\t%y0";
3954       else
3955         return "fst%z0\t%y0";
3956     default:
3957       abort ();
3958     }
3960   [(set_attr "type" "fmov,multi,multi")
3961    (set_attr "mode" "DF")])
3963 (define_insn "*truncxfdf2_i387_1"
3964   [(set (match_operand:DF 0 "memory_operand" "=m")
3965         (float_truncate:DF
3966           (match_operand:XF 1 "register_operand" "f")))]
3967   "TARGET_80387"
3969   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3970     return "fstp%z0\t%y0";
3971   else
3972     return "fst%z0\t%y0";
3974   [(set_attr "type" "fmov")
3975    (set_attr "mode" "DF")])
3977 (define_split
3978   [(set (match_operand:DF 0 "register_operand" "")
3979         (float_truncate:DF
3980          (match_operand:XF 1 "register_operand" "")))
3981    (clobber (match_operand:DF 2 "memory_operand" ""))]
3982   "TARGET_80387 && reload_completed"
3983   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3984    (set (match_dup 0) (match_dup 2))]
3985   "")
3987 (define_split
3988   [(set (match_operand:DF 0 "memory_operand" "")
3989         (float_truncate:DF
3990          (match_operand:XF 1 "register_operand" "")))
3991    (clobber (match_operand:DF 2 "memory_operand" ""))]
3992   "TARGET_80387"
3993   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3994   "")
3996 ;; %%% Break up all these bad boys.
3998 ;; Signed conversion to DImode.
4000 (define_expand "fix_truncxfdi2"
4001   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4002                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4003               (clobber (reg:CC FLAGS_REG))])]
4004   "TARGET_80387"
4005   "")
4007 (define_expand "fix_truncdfdi2"
4008   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4009                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4010               (clobber (reg:CC FLAGS_REG))])]
4011   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
4013   if (TARGET_64BIT && TARGET_SSE2)
4014    {
4015      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4016      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4017      if (out != operands[0])
4018         emit_move_insn (operands[0], out);
4019      DONE;
4020    }
4023 (define_expand "fix_truncsfdi2"
4024   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4025                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4026               (clobber (reg:CC FLAGS_REG))])] 
4027   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
4029   if (TARGET_64BIT && TARGET_SSE)
4030    {
4031      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4032      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4033      if (out != operands[0])
4034         emit_move_insn (operands[0], out);
4035      DONE;
4036    }
4039 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4040 ;; of the machinery.
4041 (define_insn_and_split "*fix_truncdi_i387"
4042   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4043         (fix:DI (match_operand 1 "register_operand" "f,f")))
4044    (clobber (reg:CC FLAGS_REG))]
4045   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4046    && !reload_completed && !reload_in_progress
4047    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4048   "#"
4049   "&& 1"
4050   [(const_int 0)]
4052   ix86_optimize_mode_switching = 1;
4053   operands[2] = assign_386_stack_local (HImode, 1);
4054   operands[3] = assign_386_stack_local (HImode, 2);
4055   if (memory_operand (operands[0], VOIDmode))
4056     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4057                                        operands[2], operands[3]));
4058   else
4059     {
4060       operands[4] = assign_386_stack_local (DImode, 0);
4061       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4062                                            operands[2], operands[3],
4063                                            operands[4]));
4064     }
4065   DONE;
4067   [(set_attr "type" "fistp")
4068    (set_attr "i387_cw" "trunc")
4069    (set_attr "mode" "DI")])
4071 (define_insn "fix_truncdi_nomemory"
4072   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4073         (fix:DI (match_operand 1 "register_operand" "f,f")))
4074    (use (match_operand:HI 2 "memory_operand" "m,m"))
4075    (use (match_operand:HI 3 "memory_operand" "m,m"))
4076    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4077    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4078   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4079    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4080   "#"
4081   [(set_attr "type" "fistp")
4082    (set_attr "i387_cw" "trunc")
4083    (set_attr "mode" "DI")])
4085 (define_insn "fix_truncdi_memory"
4086   [(set (match_operand:DI 0 "memory_operand" "=m")
4087         (fix:DI (match_operand 1 "register_operand" "f")))
4088    (use (match_operand:HI 2 "memory_operand" "m"))
4089    (use (match_operand:HI 3 "memory_operand" "m"))
4090    (clobber (match_scratch:DF 4 "=&1f"))]
4091   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4092    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4093   "* return output_fix_trunc (insn, operands);"
4094   [(set_attr "type" "fistp")
4095    (set_attr "i387_cw" "trunc")
4096    (set_attr "mode" "DI")])
4098 (define_split 
4099   [(set (match_operand:DI 0 "register_operand" "")
4100         (fix:DI (match_operand 1 "register_operand" "")))
4101    (use (match_operand:HI 2 "memory_operand" ""))
4102    (use (match_operand:HI 3 "memory_operand" ""))
4103    (clobber (match_operand:DI 4 "memory_operand" ""))
4104    (clobber (match_scratch 5 ""))]
4105   "reload_completed"
4106   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4107               (use (match_dup 2))
4108               (use (match_dup 3))
4109               (clobber (match_dup 5))])
4110    (set (match_dup 0) (match_dup 4))]
4111   "")
4113 (define_split 
4114   [(set (match_operand:DI 0 "memory_operand" "")
4115         (fix:DI (match_operand 1 "register_operand" "")))
4116    (use (match_operand:HI 2 "memory_operand" ""))
4117    (use (match_operand:HI 3 "memory_operand" ""))
4118    (clobber (match_operand:DI 4 "memory_operand" ""))
4119    (clobber (match_scratch 5 ""))]
4120   "reload_completed"
4121   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4122               (use (match_dup 2))
4123               (use (match_dup 3))
4124               (clobber (match_dup 5))])]
4125   "")
4127 ;; When SSE available, it is always faster to use it!
4128 (define_insn "fix_truncsfdi_sse"
4129   [(set (match_operand:DI 0 "register_operand" "=r,r")
4130         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4131   "TARGET_64BIT && TARGET_SSE"
4132   "cvttss2si{q}\t{%1, %0|%0, %1}"
4133   [(set_attr "type" "sseicvt")
4134    (set_attr "mode" "SF")
4135    (set_attr "athlon_decode" "double,vector")])
4137 ;; Avoid vector decoded form of the instruction.
4138 (define_peephole2
4139   [(match_scratch:SF 2 "x")
4140    (set (match_operand:DI 0 "register_operand" "")
4141         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4142   "TARGET_K8 && !optimize_size"
4143   [(set (match_dup 2) (match_dup 1))
4144    (set (match_dup 0) (fix:DI (match_dup 2)))]
4145   "")
4147 (define_insn "fix_truncdfdi_sse"
4148   [(set (match_operand:DI 0 "register_operand" "=r,r")
4149         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4150   "TARGET_64BIT && TARGET_SSE2"
4151   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4152   [(set_attr "type" "sseicvt,sseicvt")
4153    (set_attr "mode" "DF")
4154    (set_attr "athlon_decode" "double,vector")])
4156 ;; Avoid vector decoded form of the instruction.
4157 (define_peephole2
4158   [(match_scratch:DF 2 "Y")
4159    (set (match_operand:DI 0 "register_operand" "")
4160         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4161   "TARGET_K8 && !optimize_size"
4162   [(set (match_dup 2) (match_dup 1))
4163    (set (match_dup 0) (fix:DI (match_dup 2)))]
4164   "")
4166 ;; Signed conversion to SImode.
4168 (define_expand "fix_truncxfsi2"
4169   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4170                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4171               (clobber (reg:CC FLAGS_REG))])]
4172   "TARGET_80387"
4173   "")
4175 (define_expand "fix_truncdfsi2"
4176   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4177                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4178               (clobber (reg:CC FLAGS_REG))])]
4179   "TARGET_80387 || TARGET_SSE2"
4181   if (TARGET_SSE2)
4182    {
4183      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4184      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4185      if (out != operands[0])
4186         emit_move_insn (operands[0], out);
4187      DONE;
4188    }
4191 (define_expand "fix_truncsfsi2"
4192   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4193                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4194               (clobber (reg:CC FLAGS_REG))])] 
4195   "TARGET_80387 || TARGET_SSE"
4197   if (TARGET_SSE)
4198    {
4199      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4200      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4201      if (out != operands[0])
4202         emit_move_insn (operands[0], out);
4203      DONE;
4204    }
4207 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4208 ;; of the machinery.
4209 (define_insn_and_split "*fix_truncsi_i387"
4210   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4211         (fix:SI (match_operand 1 "register_operand" "f,f")))
4212    (clobber (reg:CC FLAGS_REG))]
4213   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4214    && !reload_completed && !reload_in_progress
4215    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4216   "#"
4217   "&& 1"
4218   [(const_int 0)]
4220   ix86_optimize_mode_switching = 1;
4221   operands[2] = assign_386_stack_local (HImode, 1);
4222   operands[3] = assign_386_stack_local (HImode, 2);
4223   if (memory_operand (operands[0], VOIDmode))
4224     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4225                                        operands[2], operands[3]));
4226   else
4227     {
4228       operands[4] = assign_386_stack_local (SImode, 0);
4229       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4230                                            operands[2], operands[3],
4231                                            operands[4]));
4232     }
4233   DONE;
4235   [(set_attr "type" "fistp")
4236    (set_attr "i387_cw" "trunc")
4237    (set_attr "mode" "SI")])
4239 (define_insn "fix_truncsi_nomemory"
4240   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4241         (fix:SI (match_operand 1 "register_operand" "f,f")))
4242    (use (match_operand:HI 2 "memory_operand" "m,m"))
4243    (use (match_operand:HI 3 "memory_operand" "m,m"))
4244    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4245   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4246    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4247   "#"
4248   [(set_attr "type" "fistp")
4249    (set_attr "i387_cw" "trunc")
4250    (set_attr "mode" "SI")])
4252 (define_insn "fix_truncsi_memory"
4253   [(set (match_operand:SI 0 "memory_operand" "=m")
4254         (fix:SI (match_operand 1 "register_operand" "f")))
4255    (use (match_operand:HI 2 "memory_operand" "m"))
4256    (use (match_operand:HI 3 "memory_operand" "m"))]
4257   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4258    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4259   "* return output_fix_trunc (insn, operands);"
4260   [(set_attr "type" "fistp")
4261    (set_attr "i387_cw" "trunc")
4262    (set_attr "mode" "SI")])
4264 ;; When SSE available, it is always faster to use it!
4265 (define_insn "fix_truncsfsi_sse"
4266   [(set (match_operand:SI 0 "register_operand" "=r,r")
4267         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4268   "TARGET_SSE"
4269   "cvttss2si\t{%1, %0|%0, %1}"
4270   [(set_attr "type" "sseicvt")
4271    (set_attr "mode" "DF")
4272    (set_attr "athlon_decode" "double,vector")])
4274 ;; Avoid vector decoded form of the instruction.
4275 (define_peephole2
4276   [(match_scratch:SF 2 "x")
4277    (set (match_operand:SI 0 "register_operand" "")
4278         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4279   "TARGET_K8 && !optimize_size"
4280   [(set (match_dup 2) (match_dup 1))
4281    (set (match_dup 0) (fix:SI (match_dup 2)))]
4282   "")
4284 (define_insn "fix_truncdfsi_sse"
4285   [(set (match_operand:SI 0 "register_operand" "=r,r")
4286         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4287   "TARGET_SSE2"
4288   "cvttsd2si\t{%1, %0|%0, %1}"
4289   [(set_attr "type" "sseicvt")
4290    (set_attr "mode" "DF")
4291    (set_attr "athlon_decode" "double,vector")])
4293 ;; Avoid vector decoded form of the instruction.
4294 (define_peephole2
4295   [(match_scratch:DF 2 "Y")
4296    (set (match_operand:SI 0 "register_operand" "")
4297         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4298   "TARGET_K8 && !optimize_size"
4299   [(set (match_dup 2) (match_dup 1))
4300    (set (match_dup 0) (fix:SI (match_dup 2)))]
4301   "")
4303 (define_split 
4304   [(set (match_operand:SI 0 "register_operand" "")
4305         (fix:SI (match_operand 1 "register_operand" "")))
4306    (use (match_operand:HI 2 "memory_operand" ""))
4307    (use (match_operand:HI 3 "memory_operand" ""))
4308    (clobber (match_operand:SI 4 "memory_operand" ""))]
4309   "reload_completed"
4310   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4311               (use (match_dup 2))
4312               (use (match_dup 3))])
4313    (set (match_dup 0) (match_dup 4))]
4314   "")
4316 (define_split 
4317   [(set (match_operand:SI 0 "memory_operand" "")
4318         (fix:SI (match_operand 1 "register_operand" "")))
4319    (use (match_operand:HI 2 "memory_operand" ""))
4320    (use (match_operand:HI 3 "memory_operand" ""))
4321    (clobber (match_operand:SI 4 "memory_operand" ""))]
4322   "reload_completed"
4323   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4324               (use (match_dup 2))
4325               (use (match_dup 3))])]
4326   "")
4328 ;; Signed conversion to HImode.
4330 (define_expand "fix_truncxfhi2"
4331   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4332                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4333               (clobber (reg:CC FLAGS_REG))])] 
4334   "TARGET_80387"
4335   "")
4337 (define_expand "fix_truncdfhi2"
4338   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4339                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4340               (clobber (reg:CC FLAGS_REG))])]
4341   "TARGET_80387 && !TARGET_SSE2"
4342   "")
4344 (define_expand "fix_truncsfhi2"
4345   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4346                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4347                (clobber (reg:CC FLAGS_REG))])]
4348   "TARGET_80387 && !TARGET_SSE"
4349   "")
4351 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4352 ;; of the machinery.
4353 (define_insn_and_split "*fix_trunchi_i387"
4354   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4355         (fix:HI (match_operand 1 "register_operand" "f,f")))
4356    (clobber (reg:CC FLAGS_REG))]
4357   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4358    && !reload_completed && !reload_in_progress
4359    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4360   "#"
4361   "&& 1"
4362   [(const_int 0)]
4364   ix86_optimize_mode_switching = 1;
4365   operands[2] = assign_386_stack_local (HImode, 1);
4366   operands[3] = assign_386_stack_local (HImode, 2);
4367   if (memory_operand (operands[0], VOIDmode))
4368     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4369                                        operands[2], operands[3]));
4370   else
4371     {
4372       operands[4] = assign_386_stack_local (HImode, 0);
4373       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4374                                            operands[2], operands[3],
4375                                            operands[4]));
4376     }
4377   DONE;
4379   [(set_attr "type" "fistp")
4380    (set_attr "i387_cw" "trunc")
4381    (set_attr "mode" "HI")])
4383 (define_insn "fix_trunchi_nomemory"
4384   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4385         (fix:HI (match_operand 1 "register_operand" "f,f")))
4386    (use (match_operand:HI 2 "memory_operand" "m,m"))
4387    (use (match_operand:HI 3 "memory_operand" "m,m"))
4388    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4389   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4390    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4391   "#"
4392   [(set_attr "type" "fistp")
4393    (set_attr "i387_cw" "trunc")
4394    (set_attr "mode" "HI")])
4396 (define_insn "fix_trunchi_memory"
4397   [(set (match_operand:HI 0 "memory_operand" "=m")
4398         (fix:HI (match_operand 1 "register_operand" "f")))
4399    (use (match_operand:HI 2 "memory_operand" "m"))
4400    (use (match_operand:HI 3 "memory_operand" "m"))]
4401   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4402    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4403   "* return output_fix_trunc (insn, operands);"
4404   [(set_attr "type" "fistp")
4405    (set_attr "i387_cw" "trunc")
4406    (set_attr "mode" "HI")])
4408 (define_split 
4409   [(set (match_operand:HI 0 "memory_operand" "")
4410         (fix:HI (match_operand 1 "register_operand" "")))
4411    (use (match_operand:HI 2 "memory_operand" ""))
4412    (use (match_operand:HI 3 "memory_operand" ""))
4413    (clobber (match_operand:HI 4 "memory_operand" ""))]
4414   "reload_completed"
4415   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4416               (use (match_dup 2))
4417               (use (match_dup 3))])]
4418   "")
4420 (define_split 
4421   [(set (match_operand:HI 0 "register_operand" "")
4422         (fix:HI (match_operand 1 "register_operand" "")))
4423    (use (match_operand:HI 2 "memory_operand" ""))
4424    (use (match_operand:HI 3 "memory_operand" ""))
4425    (clobber (match_operand:HI 4 "memory_operand" ""))]
4426   "reload_completed"
4427   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4428               (use (match_dup 2))
4429               (use (match_dup 3))
4430               (clobber (match_dup 4))])
4431    (set (match_dup 0) (match_dup 4))]
4432   "")
4434 (define_insn "x86_fnstcw_1"
4435   [(set (match_operand:HI 0 "memory_operand" "=m")
4436         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4437   "TARGET_80387"
4438   "fnstcw\t%0"
4439   [(set_attr "length" "2")
4440    (set_attr "mode" "HI")
4441    (set_attr "unit" "i387")])
4443 (define_insn "x86_fldcw_1"
4444   [(set (reg:HI FPSR_REG)
4445         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4446   "TARGET_80387"
4447   "fldcw\t%0"
4448   [(set_attr "length" "2")
4449    (set_attr "mode" "HI")
4450    (set_attr "unit" "i387")
4451    (set_attr "athlon_decode" "vector")])
4453 ;; Conversion between fixed point and floating point.
4455 ;; Even though we only accept memory inputs, the backend _really_
4456 ;; wants to be able to do this between registers.
4458 (define_expand "floathisf2"
4459   [(set (match_operand:SF 0 "register_operand" "")
4460         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4461   "TARGET_80387 || TARGET_SSE_MATH"
4463   if (TARGET_SSE_MATH)
4464     {
4465       emit_insn (gen_floatsisf2 (operands[0],
4466                                  convert_to_mode (SImode, operands[1], 0)));
4467       DONE;
4468     }
4471 (define_insn "*floathisf2_i387"
4472   [(set (match_operand:SF 0 "register_operand" "=f,f")
4473         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4474   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4475   "@
4476    fild%z1\t%1
4477    #"
4478   [(set_attr "type" "fmov,multi")
4479    (set_attr "mode" "SF")
4480    (set_attr "fp_int_src" "true")])
4482 (define_expand "floatsisf2"
4483   [(set (match_operand:SF 0 "register_operand" "")
4484         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4485   "TARGET_80387 || TARGET_SSE_MATH"
4486   "")
4488 (define_insn "*floatsisf2_mixed"
4489   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4490         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4491   "TARGET_MIX_SSE_I387"
4492   "@
4493    fild%z1\t%1
4494    #
4495    cvtsi2ss\t{%1, %0|%0, %1}
4496    cvtsi2ss\t{%1, %0|%0, %1}"
4497   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4498    (set_attr "mode" "SF")
4499    (set_attr "athlon_decode" "*,*,vector,double")
4500    (set_attr "fp_int_src" "true")])
4502 (define_insn "*floatsisf2_sse"
4503   [(set (match_operand:SF 0 "register_operand" "=x,x")
4504         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4505   "TARGET_SSE_MATH"
4506   "cvtsi2ss\t{%1, %0|%0, %1}"
4507   [(set_attr "type" "sseicvt")
4508    (set_attr "mode" "SF")
4509    (set_attr "athlon_decode" "vector,double")
4510    (set_attr "fp_int_src" "true")])
4512 (define_insn "*floatsisf2_i387"
4513   [(set (match_operand:SF 0 "register_operand" "=f,f")
4514         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4515   "TARGET_80387"
4516   "@
4517    fild%z1\t%1
4518    #"
4519   [(set_attr "type" "fmov,multi")
4520    (set_attr "mode" "SF")
4521    (set_attr "fp_int_src" "true")])
4523 (define_expand "floatdisf2"
4524   [(set (match_operand:SF 0 "register_operand" "")
4525         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4526   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4527   "")
4529 (define_insn "*floatdisf2_mixed"
4530   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4531         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4532   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4533   "@
4534    fild%z1\t%1
4535    #
4536    cvtsi2ss{q}\t{%1, %0|%0, %1}
4537    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4538   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4539    (set_attr "mode" "SF")
4540    (set_attr "athlon_decode" "*,*,vector,double")
4541    (set_attr "fp_int_src" "true")])
4543 (define_insn "*floatdisf2_sse"
4544   [(set (match_operand:SF 0 "register_operand" "=x,x")
4545         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4546   "TARGET_64BIT && TARGET_SSE_MATH"
4547   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4548   [(set_attr "type" "sseicvt")
4549    (set_attr "mode" "SF")
4550    (set_attr "athlon_decode" "vector,double")
4551    (set_attr "fp_int_src" "true")])
4553 (define_insn "*floatdisf2_i387"
4554   [(set (match_operand:SF 0 "register_operand" "=f,f")
4555         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4556   "TARGET_80387"
4557   "@
4558    fild%z1\t%1
4559    #"
4560   [(set_attr "type" "fmov,multi")
4561    (set_attr "mode" "SF")
4562    (set_attr "fp_int_src" "true")])
4564 (define_expand "floathidf2"
4565   [(set (match_operand:DF 0 "register_operand" "")
4566         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4567   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4569   if (TARGET_SSE2 && TARGET_SSE_MATH)
4570     {
4571       emit_insn (gen_floatsidf2 (operands[0],
4572                                  convert_to_mode (SImode, operands[1], 0)));
4573       DONE;
4574     }
4577 (define_insn "*floathidf2_i387"
4578   [(set (match_operand:DF 0 "register_operand" "=f,f")
4579         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4580   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4581   "@
4582    fild%z1\t%1
4583    #"
4584   [(set_attr "type" "fmov,multi")
4585    (set_attr "mode" "DF")
4586    (set_attr "fp_int_src" "true")])
4588 (define_expand "floatsidf2"
4589   [(set (match_operand:DF 0 "register_operand" "")
4590         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4591   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4592   "")
4594 (define_insn "*floatsidf2_mixed"
4595   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4596         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4597   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4598   "@
4599    fild%z1\t%1
4600    #
4601    cvtsi2sd\t{%1, %0|%0, %1}
4602    cvtsi2sd\t{%1, %0|%0, %1}"
4603   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4604    (set_attr "mode" "DF")
4605    (set_attr "athlon_decode" "*,*,double,direct")
4606    (set_attr "fp_int_src" "true")])
4608 (define_insn "*floatsidf2_sse"
4609   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4610         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4611   "TARGET_SSE2 && TARGET_SSE_MATH"
4612   "cvtsi2sd\t{%1, %0|%0, %1}"
4613   [(set_attr "type" "sseicvt")
4614    (set_attr "mode" "DF")
4615    (set_attr "athlon_decode" "double,direct")
4616    (set_attr "fp_int_src" "true")])
4618 (define_insn "*floatsidf2_i387"
4619   [(set (match_operand:DF 0 "register_operand" "=f,f")
4620         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4621   "TARGET_80387"
4622   "@
4623    fild%z1\t%1
4624    #"
4625   [(set_attr "type" "fmov,multi")
4626    (set_attr "mode" "DF")
4627    (set_attr "fp_int_src" "true")])
4629 (define_expand "floatdidf2"
4630   [(set (match_operand:DF 0 "register_operand" "")
4631         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4632   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4633   "")
4635 (define_insn "*floatdidf2_mixed"
4636   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4637         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4638   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4639   "@
4640    fild%z1\t%1
4641    #
4642    cvtsi2sd{q}\t{%1, %0|%0, %1}
4643    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4644   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4645    (set_attr "mode" "DF")
4646    (set_attr "athlon_decode" "*,*,double,direct")
4647    (set_attr "fp_int_src" "true")])
4649 (define_insn "*floatdidf2_sse"
4650   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4651         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4652   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4653   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4654   [(set_attr "type" "sseicvt")
4655    (set_attr "mode" "DF")
4656    (set_attr "athlon_decode" "double,direct")
4657    (set_attr "fp_int_src" "true")])
4659 (define_insn "*floatdidf2_i387"
4660   [(set (match_operand:DF 0 "register_operand" "=f,f")
4661         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4662   "TARGET_80387"
4663   "@
4664    fild%z1\t%1
4665    #"
4666   [(set_attr "type" "fmov,multi")
4667    (set_attr "mode" "DF")
4668    (set_attr "fp_int_src" "true")])
4670 (define_insn "floathixf2"
4671   [(set (match_operand:XF 0 "register_operand" "=f,f")
4672         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4673   "TARGET_80387"
4674   "@
4675    fild%z1\t%1
4676    #"
4677   [(set_attr "type" "fmov,multi")
4678    (set_attr "mode" "XF")
4679    (set_attr "fp_int_src" "true")])
4681 (define_insn "floatsixf2"
4682   [(set (match_operand:XF 0 "register_operand" "=f,f")
4683         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4684   "TARGET_80387"
4685   "@
4686    fild%z1\t%1
4687    #"
4688   [(set_attr "type" "fmov,multi")
4689    (set_attr "mode" "XF")
4690    (set_attr "fp_int_src" "true")])
4692 (define_insn "floatdixf2"
4693   [(set (match_operand:XF 0 "register_operand" "=f,f")
4694         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4695   "TARGET_80387"
4696   "@
4697    fild%z1\t%1
4698    #"
4699   [(set_attr "type" "fmov,multi")
4700    (set_attr "mode" "XF")
4701    (set_attr "fp_int_src" "true")])
4703 ;; %%% Kill these when reload knows how to do it.
4704 (define_split
4705   [(set (match_operand 0 "fp_register_operand" "")
4706         (float (match_operand 1 "register_operand" "")))]
4707   "reload_completed
4708    && TARGET_80387
4709    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4710   [(const_int 0)]
4712   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4713   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4714   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4715   ix86_free_from_memory (GET_MODE (operands[1]));
4716   DONE;
4719 (define_expand "floatunssisf2"
4720   [(use (match_operand:SF 0 "register_operand" ""))
4721    (use (match_operand:SI 1 "register_operand" ""))]
4722   "!TARGET_64BIT && TARGET_SSE_MATH"
4723   "x86_emit_floatuns (operands); DONE;")
4725 (define_expand "floatunsdisf2"
4726   [(use (match_operand:SF 0 "register_operand" ""))
4727    (use (match_operand:DI 1 "register_operand" ""))]
4728   "TARGET_64BIT && TARGET_SSE_MATH"
4729   "x86_emit_floatuns (operands); DONE;")
4731 (define_expand "floatunsdidf2"
4732   [(use (match_operand:DF 0 "register_operand" ""))
4733    (use (match_operand:DI 1 "register_operand" ""))]
4734   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4735   "x86_emit_floatuns (operands); DONE;")
4737 ;; SSE extract/set expanders
4740 ;; Add instructions
4742 ;; %%% splits for addsidi3
4743 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4744 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4745 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4747 (define_expand "adddi3"
4748   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4749         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4750                  (match_operand:DI 2 "x86_64_general_operand" "")))
4751    (clobber (reg:CC FLAGS_REG))]
4752   ""
4753   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4755 (define_insn "*adddi3_1"
4756   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4757         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4758                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4761   "#")
4763 (define_split
4764   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4765         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4766                  (match_operand:DI 2 "general_operand" "")))
4767    (clobber (reg:CC FLAGS_REG))]
4768   "!TARGET_64BIT && reload_completed"
4769   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4770                                           UNSPEC_ADD_CARRY))
4771               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4772    (parallel [(set (match_dup 3)
4773                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4774                                      (match_dup 4))
4775                             (match_dup 5)))
4776               (clobber (reg:CC FLAGS_REG))])]
4777   "split_di (operands+0, 1, operands+0, operands+3);
4778    split_di (operands+1, 1, operands+1, operands+4);
4779    split_di (operands+2, 1, operands+2, operands+5);")
4781 (define_insn "adddi3_carry_rex64"
4782   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4783           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4784                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4785                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4786    (clobber (reg:CC FLAGS_REG))]
4787   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4788   "adc{q}\t{%2, %0|%0, %2}"
4789   [(set_attr "type" "alu")
4790    (set_attr "pent_pair" "pu")
4791    (set_attr "mode" "DI")])
4793 (define_insn "*adddi3_cc_rex64"
4794   [(set (reg:CC FLAGS_REG)
4795         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4796                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4797                    UNSPEC_ADD_CARRY))
4798    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4799         (plus:DI (match_dup 1) (match_dup 2)))]
4800   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4801   "add{q}\t{%2, %0|%0, %2}"
4802   [(set_attr "type" "alu")
4803    (set_attr "mode" "DI")])
4805 (define_insn "addqi3_carry"
4806   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4807           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4808                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4809                    (match_operand:QI 2 "general_operand" "qi,qm")))
4810    (clobber (reg:CC FLAGS_REG))]
4811   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4812   "adc{b}\t{%2, %0|%0, %2}"
4813   [(set_attr "type" "alu")
4814    (set_attr "pent_pair" "pu")
4815    (set_attr "mode" "QI")])
4817 (define_insn "addhi3_carry"
4818   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4819           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4820                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4821                    (match_operand:HI 2 "general_operand" "ri,rm")))
4822    (clobber (reg:CC FLAGS_REG))]
4823   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4824   "adc{w}\t{%2, %0|%0, %2}"
4825   [(set_attr "type" "alu")
4826    (set_attr "pent_pair" "pu")
4827    (set_attr "mode" "HI")])
4829 (define_insn "addsi3_carry"
4830   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4831           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4832                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4833                    (match_operand:SI 2 "general_operand" "ri,rm")))
4834    (clobber (reg:CC FLAGS_REG))]
4835   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4836   "adc{l}\t{%2, %0|%0, %2}"
4837   [(set_attr "type" "alu")
4838    (set_attr "pent_pair" "pu")
4839    (set_attr "mode" "SI")])
4841 (define_insn "*addsi3_carry_zext"
4842   [(set (match_operand:DI 0 "register_operand" "=r")
4843           (zero_extend:DI 
4844             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4845                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4846                      (match_operand:SI 2 "general_operand" "rim"))))
4847    (clobber (reg:CC FLAGS_REG))]
4848   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4849   "adc{l}\t{%2, %k0|%k0, %2}"
4850   [(set_attr "type" "alu")
4851    (set_attr "pent_pair" "pu")
4852    (set_attr "mode" "SI")])
4854 (define_insn "*addsi3_cc"
4855   [(set (reg:CC FLAGS_REG)
4856         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4857                     (match_operand:SI 2 "general_operand" "ri,rm")]
4858                    UNSPEC_ADD_CARRY))
4859    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4860         (plus:SI (match_dup 1) (match_dup 2)))]
4861   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4862   "add{l}\t{%2, %0|%0, %2}"
4863   [(set_attr "type" "alu")
4864    (set_attr "mode" "SI")])
4866 (define_insn "addqi3_cc"
4867   [(set (reg:CC FLAGS_REG)
4868         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4869                     (match_operand:QI 2 "general_operand" "qi,qm")]
4870                    UNSPEC_ADD_CARRY))
4871    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4872         (plus:QI (match_dup 1) (match_dup 2)))]
4873   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4874   "add{b}\t{%2, %0|%0, %2}"
4875   [(set_attr "type" "alu")
4876    (set_attr "mode" "QI")])
4878 (define_expand "addsi3"
4879   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4880                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4881                             (match_operand:SI 2 "general_operand" "")))
4882               (clobber (reg:CC FLAGS_REG))])]
4883   ""
4884   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4886 (define_insn "*lea_1"
4887   [(set (match_operand:SI 0 "register_operand" "=r")
4888         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4889   "!TARGET_64BIT"
4890   "lea{l}\t{%a1, %0|%0, %a1}"
4891   [(set_attr "type" "lea")
4892    (set_attr "mode" "SI")])
4894 (define_insn "*lea_1_rex64"
4895   [(set (match_operand:SI 0 "register_operand" "=r")
4896         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4897   "TARGET_64BIT"
4898   "lea{l}\t{%a1, %0|%0, %a1}"
4899   [(set_attr "type" "lea")
4900    (set_attr "mode" "SI")])
4902 (define_insn "*lea_1_zext"
4903   [(set (match_operand:DI 0 "register_operand" "=r")
4904         (zero_extend:DI
4905          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4906   "TARGET_64BIT"
4907   "lea{l}\t{%a1, %k0|%k0, %a1}"
4908   [(set_attr "type" "lea")
4909    (set_attr "mode" "SI")])
4911 (define_insn "*lea_2_rex64"
4912   [(set (match_operand:DI 0 "register_operand" "=r")
4913         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4914   "TARGET_64BIT"
4915   "lea{q}\t{%a1, %0|%0, %a1}"
4916   [(set_attr "type" "lea")
4917    (set_attr "mode" "DI")])
4919 ;; The lea patterns for non-Pmodes needs to be matched by several
4920 ;; insns converted to real lea by splitters.
4922 (define_insn_and_split "*lea_general_1"
4923   [(set (match_operand 0 "register_operand" "=r")
4924         (plus (plus (match_operand 1 "index_register_operand" "l")
4925                     (match_operand 2 "register_operand" "r"))
4926               (match_operand 3 "immediate_operand" "i")))]
4927   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4928     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4929    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4930    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4931    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4932    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4933        || GET_MODE (operands[3]) == VOIDmode)"
4934   "#"
4935   "&& reload_completed"
4936   [(const_int 0)]
4938   rtx pat;
4939   operands[0] = gen_lowpart (SImode, operands[0]);
4940   operands[1] = gen_lowpart (Pmode, operands[1]);
4941   operands[2] = gen_lowpart (Pmode, operands[2]);
4942   operands[3] = gen_lowpart (Pmode, operands[3]);
4943   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4944                       operands[3]);
4945   if (Pmode != SImode)
4946     pat = gen_rtx_SUBREG (SImode, pat, 0);
4947   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4948   DONE;
4950   [(set_attr "type" "lea")
4951    (set_attr "mode" "SI")])
4953 (define_insn_and_split "*lea_general_1_zext"
4954   [(set (match_operand:DI 0 "register_operand" "=r")
4955         (zero_extend:DI
4956           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4957                             (match_operand:SI 2 "register_operand" "r"))
4958                    (match_operand:SI 3 "immediate_operand" "i"))))]
4959   "TARGET_64BIT"
4960   "#"
4961   "&& reload_completed"
4962   [(set (match_dup 0)
4963         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4964                                                      (match_dup 2))
4965                                             (match_dup 3)) 0)))]
4967   operands[1] = gen_lowpart (Pmode, operands[1]);
4968   operands[2] = gen_lowpart (Pmode, operands[2]);
4969   operands[3] = gen_lowpart (Pmode, operands[3]);
4971   [(set_attr "type" "lea")
4972    (set_attr "mode" "SI")])
4974 (define_insn_and_split "*lea_general_2"
4975   [(set (match_operand 0 "register_operand" "=r")
4976         (plus (mult (match_operand 1 "index_register_operand" "l")
4977                     (match_operand 2 "const248_operand" "i"))
4978               (match_operand 3 "nonmemory_operand" "ri")))]
4979   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4980     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4981    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4982    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4983    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4984        || GET_MODE (operands[3]) == VOIDmode)"
4985   "#"
4986   "&& reload_completed"
4987   [(const_int 0)]
4989   rtx pat;
4990   operands[0] = gen_lowpart (SImode, operands[0]);
4991   operands[1] = gen_lowpart (Pmode, operands[1]);
4992   operands[3] = gen_lowpart (Pmode, operands[3]);
4993   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4994                       operands[3]);
4995   if (Pmode != SImode)
4996     pat = gen_rtx_SUBREG (SImode, pat, 0);
4997   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4998   DONE;
5000   [(set_attr "type" "lea")
5001    (set_attr "mode" "SI")])
5003 (define_insn_and_split "*lea_general_2_zext"
5004   [(set (match_operand:DI 0 "register_operand" "=r")
5005         (zero_extend:DI
5006           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5007                             (match_operand:SI 2 "const248_operand" "n"))
5008                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5009   "TARGET_64BIT"
5010   "#"
5011   "&& reload_completed"
5012   [(set (match_dup 0)
5013         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5014                                                      (match_dup 2))
5015                                             (match_dup 3)) 0)))]
5017   operands[1] = gen_lowpart (Pmode, operands[1]);
5018   operands[3] = gen_lowpart (Pmode, operands[3]);
5020   [(set_attr "type" "lea")
5021    (set_attr "mode" "SI")])
5023 (define_insn_and_split "*lea_general_3"
5024   [(set (match_operand 0 "register_operand" "=r")
5025         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5026                           (match_operand 2 "const248_operand" "i"))
5027                     (match_operand 3 "register_operand" "r"))
5028               (match_operand 4 "immediate_operand" "i")))]
5029   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5030     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5031    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5032    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5033    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5034   "#"
5035   "&& reload_completed"
5036   [(const_int 0)]
5038   rtx pat;
5039   operands[0] = gen_lowpart (SImode, operands[0]);
5040   operands[1] = gen_lowpart (Pmode, operands[1]);
5041   operands[3] = gen_lowpart (Pmode, operands[3]);
5042   operands[4] = gen_lowpart (Pmode, operands[4]);
5043   pat = gen_rtx_PLUS (Pmode,
5044                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5045                                                          operands[2]),
5046                                     operands[3]),
5047                       operands[4]);
5048   if (Pmode != SImode)
5049     pat = gen_rtx_SUBREG (SImode, pat, 0);
5050   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5051   DONE;
5053   [(set_attr "type" "lea")
5054    (set_attr "mode" "SI")])
5056 (define_insn_and_split "*lea_general_3_zext"
5057   [(set (match_operand:DI 0 "register_operand" "=r")
5058         (zero_extend:DI
5059           (plus:SI (plus:SI (mult:SI
5060                               (match_operand:SI 1 "index_register_operand" "l")
5061                               (match_operand:SI 2 "const248_operand" "n"))
5062                             (match_operand:SI 3 "register_operand" "r"))
5063                    (match_operand:SI 4 "immediate_operand" "i"))))]
5064   "TARGET_64BIT"
5065   "#"
5066   "&& reload_completed"
5067   [(set (match_dup 0)
5068         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5069                                                               (match_dup 2))
5070                                                      (match_dup 3))
5071                                             (match_dup 4)) 0)))]
5073   operands[1] = gen_lowpart (Pmode, operands[1]);
5074   operands[3] = gen_lowpart (Pmode, operands[3]);
5075   operands[4] = gen_lowpart (Pmode, operands[4]);
5077   [(set_attr "type" "lea")
5078    (set_attr "mode" "SI")])
5080 (define_insn "*adddi_1_rex64"
5081   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5082         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5083                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5084    (clobber (reg:CC FLAGS_REG))]
5085   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5087   switch (get_attr_type (insn))
5088     {
5089     case TYPE_LEA:
5090       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5091       return "lea{q}\t{%a2, %0|%0, %a2}";
5093     case TYPE_INCDEC:
5094       if (! rtx_equal_p (operands[0], operands[1]))
5095         abort ();
5096       if (operands[2] == const1_rtx)
5097         return "inc{q}\t%0";
5098       else if (operands[2] == constm1_rtx)
5099         return "dec{q}\t%0";
5100       else
5101         abort ();
5103     default:
5104       if (! rtx_equal_p (operands[0], operands[1]))
5105         abort ();
5107       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5108          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5109       if (GET_CODE (operands[2]) == CONST_INT
5110           /* Avoid overflows.  */
5111           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5112           && (INTVAL (operands[2]) == 128
5113               || (INTVAL (operands[2]) < 0
5114                   && INTVAL (operands[2]) != -128)))
5115         {
5116           operands[2] = GEN_INT (-INTVAL (operands[2]));
5117           return "sub{q}\t{%2, %0|%0, %2}";
5118         }
5119       return "add{q}\t{%2, %0|%0, %2}";
5120     }
5122   [(set (attr "type")
5123      (cond [(eq_attr "alternative" "2")
5124               (const_string "lea")
5125             ; Current assemblers are broken and do not allow @GOTOFF in
5126             ; ought but a memory context.
5127             (match_operand:DI 2 "pic_symbolic_operand" "")
5128               (const_string "lea")
5129             (match_operand:DI 2 "incdec_operand" "")
5130               (const_string "incdec")
5131            ]
5132            (const_string "alu")))
5133    (set_attr "mode" "DI")])
5135 ;; Convert lea to the lea pattern to avoid flags dependency.
5136 (define_split
5137   [(set (match_operand:DI 0 "register_operand" "")
5138         (plus:DI (match_operand:DI 1 "register_operand" "")
5139                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5140    (clobber (reg:CC FLAGS_REG))]
5141   "TARGET_64BIT && reload_completed
5142    && true_regnum (operands[0]) != true_regnum (operands[1])"
5143   [(set (match_dup 0)
5144         (plus:DI (match_dup 1)
5145                  (match_dup 2)))]
5146   "")
5148 (define_insn "*adddi_2_rex64"
5149   [(set (reg FLAGS_REG)
5150         (compare
5151           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5152                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5153           (const_int 0)))                       
5154    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5155         (plus:DI (match_dup 1) (match_dup 2)))]
5156   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5157    && ix86_binary_operator_ok (PLUS, DImode, operands)
5158    /* Current assemblers are broken and do not allow @GOTOFF in
5159       ought but a memory context.  */
5160    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5162   switch (get_attr_type (insn))
5163     {
5164     case TYPE_INCDEC:
5165       if (! rtx_equal_p (operands[0], operands[1]))
5166         abort ();
5167       if (operands[2] == const1_rtx)
5168         return "inc{q}\t%0";
5169       else if (operands[2] == constm1_rtx)
5170         return "dec{q}\t%0";
5171       else
5172         abort ();
5174     default:
5175       if (! rtx_equal_p (operands[0], operands[1]))
5176         abort ();
5177       /* ???? We ought to handle there the 32bit case too
5178          - do we need new constraint?  */
5179       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5180          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5181       if (GET_CODE (operands[2]) == CONST_INT
5182           /* Avoid overflows.  */
5183           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5184           && (INTVAL (operands[2]) == 128
5185               || (INTVAL (operands[2]) < 0
5186                   && INTVAL (operands[2]) != -128)))
5187         {
5188           operands[2] = GEN_INT (-INTVAL (operands[2]));
5189           return "sub{q}\t{%2, %0|%0, %2}";
5190         }
5191       return "add{q}\t{%2, %0|%0, %2}";
5192     }
5194   [(set (attr "type")
5195      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5196         (const_string "incdec")
5197         (const_string "alu")))
5198    (set_attr "mode" "DI")])
5200 (define_insn "*adddi_3_rex64"
5201   [(set (reg FLAGS_REG)
5202         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5203                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5204    (clobber (match_scratch:DI 0 "=r"))]
5205   "TARGET_64BIT
5206    && ix86_match_ccmode (insn, CCZmode)
5207    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5208    /* Current assemblers are broken and do not allow @GOTOFF in
5209       ought but a memory context.  */
5210    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5212   switch (get_attr_type (insn))
5213     {
5214     case TYPE_INCDEC:
5215       if (! rtx_equal_p (operands[0], operands[1]))
5216         abort ();
5217       if (operands[2] == const1_rtx)
5218         return "inc{q}\t%0";
5219       else if (operands[2] == constm1_rtx)
5220         return "dec{q}\t%0";
5221       else
5222         abort ();
5224     default:
5225       if (! rtx_equal_p (operands[0], operands[1]))
5226         abort ();
5227       /* ???? We ought to handle there the 32bit case too
5228          - do we need new constraint?  */
5229       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5230          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5231       if (GET_CODE (operands[2]) == CONST_INT
5232           /* Avoid overflows.  */
5233           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5234           && (INTVAL (operands[2]) == 128
5235               || (INTVAL (operands[2]) < 0
5236                   && INTVAL (operands[2]) != -128)))
5237         {
5238           operands[2] = GEN_INT (-INTVAL (operands[2]));
5239           return "sub{q}\t{%2, %0|%0, %2}";
5240         }
5241       return "add{q}\t{%2, %0|%0, %2}";
5242     }
5244   [(set (attr "type")
5245      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5246         (const_string "incdec")
5247         (const_string "alu")))
5248    (set_attr "mode" "DI")])
5250 ; For comparisons against 1, -1 and 128, we may generate better code
5251 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5252 ; is matched then.  We can't accept general immediate, because for
5253 ; case of overflows,  the result is messed up.
5254 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5255 ; when negated.
5256 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5257 ; only for comparisons not depending on it.
5258 (define_insn "*adddi_4_rex64"
5259   [(set (reg FLAGS_REG)
5260         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5261                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5262    (clobber (match_scratch:DI 0 "=rm"))]
5263   "TARGET_64BIT
5264    &&  ix86_match_ccmode (insn, CCGCmode)"
5266   switch (get_attr_type (insn))
5267     {
5268     case TYPE_INCDEC:
5269       if (operands[2] == constm1_rtx)
5270         return "inc{q}\t%0";
5271       else if (operands[2] == const1_rtx)
5272         return "dec{q}\t%0";
5273       else
5274         abort();
5276     default:
5277       if (! rtx_equal_p (operands[0], operands[1]))
5278         abort ();
5279       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5280          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5281       if ((INTVAL (operands[2]) == -128
5282            || (INTVAL (operands[2]) > 0
5283                && INTVAL (operands[2]) != 128))
5284           /* Avoid overflows.  */
5285           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5286         return "sub{q}\t{%2, %0|%0, %2}";
5287       operands[2] = GEN_INT (-INTVAL (operands[2]));
5288       return "add{q}\t{%2, %0|%0, %2}";
5289     }
5291   [(set (attr "type")
5292      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5293         (const_string "incdec")
5294         (const_string "alu")))
5295    (set_attr "mode" "DI")])
5297 (define_insn "*adddi_5_rex64"
5298   [(set (reg FLAGS_REG)
5299         (compare
5300           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5301                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5302           (const_int 0)))                       
5303    (clobber (match_scratch:DI 0 "=r"))]
5304   "TARGET_64BIT
5305    && ix86_match_ccmode (insn, CCGOCmode)
5306    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5307    /* Current assemblers are broken and do not allow @GOTOFF in
5308       ought but a memory context.  */
5309    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5311   switch (get_attr_type (insn))
5312     {
5313     case TYPE_INCDEC:
5314       if (! rtx_equal_p (operands[0], operands[1]))
5315         abort ();
5316       if (operands[2] == const1_rtx)
5317         return "inc{q}\t%0";
5318       else if (operands[2] == constm1_rtx)
5319         return "dec{q}\t%0";
5320       else
5321         abort();
5323     default:
5324       if (! rtx_equal_p (operands[0], operands[1]))
5325         abort ();
5326       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5327          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5328       if (GET_CODE (operands[2]) == CONST_INT
5329           /* Avoid overflows.  */
5330           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5331           && (INTVAL (operands[2]) == 128
5332               || (INTVAL (operands[2]) < 0
5333                   && INTVAL (operands[2]) != -128)))
5334         {
5335           operands[2] = GEN_INT (-INTVAL (operands[2]));
5336           return "sub{q}\t{%2, %0|%0, %2}";
5337         }
5338       return "add{q}\t{%2, %0|%0, %2}";
5339     }
5341   [(set (attr "type")
5342      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5343         (const_string "incdec")
5344         (const_string "alu")))
5345    (set_attr "mode" "DI")])
5348 (define_insn "*addsi_1"
5349   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5350         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5351                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5352    (clobber (reg:CC FLAGS_REG))]
5353   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5355   switch (get_attr_type (insn))
5356     {
5357     case TYPE_LEA:
5358       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5359       return "lea{l}\t{%a2, %0|%0, %a2}";
5361     case TYPE_INCDEC:
5362       if (! rtx_equal_p (operands[0], operands[1]))
5363         abort ();
5364       if (operands[2] == const1_rtx)
5365         return "inc{l}\t%0";
5366       else if (operands[2] == constm1_rtx)
5367         return "dec{l}\t%0";
5368       else
5369         abort();
5371     default:
5372       if (! rtx_equal_p (operands[0], operands[1]))
5373         abort ();
5375       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5376          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5377       if (GET_CODE (operands[2]) == CONST_INT
5378           && (INTVAL (operands[2]) == 128
5379               || (INTVAL (operands[2]) < 0
5380                   && INTVAL (operands[2]) != -128)))
5381         {
5382           operands[2] = GEN_INT (-INTVAL (operands[2]));
5383           return "sub{l}\t{%2, %0|%0, %2}";
5384         }
5385       return "add{l}\t{%2, %0|%0, %2}";
5386     }
5388   [(set (attr "type")
5389      (cond [(eq_attr "alternative" "2")
5390               (const_string "lea")
5391             ; Current assemblers are broken and do not allow @GOTOFF in
5392             ; ought but a memory context.
5393             (match_operand:SI 2 "pic_symbolic_operand" "")
5394               (const_string "lea")
5395             (match_operand:SI 2 "incdec_operand" "")
5396               (const_string "incdec")
5397            ]
5398            (const_string "alu")))
5399    (set_attr "mode" "SI")])
5401 ;; Convert lea to the lea pattern to avoid flags dependency.
5402 (define_split
5403   [(set (match_operand 0 "register_operand" "")
5404         (plus (match_operand 1 "register_operand" "")
5405               (match_operand 2 "nonmemory_operand" "")))
5406    (clobber (reg:CC FLAGS_REG))]
5407   "reload_completed
5408    && true_regnum (operands[0]) != true_regnum (operands[1])"
5409   [(const_int 0)]
5411   rtx pat;
5412   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5413      may confuse gen_lowpart.  */
5414   if (GET_MODE (operands[0]) != Pmode)
5415     {
5416       operands[1] = gen_lowpart (Pmode, operands[1]);
5417       operands[2] = gen_lowpart (Pmode, operands[2]);
5418     }
5419   operands[0] = gen_lowpart (SImode, operands[0]);
5420   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5421   if (Pmode != SImode)
5422     pat = gen_rtx_SUBREG (SImode, pat, 0);
5423   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5424   DONE;
5427 ;; It may seem that nonimmediate operand is proper one for operand 1.
5428 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5429 ;; we take care in ix86_binary_operator_ok to not allow two memory
5430 ;; operands so proper swapping will be done in reload.  This allow
5431 ;; patterns constructed from addsi_1 to match.
5432 (define_insn "addsi_1_zext"
5433   [(set (match_operand:DI 0 "register_operand" "=r,r")
5434         (zero_extend:DI
5435           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5436                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5437    (clobber (reg:CC FLAGS_REG))]
5438   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5440   switch (get_attr_type (insn))
5441     {
5442     case TYPE_LEA:
5443       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5444       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5446     case TYPE_INCDEC:
5447       if (operands[2] == const1_rtx)
5448         return "inc{l}\t%k0";
5449       else if (operands[2] == constm1_rtx)
5450         return "dec{l}\t%k0";
5451       else
5452         abort();
5454     default:
5455       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5456          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5457       if (GET_CODE (operands[2]) == CONST_INT
5458           && (INTVAL (operands[2]) == 128
5459               || (INTVAL (operands[2]) < 0
5460                   && INTVAL (operands[2]) != -128)))
5461         {
5462           operands[2] = GEN_INT (-INTVAL (operands[2]));
5463           return "sub{l}\t{%2, %k0|%k0, %2}";
5464         }
5465       return "add{l}\t{%2, %k0|%k0, %2}";
5466     }
5468   [(set (attr "type")
5469      (cond [(eq_attr "alternative" "1")
5470               (const_string "lea")
5471             ; Current assemblers are broken and do not allow @GOTOFF in
5472             ; ought but a memory context.
5473             (match_operand:SI 2 "pic_symbolic_operand" "")
5474               (const_string "lea")
5475             (match_operand:SI 2 "incdec_operand" "")
5476               (const_string "incdec")
5477            ]
5478            (const_string "alu")))
5479    (set_attr "mode" "SI")])
5481 ;; Convert lea to the lea pattern to avoid flags dependency.
5482 (define_split
5483   [(set (match_operand:DI 0 "register_operand" "")
5484         (zero_extend:DI
5485           (plus:SI (match_operand:SI 1 "register_operand" "")
5486                    (match_operand:SI 2 "nonmemory_operand" ""))))
5487    (clobber (reg:CC FLAGS_REG))]
5488   "TARGET_64BIT && reload_completed
5489    && true_regnum (operands[0]) != true_regnum (operands[1])"
5490   [(set (match_dup 0)
5491         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5493   operands[1] = gen_lowpart (Pmode, operands[1]);
5494   operands[2] = gen_lowpart (Pmode, operands[2]);
5497 (define_insn "*addsi_2"
5498   [(set (reg FLAGS_REG)
5499         (compare
5500           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5501                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5502           (const_int 0)))                       
5503    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5504         (plus:SI (match_dup 1) (match_dup 2)))]
5505   "ix86_match_ccmode (insn, CCGOCmode)
5506    && ix86_binary_operator_ok (PLUS, SImode, operands)
5507    /* Current assemblers are broken and do not allow @GOTOFF in
5508       ought but a memory context.  */
5509    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5511   switch (get_attr_type (insn))
5512     {
5513     case TYPE_INCDEC:
5514       if (! rtx_equal_p (operands[0], operands[1]))
5515         abort ();
5516       if (operands[2] == const1_rtx)
5517         return "inc{l}\t%0";
5518       else if (operands[2] == constm1_rtx)
5519         return "dec{l}\t%0";
5520       else
5521         abort();
5523     default:
5524       if (! rtx_equal_p (operands[0], operands[1]))
5525         abort ();
5526       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5527          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5528       if (GET_CODE (operands[2]) == CONST_INT
5529           && (INTVAL (operands[2]) == 128
5530               || (INTVAL (operands[2]) < 0
5531                   && INTVAL (operands[2]) != -128)))
5532         {
5533           operands[2] = GEN_INT (-INTVAL (operands[2]));
5534           return "sub{l}\t{%2, %0|%0, %2}";
5535         }
5536       return "add{l}\t{%2, %0|%0, %2}";
5537     }
5539   [(set (attr "type")
5540      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5541         (const_string "incdec")
5542         (const_string "alu")))
5543    (set_attr "mode" "SI")])
5545 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5546 (define_insn "*addsi_2_zext"
5547   [(set (reg FLAGS_REG)
5548         (compare
5549           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5550                    (match_operand:SI 2 "general_operand" "rmni"))
5551           (const_int 0)))                       
5552    (set (match_operand:DI 0 "register_operand" "=r")
5553         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5554   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5555    && ix86_binary_operator_ok (PLUS, SImode, operands)
5556    /* Current assemblers are broken and do not allow @GOTOFF in
5557       ought but a memory context.  */
5558    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5560   switch (get_attr_type (insn))
5561     {
5562     case TYPE_INCDEC:
5563       if (operands[2] == const1_rtx)
5564         return "inc{l}\t%k0";
5565       else if (operands[2] == constm1_rtx)
5566         return "dec{l}\t%k0";
5567       else
5568         abort();
5570     default:
5571       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5572          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5573       if (GET_CODE (operands[2]) == CONST_INT
5574           && (INTVAL (operands[2]) == 128
5575               || (INTVAL (operands[2]) < 0
5576                   && INTVAL (operands[2]) != -128)))
5577         {
5578           operands[2] = GEN_INT (-INTVAL (operands[2]));
5579           return "sub{l}\t{%2, %k0|%k0, %2}";
5580         }
5581       return "add{l}\t{%2, %k0|%k0, %2}";
5582     }
5584   [(set (attr "type")
5585      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5586         (const_string "incdec")
5587         (const_string "alu")))
5588    (set_attr "mode" "SI")])
5590 (define_insn "*addsi_3"
5591   [(set (reg FLAGS_REG)
5592         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5593                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5594    (clobber (match_scratch:SI 0 "=r"))]
5595   "ix86_match_ccmode (insn, CCZmode)
5596    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5597    /* Current assemblers are broken and do not allow @GOTOFF in
5598       ought but a memory context.  */
5599    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5601   switch (get_attr_type (insn))
5602     {
5603     case TYPE_INCDEC:
5604       if (! rtx_equal_p (operands[0], operands[1]))
5605         abort ();
5606       if (operands[2] == const1_rtx)
5607         return "inc{l}\t%0";
5608       else if (operands[2] == constm1_rtx)
5609         return "dec{l}\t%0";
5610       else
5611         abort();
5613     default:
5614       if (! rtx_equal_p (operands[0], operands[1]))
5615         abort ();
5616       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5617          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5618       if (GET_CODE (operands[2]) == CONST_INT
5619           && (INTVAL (operands[2]) == 128
5620               || (INTVAL (operands[2]) < 0
5621                   && INTVAL (operands[2]) != -128)))
5622         {
5623           operands[2] = GEN_INT (-INTVAL (operands[2]));
5624           return "sub{l}\t{%2, %0|%0, %2}";
5625         }
5626       return "add{l}\t{%2, %0|%0, %2}";
5627     }
5629   [(set (attr "type")
5630      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5631         (const_string "incdec")
5632         (const_string "alu")))
5633    (set_attr "mode" "SI")])
5635 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5636 (define_insn "*addsi_3_zext"
5637   [(set (reg FLAGS_REG)
5638         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5639                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5640    (set (match_operand:DI 0 "register_operand" "=r")
5641         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5642   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5643    && ix86_binary_operator_ok (PLUS, SImode, operands)
5644    /* Current assemblers are broken and do not allow @GOTOFF in
5645       ought but a memory context.  */
5646    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5648   switch (get_attr_type (insn))
5649     {
5650     case TYPE_INCDEC:
5651       if (operands[2] == const1_rtx)
5652         return "inc{l}\t%k0";
5653       else if (operands[2] == constm1_rtx)
5654         return "dec{l}\t%k0";
5655       else
5656         abort();
5658     default:
5659       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5661       if (GET_CODE (operands[2]) == CONST_INT
5662           && (INTVAL (operands[2]) == 128
5663               || (INTVAL (operands[2]) < 0
5664                   && INTVAL (operands[2]) != -128)))
5665         {
5666           operands[2] = GEN_INT (-INTVAL (operands[2]));
5667           return "sub{l}\t{%2, %k0|%k0, %2}";
5668         }
5669       return "add{l}\t{%2, %k0|%k0, %2}";
5670     }
5672   [(set (attr "type")
5673      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674         (const_string "incdec")
5675         (const_string "alu")))
5676    (set_attr "mode" "SI")])
5678 ; For comparisons against 1, -1 and 128, we may generate better code
5679 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5680 ; is matched then.  We can't accept general immediate, because for
5681 ; case of overflows,  the result is messed up.
5682 ; This pattern also don't hold of 0x80000000, since the value overflows
5683 ; when negated.
5684 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5685 ; only for comparisons not depending on it.
5686 (define_insn "*addsi_4"
5687   [(set (reg FLAGS_REG)
5688         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5689                  (match_operand:SI 2 "const_int_operand" "n")))
5690    (clobber (match_scratch:SI 0 "=rm"))]
5691   "ix86_match_ccmode (insn, CCGCmode)
5692    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5694   switch (get_attr_type (insn))
5695     {
5696     case TYPE_INCDEC:
5697       if (operands[2] == constm1_rtx)
5698         return "inc{l}\t%0";
5699       else if (operands[2] == const1_rtx)
5700         return "dec{l}\t%0";
5701       else
5702         abort();
5704     default:
5705       if (! rtx_equal_p (operands[0], operands[1]))
5706         abort ();
5707       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5708          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5709       if ((INTVAL (operands[2]) == -128
5710            || (INTVAL (operands[2]) > 0
5711                && INTVAL (operands[2]) != 128)))
5712         return "sub{l}\t{%2, %0|%0, %2}";
5713       operands[2] = GEN_INT (-INTVAL (operands[2]));
5714       return "add{l}\t{%2, %0|%0, %2}";
5715     }
5717   [(set (attr "type")
5718      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5719         (const_string "incdec")
5720         (const_string "alu")))
5721    (set_attr "mode" "SI")])
5723 (define_insn "*addsi_5"
5724   [(set (reg FLAGS_REG)
5725         (compare
5726           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5727                    (match_operand:SI 2 "general_operand" "rmni"))
5728           (const_int 0)))                       
5729    (clobber (match_scratch:SI 0 "=r"))]
5730   "ix86_match_ccmode (insn, CCGOCmode)
5731    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5732    /* Current assemblers are broken and do not allow @GOTOFF in
5733       ought but a memory context.  */
5734    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5736   switch (get_attr_type (insn))
5737     {
5738     case TYPE_INCDEC:
5739       if (! rtx_equal_p (operands[0], operands[1]))
5740         abort ();
5741       if (operands[2] == const1_rtx)
5742         return "inc{l}\t%0";
5743       else if (operands[2] == constm1_rtx)
5744         return "dec{l}\t%0";
5745       else
5746         abort();
5748     default:
5749       if (! rtx_equal_p (operands[0], operands[1]))
5750         abort ();
5751       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5752          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5753       if (GET_CODE (operands[2]) == CONST_INT
5754           && (INTVAL (operands[2]) == 128
5755               || (INTVAL (operands[2]) < 0
5756                   && INTVAL (operands[2]) != -128)))
5757         {
5758           operands[2] = GEN_INT (-INTVAL (operands[2]));
5759           return "sub{l}\t{%2, %0|%0, %2}";
5760         }
5761       return "add{l}\t{%2, %0|%0, %2}";
5762     }
5764   [(set (attr "type")
5765      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5766         (const_string "incdec")
5767         (const_string "alu")))
5768    (set_attr "mode" "SI")])
5770 (define_expand "addhi3"
5771   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5772                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5773                             (match_operand:HI 2 "general_operand" "")))
5774               (clobber (reg:CC FLAGS_REG))])]
5775   "TARGET_HIMODE_MATH"
5776   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5778 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5779 ;; type optimizations enabled by define-splits.  This is not important
5780 ;; for PII, and in fact harmful because of partial register stalls.
5782 (define_insn "*addhi_1_lea"
5783   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5784         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5785                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5786    (clobber (reg:CC FLAGS_REG))]
5787   "!TARGET_PARTIAL_REG_STALL
5788    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5790   switch (get_attr_type (insn))
5791     {
5792     case TYPE_LEA:
5793       return "#";
5794     case TYPE_INCDEC:
5795       if (operands[2] == const1_rtx)
5796         return "inc{w}\t%0";
5797       else if (operands[2] == constm1_rtx)
5798         return "dec{w}\t%0";
5799       abort();
5801     default:
5802       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5803          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5804       if (GET_CODE (operands[2]) == CONST_INT
5805           && (INTVAL (operands[2]) == 128
5806               || (INTVAL (operands[2]) < 0
5807                   && INTVAL (operands[2]) != -128)))
5808         {
5809           operands[2] = GEN_INT (-INTVAL (operands[2]));
5810           return "sub{w}\t{%2, %0|%0, %2}";
5811         }
5812       return "add{w}\t{%2, %0|%0, %2}";
5813     }
5815   [(set (attr "type")
5816      (if_then_else (eq_attr "alternative" "2")
5817         (const_string "lea")
5818         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5819            (const_string "incdec")
5820            (const_string "alu"))))
5821    (set_attr "mode" "HI,HI,SI")])
5823 (define_insn "*addhi_1"
5824   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5825         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5826                  (match_operand:HI 2 "general_operand" "ri,rm")))
5827    (clobber (reg:CC FLAGS_REG))]
5828   "TARGET_PARTIAL_REG_STALL
5829    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5831   switch (get_attr_type (insn))
5832     {
5833     case TYPE_INCDEC:
5834       if (operands[2] == const1_rtx)
5835         return "inc{w}\t%0";
5836       else if (operands[2] == constm1_rtx)
5837         return "dec{w}\t%0";
5838       abort();
5840     default:
5841       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5843       if (GET_CODE (operands[2]) == CONST_INT
5844           && (INTVAL (operands[2]) == 128
5845               || (INTVAL (operands[2]) < 0
5846                   && INTVAL (operands[2]) != -128)))
5847         {
5848           operands[2] = GEN_INT (-INTVAL (operands[2]));
5849           return "sub{w}\t{%2, %0|%0, %2}";
5850         }
5851       return "add{w}\t{%2, %0|%0, %2}";
5852     }
5854   [(set (attr "type")
5855      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5856         (const_string "incdec")
5857         (const_string "alu")))
5858    (set_attr "mode" "HI")])
5860 (define_insn "*addhi_2"
5861   [(set (reg FLAGS_REG)
5862         (compare
5863           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5864                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5865           (const_int 0)))                       
5866    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5867         (plus:HI (match_dup 1) (match_dup 2)))]
5868   "ix86_match_ccmode (insn, CCGOCmode)
5869    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5871   switch (get_attr_type (insn))
5872     {
5873     case TYPE_INCDEC:
5874       if (operands[2] == const1_rtx)
5875         return "inc{w}\t%0";
5876       else if (operands[2] == constm1_rtx)
5877         return "dec{w}\t%0";
5878       abort();
5880     default:
5881       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5882          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5883       if (GET_CODE (operands[2]) == CONST_INT
5884           && (INTVAL (operands[2]) == 128
5885               || (INTVAL (operands[2]) < 0
5886                   && INTVAL (operands[2]) != -128)))
5887         {
5888           operands[2] = GEN_INT (-INTVAL (operands[2]));
5889           return "sub{w}\t{%2, %0|%0, %2}";
5890         }
5891       return "add{w}\t{%2, %0|%0, %2}";
5892     }
5894   [(set (attr "type")
5895      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5896         (const_string "incdec")
5897         (const_string "alu")))
5898    (set_attr "mode" "HI")])
5900 (define_insn "*addhi_3"
5901   [(set (reg FLAGS_REG)
5902         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5903                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5904    (clobber (match_scratch:HI 0 "=r"))]
5905   "ix86_match_ccmode (insn, CCZmode)
5906    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5908   switch (get_attr_type (insn))
5909     {
5910     case TYPE_INCDEC:
5911       if (operands[2] == const1_rtx)
5912         return "inc{w}\t%0";
5913       else if (operands[2] == constm1_rtx)
5914         return "dec{w}\t%0";
5915       abort();
5917     default:
5918       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5919          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5920       if (GET_CODE (operands[2]) == CONST_INT
5921           && (INTVAL (operands[2]) == 128
5922               || (INTVAL (operands[2]) < 0
5923                   && INTVAL (operands[2]) != -128)))
5924         {
5925           operands[2] = GEN_INT (-INTVAL (operands[2]));
5926           return "sub{w}\t{%2, %0|%0, %2}";
5927         }
5928       return "add{w}\t{%2, %0|%0, %2}";
5929     }
5931   [(set (attr "type")
5932      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5933         (const_string "incdec")
5934         (const_string "alu")))
5935    (set_attr "mode" "HI")])
5937 ; See comments above addsi_4 for details.
5938 (define_insn "*addhi_4"
5939   [(set (reg FLAGS_REG)
5940         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5941                  (match_operand:HI 2 "const_int_operand" "n")))
5942    (clobber (match_scratch:HI 0 "=rm"))]
5943   "ix86_match_ccmode (insn, CCGCmode)
5944    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5946   switch (get_attr_type (insn))
5947     {
5948     case TYPE_INCDEC:
5949       if (operands[2] == constm1_rtx)
5950         return "inc{w}\t%0";
5951       else if (operands[2] == const1_rtx)
5952         return "dec{w}\t%0";
5953       else
5954         abort();
5956     default:
5957       if (! rtx_equal_p (operands[0], operands[1]))
5958         abort ();
5959       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5960          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5961       if ((INTVAL (operands[2]) == -128
5962            || (INTVAL (operands[2]) > 0
5963                && INTVAL (operands[2]) != 128)))
5964         return "sub{w}\t{%2, %0|%0, %2}";
5965       operands[2] = GEN_INT (-INTVAL (operands[2]));
5966       return "add{w}\t{%2, %0|%0, %2}";
5967     }
5969   [(set (attr "type")
5970      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5971         (const_string "incdec")
5972         (const_string "alu")))
5973    (set_attr "mode" "SI")])
5976 (define_insn "*addhi_5"
5977   [(set (reg FLAGS_REG)
5978         (compare
5979           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5980                    (match_operand:HI 2 "general_operand" "rmni"))
5981           (const_int 0)))                       
5982    (clobber (match_scratch:HI 0 "=r"))]
5983   "ix86_match_ccmode (insn, CCGOCmode)
5984    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5986   switch (get_attr_type (insn))
5987     {
5988     case TYPE_INCDEC:
5989       if (operands[2] == const1_rtx)
5990         return "inc{w}\t%0";
5991       else if (operands[2] == constm1_rtx)
5992         return "dec{w}\t%0";
5993       abort();
5995     default:
5996       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5997          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5998       if (GET_CODE (operands[2]) == CONST_INT
5999           && (INTVAL (operands[2]) == 128
6000               || (INTVAL (operands[2]) < 0
6001                   && INTVAL (operands[2]) != -128)))
6002         {
6003           operands[2] = GEN_INT (-INTVAL (operands[2]));
6004           return "sub{w}\t{%2, %0|%0, %2}";
6005         }
6006       return "add{w}\t{%2, %0|%0, %2}";
6007     }
6009   [(set (attr "type")
6010      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6011         (const_string "incdec")
6012         (const_string "alu")))
6013    (set_attr "mode" "HI")])
6015 (define_expand "addqi3"
6016   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6017                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6018                             (match_operand:QI 2 "general_operand" "")))
6019               (clobber (reg:CC FLAGS_REG))])]
6020   "TARGET_QIMODE_MATH"
6021   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6023 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6024 (define_insn "*addqi_1_lea"
6025   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6026         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6027                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6028    (clobber (reg:CC FLAGS_REG))]
6029   "!TARGET_PARTIAL_REG_STALL
6030    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6032   int widen = (which_alternative == 2);
6033   switch (get_attr_type (insn))
6034     {
6035     case TYPE_LEA:
6036       return "#";
6037     case TYPE_INCDEC:
6038       if (operands[2] == const1_rtx)
6039         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6040       else if (operands[2] == constm1_rtx)
6041         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6042       abort();
6044     default:
6045       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6046          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6047       if (GET_CODE (operands[2]) == CONST_INT
6048           && (INTVAL (operands[2]) == 128
6049               || (INTVAL (operands[2]) < 0
6050                   && INTVAL (operands[2]) != -128)))
6051         {
6052           operands[2] = GEN_INT (-INTVAL (operands[2]));
6053           if (widen)
6054             return "sub{l}\t{%2, %k0|%k0, %2}";
6055           else
6056             return "sub{b}\t{%2, %0|%0, %2}";
6057         }
6058       if (widen)
6059         return "add{l}\t{%k2, %k0|%k0, %k2}";
6060       else
6061         return "add{b}\t{%2, %0|%0, %2}";
6062     }
6064   [(set (attr "type")
6065      (if_then_else (eq_attr "alternative" "3")
6066         (const_string "lea")
6067         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6068            (const_string "incdec")
6069            (const_string "alu"))))
6070    (set_attr "mode" "QI,QI,SI,SI")])
6072 (define_insn "*addqi_1"
6073   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6074         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6075                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6076    (clobber (reg:CC FLAGS_REG))]
6077   "TARGET_PARTIAL_REG_STALL
6078    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6080   int widen = (which_alternative == 2);
6081   switch (get_attr_type (insn))
6082     {
6083     case TYPE_INCDEC:
6084       if (operands[2] == const1_rtx)
6085         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6086       else if (operands[2] == constm1_rtx)
6087         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6088       abort();
6090     default:
6091       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6092          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6093       if (GET_CODE (operands[2]) == CONST_INT
6094           && (INTVAL (operands[2]) == 128
6095               || (INTVAL (operands[2]) < 0
6096                   && INTVAL (operands[2]) != -128)))
6097         {
6098           operands[2] = GEN_INT (-INTVAL (operands[2]));
6099           if (widen)
6100             return "sub{l}\t{%2, %k0|%k0, %2}";
6101           else
6102             return "sub{b}\t{%2, %0|%0, %2}";
6103         }
6104       if (widen)
6105         return "add{l}\t{%k2, %k0|%k0, %k2}";
6106       else
6107         return "add{b}\t{%2, %0|%0, %2}";
6108     }
6110   [(set (attr "type")
6111      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6112         (const_string "incdec")
6113         (const_string "alu")))
6114    (set_attr "mode" "QI,QI,SI")])
6116 (define_insn "*addqi_1_slp"
6117   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6118         (plus:QI (match_dup 0)
6119                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6120    (clobber (reg:CC FLAGS_REG))]
6121   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6122    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6124   switch (get_attr_type (insn))
6125     {
6126     case TYPE_INCDEC:
6127       if (operands[1] == const1_rtx)
6128         return "inc{b}\t%0";
6129       else if (operands[1] == constm1_rtx)
6130         return "dec{b}\t%0";
6131       abort();
6133     default:
6134       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6135       if (GET_CODE (operands[1]) == CONST_INT
6136           && INTVAL (operands[1]) < 0)
6137         {
6138           operands[1] = GEN_INT (-INTVAL (operands[1]));
6139           return "sub{b}\t{%1, %0|%0, %1}";
6140         }
6141       return "add{b}\t{%1, %0|%0, %1}";
6142     }
6144   [(set (attr "type")
6145      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6146         (const_string "incdec")
6147         (const_string "alu1")))
6148    (set (attr "memory")
6149      (if_then_else (match_operand 1 "memory_operand" "")
6150         (const_string "load")
6151         (const_string "none")))
6152    (set_attr "mode" "QI")])
6154 (define_insn "*addqi_2"
6155   [(set (reg FLAGS_REG)
6156         (compare
6157           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6158                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6159           (const_int 0)))
6160    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6161         (plus:QI (match_dup 1) (match_dup 2)))]
6162   "ix86_match_ccmode (insn, CCGOCmode)
6163    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6165   switch (get_attr_type (insn))
6166     {
6167     case TYPE_INCDEC:
6168       if (operands[2] == const1_rtx)
6169         return "inc{b}\t%0";
6170       else if (operands[2] == constm1_rtx
6171                || (GET_CODE (operands[2]) == CONST_INT
6172                    && INTVAL (operands[2]) == 255))
6173         return "dec{b}\t%0";
6174       abort();
6176     default:
6177       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6178       if (GET_CODE (operands[2]) == CONST_INT
6179           && INTVAL (operands[2]) < 0)
6180         {
6181           operands[2] = GEN_INT (-INTVAL (operands[2]));
6182           return "sub{b}\t{%2, %0|%0, %2}";
6183         }
6184       return "add{b}\t{%2, %0|%0, %2}";
6185     }
6187   [(set (attr "type")
6188      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6189         (const_string "incdec")
6190         (const_string "alu")))
6191    (set_attr "mode" "QI")])
6193 (define_insn "*addqi_3"
6194   [(set (reg FLAGS_REG)
6195         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6196                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6197    (clobber (match_scratch:QI 0 "=q"))]
6198   "ix86_match_ccmode (insn, CCZmode)
6199    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6201   switch (get_attr_type (insn))
6202     {
6203     case TYPE_INCDEC:
6204       if (operands[2] == const1_rtx)
6205         return "inc{b}\t%0";
6206       else if (operands[2] == constm1_rtx
6207                || (GET_CODE (operands[2]) == CONST_INT
6208                    && INTVAL (operands[2]) == 255))
6209         return "dec{b}\t%0";
6210       abort();
6212     default:
6213       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6214       if (GET_CODE (operands[2]) == CONST_INT
6215           && INTVAL (operands[2]) < 0)
6216         {
6217           operands[2] = GEN_INT (-INTVAL (operands[2]));
6218           return "sub{b}\t{%2, %0|%0, %2}";
6219         }
6220       return "add{b}\t{%2, %0|%0, %2}";
6221     }
6223   [(set (attr "type")
6224      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6225         (const_string "incdec")
6226         (const_string "alu")))
6227    (set_attr "mode" "QI")])
6229 ; See comments above addsi_4 for details.
6230 (define_insn "*addqi_4"
6231   [(set (reg FLAGS_REG)
6232         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6233                  (match_operand:QI 2 "const_int_operand" "n")))
6234    (clobber (match_scratch:QI 0 "=qm"))]
6235   "ix86_match_ccmode (insn, CCGCmode)
6236    && (INTVAL (operands[2]) & 0xff) != 0x80"
6238   switch (get_attr_type (insn))
6239     {
6240     case TYPE_INCDEC:
6241       if (operands[2] == constm1_rtx
6242           || (GET_CODE (operands[2]) == CONST_INT
6243               && INTVAL (operands[2]) == 255))
6244         return "inc{b}\t%0";
6245       else if (operands[2] == const1_rtx)
6246         return "dec{b}\t%0";
6247       else
6248         abort();
6250     default:
6251       if (! rtx_equal_p (operands[0], operands[1]))
6252         abort ();
6253       if (INTVAL (operands[2]) < 0)
6254         {
6255           operands[2] = GEN_INT (-INTVAL (operands[2]));
6256           return "add{b}\t{%2, %0|%0, %2}";
6257         }
6258       return "sub{b}\t{%2, %0|%0, %2}";
6259     }
6261   [(set (attr "type")
6262      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6263         (const_string "incdec")
6264         (const_string "alu")))
6265    (set_attr "mode" "QI")])
6268 (define_insn "*addqi_5"
6269   [(set (reg FLAGS_REG)
6270         (compare
6271           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6272                    (match_operand:QI 2 "general_operand" "qmni"))
6273           (const_int 0)))
6274    (clobber (match_scratch:QI 0 "=q"))]
6275   "ix86_match_ccmode (insn, CCGOCmode)
6276    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6278   switch (get_attr_type (insn))
6279     {
6280     case TYPE_INCDEC:
6281       if (operands[2] == const1_rtx)
6282         return "inc{b}\t%0";
6283       else if (operands[2] == constm1_rtx
6284                || (GET_CODE (operands[2]) == CONST_INT
6285                    && INTVAL (operands[2]) == 255))
6286         return "dec{b}\t%0";
6287       abort();
6289     default:
6290       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6291       if (GET_CODE (operands[2]) == CONST_INT
6292           && INTVAL (operands[2]) < 0)
6293         {
6294           operands[2] = GEN_INT (-INTVAL (operands[2]));
6295           return "sub{b}\t{%2, %0|%0, %2}";
6296         }
6297       return "add{b}\t{%2, %0|%0, %2}";
6298     }
6300   [(set (attr "type")
6301      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6302         (const_string "incdec")
6303         (const_string "alu")))
6304    (set_attr "mode" "QI")])
6307 (define_insn "addqi_ext_1"
6308   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6309                          (const_int 8)
6310                          (const_int 8))
6311         (plus:SI
6312           (zero_extract:SI
6313             (match_operand 1 "ext_register_operand" "0")
6314             (const_int 8)
6315             (const_int 8))
6316           (match_operand:QI 2 "general_operand" "Qmn")))
6317    (clobber (reg:CC FLAGS_REG))]
6318   "!TARGET_64BIT"
6320   switch (get_attr_type (insn))
6321     {
6322     case TYPE_INCDEC:
6323       if (operands[2] == const1_rtx)
6324         return "inc{b}\t%h0";
6325       else if (operands[2] == constm1_rtx
6326                || (GET_CODE (operands[2]) == CONST_INT
6327                    && INTVAL (operands[2]) == 255))
6328         return "dec{b}\t%h0";
6329       abort();
6331     default:
6332       return "add{b}\t{%2, %h0|%h0, %2}";
6333     }
6335   [(set (attr "type")
6336      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6337         (const_string "incdec")
6338         (const_string "alu")))
6339    (set_attr "mode" "QI")])
6341 (define_insn "*addqi_ext_1_rex64"
6342   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6343                          (const_int 8)
6344                          (const_int 8))
6345         (plus:SI
6346           (zero_extract:SI
6347             (match_operand 1 "ext_register_operand" "0")
6348             (const_int 8)
6349             (const_int 8))
6350           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6351    (clobber (reg:CC FLAGS_REG))]
6352   "TARGET_64BIT"
6354   switch (get_attr_type (insn))
6355     {
6356     case TYPE_INCDEC:
6357       if (operands[2] == const1_rtx)
6358         return "inc{b}\t%h0";
6359       else if (operands[2] == constm1_rtx
6360                || (GET_CODE (operands[2]) == CONST_INT
6361                    && INTVAL (operands[2]) == 255))
6362         return "dec{b}\t%h0";
6363       abort();
6365     default:
6366       return "add{b}\t{%2, %h0|%h0, %2}";
6367     }
6369   [(set (attr "type")
6370      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6371         (const_string "incdec")
6372         (const_string "alu")))
6373    (set_attr "mode" "QI")])
6375 (define_insn "*addqi_ext_2"
6376   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6377                          (const_int 8)
6378                          (const_int 8))
6379         (plus:SI
6380           (zero_extract:SI
6381             (match_operand 1 "ext_register_operand" "%0")
6382             (const_int 8)
6383             (const_int 8))
6384           (zero_extract:SI
6385             (match_operand 2 "ext_register_operand" "Q")
6386             (const_int 8)
6387             (const_int 8))))
6388    (clobber (reg:CC FLAGS_REG))]
6389   ""
6390   "add{b}\t{%h2, %h0|%h0, %h2}"
6391   [(set_attr "type" "alu")
6392    (set_attr "mode" "QI")])
6394 ;; The patterns that match these are at the end of this file.
6396 (define_expand "addxf3"
6397   [(set (match_operand:XF 0 "register_operand" "")
6398         (plus:XF (match_operand:XF 1 "register_operand" "")
6399                  (match_operand:XF 2 "register_operand" "")))]
6400   "TARGET_80387"
6401   "")
6403 (define_expand "adddf3"
6404   [(set (match_operand:DF 0 "register_operand" "")
6405         (plus:DF (match_operand:DF 1 "register_operand" "")
6406                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6407   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6408   "")
6410 (define_expand "addsf3"
6411   [(set (match_operand:SF 0 "register_operand" "")
6412         (plus:SF (match_operand:SF 1 "register_operand" "")
6413                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6414   "TARGET_80387 || TARGET_SSE_MATH"
6415   "")
6417 ;; Subtract instructions
6419 ;; %%% splits for subsidi3
6421 (define_expand "subdi3"
6422   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6423                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6424                              (match_operand:DI 2 "x86_64_general_operand" "")))
6425               (clobber (reg:CC FLAGS_REG))])]
6426   ""
6427   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6429 (define_insn "*subdi3_1"
6430   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6431         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6432                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6433    (clobber (reg:CC FLAGS_REG))]
6434   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6435   "#")
6437 (define_split
6438   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6439         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6440                   (match_operand:DI 2 "general_operand" "")))
6441    (clobber (reg:CC FLAGS_REG))]
6442   "!TARGET_64BIT && reload_completed"
6443   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6444               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6445    (parallel [(set (match_dup 3)
6446                    (minus:SI (match_dup 4)
6447                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6448                                       (match_dup 5))))
6449               (clobber (reg:CC FLAGS_REG))])]
6450   "split_di (operands+0, 1, operands+0, operands+3);
6451    split_di (operands+1, 1, operands+1, operands+4);
6452    split_di (operands+2, 1, operands+2, operands+5);")
6454 (define_insn "subdi3_carry_rex64"
6455   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6456           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6457             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6458                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6459    (clobber (reg:CC FLAGS_REG))]
6460   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6461   "sbb{q}\t{%2, %0|%0, %2}"
6462   [(set_attr "type" "alu")
6463    (set_attr "pent_pair" "pu")
6464    (set_attr "mode" "DI")])
6466 (define_insn "*subdi_1_rex64"
6467   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6468         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6469                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6470    (clobber (reg:CC FLAGS_REG))]
6471   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6472   "sub{q}\t{%2, %0|%0, %2}"
6473   [(set_attr "type" "alu")
6474    (set_attr "mode" "DI")])
6476 (define_insn "*subdi_2_rex64"
6477   [(set (reg FLAGS_REG)
6478         (compare
6479           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6480                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6481           (const_int 0)))
6482    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6483         (minus:DI (match_dup 1) (match_dup 2)))]
6484   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6485    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6486   "sub{q}\t{%2, %0|%0, %2}"
6487   [(set_attr "type" "alu")
6488    (set_attr "mode" "DI")])
6490 (define_insn "*subdi_3_rex63"
6491   [(set (reg FLAGS_REG)
6492         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6493                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6494    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6495         (minus:DI (match_dup 1) (match_dup 2)))]
6496   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6497    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6498   "sub{q}\t{%2, %0|%0, %2}"
6499   [(set_attr "type" "alu")
6500    (set_attr "mode" "DI")])
6502 (define_insn "subqi3_carry"
6503   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6504           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6505             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6506                (match_operand:QI 2 "general_operand" "qi,qm"))))
6507    (clobber (reg:CC FLAGS_REG))]
6508   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6509   "sbb{b}\t{%2, %0|%0, %2}"
6510   [(set_attr "type" "alu")
6511    (set_attr "pent_pair" "pu")
6512    (set_attr "mode" "QI")])
6514 (define_insn "subhi3_carry"
6515   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6516           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6517             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6518                (match_operand:HI 2 "general_operand" "ri,rm"))))
6519    (clobber (reg:CC FLAGS_REG))]
6520   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6521   "sbb{w}\t{%2, %0|%0, %2}"
6522   [(set_attr "type" "alu")
6523    (set_attr "pent_pair" "pu")
6524    (set_attr "mode" "HI")])
6526 (define_insn "subsi3_carry"
6527   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6528           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6529             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6530                (match_operand:SI 2 "general_operand" "ri,rm"))))
6531    (clobber (reg:CC FLAGS_REG))]
6532   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6533   "sbb{l}\t{%2, %0|%0, %2}"
6534   [(set_attr "type" "alu")
6535    (set_attr "pent_pair" "pu")
6536    (set_attr "mode" "SI")])
6538 (define_insn "subsi3_carry_zext"
6539   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6540           (zero_extend:DI
6541             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6542               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6543                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6544    (clobber (reg:CC FLAGS_REG))]
6545   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6546   "sbb{l}\t{%2, %k0|%k0, %2}"
6547   [(set_attr "type" "alu")
6548    (set_attr "pent_pair" "pu")
6549    (set_attr "mode" "SI")])
6551 (define_expand "subsi3"
6552   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6553                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6554                              (match_operand:SI 2 "general_operand" "")))
6555               (clobber (reg:CC FLAGS_REG))])]
6556   ""
6557   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6559 (define_insn "*subsi_1"
6560   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6561         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6562                   (match_operand:SI 2 "general_operand" "ri,rm")))
6563    (clobber (reg:CC FLAGS_REG))]
6564   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6565   "sub{l}\t{%2, %0|%0, %2}"
6566   [(set_attr "type" "alu")
6567    (set_attr "mode" "SI")])
6569 (define_insn "*subsi_1_zext"
6570   [(set (match_operand:DI 0 "register_operand" "=r")
6571         (zero_extend:DI
6572           (minus:SI (match_operand:SI 1 "register_operand" "0")
6573                     (match_operand:SI 2 "general_operand" "rim"))))
6574    (clobber (reg:CC FLAGS_REG))]
6575   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6576   "sub{l}\t{%2, %k0|%k0, %2}"
6577   [(set_attr "type" "alu")
6578    (set_attr "mode" "SI")])
6580 (define_insn "*subsi_2"
6581   [(set (reg FLAGS_REG)
6582         (compare
6583           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6584                     (match_operand:SI 2 "general_operand" "ri,rm"))
6585           (const_int 0)))
6586    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6587         (minus:SI (match_dup 1) (match_dup 2)))]
6588   "ix86_match_ccmode (insn, CCGOCmode)
6589    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6590   "sub{l}\t{%2, %0|%0, %2}"
6591   [(set_attr "type" "alu")
6592    (set_attr "mode" "SI")])
6594 (define_insn "*subsi_2_zext"
6595   [(set (reg FLAGS_REG)
6596         (compare
6597           (minus:SI (match_operand:SI 1 "register_operand" "0")
6598                     (match_operand:SI 2 "general_operand" "rim"))
6599           (const_int 0)))
6600    (set (match_operand:DI 0 "register_operand" "=r")
6601         (zero_extend:DI
6602           (minus:SI (match_dup 1)
6603                     (match_dup 2))))]
6604   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6605    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6606   "sub{l}\t{%2, %k0|%k0, %2}"
6607   [(set_attr "type" "alu")
6608    (set_attr "mode" "SI")])
6610 (define_insn "*subsi_3"
6611   [(set (reg FLAGS_REG)
6612         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6613                  (match_operand:SI 2 "general_operand" "ri,rm")))
6614    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6615         (minus:SI (match_dup 1) (match_dup 2)))]
6616   "ix86_match_ccmode (insn, CCmode)
6617    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6618   "sub{l}\t{%2, %0|%0, %2}"
6619   [(set_attr "type" "alu")
6620    (set_attr "mode" "SI")])
6622 (define_insn "*subsi_3_zext"
6623   [(set (reg FLAGS_REG)
6624         (compare (match_operand:SI 1 "register_operand" "0")
6625                  (match_operand:SI 2 "general_operand" "rim")))
6626    (set (match_operand:DI 0 "register_operand" "=r")
6627         (zero_extend:DI
6628           (minus:SI (match_dup 1)
6629                     (match_dup 2))))]
6630   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6631    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6632   "sub{q}\t{%2, %0|%0, %2}"
6633   [(set_attr "type" "alu")
6634    (set_attr "mode" "DI")])
6636 (define_expand "subhi3"
6637   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6638                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6639                              (match_operand:HI 2 "general_operand" "")))
6640               (clobber (reg:CC FLAGS_REG))])]
6641   "TARGET_HIMODE_MATH"
6642   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6644 (define_insn "*subhi_1"
6645   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6646         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6647                   (match_operand:HI 2 "general_operand" "ri,rm")))
6648    (clobber (reg:CC FLAGS_REG))]
6649   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6650   "sub{w}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "HI")])
6654 (define_insn "*subhi_2"
6655   [(set (reg FLAGS_REG)
6656         (compare
6657           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6658                     (match_operand:HI 2 "general_operand" "ri,rm"))
6659           (const_int 0)))
6660    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6661         (minus:HI (match_dup 1) (match_dup 2)))]
6662   "ix86_match_ccmode (insn, CCGOCmode)
6663    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6664   "sub{w}\t{%2, %0|%0, %2}"
6665   [(set_attr "type" "alu")
6666    (set_attr "mode" "HI")])
6668 (define_insn "*subhi_3"
6669   [(set (reg FLAGS_REG)
6670         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6671                  (match_operand:HI 2 "general_operand" "ri,rm")))
6672    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6673         (minus:HI (match_dup 1) (match_dup 2)))]
6674   "ix86_match_ccmode (insn, CCmode)
6675    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6676   "sub{w}\t{%2, %0|%0, %2}"
6677   [(set_attr "type" "alu")
6678    (set_attr "mode" "HI")])
6680 (define_expand "subqi3"
6681   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6682                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6683                              (match_operand:QI 2 "general_operand" "")))
6684               (clobber (reg:CC FLAGS_REG))])]
6685   "TARGET_QIMODE_MATH"
6686   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6688 (define_insn "*subqi_1"
6689   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6690         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6691                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6692    (clobber (reg:CC FLAGS_REG))]
6693   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6694   "sub{b}\t{%2, %0|%0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "mode" "QI")])
6698 (define_insn "*subqi_1_slp"
6699   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6700         (minus:QI (match_dup 0)
6701                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6702    (clobber (reg:CC FLAGS_REG))]
6703   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6704    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6705   "sub{b}\t{%1, %0|%0, %1}"
6706   [(set_attr "type" "alu1")
6707    (set_attr "mode" "QI")])
6709 (define_insn "*subqi_2"
6710   [(set (reg FLAGS_REG)
6711         (compare
6712           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6713                     (match_operand:QI 2 "general_operand" "qi,qm"))
6714           (const_int 0)))
6715    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6716         (minus:HI (match_dup 1) (match_dup 2)))]
6717   "ix86_match_ccmode (insn, CCGOCmode)
6718    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6719   "sub{b}\t{%2, %0|%0, %2}"
6720   [(set_attr "type" "alu")
6721    (set_attr "mode" "QI")])
6723 (define_insn "*subqi_3"
6724   [(set (reg FLAGS_REG)
6725         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6726                  (match_operand:QI 2 "general_operand" "qi,qm")))
6727    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6728         (minus:HI (match_dup 1) (match_dup 2)))]
6729   "ix86_match_ccmode (insn, CCmode)
6730    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6731   "sub{b}\t{%2, %0|%0, %2}"
6732   [(set_attr "type" "alu")
6733    (set_attr "mode" "QI")])
6735 ;; The patterns that match these are at the end of this file.
6737 (define_expand "subxf3"
6738   [(set (match_operand:XF 0 "register_operand" "")
6739         (minus:XF (match_operand:XF 1 "register_operand" "")
6740                   (match_operand:XF 2 "register_operand" "")))]
6741   "TARGET_80387"
6742   "")
6744 (define_expand "subdf3"
6745   [(set (match_operand:DF 0 "register_operand" "")
6746         (minus:DF (match_operand:DF 1 "register_operand" "")
6747                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6748   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6749   "")
6751 (define_expand "subsf3"
6752   [(set (match_operand:SF 0 "register_operand" "")
6753         (minus:SF (match_operand:SF 1 "register_operand" "")
6754                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6755   "TARGET_80387 || TARGET_SSE_MATH"
6756   "")
6758 ;; Multiply instructions
6760 (define_expand "muldi3"
6761   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6762                    (mult:DI (match_operand:DI 1 "register_operand" "")
6763                             (match_operand:DI 2 "x86_64_general_operand" "")))
6764               (clobber (reg:CC FLAGS_REG))])]
6765   "TARGET_64BIT"
6766   "")
6768 (define_insn "*muldi3_1_rex64"
6769   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6770         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6771                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6772    (clobber (reg:CC FLAGS_REG))]
6773   "TARGET_64BIT
6774    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6775   "@
6776    imul{q}\t{%2, %1, %0|%0, %1, %2}
6777    imul{q}\t{%2, %1, %0|%0, %1, %2}
6778    imul{q}\t{%2, %0|%0, %2}"
6779   [(set_attr "type" "imul")
6780    (set_attr "prefix_0f" "0,0,1")
6781    (set (attr "athlon_decode")
6782         (cond [(eq_attr "cpu" "athlon")
6783                   (const_string "vector")
6784                (eq_attr "alternative" "1")
6785                   (const_string "vector")
6786                (and (eq_attr "alternative" "2")
6787                     (match_operand 1 "memory_operand" ""))
6788                   (const_string "vector")]
6789               (const_string "direct")))
6790    (set_attr "mode" "DI")])
6792 (define_expand "mulsi3"
6793   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6794                    (mult:SI (match_operand:SI 1 "register_operand" "")
6795                             (match_operand:SI 2 "general_operand" "")))
6796               (clobber (reg:CC FLAGS_REG))])]
6797   ""
6798   "")
6800 (define_insn "*mulsi3_1"
6801   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6802         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6803                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6804    (clobber (reg:CC FLAGS_REG))]
6805   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6806   "@
6807    imul{l}\t{%2, %1, %0|%0, %1, %2}
6808    imul{l}\t{%2, %1, %0|%0, %1, %2}
6809    imul{l}\t{%2, %0|%0, %2}"
6810   [(set_attr "type" "imul")
6811    (set_attr "prefix_0f" "0,0,1")
6812    (set (attr "athlon_decode")
6813         (cond [(eq_attr "cpu" "athlon")
6814                   (const_string "vector")
6815                (eq_attr "alternative" "1")
6816                   (const_string "vector")
6817                (and (eq_attr "alternative" "2")
6818                     (match_operand 1 "memory_operand" ""))
6819                   (const_string "vector")]
6820               (const_string "direct")))
6821    (set_attr "mode" "SI")])
6823 (define_insn "*mulsi3_1_zext"
6824   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6825         (zero_extend:DI
6826           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6827                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6828    (clobber (reg:CC FLAGS_REG))]
6829   "TARGET_64BIT
6830    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6831   "@
6832    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6833    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6834    imul{l}\t{%2, %k0|%k0, %2}"
6835   [(set_attr "type" "imul")
6836    (set_attr "prefix_0f" "0,0,1")
6837    (set (attr "athlon_decode")
6838         (cond [(eq_attr "cpu" "athlon")
6839                   (const_string "vector")
6840                (eq_attr "alternative" "1")
6841                   (const_string "vector")
6842                (and (eq_attr "alternative" "2")
6843                     (match_operand 1 "memory_operand" ""))
6844                   (const_string "vector")]
6845               (const_string "direct")))
6846    (set_attr "mode" "SI")])
6848 (define_expand "mulhi3"
6849   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6850                    (mult:HI (match_operand:HI 1 "register_operand" "")
6851                             (match_operand:HI 2 "general_operand" "")))
6852               (clobber (reg:CC FLAGS_REG))])]
6853   "TARGET_HIMODE_MATH"
6854   "")
6856 (define_insn "*mulhi3_1"
6857   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6858         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6859                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6860    (clobber (reg:CC FLAGS_REG))]
6861   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6862   "@
6863    imul{w}\t{%2, %1, %0|%0, %1, %2}
6864    imul{w}\t{%2, %1, %0|%0, %1, %2}
6865    imul{w}\t{%2, %0|%0, %2}"
6866   [(set_attr "type" "imul")
6867    (set_attr "prefix_0f" "0,0,1")
6868    (set (attr "athlon_decode")
6869         (cond [(eq_attr "cpu" "athlon")
6870                   (const_string "vector")
6871                (eq_attr "alternative" "1,2")
6872                   (const_string "vector")]
6873               (const_string "direct")))
6874    (set_attr "mode" "HI")])
6876 (define_expand "mulqi3"
6877   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6878                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6879                             (match_operand:QI 2 "register_operand" "")))
6880               (clobber (reg:CC FLAGS_REG))])]
6881   "TARGET_QIMODE_MATH"
6882   "")
6884 (define_insn "*mulqi3_1"
6885   [(set (match_operand:QI 0 "register_operand" "=a")
6886         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6887                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6888    (clobber (reg:CC FLAGS_REG))]
6889   "TARGET_QIMODE_MATH
6890    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6891   "mul{b}\t%2"
6892   [(set_attr "type" "imul")
6893    (set_attr "length_immediate" "0")
6894    (set (attr "athlon_decode")
6895      (if_then_else (eq_attr "cpu" "athlon")
6896         (const_string "vector")
6897         (const_string "direct")))
6898    (set_attr "mode" "QI")])
6900 (define_expand "umulqihi3"
6901   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6902                    (mult:HI (zero_extend:HI
6903                               (match_operand:QI 1 "nonimmediate_operand" ""))
6904                             (zero_extend:HI
6905                               (match_operand:QI 2 "register_operand" ""))))
6906               (clobber (reg:CC FLAGS_REG))])]
6907   "TARGET_QIMODE_MATH"
6908   "")
6910 (define_insn "*umulqihi3_1"
6911   [(set (match_operand:HI 0 "register_operand" "=a")
6912         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6913                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6914    (clobber (reg:CC FLAGS_REG))]
6915   "TARGET_QIMODE_MATH
6916    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6917   "mul{b}\t%2"
6918   [(set_attr "type" "imul")
6919    (set_attr "length_immediate" "0")
6920    (set (attr "athlon_decode")
6921      (if_then_else (eq_attr "cpu" "athlon")
6922         (const_string "vector")
6923         (const_string "direct")))
6924    (set_attr "mode" "QI")])
6926 (define_expand "mulqihi3"
6927   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6928                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6929                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6930               (clobber (reg:CC FLAGS_REG))])]
6931   "TARGET_QIMODE_MATH"
6932   "")
6934 (define_insn "*mulqihi3_insn"
6935   [(set (match_operand:HI 0 "register_operand" "=a")
6936         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6937                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6938    (clobber (reg:CC FLAGS_REG))]
6939   "TARGET_QIMODE_MATH
6940    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6941   "imul{b}\t%2"
6942   [(set_attr "type" "imul")
6943    (set_attr "length_immediate" "0")
6944    (set (attr "athlon_decode")
6945      (if_then_else (eq_attr "cpu" "athlon")
6946         (const_string "vector")
6947         (const_string "direct")))
6948    (set_attr "mode" "QI")])
6950 (define_expand "umulditi3"
6951   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6952                    (mult:TI (zero_extend:TI
6953                               (match_operand:DI 1 "nonimmediate_operand" ""))
6954                             (zero_extend:TI
6955                               (match_operand:DI 2 "register_operand" ""))))
6956               (clobber (reg:CC FLAGS_REG))])]
6957   "TARGET_64BIT"
6958   "")
6960 (define_insn "*umulditi3_insn"
6961   [(set (match_operand:TI 0 "register_operand" "=A")
6962         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6963                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6964    (clobber (reg:CC FLAGS_REG))]
6965   "TARGET_64BIT
6966    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6967   "mul{q}\t%2"
6968   [(set_attr "type" "imul")
6969    (set_attr "length_immediate" "0")
6970    (set (attr "athlon_decode")
6971      (if_then_else (eq_attr "cpu" "athlon")
6972         (const_string "vector")
6973         (const_string "double")))
6974    (set_attr "mode" "DI")])
6976 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6977 (define_expand "umulsidi3"
6978   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6979                    (mult:DI (zero_extend:DI
6980                               (match_operand:SI 1 "nonimmediate_operand" ""))
6981                             (zero_extend:DI
6982                               (match_operand:SI 2 "register_operand" ""))))
6983               (clobber (reg:CC FLAGS_REG))])]
6984   "!TARGET_64BIT"
6985   "")
6987 (define_insn "*umulsidi3_insn"
6988   [(set (match_operand:DI 0 "register_operand" "=A")
6989         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6990                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6991    (clobber (reg:CC FLAGS_REG))]
6992   "!TARGET_64BIT
6993    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6994   "mul{l}\t%2"
6995   [(set_attr "type" "imul")
6996    (set_attr "length_immediate" "0")
6997    (set (attr "athlon_decode")
6998      (if_then_else (eq_attr "cpu" "athlon")
6999         (const_string "vector")
7000         (const_string "double")))
7001    (set_attr "mode" "SI")])
7003 (define_expand "mulditi3"
7004   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7005                    (mult:TI (sign_extend:TI
7006                               (match_operand:DI 1 "nonimmediate_operand" ""))
7007                             (sign_extend:TI
7008                               (match_operand:DI 2 "register_operand" ""))))
7009               (clobber (reg:CC FLAGS_REG))])]
7010   "TARGET_64BIT"
7011   "")
7013 (define_insn "*mulditi3_insn"
7014   [(set (match_operand:TI 0 "register_operand" "=A")
7015         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7016                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7017    (clobber (reg:CC FLAGS_REG))]
7018   "TARGET_64BIT
7019    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7020   "imul{q}\t%2"
7021   [(set_attr "type" "imul")
7022    (set_attr "length_immediate" "0")
7023    (set (attr "athlon_decode")
7024      (if_then_else (eq_attr "cpu" "athlon")
7025         (const_string "vector")
7026         (const_string "double")))
7027    (set_attr "mode" "DI")])
7029 (define_expand "mulsidi3"
7030   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7031                    (mult:DI (sign_extend:DI
7032                               (match_operand:SI 1 "nonimmediate_operand" ""))
7033                             (sign_extend:DI
7034                               (match_operand:SI 2 "register_operand" ""))))
7035               (clobber (reg:CC FLAGS_REG))])]
7036   "!TARGET_64BIT"
7037   "")
7039 (define_insn "*mulsidi3_insn"
7040   [(set (match_operand:DI 0 "register_operand" "=A")
7041         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7042                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7043    (clobber (reg:CC FLAGS_REG))]
7044   "!TARGET_64BIT
7045    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7046   "imul{l}\t%2"
7047   [(set_attr "type" "imul")
7048    (set_attr "length_immediate" "0")
7049    (set (attr "athlon_decode")
7050      (if_then_else (eq_attr "cpu" "athlon")
7051         (const_string "vector")
7052         (const_string "double")))
7053    (set_attr "mode" "SI")])
7055 (define_expand "umuldi3_highpart"
7056   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7057                    (truncate:DI
7058                      (lshiftrt:TI
7059                        (mult:TI (zero_extend:TI
7060                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7061                                 (zero_extend:TI
7062                                   (match_operand:DI 2 "register_operand" "")))
7063                        (const_int 64))))
7064               (clobber (match_scratch:DI 3 ""))
7065               (clobber (reg:CC FLAGS_REG))])]
7066   "TARGET_64BIT"
7067   "")
7069 (define_insn "*umuldi3_highpart_rex64"
7070   [(set (match_operand:DI 0 "register_operand" "=d")
7071         (truncate:DI
7072           (lshiftrt:TI
7073             (mult:TI (zero_extend:TI
7074                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7075                      (zero_extend:TI
7076                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7077             (const_int 64))))
7078    (clobber (match_scratch:DI 3 "=1"))
7079    (clobber (reg:CC FLAGS_REG))]
7080   "TARGET_64BIT
7081    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7082   "mul{q}\t%2"
7083   [(set_attr "type" "imul")
7084    (set_attr "length_immediate" "0")
7085    (set (attr "athlon_decode")
7086      (if_then_else (eq_attr "cpu" "athlon")
7087         (const_string "vector")
7088         (const_string "double")))
7089    (set_attr "mode" "DI")])
7091 (define_expand "umulsi3_highpart"
7092   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7093                    (truncate:SI
7094                      (lshiftrt:DI
7095                        (mult:DI (zero_extend:DI
7096                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7097                                 (zero_extend:DI
7098                                   (match_operand:SI 2 "register_operand" "")))
7099                        (const_int 32))))
7100               (clobber (match_scratch:SI 3 ""))
7101               (clobber (reg:CC FLAGS_REG))])]
7102   ""
7103   "")
7105 (define_insn "*umulsi3_highpart_insn"
7106   [(set (match_operand:SI 0 "register_operand" "=d")
7107         (truncate:SI
7108           (lshiftrt:DI
7109             (mult:DI (zero_extend:DI
7110                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7111                      (zero_extend:DI
7112                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7113             (const_int 32))))
7114    (clobber (match_scratch:SI 3 "=1"))
7115    (clobber (reg:CC FLAGS_REG))]
7116   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7117   "mul{l}\t%2"
7118   [(set_attr "type" "imul")
7119    (set_attr "length_immediate" "0")
7120    (set (attr "athlon_decode")
7121      (if_then_else (eq_attr "cpu" "athlon")
7122         (const_string "vector")
7123         (const_string "double")))
7124    (set_attr "mode" "SI")])
7126 (define_insn "*umulsi3_highpart_zext"
7127   [(set (match_operand:DI 0 "register_operand" "=d")
7128         (zero_extend:DI (truncate:SI
7129           (lshiftrt:DI
7130             (mult:DI (zero_extend:DI
7131                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7132                      (zero_extend:DI
7133                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7134             (const_int 32)))))
7135    (clobber (match_scratch:SI 3 "=1"))
7136    (clobber (reg:CC FLAGS_REG))]
7137   "TARGET_64BIT
7138    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7139   "mul{l}\t%2"
7140   [(set_attr "type" "imul")
7141    (set_attr "length_immediate" "0")
7142    (set (attr "athlon_decode")
7143      (if_then_else (eq_attr "cpu" "athlon")
7144         (const_string "vector")
7145         (const_string "double")))
7146    (set_attr "mode" "SI")])
7148 (define_expand "smuldi3_highpart"
7149   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7150                    (truncate:DI
7151                      (lshiftrt:TI
7152                        (mult:TI (sign_extend:TI
7153                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7154                                 (sign_extend:TI
7155                                   (match_operand:DI 2 "register_operand" "")))
7156                        (const_int 64))))
7157               (clobber (match_scratch:DI 3 ""))
7158               (clobber (reg:CC FLAGS_REG))])]
7159   "TARGET_64BIT"
7160   "")
7162 (define_insn "*smuldi3_highpart_rex64"
7163   [(set (match_operand:DI 0 "register_operand" "=d")
7164         (truncate:DI
7165           (lshiftrt:TI
7166             (mult:TI (sign_extend:TI
7167                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7168                      (sign_extend:TI
7169                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7170             (const_int 64))))
7171    (clobber (match_scratch:DI 3 "=1"))
7172    (clobber (reg:CC FLAGS_REG))]
7173   "TARGET_64BIT
7174    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7175   "imul{q}\t%2"
7176   [(set_attr "type" "imul")
7177    (set (attr "athlon_decode")
7178      (if_then_else (eq_attr "cpu" "athlon")
7179         (const_string "vector")
7180         (const_string "double")))
7181    (set_attr "mode" "DI")])
7183 (define_expand "smulsi3_highpart"
7184   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7185                    (truncate:SI
7186                      (lshiftrt:DI
7187                        (mult:DI (sign_extend:DI
7188                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7189                                 (sign_extend:DI
7190                                   (match_operand:SI 2 "register_operand" "")))
7191                        (const_int 32))))
7192               (clobber (match_scratch:SI 3 ""))
7193               (clobber (reg:CC FLAGS_REG))])]
7194   ""
7195   "")
7197 (define_insn "*smulsi3_highpart_insn"
7198   [(set (match_operand:SI 0 "register_operand" "=d")
7199         (truncate:SI
7200           (lshiftrt:DI
7201             (mult:DI (sign_extend:DI
7202                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7203                      (sign_extend:DI
7204                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7205             (const_int 32))))
7206    (clobber (match_scratch:SI 3 "=1"))
7207    (clobber (reg:CC FLAGS_REG))]
7208   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7209   "imul{l}\t%2"
7210   [(set_attr "type" "imul")
7211    (set (attr "athlon_decode")
7212      (if_then_else (eq_attr "cpu" "athlon")
7213         (const_string "vector")
7214         (const_string "double")))
7215    (set_attr "mode" "SI")])
7217 (define_insn "*smulsi3_highpart_zext"
7218   [(set (match_operand:DI 0 "register_operand" "=d")
7219         (zero_extend:DI (truncate:SI
7220           (lshiftrt:DI
7221             (mult:DI (sign_extend:DI
7222                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7223                      (sign_extend:DI
7224                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7225             (const_int 32)))))
7226    (clobber (match_scratch:SI 3 "=1"))
7227    (clobber (reg:CC FLAGS_REG))]
7228   "TARGET_64BIT
7229    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7230   "imul{l}\t%2"
7231   [(set_attr "type" "imul")
7232    (set (attr "athlon_decode")
7233      (if_then_else (eq_attr "cpu" "athlon")
7234         (const_string "vector")
7235         (const_string "double")))
7236    (set_attr "mode" "SI")])
7238 ;; The patterns that match these are at the end of this file.
7240 (define_expand "mulxf3"
7241   [(set (match_operand:XF 0 "register_operand" "")
7242         (mult:XF (match_operand:XF 1 "register_operand" "")
7243                  (match_operand:XF 2 "register_operand" "")))]
7244   "TARGET_80387"
7245   "")
7247 (define_expand "muldf3"
7248   [(set (match_operand:DF 0 "register_operand" "")
7249         (mult:DF (match_operand:DF 1 "register_operand" "")
7250                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7251   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7252   "")
7254 (define_expand "mulsf3"
7255   [(set (match_operand:SF 0 "register_operand" "")
7256         (mult:SF (match_operand:SF 1 "register_operand" "")
7257                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7258   "TARGET_80387 || TARGET_SSE_MATH"
7259   "")
7261 ;; Divide instructions
7263 (define_insn "divqi3"
7264   [(set (match_operand:QI 0 "register_operand" "=a")
7265         (div:QI (match_operand:HI 1 "register_operand" "0")
7266                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7267    (clobber (reg:CC FLAGS_REG))]
7268   "TARGET_QIMODE_MATH"
7269   "idiv{b}\t%2"
7270   [(set_attr "type" "idiv")
7271    (set_attr "mode" "QI")])
7273 (define_insn "udivqi3"
7274   [(set (match_operand:QI 0 "register_operand" "=a")
7275         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7276                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7277    (clobber (reg:CC FLAGS_REG))]
7278   "TARGET_QIMODE_MATH"
7279   "div{b}\t%2"
7280   [(set_attr "type" "idiv")
7281    (set_attr "mode" "QI")])
7283 ;; The patterns that match these are at the end of this file.
7285 (define_expand "divxf3"
7286   [(set (match_operand:XF 0 "register_operand" "")
7287         (div:XF (match_operand:XF 1 "register_operand" "")
7288                 (match_operand:XF 2 "register_operand" "")))]
7289   "TARGET_80387"
7290   "")
7292 (define_expand "divdf3"
7293   [(set (match_operand:DF 0 "register_operand" "")
7294         (div:DF (match_operand:DF 1 "register_operand" "")
7295                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7296    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7297    "")
7299 (define_expand "divsf3"
7300   [(set (match_operand:SF 0 "register_operand" "")
7301         (div:SF (match_operand:SF 1 "register_operand" "")
7302                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7303   "TARGET_80387 || TARGET_SSE_MATH"
7304   "")
7306 ;; Remainder instructions.
7308 (define_expand "divmoddi4"
7309   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7310                    (div:DI (match_operand:DI 1 "register_operand" "")
7311                            (match_operand:DI 2 "nonimmediate_operand" "")))
7312               (set (match_operand:DI 3 "register_operand" "")
7313                    (mod:DI (match_dup 1) (match_dup 2)))
7314               (clobber (reg:CC FLAGS_REG))])]
7315   "TARGET_64BIT"
7316   "")
7318 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7319 ;; Penalize eax case slightly because it results in worse scheduling
7320 ;; of code.
7321 (define_insn "*divmoddi4_nocltd_rex64"
7322   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7323         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7324                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7325    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7326         (mod:DI (match_dup 2) (match_dup 3)))
7327    (clobber (reg:CC FLAGS_REG))]
7328   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7329   "#"
7330   [(set_attr "type" "multi")])
7332 (define_insn "*divmoddi4_cltd_rex64"
7333   [(set (match_operand:DI 0 "register_operand" "=a")
7334         (div:DI (match_operand:DI 2 "register_operand" "a")
7335                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7336    (set (match_operand:DI 1 "register_operand" "=&d")
7337         (mod:DI (match_dup 2) (match_dup 3)))
7338    (clobber (reg:CC FLAGS_REG))]
7339   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7340   "#"
7341   [(set_attr "type" "multi")])
7343 (define_insn "*divmoddi_noext_rex64"
7344   [(set (match_operand:DI 0 "register_operand" "=a")
7345         (div:DI (match_operand:DI 1 "register_operand" "0")
7346                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7347    (set (match_operand:DI 3 "register_operand" "=d")
7348         (mod:DI (match_dup 1) (match_dup 2)))
7349    (use (match_operand:DI 4 "register_operand" "3"))
7350    (clobber (reg:CC FLAGS_REG))]
7351   "TARGET_64BIT"
7352   "idiv{q}\t%2"
7353   [(set_attr "type" "idiv")
7354    (set_attr "mode" "DI")])
7356 (define_split
7357   [(set (match_operand:DI 0 "register_operand" "")
7358         (div:DI (match_operand:DI 1 "register_operand" "")
7359                 (match_operand:DI 2 "nonimmediate_operand" "")))
7360    (set (match_operand:DI 3 "register_operand" "")
7361         (mod:DI (match_dup 1) (match_dup 2)))
7362    (clobber (reg:CC FLAGS_REG))]
7363   "TARGET_64BIT && reload_completed"
7364   [(parallel [(set (match_dup 3)
7365                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7366               (clobber (reg:CC FLAGS_REG))])
7367    (parallel [(set (match_dup 0)
7368                    (div:DI (reg:DI 0) (match_dup 2)))
7369               (set (match_dup 3)
7370                    (mod:DI (reg:DI 0) (match_dup 2)))
7371               (use (match_dup 3))
7372               (clobber (reg:CC FLAGS_REG))])]
7374   /* Avoid use of cltd in favor of a mov+shift.  */
7375   if (!TARGET_USE_CLTD && !optimize_size)
7376     {
7377       if (true_regnum (operands[1]))
7378         emit_move_insn (operands[0], operands[1]);
7379       else
7380         emit_move_insn (operands[3], operands[1]);
7381       operands[4] = operands[3];
7382     }
7383   else
7384     {
7385       if (true_regnum (operands[1]))
7386         abort();
7387       operands[4] = operands[1];
7388     }
7392 (define_expand "divmodsi4"
7393   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7394                    (div:SI (match_operand:SI 1 "register_operand" "")
7395                            (match_operand:SI 2 "nonimmediate_operand" "")))
7396               (set (match_operand:SI 3 "register_operand" "")
7397                    (mod:SI (match_dup 1) (match_dup 2)))
7398               (clobber (reg:CC FLAGS_REG))])]
7399   ""
7400   "")
7402 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7403 ;; Penalize eax case slightly because it results in worse scheduling
7404 ;; of code.
7405 (define_insn "*divmodsi4_nocltd"
7406   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7407         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7408                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7409    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7410         (mod:SI (match_dup 2) (match_dup 3)))
7411    (clobber (reg:CC FLAGS_REG))]
7412   "!optimize_size && !TARGET_USE_CLTD"
7413   "#"
7414   [(set_attr "type" "multi")])
7416 (define_insn "*divmodsi4_cltd"
7417   [(set (match_operand:SI 0 "register_operand" "=a")
7418         (div:SI (match_operand:SI 2 "register_operand" "a")
7419                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7420    (set (match_operand:SI 1 "register_operand" "=&d")
7421         (mod:SI (match_dup 2) (match_dup 3)))
7422    (clobber (reg:CC FLAGS_REG))]
7423   "optimize_size || TARGET_USE_CLTD"
7424   "#"
7425   [(set_attr "type" "multi")])
7427 (define_insn "*divmodsi_noext"
7428   [(set (match_operand:SI 0 "register_operand" "=a")
7429         (div:SI (match_operand:SI 1 "register_operand" "0")
7430                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7431    (set (match_operand:SI 3 "register_operand" "=d")
7432         (mod:SI (match_dup 1) (match_dup 2)))
7433    (use (match_operand:SI 4 "register_operand" "3"))
7434    (clobber (reg:CC FLAGS_REG))]
7435   ""
7436   "idiv{l}\t%2"
7437   [(set_attr "type" "idiv")
7438    (set_attr "mode" "SI")])
7440 (define_split
7441   [(set (match_operand:SI 0 "register_operand" "")
7442         (div:SI (match_operand:SI 1 "register_operand" "")
7443                 (match_operand:SI 2 "nonimmediate_operand" "")))
7444    (set (match_operand:SI 3 "register_operand" "")
7445         (mod:SI (match_dup 1) (match_dup 2)))
7446    (clobber (reg:CC FLAGS_REG))]
7447   "reload_completed"
7448   [(parallel [(set (match_dup 3)
7449                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7450               (clobber (reg:CC FLAGS_REG))])
7451    (parallel [(set (match_dup 0)
7452                    (div:SI (reg:SI 0) (match_dup 2)))
7453               (set (match_dup 3)
7454                    (mod:SI (reg:SI 0) (match_dup 2)))
7455               (use (match_dup 3))
7456               (clobber (reg:CC FLAGS_REG))])]
7458   /* Avoid use of cltd in favor of a mov+shift.  */
7459   if (!TARGET_USE_CLTD && !optimize_size)
7460     {
7461       if (true_regnum (operands[1]))
7462         emit_move_insn (operands[0], operands[1]);
7463       else
7464         emit_move_insn (operands[3], operands[1]);
7465       operands[4] = operands[3];
7466     }
7467   else
7468     {
7469       if (true_regnum (operands[1]))
7470         abort();
7471       operands[4] = operands[1];
7472     }
7474 ;; %%% Split me.
7475 (define_insn "divmodhi4"
7476   [(set (match_operand:HI 0 "register_operand" "=a")
7477         (div:HI (match_operand:HI 1 "register_operand" "0")
7478                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7479    (set (match_operand:HI 3 "register_operand" "=&d")
7480         (mod:HI (match_dup 1) (match_dup 2)))
7481    (clobber (reg:CC FLAGS_REG))]
7482   "TARGET_HIMODE_MATH"
7483   "cwtd\;idiv{w}\t%2"
7484   [(set_attr "type" "multi")
7485    (set_attr "length_immediate" "0")
7486    (set_attr "mode" "SI")])
7488 (define_insn "udivmoddi4"
7489   [(set (match_operand:DI 0 "register_operand" "=a")
7490         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7491                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7492    (set (match_operand:DI 3 "register_operand" "=&d")
7493         (umod:DI (match_dup 1) (match_dup 2)))
7494    (clobber (reg:CC FLAGS_REG))]
7495   "TARGET_64BIT"
7496   "xor{q}\t%3, %3\;div{q}\t%2"
7497   [(set_attr "type" "multi")
7498    (set_attr "length_immediate" "0")
7499    (set_attr "mode" "DI")])
7501 (define_insn "*udivmoddi4_noext"
7502   [(set (match_operand:DI 0 "register_operand" "=a")
7503         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7504                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7505    (set (match_operand:DI 3 "register_operand" "=d")
7506         (umod:DI (match_dup 1) (match_dup 2)))
7507    (use (match_dup 3))
7508    (clobber (reg:CC FLAGS_REG))]
7509   "TARGET_64BIT"
7510   "div{q}\t%2"
7511   [(set_attr "type" "idiv")
7512    (set_attr "mode" "DI")])
7514 (define_split
7515   [(set (match_operand:DI 0 "register_operand" "")
7516         (udiv:DI (match_operand:DI 1 "register_operand" "")
7517                  (match_operand:DI 2 "nonimmediate_operand" "")))
7518    (set (match_operand:DI 3 "register_operand" "")
7519         (umod:DI (match_dup 1) (match_dup 2)))
7520    (clobber (reg:CC FLAGS_REG))]
7521   "TARGET_64BIT && reload_completed"
7522   [(set (match_dup 3) (const_int 0))
7523    (parallel [(set (match_dup 0)
7524                    (udiv:DI (match_dup 1) (match_dup 2)))
7525               (set (match_dup 3)
7526                    (umod:DI (match_dup 1) (match_dup 2)))
7527               (use (match_dup 3))
7528               (clobber (reg:CC FLAGS_REG))])]
7529   "")
7531 (define_insn "udivmodsi4"
7532   [(set (match_operand:SI 0 "register_operand" "=a")
7533         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7534                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7535    (set (match_operand:SI 3 "register_operand" "=&d")
7536         (umod:SI (match_dup 1) (match_dup 2)))
7537    (clobber (reg:CC FLAGS_REG))]
7538   ""
7539   "xor{l}\t%3, %3\;div{l}\t%2"
7540   [(set_attr "type" "multi")
7541    (set_attr "length_immediate" "0")
7542    (set_attr "mode" "SI")])
7544 (define_insn "*udivmodsi4_noext"
7545   [(set (match_operand:SI 0 "register_operand" "=a")
7546         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7547                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7548    (set (match_operand:SI 3 "register_operand" "=d")
7549         (umod:SI (match_dup 1) (match_dup 2)))
7550    (use (match_dup 3))
7551    (clobber (reg:CC FLAGS_REG))]
7552   ""
7553   "div{l}\t%2"
7554   [(set_attr "type" "idiv")
7555    (set_attr "mode" "SI")])
7557 (define_split
7558   [(set (match_operand:SI 0 "register_operand" "")
7559         (udiv:SI (match_operand:SI 1 "register_operand" "")
7560                  (match_operand:SI 2 "nonimmediate_operand" "")))
7561    (set (match_operand:SI 3 "register_operand" "")
7562         (umod:SI (match_dup 1) (match_dup 2)))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "reload_completed"
7565   [(set (match_dup 3) (const_int 0))
7566    (parallel [(set (match_dup 0)
7567                    (udiv:SI (match_dup 1) (match_dup 2)))
7568               (set (match_dup 3)
7569                    (umod:SI (match_dup 1) (match_dup 2)))
7570               (use (match_dup 3))
7571               (clobber (reg:CC FLAGS_REG))])]
7572   "")
7574 (define_expand "udivmodhi4"
7575   [(set (match_dup 4) (const_int 0))
7576    (parallel [(set (match_operand:HI 0 "register_operand" "")
7577                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7578                             (match_operand:HI 2 "nonimmediate_operand" "")))
7579               (set (match_operand:HI 3 "register_operand" "")
7580                    (umod:HI (match_dup 1) (match_dup 2)))
7581               (use (match_dup 4))
7582               (clobber (reg:CC FLAGS_REG))])]
7583   "TARGET_HIMODE_MATH"
7584   "operands[4] = gen_reg_rtx (HImode);")
7586 (define_insn "*udivmodhi_noext"
7587   [(set (match_operand:HI 0 "register_operand" "=a")
7588         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7589                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7590    (set (match_operand:HI 3 "register_operand" "=d")
7591         (umod:HI (match_dup 1) (match_dup 2)))
7592    (use (match_operand:HI 4 "register_operand" "3"))
7593    (clobber (reg:CC FLAGS_REG))]
7594   ""
7595   "div{w}\t%2"
7596   [(set_attr "type" "idiv")
7597    (set_attr "mode" "HI")])
7599 ;; We cannot use div/idiv for double division, because it causes
7600 ;; "division by zero" on the overflow and that's not what we expect
7601 ;; from truncate.  Because true (non truncating) double division is
7602 ;; never generated, we can't create this insn anyway.
7604 ;(define_insn ""
7605 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7606 ;       (truncate:SI
7607 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7608 ;                  (zero_extend:DI
7609 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7610 ;   (set (match_operand:SI 3 "register_operand" "=d")
7611 ;       (truncate:SI
7612 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7613 ;   (clobber (reg:CC FLAGS_REG))]
7614 ;  ""
7615 ;  "div{l}\t{%2, %0|%0, %2}"
7616 ;  [(set_attr "type" "idiv")])
7618 ;;- Logical AND instructions
7620 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7621 ;; Note that this excludes ah.
7623 (define_insn "*testdi_1_rex64"
7624   [(set (reg FLAGS_REG)
7625         (compare
7626           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7627                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7628           (const_int 0)))]
7629   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7630    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7631   "@
7632    test{l}\t{%k1, %k0|%k0, %k1}
7633    test{l}\t{%k1, %k0|%k0, %k1}
7634    test{q}\t{%1, %0|%0, %1}
7635    test{q}\t{%1, %0|%0, %1}
7636    test{q}\t{%1, %0|%0, %1}"
7637   [(set_attr "type" "test")
7638    (set_attr "modrm" "0,1,0,1,1")
7639    (set_attr "mode" "SI,SI,DI,DI,DI")
7640    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7642 (define_insn "testsi_1"
7643   [(set (reg FLAGS_REG)
7644         (compare
7645           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7646                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7647           (const_int 0)))]
7648   "ix86_match_ccmode (insn, CCNOmode)
7649    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7650   "test{l}\t{%1, %0|%0, %1}"
7651   [(set_attr "type" "test")
7652    (set_attr "modrm" "0,1,1")
7653    (set_attr "mode" "SI")
7654    (set_attr "pent_pair" "uv,np,uv")])
7656 (define_expand "testsi_ccno_1"
7657   [(set (reg:CCNO FLAGS_REG)
7658         (compare:CCNO
7659           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7660                   (match_operand:SI 1 "nonmemory_operand" ""))
7661           (const_int 0)))]
7662   ""
7663   "")
7665 (define_insn "*testhi_1"
7666   [(set (reg FLAGS_REG)
7667         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7668                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7669                  (const_int 0)))]
7670   "ix86_match_ccmode (insn, CCNOmode)
7671    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7672   "test{w}\t{%1, %0|%0, %1}"
7673   [(set_attr "type" "test")
7674    (set_attr "modrm" "0,1,1")
7675    (set_attr "mode" "HI")
7676    (set_attr "pent_pair" "uv,np,uv")])
7678 (define_expand "testqi_ccz_1"
7679   [(set (reg:CCZ FLAGS_REG)
7680         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7681                              (match_operand:QI 1 "nonmemory_operand" ""))
7682                  (const_int 0)))]
7683   ""
7684   "")
7686 (define_insn "*testqi_1_maybe_si"
7687   [(set (reg FLAGS_REG)
7688         (compare
7689           (and:QI
7690             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7691             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7692           (const_int 0)))]
7693    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7694     && ix86_match_ccmode (insn,
7695                          GET_CODE (operands[1]) == CONST_INT
7696                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7698   if (which_alternative == 3)
7699     {
7700       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7701         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7702       return "test{l}\t{%1, %k0|%k0, %1}";
7703     }
7704   return "test{b}\t{%1, %0|%0, %1}";
7706   [(set_attr "type" "test")
7707    (set_attr "modrm" "0,1,1,1")
7708    (set_attr "mode" "QI,QI,QI,SI")
7709    (set_attr "pent_pair" "uv,np,uv,np")])
7711 (define_insn "*testqi_1"
7712   [(set (reg FLAGS_REG)
7713         (compare
7714           (and:QI
7715             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7716             (match_operand:QI 1 "general_operand" "n,n,qn"))
7717           (const_int 0)))]
7718   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7719    && ix86_match_ccmode (insn, CCNOmode)"
7720   "test{b}\t{%1, %0|%0, %1}"
7721   [(set_attr "type" "test")
7722    (set_attr "modrm" "0,1,1")
7723    (set_attr "mode" "QI")
7724    (set_attr "pent_pair" "uv,np,uv")])
7726 (define_expand "testqi_ext_ccno_0"
7727   [(set (reg:CCNO FLAGS_REG)
7728         (compare:CCNO
7729           (and:SI
7730             (zero_extract:SI
7731               (match_operand 0 "ext_register_operand" "")
7732               (const_int 8)
7733               (const_int 8))
7734             (match_operand 1 "const_int_operand" ""))
7735           (const_int 0)))]
7736   ""
7737   "")
7739 (define_insn "*testqi_ext_0"
7740   [(set (reg FLAGS_REG)
7741         (compare
7742           (and:SI
7743             (zero_extract:SI
7744               (match_operand 0 "ext_register_operand" "Q")
7745               (const_int 8)
7746               (const_int 8))
7747             (match_operand 1 "const_int_operand" "n"))
7748           (const_int 0)))]
7749   "ix86_match_ccmode (insn, CCNOmode)"
7750   "test{b}\t{%1, %h0|%h0, %1}"
7751   [(set_attr "type" "test")
7752    (set_attr "mode" "QI")
7753    (set_attr "length_immediate" "1")
7754    (set_attr "pent_pair" "np")])
7756 (define_insn "*testqi_ext_1"
7757   [(set (reg FLAGS_REG)
7758         (compare
7759           (and:SI
7760             (zero_extract:SI
7761               (match_operand 0 "ext_register_operand" "Q")
7762               (const_int 8)
7763               (const_int 8))
7764             (zero_extend:SI
7765               (match_operand:QI 1 "general_operand" "Qm")))
7766           (const_int 0)))]
7767   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7768    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7769   "test{b}\t{%1, %h0|%h0, %1}"
7770   [(set_attr "type" "test")
7771    (set_attr "mode" "QI")])
7773 (define_insn "*testqi_ext_1_rex64"
7774   [(set (reg FLAGS_REG)
7775         (compare
7776           (and:SI
7777             (zero_extract:SI
7778               (match_operand 0 "ext_register_operand" "Q")
7779               (const_int 8)
7780               (const_int 8))
7781             (zero_extend:SI
7782               (match_operand:QI 1 "register_operand" "Q")))
7783           (const_int 0)))]
7784   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7785   "test{b}\t{%1, %h0|%h0, %1}"
7786   [(set_attr "type" "test")
7787    (set_attr "mode" "QI")])
7789 (define_insn "*testqi_ext_2"
7790   [(set (reg FLAGS_REG)
7791         (compare
7792           (and:SI
7793             (zero_extract:SI
7794               (match_operand 0 "ext_register_operand" "Q")
7795               (const_int 8)
7796               (const_int 8))
7797             (zero_extract:SI
7798               (match_operand 1 "ext_register_operand" "Q")
7799               (const_int 8)
7800               (const_int 8)))
7801           (const_int 0)))]
7802   "ix86_match_ccmode (insn, CCNOmode)"
7803   "test{b}\t{%h1, %h0|%h0, %h1}"
7804   [(set_attr "type" "test")
7805    (set_attr "mode" "QI")])
7807 ;; Combine likes to form bit extractions for some tests.  Humor it.
7808 (define_insn "*testqi_ext_3"
7809   [(set (reg FLAGS_REG)
7810         (compare (zero_extract:SI
7811                    (match_operand 0 "nonimmediate_operand" "rm")
7812                    (match_operand:SI 1 "const_int_operand" "")
7813                    (match_operand:SI 2 "const_int_operand" ""))
7814                  (const_int 0)))]
7815   "ix86_match_ccmode (insn, CCNOmode)
7816    && (GET_MODE (operands[0]) == SImode
7817        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7818        || GET_MODE (operands[0]) == HImode
7819        || GET_MODE (operands[0]) == QImode)"
7820   "#")
7822 (define_insn "*testqi_ext_3_rex64"
7823   [(set (reg FLAGS_REG)
7824         (compare (zero_extract:DI
7825                    (match_operand 0 "nonimmediate_operand" "rm")
7826                    (match_operand:DI 1 "const_int_operand" "")
7827                    (match_operand:DI 2 "const_int_operand" ""))
7828                  (const_int 0)))]
7829   "TARGET_64BIT
7830    && ix86_match_ccmode (insn, CCNOmode)
7831    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7832    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7833    /* Ensure that resulting mask is zero or sign extended operand.  */
7834    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7835        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7836            && INTVAL (operands[1]) > 32))
7837    && (GET_MODE (operands[0]) == SImode
7838        || GET_MODE (operands[0]) == DImode
7839        || GET_MODE (operands[0]) == HImode
7840        || GET_MODE (operands[0]) == QImode)"
7841   "#")
7843 (define_split
7844   [(set (match_operand 0 "flags_reg_operand" "")
7845         (match_operator 1 "compare_operator"
7846           [(zero_extract
7847              (match_operand 2 "nonimmediate_operand" "")
7848              (match_operand 3 "const_int_operand" "")
7849              (match_operand 4 "const_int_operand" ""))
7850            (const_int 0)]))]
7851   "ix86_match_ccmode (insn, CCNOmode)"
7852   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7854   rtx val = operands[2];
7855   HOST_WIDE_INT len = INTVAL (operands[3]);
7856   HOST_WIDE_INT pos = INTVAL (operands[4]);
7857   HOST_WIDE_INT mask;
7858   enum machine_mode mode, submode;
7860   mode = GET_MODE (val);
7861   if (GET_CODE (val) == MEM)
7862     {
7863       /* ??? Combine likes to put non-volatile mem extractions in QImode
7864          no matter the size of the test.  So find a mode that works.  */
7865       if (! MEM_VOLATILE_P (val))
7866         {
7867           mode = smallest_mode_for_size (pos + len, MODE_INT);
7868           val = adjust_address (val, mode, 0);
7869         }
7870     }
7871   else if (GET_CODE (val) == SUBREG
7872            && (submode = GET_MODE (SUBREG_REG (val)),
7873                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7874            && pos + len <= GET_MODE_BITSIZE (submode))
7875     {
7876       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7877       mode = submode;
7878       val = SUBREG_REG (val);
7879     }
7880   else if (mode == HImode && pos + len <= 8)
7881     {
7882       /* Small HImode tests can be converted to QImode.  */
7883       mode = QImode;
7884       val = gen_lowpart (QImode, val);
7885     }
7887   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7888   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7890   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7893 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7894 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7895 ;; this is relatively important trick.
7896 ;; Do the conversion only post-reload to avoid limiting of the register class
7897 ;; to QI regs.
7898 (define_split
7899   [(set (match_operand 0 "flags_reg_operand" "")
7900         (match_operator 1 "compare_operator"
7901           [(and (match_operand 2 "register_operand" "")
7902                 (match_operand 3 "const_int_operand" ""))
7903            (const_int 0)]))]
7904    "reload_completed
7905     && QI_REG_P (operands[2])
7906     && GET_MODE (operands[2]) != QImode
7907     && ((ix86_match_ccmode (insn, CCZmode)
7908          && !(INTVAL (operands[3]) & ~(255 << 8)))
7909         || (ix86_match_ccmode (insn, CCNOmode)
7910             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7911   [(set (match_dup 0)
7912         (match_op_dup 1
7913           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7914                    (match_dup 3))
7915            (const_int 0)]))]
7916   "operands[2] = gen_lowpart (SImode, operands[2]);
7917    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7919 (define_split
7920   [(set (match_operand 0 "flags_reg_operand" "")
7921         (match_operator 1 "compare_operator"
7922           [(and (match_operand 2 "nonimmediate_operand" "")
7923                 (match_operand 3 "const_int_operand" ""))
7924            (const_int 0)]))]
7925    "reload_completed
7926     && GET_MODE (operands[2]) != QImode
7927     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7928     && ((ix86_match_ccmode (insn, CCZmode)
7929          && !(INTVAL (operands[3]) & ~255))
7930         || (ix86_match_ccmode (insn, CCNOmode)
7931             && !(INTVAL (operands[3]) & ~127)))"
7932   [(set (match_dup 0)
7933         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7934                          (const_int 0)]))]
7935   "operands[2] = gen_lowpart (QImode, operands[2]);
7936    operands[3] = gen_lowpart (QImode, operands[3]);")
7939 ;; %%% This used to optimize known byte-wide and operations to memory,
7940 ;; and sometimes to QImode registers.  If this is considered useful,
7941 ;; it should be done with splitters.
7943 (define_expand "anddi3"
7944   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7945         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7946                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7947    (clobber (reg:CC FLAGS_REG))]
7948   "TARGET_64BIT"
7949   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7951 (define_insn "*anddi_1_rex64"
7952   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7953         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7954                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7955    (clobber (reg:CC FLAGS_REG))]
7956   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7958   switch (get_attr_type (insn))
7959     {
7960     case TYPE_IMOVX:
7961       {
7962         enum machine_mode mode;
7964         if (GET_CODE (operands[2]) != CONST_INT)
7965           abort ();
7966         if (INTVAL (operands[2]) == 0xff)
7967           mode = QImode;
7968         else if (INTVAL (operands[2]) == 0xffff)
7969           mode = HImode;
7970         else
7971           abort ();
7972         
7973         operands[1] = gen_lowpart (mode, operands[1]);
7974         if (mode == QImode)
7975           return "movz{bq|x}\t{%1,%0|%0, %1}";
7976         else
7977           return "movz{wq|x}\t{%1,%0|%0, %1}";
7978       }
7980     default:
7981       if (! rtx_equal_p (operands[0], operands[1]))
7982         abort ();
7983       if (get_attr_mode (insn) == MODE_SI)
7984         return "and{l}\t{%k2, %k0|%k0, %k2}";
7985       else
7986         return "and{q}\t{%2, %0|%0, %2}";
7987     }
7989   [(set_attr "type" "alu,alu,alu,imovx")
7990    (set_attr "length_immediate" "*,*,*,0")
7991    (set_attr "mode" "SI,DI,DI,DI")])
7993 (define_insn "*anddi_2"
7994   [(set (reg FLAGS_REG)
7995         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7996                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7997                  (const_int 0)))
7998    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7999         (and:DI (match_dup 1) (match_dup 2)))]
8000   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8001    && ix86_binary_operator_ok (AND, DImode, operands)"
8002   "@
8003    and{l}\t{%k2, %k0|%k0, %k2}
8004    and{q}\t{%2, %0|%0, %2}
8005    and{q}\t{%2, %0|%0, %2}"
8006   [(set_attr "type" "alu")
8007    (set_attr "mode" "SI,DI,DI")])
8009 (define_expand "andsi3"
8010   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8011         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8012                 (match_operand:SI 2 "general_operand" "")))
8013    (clobber (reg:CC FLAGS_REG))]
8014   ""
8015   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8017 (define_insn "*andsi_1"
8018   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8019         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8020                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8021    (clobber (reg:CC FLAGS_REG))]
8022   "ix86_binary_operator_ok (AND, SImode, operands)"
8024   switch (get_attr_type (insn))
8025     {
8026     case TYPE_IMOVX:
8027       {
8028         enum machine_mode mode;
8030         if (GET_CODE (operands[2]) != CONST_INT)
8031           abort ();
8032         if (INTVAL (operands[2]) == 0xff)
8033           mode = QImode;
8034         else if (INTVAL (operands[2]) == 0xffff)
8035           mode = HImode;
8036         else
8037           abort ();
8038         
8039         operands[1] = gen_lowpart (mode, operands[1]);
8040         if (mode == QImode)
8041           return "movz{bl|x}\t{%1,%0|%0, %1}";
8042         else
8043           return "movz{wl|x}\t{%1,%0|%0, %1}";
8044       }
8046     default:
8047       if (! rtx_equal_p (operands[0], operands[1]))
8048         abort ();
8049       return "and{l}\t{%2, %0|%0, %2}";
8050     }
8052   [(set_attr "type" "alu,alu,imovx")
8053    (set_attr "length_immediate" "*,*,0")
8054    (set_attr "mode" "SI")])
8056 (define_split
8057   [(set (match_operand 0 "register_operand" "")
8058         (and (match_dup 0)
8059              (const_int -65536)))
8060    (clobber (reg:CC FLAGS_REG))]
8061   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8062   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8063   "operands[1] = gen_lowpart (HImode, operands[0]);")
8065 (define_split
8066   [(set (match_operand 0 "ext_register_operand" "")
8067         (and (match_dup 0)
8068              (const_int -256)))
8069    (clobber (reg:CC FLAGS_REG))]
8070   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8071   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8072   "operands[1] = gen_lowpart (QImode, operands[0]);")
8074 (define_split
8075   [(set (match_operand 0 "ext_register_operand" "")
8076         (and (match_dup 0)
8077              (const_int -65281)))
8078    (clobber (reg:CC FLAGS_REG))]
8079   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8080   [(parallel [(set (zero_extract:SI (match_dup 0)
8081                                     (const_int 8)
8082                                     (const_int 8))
8083                    (xor:SI 
8084                      (zero_extract:SI (match_dup 0)
8085                                       (const_int 8)
8086                                       (const_int 8))
8087                      (zero_extract:SI (match_dup 0)
8088                                       (const_int 8)
8089                                       (const_int 8))))
8090               (clobber (reg:CC FLAGS_REG))])]
8091   "operands[0] = gen_lowpart (SImode, operands[0]);")
8093 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8094 (define_insn "*andsi_1_zext"
8095   [(set (match_operand:DI 0 "register_operand" "=r")
8096         (zero_extend:DI
8097           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8098                   (match_operand:SI 2 "general_operand" "rim"))))
8099    (clobber (reg:CC FLAGS_REG))]
8100   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8101   "and{l}\t{%2, %k0|%k0, %2}"
8102   [(set_attr "type" "alu")
8103    (set_attr "mode" "SI")])
8105 (define_insn "*andsi_2"
8106   [(set (reg FLAGS_REG)
8107         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8108                          (match_operand:SI 2 "general_operand" "rim,ri"))
8109                  (const_int 0)))
8110    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8111         (and:SI (match_dup 1) (match_dup 2)))]
8112   "ix86_match_ccmode (insn, CCNOmode)
8113    && ix86_binary_operator_ok (AND, SImode, operands)"
8114   "and{l}\t{%2, %0|%0, %2}"
8115   [(set_attr "type" "alu")
8116    (set_attr "mode" "SI")])
8118 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8119 (define_insn "*andsi_2_zext"
8120   [(set (reg FLAGS_REG)
8121         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8122                          (match_operand:SI 2 "general_operand" "rim"))
8123                  (const_int 0)))
8124    (set (match_operand:DI 0 "register_operand" "=r")
8125         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8126   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8127    && ix86_binary_operator_ok (AND, SImode, operands)"
8128   "and{l}\t{%2, %k0|%k0, %2}"
8129   [(set_attr "type" "alu")
8130    (set_attr "mode" "SI")])
8132 (define_expand "andhi3"
8133   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8134         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8135                 (match_operand:HI 2 "general_operand" "")))
8136    (clobber (reg:CC FLAGS_REG))]
8137   "TARGET_HIMODE_MATH"
8138   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8140 (define_insn "*andhi_1"
8141   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8142         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8143                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8144    (clobber (reg:CC FLAGS_REG))]
8145   "ix86_binary_operator_ok (AND, HImode, operands)"
8147   switch (get_attr_type (insn))
8148     {
8149     case TYPE_IMOVX:
8150       if (GET_CODE (operands[2]) != CONST_INT)
8151         abort ();
8152       if (INTVAL (operands[2]) == 0xff)
8153         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8154       abort ();
8156     default:
8157       if (! rtx_equal_p (operands[0], operands[1]))
8158         abort ();
8160       return "and{w}\t{%2, %0|%0, %2}";
8161     }
8163   [(set_attr "type" "alu,alu,imovx")
8164    (set_attr "length_immediate" "*,*,0")
8165    (set_attr "mode" "HI,HI,SI")])
8167 (define_insn "*andhi_2"
8168   [(set (reg FLAGS_REG)
8169         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8170                          (match_operand:HI 2 "general_operand" "rim,ri"))
8171                  (const_int 0)))
8172    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8173         (and:HI (match_dup 1) (match_dup 2)))]
8174   "ix86_match_ccmode (insn, CCNOmode)
8175    && ix86_binary_operator_ok (AND, HImode, operands)"
8176   "and{w}\t{%2, %0|%0, %2}"
8177   [(set_attr "type" "alu")
8178    (set_attr "mode" "HI")])
8180 (define_expand "andqi3"
8181   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8182         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8183                 (match_operand:QI 2 "general_operand" "")))
8184    (clobber (reg:CC FLAGS_REG))]
8185   "TARGET_QIMODE_MATH"
8186   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8188 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8189 (define_insn "*andqi_1"
8190   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8191         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8192                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8193    (clobber (reg:CC FLAGS_REG))]
8194   "ix86_binary_operator_ok (AND, QImode, operands)"
8195   "@
8196    and{b}\t{%2, %0|%0, %2}
8197    and{b}\t{%2, %0|%0, %2}
8198    and{l}\t{%k2, %k0|%k0, %k2}"
8199   [(set_attr "type" "alu")
8200    (set_attr "mode" "QI,QI,SI")])
8202 (define_insn "*andqi_1_slp"
8203   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8204         (and:QI (match_dup 0)
8205                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8206    (clobber (reg:CC FLAGS_REG))]
8207   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8208    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8209   "and{b}\t{%1, %0|%0, %1}"
8210   [(set_attr "type" "alu1")
8211    (set_attr "mode" "QI")])
8213 (define_insn "*andqi_2_maybe_si"
8214   [(set (reg FLAGS_REG)
8215         (compare (and:QI
8216                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8217                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8218                  (const_int 0)))
8219    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8220         (and:QI (match_dup 1) (match_dup 2)))]
8221   "ix86_binary_operator_ok (AND, QImode, operands)
8222    && ix86_match_ccmode (insn,
8223                          GET_CODE (operands[2]) == CONST_INT
8224                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8226   if (which_alternative == 2)
8227     {
8228       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8229         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8230       return "and{l}\t{%2, %k0|%k0, %2}";
8231     }
8232   return "and{b}\t{%2, %0|%0, %2}";
8234   [(set_attr "type" "alu")
8235    (set_attr "mode" "QI,QI,SI")])
8237 (define_insn "*andqi_2"
8238   [(set (reg FLAGS_REG)
8239         (compare (and:QI
8240                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8241                    (match_operand:QI 2 "general_operand" "qim,qi"))
8242                  (const_int 0)))
8243    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8244         (and:QI (match_dup 1) (match_dup 2)))]
8245   "ix86_match_ccmode (insn, CCNOmode)
8246    && ix86_binary_operator_ok (AND, QImode, operands)"
8247   "and{b}\t{%2, %0|%0, %2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "QI")])
8251 (define_insn "*andqi_2_slp"
8252   [(set (reg FLAGS_REG)
8253         (compare (and:QI
8254                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8255                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8256                  (const_int 0)))
8257    (set (strict_low_part (match_dup 0))
8258         (and:QI (match_dup 0) (match_dup 1)))]
8259   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8260    && ix86_match_ccmode (insn, CCNOmode)
8261    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8262   "and{b}\t{%1, %0|%0, %1}"
8263   [(set_attr "type" "alu1")
8264    (set_attr "mode" "QI")])
8266 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8267 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8268 ;; for a QImode operand, which of course failed.
8270 (define_insn "andqi_ext_0"
8271   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8272                          (const_int 8)
8273                          (const_int 8))
8274         (and:SI 
8275           (zero_extract:SI
8276             (match_operand 1 "ext_register_operand" "0")
8277             (const_int 8)
8278             (const_int 8))
8279           (match_operand 2 "const_int_operand" "n")))
8280    (clobber (reg:CC FLAGS_REG))]
8281   ""
8282   "and{b}\t{%2, %h0|%h0, %2}"
8283   [(set_attr "type" "alu")
8284    (set_attr "length_immediate" "1")
8285    (set_attr "mode" "QI")])
8287 ;; Generated by peephole translating test to and.  This shows up
8288 ;; often in fp comparisons.
8290 (define_insn "*andqi_ext_0_cc"
8291   [(set (reg FLAGS_REG)
8292         (compare
8293           (and:SI
8294             (zero_extract:SI
8295               (match_operand 1 "ext_register_operand" "0")
8296               (const_int 8)
8297               (const_int 8))
8298             (match_operand 2 "const_int_operand" "n"))
8299           (const_int 0)))
8300    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8301                          (const_int 8)
8302                          (const_int 8))
8303         (and:SI 
8304           (zero_extract:SI
8305             (match_dup 1)
8306             (const_int 8)
8307             (const_int 8))
8308           (match_dup 2)))]
8309   "ix86_match_ccmode (insn, CCNOmode)"
8310   "and{b}\t{%2, %h0|%h0, %2}"
8311   [(set_attr "type" "alu")
8312    (set_attr "length_immediate" "1")
8313    (set_attr "mode" "QI")])
8315 (define_insn "*andqi_ext_1"
8316   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8317                          (const_int 8)
8318                          (const_int 8))
8319         (and:SI 
8320           (zero_extract:SI
8321             (match_operand 1 "ext_register_operand" "0")
8322             (const_int 8)
8323             (const_int 8))
8324           (zero_extend:SI
8325             (match_operand:QI 2 "general_operand" "Qm"))))
8326    (clobber (reg:CC FLAGS_REG))]
8327   "!TARGET_64BIT"
8328   "and{b}\t{%2, %h0|%h0, %2}"
8329   [(set_attr "type" "alu")
8330    (set_attr "length_immediate" "0")
8331    (set_attr "mode" "QI")])
8333 (define_insn "*andqi_ext_1_rex64"
8334   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8335                          (const_int 8)
8336                          (const_int 8))
8337         (and:SI 
8338           (zero_extract:SI
8339             (match_operand 1 "ext_register_operand" "0")
8340             (const_int 8)
8341             (const_int 8))
8342           (zero_extend:SI
8343             (match_operand 2 "ext_register_operand" "Q"))))
8344    (clobber (reg:CC FLAGS_REG))]
8345   "TARGET_64BIT"
8346   "and{b}\t{%2, %h0|%h0, %2}"
8347   [(set_attr "type" "alu")
8348    (set_attr "length_immediate" "0")
8349    (set_attr "mode" "QI")])
8351 (define_insn "*andqi_ext_2"
8352   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8353                          (const_int 8)
8354                          (const_int 8))
8355         (and:SI
8356           (zero_extract:SI
8357             (match_operand 1 "ext_register_operand" "%0")
8358             (const_int 8)
8359             (const_int 8))
8360           (zero_extract:SI
8361             (match_operand 2 "ext_register_operand" "Q")
8362             (const_int 8)
8363             (const_int 8))))
8364    (clobber (reg:CC FLAGS_REG))]
8365   ""
8366   "and{b}\t{%h2, %h0|%h0, %h2}"
8367   [(set_attr "type" "alu")
8368    (set_attr "length_immediate" "0")
8369    (set_attr "mode" "QI")])
8371 ;; Convert wide AND instructions with immediate operand to shorter QImode
8372 ;; equivalents when possible.
8373 ;; Don't do the splitting with memory operands, since it introduces risk
8374 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8375 ;; for size, but that can (should?) be handled by generic code instead.
8376 (define_split
8377   [(set (match_operand 0 "register_operand" "")
8378         (and (match_operand 1 "register_operand" "")
8379              (match_operand 2 "const_int_operand" "")))
8380    (clobber (reg:CC FLAGS_REG))]
8381    "reload_completed
8382     && QI_REG_P (operands[0])
8383     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8384     && !(~INTVAL (operands[2]) & ~(255 << 8))
8385     && GET_MODE (operands[0]) != QImode"
8386   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8387                    (and:SI (zero_extract:SI (match_dup 1)
8388                                             (const_int 8) (const_int 8))
8389                            (match_dup 2)))
8390               (clobber (reg:CC FLAGS_REG))])]
8391   "operands[0] = gen_lowpart (SImode, operands[0]);
8392    operands[1] = gen_lowpart (SImode, operands[1]);
8393    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8395 ;; Since AND can be encoded with sign extended immediate, this is only
8396 ;; profitable when 7th bit is not set.
8397 (define_split
8398   [(set (match_operand 0 "register_operand" "")
8399         (and (match_operand 1 "general_operand" "")
8400              (match_operand 2 "const_int_operand" "")))
8401    (clobber (reg:CC FLAGS_REG))]
8402    "reload_completed
8403     && ANY_QI_REG_P (operands[0])
8404     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8405     && !(~INTVAL (operands[2]) & ~255)
8406     && !(INTVAL (operands[2]) & 128)
8407     && GET_MODE (operands[0]) != QImode"
8408   [(parallel [(set (strict_low_part (match_dup 0))
8409                    (and:QI (match_dup 1)
8410                            (match_dup 2)))
8411               (clobber (reg:CC FLAGS_REG))])]
8412   "operands[0] = gen_lowpart (QImode, operands[0]);
8413    operands[1] = gen_lowpart (QImode, operands[1]);
8414    operands[2] = gen_lowpart (QImode, operands[2]);")
8416 ;; Logical inclusive OR instructions
8418 ;; %%% This used to optimize known byte-wide and operations to memory.
8419 ;; If this is considered useful, it should be done with splitters.
8421 (define_expand "iordi3"
8422   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8423         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8424                 (match_operand:DI 2 "x86_64_general_operand" "")))
8425    (clobber (reg:CC FLAGS_REG))]
8426   "TARGET_64BIT"
8427   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8429 (define_insn "*iordi_1_rex64"
8430   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8431         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8432                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8433    (clobber (reg:CC FLAGS_REG))]
8434   "TARGET_64BIT
8435    && ix86_binary_operator_ok (IOR, DImode, operands)"
8436   "or{q}\t{%2, %0|%0, %2}"
8437   [(set_attr "type" "alu")
8438    (set_attr "mode" "DI")])
8440 (define_insn "*iordi_2_rex64"
8441   [(set (reg FLAGS_REG)
8442         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8443                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8444                  (const_int 0)))
8445    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8446         (ior:DI (match_dup 1) (match_dup 2)))]
8447   "TARGET_64BIT
8448    && ix86_match_ccmode (insn, CCNOmode)
8449    && ix86_binary_operator_ok (IOR, DImode, operands)"
8450   "or{q}\t{%2, %0|%0, %2}"
8451   [(set_attr "type" "alu")
8452    (set_attr "mode" "DI")])
8454 (define_insn "*iordi_3_rex64"
8455   [(set (reg FLAGS_REG)
8456         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8457                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8458                  (const_int 0)))
8459    (clobber (match_scratch:DI 0 "=r"))]
8460   "TARGET_64BIT
8461    && ix86_match_ccmode (insn, CCNOmode)
8462    && ix86_binary_operator_ok (IOR, DImode, operands)"
8463   "or{q}\t{%2, %0|%0, %2}"
8464   [(set_attr "type" "alu")
8465    (set_attr "mode" "DI")])
8468 (define_expand "iorsi3"
8469   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8470         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8471                 (match_operand:SI 2 "general_operand" "")))
8472    (clobber (reg:CC FLAGS_REG))]
8473   ""
8474   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8476 (define_insn "*iorsi_1"
8477   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8478         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8479                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8480    (clobber (reg:CC FLAGS_REG))]
8481   "ix86_binary_operator_ok (IOR, SImode, operands)"
8482   "or{l}\t{%2, %0|%0, %2}"
8483   [(set_attr "type" "alu")
8484    (set_attr "mode" "SI")])
8486 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8487 (define_insn "*iorsi_1_zext"
8488   [(set (match_operand:DI 0 "register_operand" "=rm")
8489         (zero_extend:DI
8490           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8491                   (match_operand:SI 2 "general_operand" "rim"))))
8492    (clobber (reg:CC FLAGS_REG))]
8493   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8494   "or{l}\t{%2, %k0|%k0, %2}"
8495   [(set_attr "type" "alu")
8496    (set_attr "mode" "SI")])
8498 (define_insn "*iorsi_1_zext_imm"
8499   [(set (match_operand:DI 0 "register_operand" "=rm")
8500         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8501                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8502    (clobber (reg:CC FLAGS_REG))]
8503   "TARGET_64BIT"
8504   "or{l}\t{%2, %k0|%k0, %2}"
8505   [(set_attr "type" "alu")
8506    (set_attr "mode" "SI")])
8508 (define_insn "*iorsi_2"
8509   [(set (reg FLAGS_REG)
8510         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8511                          (match_operand:SI 2 "general_operand" "rim,ri"))
8512                  (const_int 0)))
8513    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8514         (ior:SI (match_dup 1) (match_dup 2)))]
8515   "ix86_match_ccmode (insn, CCNOmode)
8516    && ix86_binary_operator_ok (IOR, SImode, operands)"
8517   "or{l}\t{%2, %0|%0, %2}"
8518   [(set_attr "type" "alu")
8519    (set_attr "mode" "SI")])
8521 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8522 ;; ??? Special case for immediate operand is missing - it is tricky.
8523 (define_insn "*iorsi_2_zext"
8524   [(set (reg FLAGS_REG)
8525         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8526                          (match_operand:SI 2 "general_operand" "rim"))
8527                  (const_int 0)))
8528    (set (match_operand:DI 0 "register_operand" "=r")
8529         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8530   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8531    && ix86_binary_operator_ok (IOR, SImode, operands)"
8532   "or{l}\t{%2, %k0|%k0, %2}"
8533   [(set_attr "type" "alu")
8534    (set_attr "mode" "SI")])
8536 (define_insn "*iorsi_2_zext_imm"
8537   [(set (reg FLAGS_REG)
8538         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8539                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8540                  (const_int 0)))
8541    (set (match_operand:DI 0 "register_operand" "=r")
8542         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8543   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8544    && ix86_binary_operator_ok (IOR, SImode, operands)"
8545   "or{l}\t{%2, %k0|%k0, %2}"
8546   [(set_attr "type" "alu")
8547    (set_attr "mode" "SI")])
8549 (define_insn "*iorsi_3"
8550   [(set (reg FLAGS_REG)
8551         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8552                          (match_operand:SI 2 "general_operand" "rim"))
8553                  (const_int 0)))
8554    (clobber (match_scratch:SI 0 "=r"))]
8555   "ix86_match_ccmode (insn, CCNOmode)
8556    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8557   "or{l}\t{%2, %0|%0, %2}"
8558   [(set_attr "type" "alu")
8559    (set_attr "mode" "SI")])
8561 (define_expand "iorhi3"
8562   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8563         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8564                 (match_operand:HI 2 "general_operand" "")))
8565    (clobber (reg:CC FLAGS_REG))]
8566   "TARGET_HIMODE_MATH"
8567   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8569 (define_insn "*iorhi_1"
8570   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8571         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8572                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8573    (clobber (reg:CC FLAGS_REG))]
8574   "ix86_binary_operator_ok (IOR, HImode, operands)"
8575   "or{w}\t{%2, %0|%0, %2}"
8576   [(set_attr "type" "alu")
8577    (set_attr "mode" "HI")])
8579 (define_insn "*iorhi_2"
8580   [(set (reg FLAGS_REG)
8581         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8582                          (match_operand:HI 2 "general_operand" "rim,ri"))
8583                  (const_int 0)))
8584    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8585         (ior:HI (match_dup 1) (match_dup 2)))]
8586   "ix86_match_ccmode (insn, CCNOmode)
8587    && ix86_binary_operator_ok (IOR, HImode, operands)"
8588   "or{w}\t{%2, %0|%0, %2}"
8589   [(set_attr "type" "alu")
8590    (set_attr "mode" "HI")])
8592 (define_insn "*iorhi_3"
8593   [(set (reg FLAGS_REG)
8594         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8595                          (match_operand:HI 2 "general_operand" "rim"))
8596                  (const_int 0)))
8597    (clobber (match_scratch:HI 0 "=r"))]
8598   "ix86_match_ccmode (insn, CCNOmode)
8599    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8600   "or{w}\t{%2, %0|%0, %2}"
8601   [(set_attr "type" "alu")
8602    (set_attr "mode" "HI")])
8604 (define_expand "iorqi3"
8605   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8606         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8607                 (match_operand:QI 2 "general_operand" "")))
8608    (clobber (reg:CC FLAGS_REG))]
8609   "TARGET_QIMODE_MATH"
8610   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8612 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8613 (define_insn "*iorqi_1"
8614   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8615         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8616                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8617    (clobber (reg:CC FLAGS_REG))]
8618   "ix86_binary_operator_ok (IOR, QImode, operands)"
8619   "@
8620    or{b}\t{%2, %0|%0, %2}
8621    or{b}\t{%2, %0|%0, %2}
8622    or{l}\t{%k2, %k0|%k0, %k2}"
8623   [(set_attr "type" "alu")
8624    (set_attr "mode" "QI,QI,SI")])
8626 (define_insn "*iorqi_1_slp"
8627   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8628         (ior:QI (match_dup 0)
8629                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8630    (clobber (reg:CC FLAGS_REG))]
8631   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8632    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8633   "or{b}\t{%1, %0|%0, %1}"
8634   [(set_attr "type" "alu1")
8635    (set_attr "mode" "QI")])
8637 (define_insn "*iorqi_2"
8638   [(set (reg FLAGS_REG)
8639         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8640                          (match_operand:QI 2 "general_operand" "qim,qi"))
8641                  (const_int 0)))
8642    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8643         (ior:QI (match_dup 1) (match_dup 2)))]
8644   "ix86_match_ccmode (insn, CCNOmode)
8645    && ix86_binary_operator_ok (IOR, QImode, operands)"
8646   "or{b}\t{%2, %0|%0, %2}"
8647   [(set_attr "type" "alu")
8648    (set_attr "mode" "QI")])
8650 (define_insn "*iorqi_2_slp"
8651   [(set (reg FLAGS_REG)
8652         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8653                          (match_operand:QI 1 "general_operand" "qim,qi"))
8654                  (const_int 0)))
8655    (set (strict_low_part (match_dup 0))
8656         (ior:QI (match_dup 0) (match_dup 1)))]
8657   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8658    && ix86_match_ccmode (insn, CCNOmode)
8659    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8660   "or{b}\t{%1, %0|%0, %1}"
8661   [(set_attr "type" "alu1")
8662    (set_attr "mode" "QI")])
8664 (define_insn "*iorqi_3"
8665   [(set (reg FLAGS_REG)
8666         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8667                          (match_operand:QI 2 "general_operand" "qim"))
8668                  (const_int 0)))
8669    (clobber (match_scratch:QI 0 "=q"))]
8670   "ix86_match_ccmode (insn, CCNOmode)
8671    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8672   "or{b}\t{%2, %0|%0, %2}"
8673   [(set_attr "type" "alu")
8674    (set_attr "mode" "QI")])
8676 (define_insn "iorqi_ext_0"
8677   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8678                          (const_int 8)
8679                          (const_int 8))
8680         (ior:SI 
8681           (zero_extract:SI
8682             (match_operand 1 "ext_register_operand" "0")
8683             (const_int 8)
8684             (const_int 8))
8685           (match_operand 2 "const_int_operand" "n")))
8686    (clobber (reg:CC FLAGS_REG))]
8687   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8688   "or{b}\t{%2, %h0|%h0, %2}"
8689   [(set_attr "type" "alu")
8690    (set_attr "length_immediate" "1")
8691    (set_attr "mode" "QI")])
8693 (define_insn "*iorqi_ext_1"
8694   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8695                          (const_int 8)
8696                          (const_int 8))
8697         (ior:SI 
8698           (zero_extract:SI
8699             (match_operand 1 "ext_register_operand" "0")
8700             (const_int 8)
8701             (const_int 8))
8702           (zero_extend:SI
8703             (match_operand:QI 2 "general_operand" "Qm"))))
8704    (clobber (reg:CC FLAGS_REG))]
8705   "!TARGET_64BIT
8706    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8707   "or{b}\t{%2, %h0|%h0, %2}"
8708   [(set_attr "type" "alu")
8709    (set_attr "length_immediate" "0")
8710    (set_attr "mode" "QI")])
8712 (define_insn "*iorqi_ext_1_rex64"
8713   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8714                          (const_int 8)
8715                          (const_int 8))
8716         (ior:SI 
8717           (zero_extract:SI
8718             (match_operand 1 "ext_register_operand" "0")
8719             (const_int 8)
8720             (const_int 8))
8721           (zero_extend:SI
8722             (match_operand 2 "ext_register_operand" "Q"))))
8723    (clobber (reg:CC FLAGS_REG))]
8724   "TARGET_64BIT
8725    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8726   "or{b}\t{%2, %h0|%h0, %2}"
8727   [(set_attr "type" "alu")
8728    (set_attr "length_immediate" "0")
8729    (set_attr "mode" "QI")])
8731 (define_insn "*iorqi_ext_2"
8732   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8733                          (const_int 8)
8734                          (const_int 8))
8735         (ior:SI 
8736           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8737                            (const_int 8)
8738                            (const_int 8))
8739           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8740                            (const_int 8)
8741                            (const_int 8))))
8742    (clobber (reg:CC FLAGS_REG))]
8743   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8744   "ior{b}\t{%h2, %h0|%h0, %h2}"
8745   [(set_attr "type" "alu")
8746    (set_attr "length_immediate" "0")
8747    (set_attr "mode" "QI")])
8749 (define_split
8750   [(set (match_operand 0 "register_operand" "")
8751         (ior (match_operand 1 "register_operand" "")
8752              (match_operand 2 "const_int_operand" "")))
8753    (clobber (reg:CC FLAGS_REG))]
8754    "reload_completed
8755     && QI_REG_P (operands[0])
8756     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8757     && !(INTVAL (operands[2]) & ~(255 << 8))
8758     && GET_MODE (operands[0]) != QImode"
8759   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8760                    (ior:SI (zero_extract:SI (match_dup 1)
8761                                             (const_int 8) (const_int 8))
8762                            (match_dup 2)))
8763               (clobber (reg:CC FLAGS_REG))])]
8764   "operands[0] = gen_lowpart (SImode, operands[0]);
8765    operands[1] = gen_lowpart (SImode, operands[1]);
8766    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8768 ;; Since OR can be encoded with sign extended immediate, this is only
8769 ;; profitable when 7th bit is set.
8770 (define_split
8771   [(set (match_operand 0 "register_operand" "")
8772         (ior (match_operand 1 "general_operand" "")
8773              (match_operand 2 "const_int_operand" "")))
8774    (clobber (reg:CC FLAGS_REG))]
8775    "reload_completed
8776     && ANY_QI_REG_P (operands[0])
8777     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8778     && !(INTVAL (operands[2]) & ~255)
8779     && (INTVAL (operands[2]) & 128)
8780     && GET_MODE (operands[0]) != QImode"
8781   [(parallel [(set (strict_low_part (match_dup 0))
8782                    (ior:QI (match_dup 1)
8783                            (match_dup 2)))
8784               (clobber (reg:CC FLAGS_REG))])]
8785   "operands[0] = gen_lowpart (QImode, operands[0]);
8786    operands[1] = gen_lowpart (QImode, operands[1]);
8787    operands[2] = gen_lowpart (QImode, operands[2]);")
8789 ;; Logical XOR instructions
8791 ;; %%% This used to optimize known byte-wide and operations to memory.
8792 ;; If this is considered useful, it should be done with splitters.
8794 (define_expand "xordi3"
8795   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8796         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8797                 (match_operand:DI 2 "x86_64_general_operand" "")))
8798    (clobber (reg:CC FLAGS_REG))]
8799   "TARGET_64BIT"
8800   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8802 (define_insn "*xordi_1_rex64"
8803   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8804         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8805                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8806    (clobber (reg:CC FLAGS_REG))]
8807   "TARGET_64BIT
8808    && ix86_binary_operator_ok (XOR, DImode, operands)"
8809   "@
8810    xor{q}\t{%2, %0|%0, %2}
8811    xor{q}\t{%2, %0|%0, %2}"
8812   [(set_attr "type" "alu")
8813    (set_attr "mode" "DI,DI")])
8815 (define_insn "*xordi_2_rex64"
8816   [(set (reg FLAGS_REG)
8817         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8818                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8819                  (const_int 0)))
8820    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8821         (xor:DI (match_dup 1) (match_dup 2)))]
8822   "TARGET_64BIT
8823    && ix86_match_ccmode (insn, CCNOmode)
8824    && ix86_binary_operator_ok (XOR, DImode, operands)"
8825   "@
8826    xor{q}\t{%2, %0|%0, %2}
8827    xor{q}\t{%2, %0|%0, %2}"
8828   [(set_attr "type" "alu")
8829    (set_attr "mode" "DI,DI")])
8831 (define_insn "*xordi_3_rex64"
8832   [(set (reg FLAGS_REG)
8833         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8834                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8835                  (const_int 0)))
8836    (clobber (match_scratch:DI 0 "=r"))]
8837   "TARGET_64BIT
8838    && ix86_match_ccmode (insn, CCNOmode)
8839    && ix86_binary_operator_ok (XOR, DImode, operands)"
8840   "xor{q}\t{%2, %0|%0, %2}"
8841   [(set_attr "type" "alu")
8842    (set_attr "mode" "DI")])
8844 (define_expand "xorsi3"
8845   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8846         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8847                 (match_operand:SI 2 "general_operand" "")))
8848    (clobber (reg:CC FLAGS_REG))]
8849   ""
8850   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8852 (define_insn "*xorsi_1"
8853   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8854         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8855                 (match_operand:SI 2 "general_operand" "ri,rm")))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "ix86_binary_operator_ok (XOR, SImode, operands)"
8858   "xor{l}\t{%2, %0|%0, %2}"
8859   [(set_attr "type" "alu")
8860    (set_attr "mode" "SI")])
8862 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8863 ;; Add speccase for immediates
8864 (define_insn "*xorsi_1_zext"
8865   [(set (match_operand:DI 0 "register_operand" "=r")
8866         (zero_extend:DI
8867           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8868                   (match_operand:SI 2 "general_operand" "rim"))))
8869    (clobber (reg:CC FLAGS_REG))]
8870   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8871   "xor{l}\t{%2, %k0|%k0, %2}"
8872   [(set_attr "type" "alu")
8873    (set_attr "mode" "SI")])
8875 (define_insn "*xorsi_1_zext_imm"
8876   [(set (match_operand:DI 0 "register_operand" "=r")
8877         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8878                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8879    (clobber (reg:CC FLAGS_REG))]
8880   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8881   "xor{l}\t{%2, %k0|%k0, %2}"
8882   [(set_attr "type" "alu")
8883    (set_attr "mode" "SI")])
8885 (define_insn "*xorsi_2"
8886   [(set (reg FLAGS_REG)
8887         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8888                          (match_operand:SI 2 "general_operand" "rim,ri"))
8889                  (const_int 0)))
8890    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8891         (xor:SI (match_dup 1) (match_dup 2)))]
8892   "ix86_match_ccmode (insn, CCNOmode)
8893    && ix86_binary_operator_ok (XOR, SImode, operands)"
8894   "xor{l}\t{%2, %0|%0, %2}"
8895   [(set_attr "type" "alu")
8896    (set_attr "mode" "SI")])
8898 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8899 ;; ??? Special case for immediate operand is missing - it is tricky.
8900 (define_insn "*xorsi_2_zext"
8901   [(set (reg FLAGS_REG)
8902         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8903                          (match_operand:SI 2 "general_operand" "rim"))
8904                  (const_int 0)))
8905    (set (match_operand:DI 0 "register_operand" "=r")
8906         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8907   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8908    && ix86_binary_operator_ok (XOR, SImode, operands)"
8909   "xor{l}\t{%2, %k0|%k0, %2}"
8910   [(set_attr "type" "alu")
8911    (set_attr "mode" "SI")])
8913 (define_insn "*xorsi_2_zext_imm"
8914   [(set (reg FLAGS_REG)
8915         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8916                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8917                  (const_int 0)))
8918    (set (match_operand:DI 0 "register_operand" "=r")
8919         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8920   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8921    && ix86_binary_operator_ok (XOR, SImode, operands)"
8922   "xor{l}\t{%2, %k0|%k0, %2}"
8923   [(set_attr "type" "alu")
8924    (set_attr "mode" "SI")])
8926 (define_insn "*xorsi_3"
8927   [(set (reg FLAGS_REG)
8928         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8929                          (match_operand:SI 2 "general_operand" "rim"))
8930                  (const_int 0)))
8931    (clobber (match_scratch:SI 0 "=r"))]
8932   "ix86_match_ccmode (insn, CCNOmode)
8933    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8934   "xor{l}\t{%2, %0|%0, %2}"
8935   [(set_attr "type" "alu")
8936    (set_attr "mode" "SI")])
8938 (define_expand "xorhi3"
8939   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8940         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8941                 (match_operand:HI 2 "general_operand" "")))
8942    (clobber (reg:CC FLAGS_REG))]
8943   "TARGET_HIMODE_MATH"
8944   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8946 (define_insn "*xorhi_1"
8947   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8948         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8949                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8950    (clobber (reg:CC FLAGS_REG))]
8951   "ix86_binary_operator_ok (XOR, HImode, operands)"
8952   "xor{w}\t{%2, %0|%0, %2}"
8953   [(set_attr "type" "alu")
8954    (set_attr "mode" "HI")])
8956 (define_insn "*xorhi_2"
8957   [(set (reg FLAGS_REG)
8958         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8959                          (match_operand:HI 2 "general_operand" "rim,ri"))
8960                  (const_int 0)))
8961    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8962         (xor:HI (match_dup 1) (match_dup 2)))]
8963   "ix86_match_ccmode (insn, CCNOmode)
8964    && ix86_binary_operator_ok (XOR, HImode, operands)"
8965   "xor{w}\t{%2, %0|%0, %2}"
8966   [(set_attr "type" "alu")
8967    (set_attr "mode" "HI")])
8969 (define_insn "*xorhi_3"
8970   [(set (reg FLAGS_REG)
8971         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8972                          (match_operand:HI 2 "general_operand" "rim"))
8973                  (const_int 0)))
8974    (clobber (match_scratch:HI 0 "=r"))]
8975   "ix86_match_ccmode (insn, CCNOmode)
8976    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8977   "xor{w}\t{%2, %0|%0, %2}"
8978   [(set_attr "type" "alu")
8979    (set_attr "mode" "HI")])
8981 (define_expand "xorqi3"
8982   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8983         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8984                 (match_operand:QI 2 "general_operand" "")))
8985    (clobber (reg:CC FLAGS_REG))]
8986   "TARGET_QIMODE_MATH"
8987   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8989 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8990 (define_insn "*xorqi_1"
8991   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8992         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8993                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8994    (clobber (reg:CC FLAGS_REG))]
8995   "ix86_binary_operator_ok (XOR, QImode, operands)"
8996   "@
8997    xor{b}\t{%2, %0|%0, %2}
8998    xor{b}\t{%2, %0|%0, %2}
8999    xor{l}\t{%k2, %k0|%k0, %k2}"
9000   [(set_attr "type" "alu")
9001    (set_attr "mode" "QI,QI,SI")])
9003 (define_insn "*xorqi_1_slp"
9004   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9005         (xor:QI (match_dup 0)
9006                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9007    (clobber (reg:CC FLAGS_REG))]
9008   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9009    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9010   "xor{b}\t{%1, %0|%0, %1}"
9011   [(set_attr "type" "alu1")
9012    (set_attr "mode" "QI")])
9014 (define_insn "xorqi_ext_0"
9015   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9016                          (const_int 8)
9017                          (const_int 8))
9018         (xor:SI 
9019           (zero_extract:SI
9020             (match_operand 1 "ext_register_operand" "0")
9021             (const_int 8)
9022             (const_int 8))
9023           (match_operand 2 "const_int_operand" "n")))
9024    (clobber (reg:CC FLAGS_REG))]
9025   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9026   "xor{b}\t{%2, %h0|%h0, %2}"
9027   [(set_attr "type" "alu")
9028    (set_attr "length_immediate" "1")
9029    (set_attr "mode" "QI")])
9031 (define_insn "*xorqi_ext_1"
9032   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9033                          (const_int 8)
9034                          (const_int 8))
9035         (xor:SI 
9036           (zero_extract:SI
9037             (match_operand 1 "ext_register_operand" "0")
9038             (const_int 8)
9039             (const_int 8))
9040           (zero_extend:SI
9041             (match_operand:QI 2 "general_operand" "Qm"))))
9042    (clobber (reg:CC FLAGS_REG))]
9043   "!TARGET_64BIT
9044    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9045   "xor{b}\t{%2, %h0|%h0, %2}"
9046   [(set_attr "type" "alu")
9047    (set_attr "length_immediate" "0")
9048    (set_attr "mode" "QI")])
9050 (define_insn "*xorqi_ext_1_rex64"
9051   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9052                          (const_int 8)
9053                          (const_int 8))
9054         (xor:SI 
9055           (zero_extract:SI
9056             (match_operand 1 "ext_register_operand" "0")
9057             (const_int 8)
9058             (const_int 8))
9059           (zero_extend:SI
9060             (match_operand 2 "ext_register_operand" "Q"))))
9061    (clobber (reg:CC FLAGS_REG))]
9062   "TARGET_64BIT
9063    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9064   "xor{b}\t{%2, %h0|%h0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "length_immediate" "0")
9067    (set_attr "mode" "QI")])
9069 (define_insn "*xorqi_ext_2"
9070   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9071                          (const_int 8)
9072                          (const_int 8))
9073         (xor:SI 
9074           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9075                            (const_int 8)
9076                            (const_int 8))
9077           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9078                            (const_int 8)
9079                            (const_int 8))))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9082   "xor{b}\t{%h2, %h0|%h0, %h2}"
9083   [(set_attr "type" "alu")
9084    (set_attr "length_immediate" "0")
9085    (set_attr "mode" "QI")])
9087 (define_insn "*xorqi_cc_1"
9088   [(set (reg FLAGS_REG)
9089         (compare
9090           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9091                   (match_operand:QI 2 "general_operand" "qim,qi"))
9092           (const_int 0)))
9093    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9094         (xor:QI (match_dup 1) (match_dup 2)))]
9095   "ix86_match_ccmode (insn, CCNOmode)
9096    && ix86_binary_operator_ok (XOR, QImode, operands)"
9097   "xor{b}\t{%2, %0|%0, %2}"
9098   [(set_attr "type" "alu")
9099    (set_attr "mode" "QI")])
9101 (define_insn "*xorqi_2_slp"
9102   [(set (reg FLAGS_REG)
9103         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9104                          (match_operand:QI 1 "general_operand" "qim,qi"))
9105                  (const_int 0)))
9106    (set (strict_low_part (match_dup 0))
9107         (xor:QI (match_dup 0) (match_dup 1)))]
9108   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9109    && ix86_match_ccmode (insn, CCNOmode)
9110    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9111   "xor{b}\t{%1, %0|%0, %1}"
9112   [(set_attr "type" "alu1")
9113    (set_attr "mode" "QI")])
9115 (define_insn "*xorqi_cc_2"
9116   [(set (reg FLAGS_REG)
9117         (compare
9118           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9119                   (match_operand:QI 2 "general_operand" "qim"))
9120           (const_int 0)))
9121    (clobber (match_scratch:QI 0 "=q"))]
9122   "ix86_match_ccmode (insn, CCNOmode)
9123    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9124   "xor{b}\t{%2, %0|%0, %2}"
9125   [(set_attr "type" "alu")
9126    (set_attr "mode" "QI")])
9128 (define_insn "*xorqi_cc_ext_1"
9129   [(set (reg FLAGS_REG)
9130         (compare
9131           (xor:SI
9132             (zero_extract:SI
9133               (match_operand 1 "ext_register_operand" "0")
9134               (const_int 8)
9135               (const_int 8))
9136             (match_operand:QI 2 "general_operand" "qmn"))
9137           (const_int 0)))
9138    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9139                          (const_int 8)
9140                          (const_int 8))
9141         (xor:SI 
9142           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9143           (match_dup 2)))]
9144   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9145   "xor{b}\t{%2, %h0|%h0, %2}"
9146   [(set_attr "type" "alu")
9147    (set_attr "mode" "QI")])
9149 (define_insn "*xorqi_cc_ext_1_rex64"
9150   [(set (reg FLAGS_REG)
9151         (compare
9152           (xor:SI
9153             (zero_extract:SI
9154               (match_operand 1 "ext_register_operand" "0")
9155               (const_int 8)
9156               (const_int 8))
9157             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9158           (const_int 0)))
9159    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9160                          (const_int 8)
9161                          (const_int 8))
9162         (xor:SI 
9163           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9164           (match_dup 2)))]
9165   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9166   "xor{b}\t{%2, %h0|%h0, %2}"
9167   [(set_attr "type" "alu")
9168    (set_attr "mode" "QI")])
9170 (define_expand "xorqi_cc_ext_1"
9171   [(parallel [
9172      (set (reg:CCNO FLAGS_REG)
9173           (compare:CCNO
9174             (xor:SI
9175               (zero_extract:SI
9176                 (match_operand 1 "ext_register_operand" "")
9177                 (const_int 8)
9178                 (const_int 8))
9179               (match_operand:QI 2 "general_operand" ""))
9180             (const_int 0)))
9181      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9182                            (const_int 8)
9183                            (const_int 8))
9184           (xor:SI 
9185             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9186             (match_dup 2)))])]
9187   ""
9188   "")
9190 (define_split
9191   [(set (match_operand 0 "register_operand" "")
9192         (xor (match_operand 1 "register_operand" "")
9193              (match_operand 2 "const_int_operand" "")))
9194    (clobber (reg:CC FLAGS_REG))]
9195    "reload_completed
9196     && QI_REG_P (operands[0])
9197     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9198     && !(INTVAL (operands[2]) & ~(255 << 8))
9199     && GET_MODE (operands[0]) != QImode"
9200   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9201                    (xor:SI (zero_extract:SI (match_dup 1)
9202                                             (const_int 8) (const_int 8))
9203                            (match_dup 2)))
9204               (clobber (reg:CC FLAGS_REG))])]
9205   "operands[0] = gen_lowpart (SImode, operands[0]);
9206    operands[1] = gen_lowpart (SImode, operands[1]);
9207    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9209 ;; Since XOR can be encoded with sign extended immediate, this is only
9210 ;; profitable when 7th bit is set.
9211 (define_split
9212   [(set (match_operand 0 "register_operand" "")
9213         (xor (match_operand 1 "general_operand" "")
9214              (match_operand 2 "const_int_operand" "")))
9215    (clobber (reg:CC FLAGS_REG))]
9216    "reload_completed
9217     && ANY_QI_REG_P (operands[0])
9218     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9219     && !(INTVAL (operands[2]) & ~255)
9220     && (INTVAL (operands[2]) & 128)
9221     && GET_MODE (operands[0]) != QImode"
9222   [(parallel [(set (strict_low_part (match_dup 0))
9223                    (xor:QI (match_dup 1)
9224                            (match_dup 2)))
9225               (clobber (reg:CC FLAGS_REG))])]
9226   "operands[0] = gen_lowpart (QImode, operands[0]);
9227    operands[1] = gen_lowpart (QImode, operands[1]);
9228    operands[2] = gen_lowpart (QImode, operands[2]);")
9230 ;; Negation instructions
9232 (define_expand "negdi2"
9233   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9234                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9235               (clobber (reg:CC FLAGS_REG))])]
9236   ""
9237   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9239 (define_insn "*negdi2_1"
9240   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9241         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9242    (clobber (reg:CC FLAGS_REG))]
9243   "!TARGET_64BIT
9244    && ix86_unary_operator_ok (NEG, DImode, operands)"
9245   "#")
9247 (define_split
9248   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9249         (neg:DI (match_operand:DI 1 "general_operand" "")))
9250    (clobber (reg:CC FLAGS_REG))]
9251   "!TARGET_64BIT && reload_completed"
9252   [(parallel
9253     [(set (reg:CCZ FLAGS_REG)
9254           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9255      (set (match_dup 0) (neg:SI (match_dup 2)))])
9256    (parallel
9257     [(set (match_dup 1)
9258           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9259                             (match_dup 3))
9260                    (const_int 0)))
9261      (clobber (reg:CC FLAGS_REG))])
9262    (parallel
9263     [(set (match_dup 1)
9264           (neg:SI (match_dup 1)))
9265      (clobber (reg:CC FLAGS_REG))])]
9266   "split_di (operands+1, 1, operands+2, operands+3);
9267    split_di (operands+0, 1, operands+0, operands+1);")
9269 (define_insn "*negdi2_1_rex64"
9270   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9271         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9272    (clobber (reg:CC FLAGS_REG))]
9273   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9274   "neg{q}\t%0"
9275   [(set_attr "type" "negnot")
9276    (set_attr "mode" "DI")])
9278 ;; The problem with neg is that it does not perform (compare x 0),
9279 ;; it really performs (compare 0 x), which leaves us with the zero
9280 ;; flag being the only useful item.
9282 (define_insn "*negdi2_cmpz_rex64"
9283   [(set (reg:CCZ FLAGS_REG)
9284         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9285                      (const_int 0)))
9286    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9287         (neg:DI (match_dup 1)))]
9288   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9289   "neg{q}\t%0"
9290   [(set_attr "type" "negnot")
9291    (set_attr "mode" "DI")])
9294 (define_expand "negsi2"
9295   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9296                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9297               (clobber (reg:CC FLAGS_REG))])]
9298   ""
9299   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9301 (define_insn "*negsi2_1"
9302   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9303         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9304    (clobber (reg:CC FLAGS_REG))]
9305   "ix86_unary_operator_ok (NEG, SImode, operands)"
9306   "neg{l}\t%0"
9307   [(set_attr "type" "negnot")
9308    (set_attr "mode" "SI")])
9310 ;; Combine is quite creative about this pattern.
9311 (define_insn "*negsi2_1_zext"
9312   [(set (match_operand:DI 0 "register_operand" "=r")
9313         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9314                                         (const_int 32)))
9315                      (const_int 32)))
9316    (clobber (reg:CC FLAGS_REG))]
9317   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9318   "neg{l}\t%k0"
9319   [(set_attr "type" "negnot")
9320    (set_attr "mode" "SI")])
9322 ;; The problem with neg is that it does not perform (compare x 0),
9323 ;; it really performs (compare 0 x), which leaves us with the zero
9324 ;; flag being the only useful item.
9326 (define_insn "*negsi2_cmpz"
9327   [(set (reg:CCZ FLAGS_REG)
9328         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9329                      (const_int 0)))
9330    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9331         (neg:SI (match_dup 1)))]
9332   "ix86_unary_operator_ok (NEG, SImode, operands)"
9333   "neg{l}\t%0"
9334   [(set_attr "type" "negnot")
9335    (set_attr "mode" "SI")])
9337 (define_insn "*negsi2_cmpz_zext"
9338   [(set (reg:CCZ FLAGS_REG)
9339         (compare:CCZ (lshiftrt:DI
9340                        (neg:DI (ashift:DI
9341                                  (match_operand:DI 1 "register_operand" "0")
9342                                  (const_int 32)))
9343                        (const_int 32))
9344                      (const_int 0)))
9345    (set (match_operand:DI 0 "register_operand" "=r")
9346         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9347                                         (const_int 32)))
9348                      (const_int 32)))]
9349   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9350   "neg{l}\t%k0"
9351   [(set_attr "type" "negnot")
9352    (set_attr "mode" "SI")])
9354 (define_expand "neghi2"
9355   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9356                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9357               (clobber (reg:CC FLAGS_REG))])]
9358   "TARGET_HIMODE_MATH"
9359   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9361 (define_insn "*neghi2_1"
9362   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9363         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9364    (clobber (reg:CC FLAGS_REG))]
9365   "ix86_unary_operator_ok (NEG, HImode, operands)"
9366   "neg{w}\t%0"
9367   [(set_attr "type" "negnot")
9368    (set_attr "mode" "HI")])
9370 (define_insn "*neghi2_cmpz"
9371   [(set (reg:CCZ FLAGS_REG)
9372         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9373                      (const_int 0)))
9374    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9375         (neg:HI (match_dup 1)))]
9376   "ix86_unary_operator_ok (NEG, HImode, operands)"
9377   "neg{w}\t%0"
9378   [(set_attr "type" "negnot")
9379    (set_attr "mode" "HI")])
9381 (define_expand "negqi2"
9382   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9383                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9384               (clobber (reg:CC FLAGS_REG))])]
9385   "TARGET_QIMODE_MATH"
9386   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9388 (define_insn "*negqi2_1"
9389   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9390         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9391    (clobber (reg:CC FLAGS_REG))]
9392   "ix86_unary_operator_ok (NEG, QImode, operands)"
9393   "neg{b}\t%0"
9394   [(set_attr "type" "negnot")
9395    (set_attr "mode" "QI")])
9397 (define_insn "*negqi2_cmpz"
9398   [(set (reg:CCZ FLAGS_REG)
9399         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9400                      (const_int 0)))
9401    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9402         (neg:QI (match_dup 1)))]
9403   "ix86_unary_operator_ok (NEG, QImode, operands)"
9404   "neg{b}\t%0"
9405   [(set_attr "type" "negnot")
9406    (set_attr "mode" "QI")])
9408 ;; Changing of sign for FP values is doable using integer unit too.
9410 (define_expand "negsf2"
9411   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9412         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9413   "TARGET_80387 || TARGET_SSE_MATH"
9414   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9416 (define_expand "abssf2"
9417   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9418         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9419   "TARGET_80387 || TARGET_SSE_MATH"
9420   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9422 (define_insn "*absnegsf2_mixed"
9423   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9424         (match_operator:SF 3 "absneg_operator"
9425           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9426    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9427    (clobber (reg:CC FLAGS_REG))]
9428   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9429    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9430   "#")
9432 (define_insn "*absnegsf2_sse"
9433   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9434         (match_operator:SF 3 "absneg_operator"
9435           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9436    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "TARGET_SSE_MATH
9439    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9440   "#")
9442 (define_insn "*absnegsf2_i387"
9443   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9444         (match_operator:SF 3 "absneg_operator"
9445           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9446    (use (match_operand 2 "" ""))
9447    (clobber (reg:CC FLAGS_REG))]
9448   "TARGET_80387 && !TARGET_SSE_MATH
9449    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9450   "#")
9452 (define_expand "negdf2"
9453   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9454         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9455   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9456   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9458 (define_expand "absdf2"
9459   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9460         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9461   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9462   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9464 (define_insn "*absnegdf2_mixed"
9465   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9466         (match_operator:DF 3 "absneg_operator"
9467           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9468    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9469    (clobber (reg:CC FLAGS_REG))]
9470   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9471    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9472   "#")
9474 (define_insn "*absnegdf2_sse"
9475   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9476         (match_operator:DF 3 "absneg_operator"
9477           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9478    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9479    (clobber (reg:CC FLAGS_REG))]
9480   "TARGET_SSE2 && TARGET_SSE_MATH
9481    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9482   "#")
9484 (define_insn "*absnegdf2_i387"
9485   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9486         (match_operator:DF 3 "absneg_operator"
9487           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9488    (use (match_operand 2 "" ""))
9489    (clobber (reg:CC FLAGS_REG))]
9490   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9491    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9492   "#")
9494 (define_expand "negxf2"
9495   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9496         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9497   "TARGET_80387"
9498   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9500 (define_expand "absxf2"
9501   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9502         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9503   "TARGET_80387"
9504   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9506 (define_insn "*absnegxf2_i387"
9507   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9508         (match_operator:XF 3 "absneg_operator"
9509           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9510    (use (match_operand 2 "" ""))
9511    (clobber (reg:CC FLAGS_REG))]
9512   "TARGET_80387
9513    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9514   "#")
9516 ;; Splitters for fp abs and neg.
9518 (define_split
9519   [(set (match_operand 0 "fp_register_operand" "")
9520         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9521    (use (match_operand 2 "" ""))
9522    (clobber (reg:CC FLAGS_REG))]
9523   "reload_completed"
9524   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9526 (define_split
9527   [(set (match_operand 0 "register_operand" "")
9528         (match_operator 3 "absneg_operator"
9529           [(match_operand 1 "register_operand" "")]))
9530    (use (match_operand 2 "nonimmediate_operand" ""))
9531    (clobber (reg:CC FLAGS_REG))]
9532   "reload_completed && SSE_REG_P (operands[0])"
9533   [(set (match_dup 0) (match_dup 3))]
9535   enum machine_mode mode = GET_MODE (operands[0]);
9536   enum machine_mode vmode = GET_MODE (operands[2]);
9537   rtx tmp;
9538   
9539   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9540   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9541   if (operands_match_p (operands[0], operands[2]))
9542     {
9543       tmp = operands[1];
9544       operands[1] = operands[2];
9545       operands[2] = tmp;
9546     }
9547   if (GET_CODE (operands[3]) == ABS)
9548     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9549   else
9550     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9551   operands[3] = tmp;
9554 (define_split
9555   [(set (match_operand:SF 0 "register_operand" "")
9556         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9557    (use (match_operand:V4SF 2 "" ""))
9558    (clobber (reg:CC FLAGS_REG))]
9559   "reload_completed"
9560   [(parallel [(set (match_dup 0) (match_dup 1))
9561               (clobber (reg:CC FLAGS_REG))])]
9563   rtx tmp;
9564   operands[0] = gen_lowpart (SImode, operands[0]);
9565   if (GET_CODE (operands[1]) == ABS)
9566     {
9567       tmp = gen_int_mode (0x7fffffff, SImode);
9568       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9569     }
9570   else
9571     {
9572       tmp = gen_int_mode (0x80000000, SImode);
9573       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9574     }
9575   operands[1] = tmp;
9578 (define_split
9579   [(set (match_operand:DF 0 "register_operand" "")
9580         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9581    (use (match_operand 2 "" ""))
9582    (clobber (reg:CC FLAGS_REG))]
9583   "reload_completed"
9584   [(parallel [(set (match_dup 0) (match_dup 1))
9585               (clobber (reg:CC FLAGS_REG))])]
9587   rtx tmp;
9588   if (TARGET_64BIT)
9589     {
9590       tmp = gen_lowpart (DImode, operands[0]);
9591       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9592       operands[0] = tmp;
9594       if (GET_CODE (operands[1]) == ABS)
9595         tmp = const0_rtx;
9596       else
9597         tmp = gen_rtx_NOT (DImode, tmp);
9598     }
9599   else
9600     {
9601       operands[0] = gen_highpart (SImode, operands[0]);
9602       if (GET_CODE (operands[1]) == ABS)
9603         {
9604           tmp = gen_int_mode (0x7fffffff, SImode);
9605           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9606         }
9607       else
9608         {
9609           tmp = gen_int_mode (0x80000000, SImode);
9610           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9611         }
9612     }
9613   operands[1] = tmp;
9616 (define_split
9617   [(set (match_operand:XF 0 "register_operand" "")
9618         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9619    (use (match_operand 2 "" ""))
9620    (clobber (reg:CC FLAGS_REG))]
9621   "reload_completed"
9622   [(parallel [(set (match_dup 0) (match_dup 1))
9623               (clobber (reg:CC FLAGS_REG))])]
9625   rtx tmp;
9626   operands[0] = gen_rtx_REG (SImode,
9627                              true_regnum (operands[0])
9628                              + (TARGET_64BIT ? 1 : 2));
9629   if (GET_CODE (operands[1]) == ABS)
9630     {
9631       tmp = GEN_INT (0x7fff);
9632       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9633     }
9634   else
9635     {
9636       tmp = GEN_INT (0x8000);
9637       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9638     }
9639   operands[1] = tmp;
9642 (define_split
9643   [(set (match_operand 0 "memory_operand" "")
9644         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9645    (use (match_operand 2 "" ""))
9646    (clobber (reg:CC FLAGS_REG))]
9647   "reload_completed"
9648   [(parallel [(set (match_dup 0) (match_dup 1))
9649               (clobber (reg:CC FLAGS_REG))])]
9651   enum machine_mode mode = GET_MODE (operands[0]);
9652   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9653   rtx tmp;
9655   operands[0] = adjust_address (operands[0], QImode, size - 1);
9656   if (GET_CODE (operands[1]) == ABS)
9657     {
9658       tmp = gen_int_mode (0x7f, QImode);
9659       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9660     }
9661   else
9662     {
9663       tmp = gen_int_mode (0x80, QImode);
9664       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9665     }
9666   operands[1] = tmp;
9669 ;; Conditionalize these after reload. If they match before reload, we 
9670 ;; lose the clobber and ability to use integer instructions.
9672 (define_insn "*negsf2_1"
9673   [(set (match_operand:SF 0 "register_operand" "=f")
9674         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9675   "TARGET_80387 && reload_completed"
9676   "fchs"
9677   [(set_attr "type" "fsgn")
9678    (set_attr "mode" "SF")])
9680 (define_insn "*negdf2_1"
9681   [(set (match_operand:DF 0 "register_operand" "=f")
9682         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9683   "TARGET_80387 && reload_completed"
9684   "fchs"
9685   [(set_attr "type" "fsgn")
9686    (set_attr "mode" "DF")])
9688 (define_insn "*negxf2_1"
9689   [(set (match_operand:XF 0 "register_operand" "=f")
9690         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9691   "TARGET_80387 && reload_completed"
9692   "fchs"
9693   [(set_attr "type" "fsgn")
9694    (set_attr "mode" "XF")])
9696 (define_insn "*abssf2_1"
9697   [(set (match_operand:SF 0 "register_operand" "=f")
9698         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9699   "TARGET_80387 && reload_completed"
9700   "fabs"
9701   [(set_attr "type" "fsgn")
9702    (set_attr "mode" "SF")])
9704 (define_insn "*absdf2_1"
9705   [(set (match_operand:DF 0 "register_operand" "=f")
9706         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9707   "TARGET_80387 && reload_completed"
9708   "fabs"
9709   [(set_attr "type" "fsgn")
9710    (set_attr "mode" "DF")])
9712 (define_insn "*absxf2_1"
9713   [(set (match_operand:XF 0 "register_operand" "=f")
9714         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9715   "TARGET_80387 && reload_completed"
9716   "fabs"
9717   [(set_attr "type" "fsgn")
9718    (set_attr "mode" "DF")])
9720 (define_insn "*negextendsfdf2"
9721   [(set (match_operand:DF 0 "register_operand" "=f")
9722         (neg:DF (float_extend:DF
9723                   (match_operand:SF 1 "register_operand" "0"))))]
9724   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9725   "fchs"
9726   [(set_attr "type" "fsgn")
9727    (set_attr "mode" "DF")])
9729 (define_insn "*negextenddfxf2"
9730   [(set (match_operand:XF 0 "register_operand" "=f")
9731         (neg:XF (float_extend:XF
9732                   (match_operand:DF 1 "register_operand" "0"))))]
9733   "TARGET_80387"
9734   "fchs"
9735   [(set_attr "type" "fsgn")
9736    (set_attr "mode" "XF")])
9738 (define_insn "*negextendsfxf2"
9739   [(set (match_operand:XF 0 "register_operand" "=f")
9740         (neg:XF (float_extend:XF
9741                   (match_operand:SF 1 "register_operand" "0"))))]
9742   "TARGET_80387"
9743   "fchs"
9744   [(set_attr "type" "fsgn")
9745    (set_attr "mode" "XF")])
9747 (define_insn "*absextendsfdf2"
9748   [(set (match_operand:DF 0 "register_operand" "=f")
9749         (abs:DF (float_extend:DF
9750                   (match_operand:SF 1 "register_operand" "0"))))]
9751   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9752   "fabs"
9753   [(set_attr "type" "fsgn")
9754    (set_attr "mode" "DF")])
9756 (define_insn "*absextenddfxf2"
9757   [(set (match_operand:XF 0 "register_operand" "=f")
9758         (abs:XF (float_extend:XF
9759           (match_operand:DF 1 "register_operand" "0"))))]
9760   "TARGET_80387"
9761   "fabs"
9762   [(set_attr "type" "fsgn")
9763    (set_attr "mode" "XF")])
9765 (define_insn "*absextendsfxf2"
9766   [(set (match_operand:XF 0 "register_operand" "=f")
9767         (abs:XF (float_extend:XF
9768           (match_operand:SF 1 "register_operand" "0"))))]
9769   "TARGET_80387"
9770   "fabs"
9771   [(set_attr "type" "fsgn")
9772    (set_attr "mode" "XF")])
9774 ;; One complement instructions
9776 (define_expand "one_cmpldi2"
9777   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9778         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9779   "TARGET_64BIT"
9780   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9782 (define_insn "*one_cmpldi2_1_rex64"
9783   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9784         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9785   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9786   "not{q}\t%0"
9787   [(set_attr "type" "negnot")
9788    (set_attr "mode" "DI")])
9790 (define_insn "*one_cmpldi2_2_rex64"
9791   [(set (reg FLAGS_REG)
9792         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9793                  (const_int 0)))
9794    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9795         (not:DI (match_dup 1)))]
9796   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9797    && ix86_unary_operator_ok (NOT, DImode, operands)"
9798   "#"
9799   [(set_attr "type" "alu1")
9800    (set_attr "mode" "DI")])
9802 (define_split
9803   [(set (match_operand 0 "flags_reg_operand" "")
9804         (match_operator 2 "compare_operator"
9805           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9806            (const_int 0)]))
9807    (set (match_operand:DI 1 "nonimmediate_operand" "")
9808         (not:DI (match_dup 3)))]
9809   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9810   [(parallel [(set (match_dup 0)
9811                    (match_op_dup 2
9812                      [(xor:DI (match_dup 3) (const_int -1))
9813                       (const_int 0)]))
9814               (set (match_dup 1)
9815                    (xor:DI (match_dup 3) (const_int -1)))])]
9816   "")
9818 (define_expand "one_cmplsi2"
9819   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9820         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9821   ""
9822   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9824 (define_insn "*one_cmplsi2_1"
9825   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9826         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9827   "ix86_unary_operator_ok (NOT, SImode, operands)"
9828   "not{l}\t%0"
9829   [(set_attr "type" "negnot")
9830    (set_attr "mode" "SI")])
9832 ;; ??? Currently never generated - xor is used instead.
9833 (define_insn "*one_cmplsi2_1_zext"
9834   [(set (match_operand:DI 0 "register_operand" "=r")
9835         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9836   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9837   "not{l}\t%k0"
9838   [(set_attr "type" "negnot")
9839    (set_attr "mode" "SI")])
9841 (define_insn "*one_cmplsi2_2"
9842   [(set (reg FLAGS_REG)
9843         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9844                  (const_int 0)))
9845    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9846         (not:SI (match_dup 1)))]
9847   "ix86_match_ccmode (insn, CCNOmode)
9848    && ix86_unary_operator_ok (NOT, SImode, operands)"
9849   "#"
9850   [(set_attr "type" "alu1")
9851    (set_attr "mode" "SI")])
9853 (define_split
9854   [(set (match_operand 0 "flags_reg_operand" "")
9855         (match_operator 2 "compare_operator"
9856           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9857            (const_int 0)]))
9858    (set (match_operand:SI 1 "nonimmediate_operand" "")
9859         (not:SI (match_dup 3)))]
9860   "ix86_match_ccmode (insn, CCNOmode)"
9861   [(parallel [(set (match_dup 0)
9862                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9863                                     (const_int 0)]))
9864               (set (match_dup 1)
9865                    (xor:SI (match_dup 3) (const_int -1)))])]
9866   "")
9868 ;; ??? Currently never generated - xor is used instead.
9869 (define_insn "*one_cmplsi2_2_zext"
9870   [(set (reg FLAGS_REG)
9871         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9872                  (const_int 0)))
9873    (set (match_operand:DI 0 "register_operand" "=r")
9874         (zero_extend:DI (not:SI (match_dup 1))))]
9875   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9876    && ix86_unary_operator_ok (NOT, SImode, operands)"
9877   "#"
9878   [(set_attr "type" "alu1")
9879    (set_attr "mode" "SI")])
9881 (define_split
9882   [(set (match_operand 0 "flags_reg_operand" "")
9883         (match_operator 2 "compare_operator"
9884           [(not:SI (match_operand:SI 3 "register_operand" ""))
9885            (const_int 0)]))
9886    (set (match_operand:DI 1 "register_operand" "")
9887         (zero_extend:DI (not:SI (match_dup 3))))]
9888   "ix86_match_ccmode (insn, CCNOmode)"
9889   [(parallel [(set (match_dup 0)
9890                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9891                                     (const_int 0)]))
9892               (set (match_dup 1)
9893                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9894   "")
9896 (define_expand "one_cmplhi2"
9897   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9898         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9899   "TARGET_HIMODE_MATH"
9900   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9902 (define_insn "*one_cmplhi2_1"
9903   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9904         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9905   "ix86_unary_operator_ok (NOT, HImode, operands)"
9906   "not{w}\t%0"
9907   [(set_attr "type" "negnot")
9908    (set_attr "mode" "HI")])
9910 (define_insn "*one_cmplhi2_2"
9911   [(set (reg FLAGS_REG)
9912         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9913                  (const_int 0)))
9914    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9915         (not:HI (match_dup 1)))]
9916   "ix86_match_ccmode (insn, CCNOmode)
9917    && ix86_unary_operator_ok (NEG, HImode, operands)"
9918   "#"
9919   [(set_attr "type" "alu1")
9920    (set_attr "mode" "HI")])
9922 (define_split
9923   [(set (match_operand 0 "flags_reg_operand" "")
9924         (match_operator 2 "compare_operator"
9925           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9926            (const_int 0)]))
9927    (set (match_operand:HI 1 "nonimmediate_operand" "")
9928         (not:HI (match_dup 3)))]
9929   "ix86_match_ccmode (insn, CCNOmode)"
9930   [(parallel [(set (match_dup 0)
9931                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
9932                                     (const_int 0)]))
9933               (set (match_dup 1)
9934                    (xor:HI (match_dup 3) (const_int -1)))])]
9935   "")
9937 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9938 (define_expand "one_cmplqi2"
9939   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9940         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
9941   "TARGET_QIMODE_MATH"
9942   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
9944 (define_insn "*one_cmplqi2_1"
9945   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9946         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9947   "ix86_unary_operator_ok (NOT, QImode, operands)"
9948   "@
9949    not{b}\t%0
9950    not{l}\t%k0"
9951   [(set_attr "type" "negnot")
9952    (set_attr "mode" "QI,SI")])
9954 (define_insn "*one_cmplqi2_2"
9955   [(set (reg FLAGS_REG)
9956         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9957                  (const_int 0)))
9958    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9959         (not:QI (match_dup 1)))]
9960   "ix86_match_ccmode (insn, CCNOmode)
9961    && ix86_unary_operator_ok (NOT, QImode, operands)"
9962   "#"
9963   [(set_attr "type" "alu1")
9964    (set_attr "mode" "QI")])
9966 (define_split
9967   [(set (match_operand 0 "flags_reg_operand" "")
9968         (match_operator 2 "compare_operator"
9969           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
9970            (const_int 0)]))
9971    (set (match_operand:QI 1 "nonimmediate_operand" "")
9972         (not:QI (match_dup 3)))]
9973   "ix86_match_ccmode (insn, CCNOmode)"
9974   [(parallel [(set (match_dup 0)
9975                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
9976                                     (const_int 0)]))
9977               (set (match_dup 1)
9978                    (xor:QI (match_dup 3) (const_int -1)))])]
9979   "")
9981 ;; Arithmetic shift instructions
9983 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9984 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9985 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9986 ;; from the assembler input.
9988 ;; This instruction shifts the target reg/mem as usual, but instead of
9989 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9990 ;; is a left shift double, bits are taken from the high order bits of
9991 ;; reg, else if the insn is a shift right double, bits are taken from the
9992 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9993 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9995 ;; Since sh[lr]d does not change the `reg' operand, that is done
9996 ;; separately, making all shifts emit pairs of shift double and normal
9997 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9998 ;; support a 63 bit shift, each shift where the count is in a reg expands
9999 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10001 ;; If the shift count is a constant, we need never emit more than one
10002 ;; shift pair, instead using moves and sign extension for counts greater
10003 ;; than 31.
10005 (define_expand "ashldi3"
10006   [(set (match_operand:DI 0 "shiftdi_operand" "")
10007         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10008                    (match_operand:QI 2 "nonmemory_operand" "")))]
10009   ""
10010   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10012 (define_insn "*ashldi3_1_rex64"
10013   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10014         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10015                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10016    (clobber (reg:CC FLAGS_REG))]
10017   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10019   switch (get_attr_type (insn))
10020     {
10021     case TYPE_ALU:
10022       if (operands[2] != const1_rtx)
10023         abort ();
10024       if (!rtx_equal_p (operands[0], operands[1]))
10025         abort ();
10026       return "add{q}\t{%0, %0|%0, %0}";
10028     case TYPE_LEA:
10029       if (GET_CODE (operands[2]) != CONST_INT
10030           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10031         abort ();
10032       operands[1] = gen_rtx_MULT (DImode, operands[1],
10033                                   GEN_INT (1 << INTVAL (operands[2])));
10034       return "lea{q}\t{%a1, %0|%0, %a1}";
10036     default:
10037       if (REG_P (operands[2]))
10038         return "sal{q}\t{%b2, %0|%0, %b2}";
10039       else if (operands[2] == const1_rtx
10040                && (TARGET_SHIFT1 || optimize_size))
10041         return "sal{q}\t%0";
10042       else
10043         return "sal{q}\t{%2, %0|%0, %2}";
10044     }
10046   [(set (attr "type")
10047      (cond [(eq_attr "alternative" "1")
10048               (const_string "lea")
10049             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10050                           (const_int 0))
10051                       (match_operand 0 "register_operand" ""))
10052                  (match_operand 2 "const1_operand" ""))
10053               (const_string "alu")
10054            ]
10055            (const_string "ishift")))
10056    (set_attr "mode" "DI")])
10058 ;; Convert lea to the lea pattern to avoid flags dependency.
10059 (define_split
10060   [(set (match_operand:DI 0 "register_operand" "")
10061         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10062                    (match_operand:QI 2 "immediate_operand" "")))
10063    (clobber (reg:CC FLAGS_REG))]
10064   "TARGET_64BIT && reload_completed
10065    && true_regnum (operands[0]) != true_regnum (operands[1])"
10066   [(set (match_dup 0)
10067         (mult:DI (match_dup 1)
10068                  (match_dup 2)))]
10069   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10071 ;; This pattern can't accept a variable shift count, since shifts by
10072 ;; zero don't affect the flags.  We assume that shifts by constant
10073 ;; zero are optimized away.
10074 (define_insn "*ashldi3_cmp_rex64"
10075   [(set (reg FLAGS_REG)
10076         (compare
10077           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10078                      (match_operand:QI 2 "immediate_operand" "e"))
10079           (const_int 0)))
10080    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10081         (ashift:DI (match_dup 1) (match_dup 2)))]
10082   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10083    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10085   switch (get_attr_type (insn))
10086     {
10087     case TYPE_ALU:
10088       if (operands[2] != const1_rtx)
10089         abort ();
10090       return "add{q}\t{%0, %0|%0, %0}";
10092     default:
10093       if (REG_P (operands[2]))
10094         return "sal{q}\t{%b2, %0|%0, %b2}";
10095       else if (operands[2] == const1_rtx
10096                && (TARGET_SHIFT1 || optimize_size))
10097         return "sal{q}\t%0";
10098       else
10099         return "sal{q}\t{%2, %0|%0, %2}";
10100     }
10102   [(set (attr "type")
10103      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10104                           (const_int 0))
10105                       (match_operand 0 "register_operand" ""))
10106                  (match_operand 2 "const1_operand" ""))
10107               (const_string "alu")
10108            ]
10109            (const_string "ishift")))
10110    (set_attr "mode" "DI")])
10112 (define_insn "*ashldi3_1"
10113   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10114         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10115                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10116    (clobber (reg:CC FLAGS_REG))]
10117   "!TARGET_64BIT"
10118   "#"
10119   [(set_attr "type" "multi")])
10121 ;; By default we don't ask for a scratch register, because when DImode
10122 ;; values are manipulated, registers are already at a premium.  But if
10123 ;; we have one handy, we won't turn it away.
10124 (define_peephole2
10125   [(match_scratch:SI 3 "r")
10126    (parallel [(set (match_operand:DI 0 "register_operand" "")
10127                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10128                               (match_operand:QI 2 "nonmemory_operand" "")))
10129               (clobber (reg:CC FLAGS_REG))])
10130    (match_dup 3)]
10131   "!TARGET_64BIT && TARGET_CMOVE"
10132   [(const_int 0)]
10133   "ix86_split_ashldi (operands, operands[3]); DONE;")
10135 (define_split
10136   [(set (match_operand:DI 0 "register_operand" "")
10137         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10138                    (match_operand:QI 2 "nonmemory_operand" "")))
10139    (clobber (reg:CC FLAGS_REG))]
10140   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10141   [(const_int 0)]
10142   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10144 (define_insn "x86_shld_1"
10145   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10146         (ior:SI (ashift:SI (match_dup 0)
10147                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10148                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10149                   (minus:QI (const_int 32) (match_dup 2)))))
10150    (clobber (reg:CC FLAGS_REG))]
10151   ""
10152   "@
10153    shld{l}\t{%2, %1, %0|%0, %1, %2}
10154    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10155   [(set_attr "type" "ishift")
10156    (set_attr "prefix_0f" "1")
10157    (set_attr "mode" "SI")
10158    (set_attr "pent_pair" "np")
10159    (set_attr "athlon_decode" "vector")])
10161 (define_expand "x86_shift_adj_1"
10162   [(set (reg:CCZ FLAGS_REG)
10163         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10164                              (const_int 32))
10165                      (const_int 0)))
10166    (set (match_operand:SI 0 "register_operand" "")
10167         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10168                          (match_operand:SI 1 "register_operand" "")
10169                          (match_dup 0)))
10170    (set (match_dup 1)
10171         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10172                          (match_operand:SI 3 "register_operand" "r")
10173                          (match_dup 1)))]
10174   "TARGET_CMOVE"
10175   "")
10177 (define_expand "x86_shift_adj_2"
10178   [(use (match_operand:SI 0 "register_operand" ""))
10179    (use (match_operand:SI 1 "register_operand" ""))
10180    (use (match_operand:QI 2 "register_operand" ""))]
10181   ""
10183   rtx label = gen_label_rtx ();
10184   rtx tmp;
10186   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10188   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10189   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10190   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10191                               gen_rtx_LABEL_REF (VOIDmode, label),
10192                               pc_rtx);
10193   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10194   JUMP_LABEL (tmp) = label;
10196   emit_move_insn (operands[0], operands[1]);
10197   ix86_expand_clear (operands[1]);
10199   emit_label (label);
10200   LABEL_NUSES (label) = 1;
10202   DONE;
10205 (define_expand "ashlsi3"
10206   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10207         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10208                    (match_operand:QI 2 "nonmemory_operand" "")))
10209    (clobber (reg:CC FLAGS_REG))]
10210   ""
10211   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10213 (define_insn "*ashlsi3_1"
10214   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10215         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10216                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10217    (clobber (reg:CC FLAGS_REG))]
10218   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10220   switch (get_attr_type (insn))
10221     {
10222     case TYPE_ALU:
10223       if (operands[2] != const1_rtx)
10224         abort ();
10225       if (!rtx_equal_p (operands[0], operands[1]))
10226         abort ();
10227       return "add{l}\t{%0, %0|%0, %0}";
10229     case TYPE_LEA:
10230       return "#";
10232     default:
10233       if (REG_P (operands[2]))
10234         return "sal{l}\t{%b2, %0|%0, %b2}";
10235       else if (operands[2] == const1_rtx
10236                && (TARGET_SHIFT1 || optimize_size))
10237         return "sal{l}\t%0";
10238       else
10239         return "sal{l}\t{%2, %0|%0, %2}";
10240     }
10242   [(set (attr "type")
10243      (cond [(eq_attr "alternative" "1")
10244               (const_string "lea")
10245             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10246                           (const_int 0))
10247                       (match_operand 0 "register_operand" ""))
10248                  (match_operand 2 "const1_operand" ""))
10249               (const_string "alu")
10250            ]
10251            (const_string "ishift")))
10252    (set_attr "mode" "SI")])
10254 ;; Convert lea to the lea pattern to avoid flags dependency.
10255 (define_split
10256   [(set (match_operand 0 "register_operand" "")
10257         (ashift (match_operand 1 "index_register_operand" "")
10258                 (match_operand:QI 2 "const_int_operand" "")))
10259    (clobber (reg:CC FLAGS_REG))]
10260   "reload_completed
10261    && true_regnum (operands[0]) != true_regnum (operands[1])
10262    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10263   [(const_int 0)]
10265   rtx pat;
10266   enum machine_mode mode = GET_MODE (operands[0]);
10268   if (GET_MODE_SIZE (mode) < 4)
10269     operands[0] = gen_lowpart (SImode, operands[0]);
10270   if (mode != Pmode)
10271     operands[1] = gen_lowpart (Pmode, operands[1]);
10272   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10274   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10275   if (Pmode != SImode)
10276     pat = gen_rtx_SUBREG (SImode, pat, 0);
10277   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10278   DONE;
10281 ;; Rare case of shifting RSP is handled by generating move and shift
10282 (define_split
10283   [(set (match_operand 0 "register_operand" "")
10284         (ashift (match_operand 1 "register_operand" "")
10285                 (match_operand:QI 2 "const_int_operand" "")))
10286    (clobber (reg:CC FLAGS_REG))]
10287   "reload_completed
10288    && true_regnum (operands[0]) != true_regnum (operands[1])"
10289   [(const_int 0)]
10291   rtx pat, clob;
10292   emit_move_insn (operands[1], operands[0]);
10293   pat = gen_rtx_SET (VOIDmode, operands[0],
10294                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10295                                      operands[0], operands[2]));
10296   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10297   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10298   DONE;
10301 (define_insn "*ashlsi3_1_zext"
10302   [(set (match_operand:DI 0 "register_operand" "=r,r")
10303         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10304                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10305    (clobber (reg:CC FLAGS_REG))]
10306   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10308   switch (get_attr_type (insn))
10309     {
10310     case TYPE_ALU:
10311       if (operands[2] != const1_rtx)
10312         abort ();
10313       return "add{l}\t{%k0, %k0|%k0, %k0}";
10315     case TYPE_LEA:
10316       return "#";
10318     default:
10319       if (REG_P (operands[2]))
10320         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10321       else if (operands[2] == const1_rtx
10322                && (TARGET_SHIFT1 || optimize_size))
10323         return "sal{l}\t%k0";
10324       else
10325         return "sal{l}\t{%2, %k0|%k0, %2}";
10326     }
10328   [(set (attr "type")
10329      (cond [(eq_attr "alternative" "1")
10330               (const_string "lea")
10331             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10332                      (const_int 0))
10333                  (match_operand 2 "const1_operand" ""))
10334               (const_string "alu")
10335            ]
10336            (const_string "ishift")))
10337    (set_attr "mode" "SI")])
10339 ;; Convert lea to the lea pattern to avoid flags dependency.
10340 (define_split
10341   [(set (match_operand:DI 0 "register_operand" "")
10342         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10343                                 (match_operand:QI 2 "const_int_operand" ""))))
10344    (clobber (reg:CC FLAGS_REG))]
10345   "TARGET_64BIT && reload_completed
10346    && true_regnum (operands[0]) != true_regnum (operands[1])"
10347   [(set (match_dup 0) (zero_extend:DI
10348                         (subreg:SI (mult:SI (match_dup 1)
10349                                             (match_dup 2)) 0)))]
10351   operands[1] = gen_lowpart (Pmode, operands[1]);
10352   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10355 ;; This pattern can't accept a variable shift count, since shifts by
10356 ;; zero don't affect the flags.  We assume that shifts by constant
10357 ;; zero are optimized away.
10358 (define_insn "*ashlsi3_cmp"
10359   [(set (reg FLAGS_REG)
10360         (compare
10361           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10362                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10363           (const_int 0)))
10364    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10365         (ashift:SI (match_dup 1) (match_dup 2)))]
10366   "ix86_match_ccmode (insn, CCGOCmode)
10367    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10369   switch (get_attr_type (insn))
10370     {
10371     case TYPE_ALU:
10372       if (operands[2] != const1_rtx)
10373         abort ();
10374       return "add{l}\t{%0, %0|%0, %0}";
10376     default:
10377       if (REG_P (operands[2]))
10378         return "sal{l}\t{%b2, %0|%0, %b2}";
10379       else if (operands[2] == const1_rtx
10380                && (TARGET_SHIFT1 || optimize_size))
10381         return "sal{l}\t%0";
10382       else
10383         return "sal{l}\t{%2, %0|%0, %2}";
10384     }
10386   [(set (attr "type")
10387      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10388                           (const_int 0))
10389                       (match_operand 0 "register_operand" ""))
10390                  (match_operand 2 "const1_operand" ""))
10391               (const_string "alu")
10392            ]
10393            (const_string "ishift")))
10394    (set_attr "mode" "SI")])
10396 (define_insn "*ashlsi3_cmp_zext"
10397   [(set (reg FLAGS_REG)
10398         (compare
10399           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10400                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10401           (const_int 0)))
10402    (set (match_operand:DI 0 "register_operand" "=r")
10403         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10404   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10405    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10407   switch (get_attr_type (insn))
10408     {
10409     case TYPE_ALU:
10410       if (operands[2] != const1_rtx)
10411         abort ();
10412       return "add{l}\t{%k0, %k0|%k0, %k0}";
10414     default:
10415       if (REG_P (operands[2]))
10416         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10417       else if (operands[2] == const1_rtx
10418                && (TARGET_SHIFT1 || optimize_size))
10419         return "sal{l}\t%k0";
10420       else
10421         return "sal{l}\t{%2, %k0|%k0, %2}";
10422     }
10424   [(set (attr "type")
10425      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10426                      (const_int 0))
10427                  (match_operand 2 "const1_operand" ""))
10428               (const_string "alu")
10429            ]
10430            (const_string "ishift")))
10431    (set_attr "mode" "SI")])
10433 (define_expand "ashlhi3"
10434   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10435         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10436                    (match_operand:QI 2 "nonmemory_operand" "")))
10437    (clobber (reg:CC FLAGS_REG))]
10438   "TARGET_HIMODE_MATH"
10439   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10441 (define_insn "*ashlhi3_1_lea"
10442   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10443         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10444                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10445    (clobber (reg:CC FLAGS_REG))]
10446   "!TARGET_PARTIAL_REG_STALL
10447    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10449   switch (get_attr_type (insn))
10450     {
10451     case TYPE_LEA:
10452       return "#";
10453     case TYPE_ALU:
10454       if (operands[2] != const1_rtx)
10455         abort ();
10456       return "add{w}\t{%0, %0|%0, %0}";
10458     default:
10459       if (REG_P (operands[2]))
10460         return "sal{w}\t{%b2, %0|%0, %b2}";
10461       else if (operands[2] == const1_rtx
10462                && (TARGET_SHIFT1 || optimize_size))
10463         return "sal{w}\t%0";
10464       else
10465         return "sal{w}\t{%2, %0|%0, %2}";
10466     }
10468   [(set (attr "type")
10469      (cond [(eq_attr "alternative" "1")
10470               (const_string "lea")
10471             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10472                           (const_int 0))
10473                       (match_operand 0 "register_operand" ""))
10474                  (match_operand 2 "const1_operand" ""))
10475               (const_string "alu")
10476            ]
10477            (const_string "ishift")))
10478    (set_attr "mode" "HI,SI")])
10480 (define_insn "*ashlhi3_1"
10481   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10482         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10483                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10484    (clobber (reg:CC FLAGS_REG))]
10485   "TARGET_PARTIAL_REG_STALL
10486    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10488   switch (get_attr_type (insn))
10489     {
10490     case TYPE_ALU:
10491       if (operands[2] != const1_rtx)
10492         abort ();
10493       return "add{w}\t{%0, %0|%0, %0}";
10495     default:
10496       if (REG_P (operands[2]))
10497         return "sal{w}\t{%b2, %0|%0, %b2}";
10498       else if (operands[2] == const1_rtx
10499                && (TARGET_SHIFT1 || optimize_size))
10500         return "sal{w}\t%0";
10501       else
10502         return "sal{w}\t{%2, %0|%0, %2}";
10503     }
10505   [(set (attr "type")
10506      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10507                           (const_int 0))
10508                       (match_operand 0 "register_operand" ""))
10509                  (match_operand 2 "const1_operand" ""))
10510               (const_string "alu")
10511            ]
10512            (const_string "ishift")))
10513    (set_attr "mode" "HI")])
10515 ;; This pattern can't accept a variable shift count, since shifts by
10516 ;; zero don't affect the flags.  We assume that shifts by constant
10517 ;; zero are optimized away.
10518 (define_insn "*ashlhi3_cmp"
10519   [(set (reg FLAGS_REG)
10520         (compare
10521           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10522                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10523           (const_int 0)))
10524    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10525         (ashift:HI (match_dup 1) (match_dup 2)))]
10526   "ix86_match_ccmode (insn, CCGOCmode)
10527    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10529   switch (get_attr_type (insn))
10530     {
10531     case TYPE_ALU:
10532       if (operands[2] != const1_rtx)
10533         abort ();
10534       return "add{w}\t{%0, %0|%0, %0}";
10536     default:
10537       if (REG_P (operands[2]))
10538         return "sal{w}\t{%b2, %0|%0, %b2}";
10539       else if (operands[2] == const1_rtx
10540                && (TARGET_SHIFT1 || optimize_size))
10541         return "sal{w}\t%0";
10542       else
10543         return "sal{w}\t{%2, %0|%0, %2}";
10544     }
10546   [(set (attr "type")
10547      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10548                           (const_int 0))
10549                       (match_operand 0 "register_operand" ""))
10550                  (match_operand 2 "const1_operand" ""))
10551               (const_string "alu")
10552            ]
10553            (const_string "ishift")))
10554    (set_attr "mode" "HI")])
10556 (define_expand "ashlqi3"
10557   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10558         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10559                    (match_operand:QI 2 "nonmemory_operand" "")))
10560    (clobber (reg:CC FLAGS_REG))]
10561   "TARGET_QIMODE_MATH"
10562   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10564 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10566 (define_insn "*ashlqi3_1_lea"
10567   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10568         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10569                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10570    (clobber (reg:CC FLAGS_REG))]
10571   "!TARGET_PARTIAL_REG_STALL
10572    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10574   switch (get_attr_type (insn))
10575     {
10576     case TYPE_LEA:
10577       return "#";
10578     case TYPE_ALU:
10579       if (operands[2] != const1_rtx)
10580         abort ();
10581       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10582         return "add{l}\t{%k0, %k0|%k0, %k0}";
10583       else
10584         return "add{b}\t{%0, %0|%0, %0}";
10586     default:
10587       if (REG_P (operands[2]))
10588         {
10589           if (get_attr_mode (insn) == MODE_SI)
10590             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10591           else
10592             return "sal{b}\t{%b2, %0|%0, %b2}";
10593         }
10594       else if (operands[2] == const1_rtx
10595                && (TARGET_SHIFT1 || optimize_size))
10596         {
10597           if (get_attr_mode (insn) == MODE_SI)
10598             return "sal{l}\t%0";
10599           else
10600             return "sal{b}\t%0";
10601         }
10602       else
10603         {
10604           if (get_attr_mode (insn) == MODE_SI)
10605             return "sal{l}\t{%2, %k0|%k0, %2}";
10606           else
10607             return "sal{b}\t{%2, %0|%0, %2}";
10608         }
10609     }
10611   [(set (attr "type")
10612      (cond [(eq_attr "alternative" "2")
10613               (const_string "lea")
10614             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10615                           (const_int 0))
10616                       (match_operand 0 "register_operand" ""))
10617                  (match_operand 2 "const1_operand" ""))
10618               (const_string "alu")
10619            ]
10620            (const_string "ishift")))
10621    (set_attr "mode" "QI,SI,SI")])
10623 (define_insn "*ashlqi3_1"
10624   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10625         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10626                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10627    (clobber (reg:CC FLAGS_REG))]
10628   "TARGET_PARTIAL_REG_STALL
10629    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10631   switch (get_attr_type (insn))
10632     {
10633     case TYPE_ALU:
10634       if (operands[2] != const1_rtx)
10635         abort ();
10636       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10637         return "add{l}\t{%k0, %k0|%k0, %k0}";
10638       else
10639         return "add{b}\t{%0, %0|%0, %0}";
10641     default:
10642       if (REG_P (operands[2]))
10643         {
10644           if (get_attr_mode (insn) == MODE_SI)
10645             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10646           else
10647             return "sal{b}\t{%b2, %0|%0, %b2}";
10648         }
10649       else if (operands[2] == const1_rtx
10650                && (TARGET_SHIFT1 || optimize_size))
10651         {
10652           if (get_attr_mode (insn) == MODE_SI)
10653             return "sal{l}\t%0";
10654           else
10655             return "sal{b}\t%0";
10656         }
10657       else
10658         {
10659           if (get_attr_mode (insn) == MODE_SI)
10660             return "sal{l}\t{%2, %k0|%k0, %2}";
10661           else
10662             return "sal{b}\t{%2, %0|%0, %2}";
10663         }
10664     }
10666   [(set (attr "type")
10667      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10668                           (const_int 0))
10669                       (match_operand 0 "register_operand" ""))
10670                  (match_operand 2 "const1_operand" ""))
10671               (const_string "alu")
10672            ]
10673            (const_string "ishift")))
10674    (set_attr "mode" "QI,SI")])
10676 ;; This pattern can't accept a variable shift count, since shifts by
10677 ;; zero don't affect the flags.  We assume that shifts by constant
10678 ;; zero are optimized away.
10679 (define_insn "*ashlqi3_cmp"
10680   [(set (reg FLAGS_REG)
10681         (compare
10682           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10683                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10684           (const_int 0)))
10685    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10686         (ashift:QI (match_dup 1) (match_dup 2)))]
10687   "ix86_match_ccmode (insn, CCGOCmode)
10688    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10690   switch (get_attr_type (insn))
10691     {
10692     case TYPE_ALU:
10693       if (operands[2] != const1_rtx)
10694         abort ();
10695       return "add{b}\t{%0, %0|%0, %0}";
10697     default:
10698       if (REG_P (operands[2]))
10699         return "sal{b}\t{%b2, %0|%0, %b2}";
10700       else if (operands[2] == const1_rtx
10701                && (TARGET_SHIFT1 || optimize_size))
10702         return "sal{b}\t%0";
10703       else
10704         return "sal{b}\t{%2, %0|%0, %2}";
10705     }
10707   [(set (attr "type")
10708      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10709                           (const_int 0))
10710                       (match_operand 0 "register_operand" ""))
10711                  (match_operand 2 "const1_operand" ""))
10712               (const_string "alu")
10713            ]
10714            (const_string "ishift")))
10715    (set_attr "mode" "QI")])
10717 ;; See comment above `ashldi3' about how this works.
10719 (define_expand "ashrdi3"
10720   [(set (match_operand:DI 0 "shiftdi_operand" "")
10721         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10722                      (match_operand:QI 2 "nonmemory_operand" "")))]
10723   ""
10724   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10726 (define_insn "*ashrdi3_63_rex64"
10727   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10728         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10729                      (match_operand:DI 2 "const_int_operand" "i,i")))
10730    (clobber (reg:CC FLAGS_REG))]
10731   "TARGET_64BIT && INTVAL (operands[2]) == 63
10732    && (TARGET_USE_CLTD || optimize_size)
10733    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10734   "@
10735    {cqto|cqo}
10736    sar{q}\t{%2, %0|%0, %2}"
10737   [(set_attr "type" "imovx,ishift")
10738    (set_attr "prefix_0f" "0,*")
10739    (set_attr "length_immediate" "0,*")
10740    (set_attr "modrm" "0,1")
10741    (set_attr "mode" "DI")])
10743 (define_insn "*ashrdi3_1_one_bit_rex64"
10744   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10745         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10746                      (match_operand:QI 2 "const1_operand" "")))
10747    (clobber (reg:CC FLAGS_REG))]
10748   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10749    && (TARGET_SHIFT1 || optimize_size)"
10750   "sar{q}\t%0"
10751   [(set_attr "type" "ishift")
10752    (set (attr "length") 
10753      (if_then_else (match_operand:DI 0 "register_operand" "") 
10754         (const_string "2")
10755         (const_string "*")))])
10757 (define_insn "*ashrdi3_1_rex64"
10758   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10759         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10760                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10761    (clobber (reg:CC FLAGS_REG))]
10762   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10763   "@
10764    sar{q}\t{%2, %0|%0, %2}
10765    sar{q}\t{%b2, %0|%0, %b2}"
10766   [(set_attr "type" "ishift")
10767    (set_attr "mode" "DI")])
10769 ;; This pattern can't accept a variable shift count, since shifts by
10770 ;; zero don't affect the flags.  We assume that shifts by constant
10771 ;; zero are optimized away.
10772 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10773   [(set (reg FLAGS_REG)
10774         (compare
10775           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10776                        (match_operand:QI 2 "const1_operand" ""))
10777           (const_int 0)))
10778    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10779         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10780   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10781    && (TARGET_SHIFT1 || optimize_size)
10782    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10783   "sar{q}\t%0"
10784   [(set_attr "type" "ishift")
10785    (set (attr "length") 
10786      (if_then_else (match_operand:DI 0 "register_operand" "") 
10787         (const_string "2")
10788         (const_string "*")))])
10790 ;; This pattern can't accept a variable shift count, since shifts by
10791 ;; zero don't affect the flags.  We assume that shifts by constant
10792 ;; zero are optimized away.
10793 (define_insn "*ashrdi3_cmp_rex64"
10794   [(set (reg FLAGS_REG)
10795         (compare
10796           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10797                        (match_operand:QI 2 "const_int_operand" "n"))
10798           (const_int 0)))
10799    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10800         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10801   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10802    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10803   "sar{q}\t{%2, %0|%0, %2}"
10804   [(set_attr "type" "ishift")
10805    (set_attr "mode" "DI")])
10807 (define_insn "*ashrdi3_1"
10808   [(set (match_operand:DI 0 "register_operand" "=r")
10809         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10810                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10811    (clobber (reg:CC FLAGS_REG))]
10812   "!TARGET_64BIT"
10813   "#"
10814   [(set_attr "type" "multi")])
10816 ;; By default we don't ask for a scratch register, because when DImode
10817 ;; values are manipulated, registers are already at a premium.  But if
10818 ;; we have one handy, we won't turn it away.
10819 (define_peephole2
10820   [(match_scratch:SI 3 "r")
10821    (parallel [(set (match_operand:DI 0 "register_operand" "")
10822                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10823                                 (match_operand:QI 2 "nonmemory_operand" "")))
10824               (clobber (reg:CC FLAGS_REG))])
10825    (match_dup 3)]
10826   "!TARGET_64BIT && TARGET_CMOVE"
10827   [(const_int 0)]
10828   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10830 (define_split
10831   [(set (match_operand:DI 0 "register_operand" "")
10832         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10833                      (match_operand:QI 2 "nonmemory_operand" "")))
10834    (clobber (reg:CC FLAGS_REG))]
10835   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10836   [(const_int 0)]
10837   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10839 (define_insn "x86_shrd_1"
10840   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10841         (ior:SI (ashiftrt:SI (match_dup 0)
10842                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10843                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10844                   (minus:QI (const_int 32) (match_dup 2)))))
10845    (clobber (reg:CC FLAGS_REG))]
10846   ""
10847   "@
10848    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10849    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10850   [(set_attr "type" "ishift")
10851    (set_attr "prefix_0f" "1")
10852    (set_attr "pent_pair" "np")
10853    (set_attr "mode" "SI")])
10855 (define_expand "x86_shift_adj_3"
10856   [(use (match_operand:SI 0 "register_operand" ""))
10857    (use (match_operand:SI 1 "register_operand" ""))
10858    (use (match_operand:QI 2 "register_operand" ""))]
10859   ""
10861   rtx label = gen_label_rtx ();
10862   rtx tmp;
10864   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10866   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10867   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10868   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10869                               gen_rtx_LABEL_REF (VOIDmode, label),
10870                               pc_rtx);
10871   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10872   JUMP_LABEL (tmp) = label;
10874   emit_move_insn (operands[0], operands[1]);
10875   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10877   emit_label (label);
10878   LABEL_NUSES (label) = 1;
10880   DONE;
10883 (define_insn "ashrsi3_31"
10884   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10885         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10886                      (match_operand:SI 2 "const_int_operand" "i,i")))
10887    (clobber (reg:CC FLAGS_REG))]
10888   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10889    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10890   "@
10891    {cltd|cdq}
10892    sar{l}\t{%2, %0|%0, %2}"
10893   [(set_attr "type" "imovx,ishift")
10894    (set_attr "prefix_0f" "0,*")
10895    (set_attr "length_immediate" "0,*")
10896    (set_attr "modrm" "0,1")
10897    (set_attr "mode" "SI")])
10899 (define_insn "*ashrsi3_31_zext"
10900   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10901         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10902                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10903    (clobber (reg:CC FLAGS_REG))]
10904   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10905    && INTVAL (operands[2]) == 31
10906    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10907   "@
10908    {cltd|cdq}
10909    sar{l}\t{%2, %k0|%k0, %2}"
10910   [(set_attr "type" "imovx,ishift")
10911    (set_attr "prefix_0f" "0,*")
10912    (set_attr "length_immediate" "0,*")
10913    (set_attr "modrm" "0,1")
10914    (set_attr "mode" "SI")])
10916 (define_expand "ashrsi3"
10917   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10918         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10919                      (match_operand:QI 2 "nonmemory_operand" "")))
10920    (clobber (reg:CC FLAGS_REG))]
10921   ""
10922   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10924 (define_insn "*ashrsi3_1_one_bit"
10925   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10926         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10927                      (match_operand:QI 2 "const1_operand" "")))
10928    (clobber (reg:CC FLAGS_REG))]
10929   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10930    && (TARGET_SHIFT1 || optimize_size)"
10931   "sar{l}\t%0"
10932   [(set_attr "type" "ishift")
10933    (set (attr "length") 
10934      (if_then_else (match_operand:SI 0 "register_operand" "") 
10935         (const_string "2")
10936         (const_string "*")))])
10938 (define_insn "*ashrsi3_1_one_bit_zext"
10939   [(set (match_operand:DI 0 "register_operand" "=r")
10940         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10941                                      (match_operand:QI 2 "const1_operand" ""))))
10942    (clobber (reg:CC FLAGS_REG))]
10943   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10944    && (TARGET_SHIFT1 || optimize_size)"
10945   "sar{l}\t%k0"
10946   [(set_attr "type" "ishift")
10947    (set_attr "length" "2")])
10949 (define_insn "*ashrsi3_1"
10950   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
10951         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
10952                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
10953    (clobber (reg:CC FLAGS_REG))]
10954   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10955   "@
10956    sar{l}\t{%2, %0|%0, %2}
10957    sar{l}\t{%b2, %0|%0, %b2}"
10958   [(set_attr "type" "ishift")
10959    (set_attr "mode" "SI")])
10961 (define_insn "*ashrsi3_1_zext"
10962   [(set (match_operand:DI 0 "register_operand" "=r,r")
10963         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
10964                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
10965    (clobber (reg:CC FLAGS_REG))]
10966   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10967   "@
10968    sar{l}\t{%2, %k0|%k0, %2}
10969    sar{l}\t{%b2, %k0|%k0, %b2}"
10970   [(set_attr "type" "ishift")
10971    (set_attr "mode" "SI")])
10973 ;; This pattern can't accept a variable shift count, since shifts by
10974 ;; zero don't affect the flags.  We assume that shifts by constant
10975 ;; zero are optimized away.
10976 (define_insn "*ashrsi3_one_bit_cmp"
10977   [(set (reg FLAGS_REG)
10978         (compare
10979           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10980                        (match_operand:QI 2 "const1_operand" ""))
10981           (const_int 0)))
10982    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10983         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
10984   "ix86_match_ccmode (insn, CCGOCmode)
10985    && (TARGET_SHIFT1 || optimize_size)
10986    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10987   "sar{l}\t%0"
10988   [(set_attr "type" "ishift")
10989    (set (attr "length") 
10990      (if_then_else (match_operand:SI 0 "register_operand" "") 
10991         (const_string "2")
10992         (const_string "*")))])
10994 (define_insn "*ashrsi3_one_bit_cmp_zext"
10995   [(set (reg FLAGS_REG)
10996         (compare
10997           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10998                        (match_operand:QI 2 "const1_operand" ""))
10999           (const_int 0)))
11000    (set (match_operand:DI 0 "register_operand" "=r")
11001         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11002   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11003    && (TARGET_SHIFT1 || optimize_size)
11004    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11005   "sar{l}\t%k0"
11006   [(set_attr "type" "ishift")
11007    (set_attr "length" "2")])
11009 ;; This pattern can't accept a variable shift count, since shifts by
11010 ;; zero don't affect the flags.  We assume that shifts by constant
11011 ;; zero are optimized away.
11012 (define_insn "*ashrsi3_cmp"
11013   [(set (reg FLAGS_REG)
11014         (compare
11015           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11016                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11017           (const_int 0)))
11018    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11019         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11020   "ix86_match_ccmode (insn, CCGOCmode)
11021    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11022   "sar{l}\t{%2, %0|%0, %2}"
11023   [(set_attr "type" "ishift")
11024    (set_attr "mode" "SI")])
11026 (define_insn "*ashrsi3_cmp_zext"
11027   [(set (reg FLAGS_REG)
11028         (compare
11029           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11030                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11031           (const_int 0)))
11032    (set (match_operand:DI 0 "register_operand" "=r")
11033         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11034   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11035    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11036   "sar{l}\t{%2, %k0|%k0, %2}"
11037   [(set_attr "type" "ishift")
11038    (set_attr "mode" "SI")])
11040 (define_expand "ashrhi3"
11041   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11042         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11043                      (match_operand:QI 2 "nonmemory_operand" "")))
11044    (clobber (reg:CC FLAGS_REG))]
11045   "TARGET_HIMODE_MATH"
11046   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11048 (define_insn "*ashrhi3_1_one_bit"
11049   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11050         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11051                      (match_operand:QI 2 "const1_operand" "")))
11052    (clobber (reg:CC FLAGS_REG))]
11053   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11054    && (TARGET_SHIFT1 || optimize_size)"
11055   "sar{w}\t%0"
11056   [(set_attr "type" "ishift")
11057    (set (attr "length") 
11058      (if_then_else (match_operand 0 "register_operand" "") 
11059         (const_string "2")
11060         (const_string "*")))])
11062 (define_insn "*ashrhi3_1"
11063   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11064         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11065                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11066    (clobber (reg:CC FLAGS_REG))]
11067   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11068   "@
11069    sar{w}\t{%2, %0|%0, %2}
11070    sar{w}\t{%b2, %0|%0, %b2}"
11071   [(set_attr "type" "ishift")
11072    (set_attr "mode" "HI")])
11074 ;; This pattern can't accept a variable shift count, since shifts by
11075 ;; zero don't affect the flags.  We assume that shifts by constant
11076 ;; zero are optimized away.
11077 (define_insn "*ashrhi3_one_bit_cmp"
11078   [(set (reg FLAGS_REG)
11079         (compare
11080           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11081                        (match_operand:QI 2 "const1_operand" ""))
11082           (const_int 0)))
11083    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11084         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11085   "ix86_match_ccmode (insn, CCGOCmode)
11086    && (TARGET_SHIFT1 || optimize_size)
11087    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11088   "sar{w}\t%0"
11089   [(set_attr "type" "ishift")
11090    (set (attr "length") 
11091      (if_then_else (match_operand 0 "register_operand" "") 
11092         (const_string "2")
11093         (const_string "*")))])
11095 ;; This pattern can't accept a variable shift count, since shifts by
11096 ;; zero don't affect the flags.  We assume that shifts by constant
11097 ;; zero are optimized away.
11098 (define_insn "*ashrhi3_cmp"
11099   [(set (reg FLAGS_REG)
11100         (compare
11101           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11102                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11103           (const_int 0)))
11104    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11105         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11106   "ix86_match_ccmode (insn, CCGOCmode)
11107    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11108   "sar{w}\t{%2, %0|%0, %2}"
11109   [(set_attr "type" "ishift")
11110    (set_attr "mode" "HI")])
11112 (define_expand "ashrqi3"
11113   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11114         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11115                      (match_operand:QI 2 "nonmemory_operand" "")))
11116    (clobber (reg:CC FLAGS_REG))]
11117   "TARGET_QIMODE_MATH"
11118   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11120 (define_insn "*ashrqi3_1_one_bit"
11121   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11122         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11123                      (match_operand:QI 2 "const1_operand" "")))
11124    (clobber (reg:CC FLAGS_REG))]
11125   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11126    && (TARGET_SHIFT1 || optimize_size)"
11127   "sar{b}\t%0"
11128   [(set_attr "type" "ishift")
11129    (set (attr "length") 
11130      (if_then_else (match_operand 0 "register_operand" "") 
11131         (const_string "2")
11132         (const_string "*")))])
11134 (define_insn "*ashrqi3_1_one_bit_slp"
11135   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11136         (ashiftrt:QI (match_dup 0)
11137                      (match_operand:QI 1 "const1_operand" "")))
11138    (clobber (reg:CC FLAGS_REG))]
11139   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11140    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11141    && (TARGET_SHIFT1 || optimize_size)"
11142   "sar{b}\t%0"
11143   [(set_attr "type" "ishift1")
11144    (set (attr "length") 
11145      (if_then_else (match_operand 0 "register_operand" "") 
11146         (const_string "2")
11147         (const_string "*")))])
11149 (define_insn "*ashrqi3_1"
11150   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11151         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11152                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11153    (clobber (reg:CC FLAGS_REG))]
11154   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11155   "@
11156    sar{b}\t{%2, %0|%0, %2}
11157    sar{b}\t{%b2, %0|%0, %b2}"
11158   [(set_attr "type" "ishift")
11159    (set_attr "mode" "QI")])
11161 (define_insn "*ashrqi3_1_slp"
11162   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11163         (ashiftrt:QI (match_dup 0)
11164                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11165    (clobber (reg:CC FLAGS_REG))]
11166   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11168   "@
11169    sar{b}\t{%1, %0|%0, %1}
11170    sar{b}\t{%b1, %0|%0, %b1}"
11171   [(set_attr "type" "ishift1")
11172    (set_attr "mode" "QI")])
11174 ;; This pattern can't accept a variable shift count, since shifts by
11175 ;; zero don't affect the flags.  We assume that shifts by constant
11176 ;; zero are optimized away.
11177 (define_insn "*ashrqi3_one_bit_cmp"
11178   [(set (reg FLAGS_REG)
11179         (compare
11180           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11181                        (match_operand:QI 2 "const1_operand" "I"))
11182           (const_int 0)))
11183    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11184         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11185   "ix86_match_ccmode (insn, CCGOCmode)
11186    && (TARGET_SHIFT1 || optimize_size)
11187    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11188   "sar{b}\t%0"
11189   [(set_attr "type" "ishift")
11190    (set (attr "length") 
11191      (if_then_else (match_operand 0 "register_operand" "") 
11192         (const_string "2")
11193         (const_string "*")))])
11195 ;; This pattern can't accept a variable shift count, since shifts by
11196 ;; zero don't affect the flags.  We assume that shifts by constant
11197 ;; zero are optimized away.
11198 (define_insn "*ashrqi3_cmp"
11199   [(set (reg FLAGS_REG)
11200         (compare
11201           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11202                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11203           (const_int 0)))
11204    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11205         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11206   "ix86_match_ccmode (insn, CCGOCmode)
11207    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11208   "sar{b}\t{%2, %0|%0, %2}"
11209   [(set_attr "type" "ishift")
11210    (set_attr "mode" "QI")])
11212 ;; Logical shift instructions
11214 ;; See comment above `ashldi3' about how this works.
11216 (define_expand "lshrdi3"
11217   [(set (match_operand:DI 0 "shiftdi_operand" "")
11218         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11219                      (match_operand:QI 2 "nonmemory_operand" "")))]
11220   ""
11221   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11223 (define_insn "*lshrdi3_1_one_bit_rex64"
11224   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11225         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11226                      (match_operand:QI 2 "const1_operand" "")))
11227    (clobber (reg:CC FLAGS_REG))]
11228   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11229    && (TARGET_SHIFT1 || optimize_size)"
11230   "shr{q}\t%0"
11231   [(set_attr "type" "ishift")
11232    (set (attr "length") 
11233      (if_then_else (match_operand:DI 0 "register_operand" "") 
11234         (const_string "2")
11235         (const_string "*")))])
11237 (define_insn "*lshrdi3_1_rex64"
11238   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11239         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11240                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11241    (clobber (reg:CC FLAGS_REG))]
11242   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11243   "@
11244    shr{q}\t{%2, %0|%0, %2}
11245    shr{q}\t{%b2, %0|%0, %b2}"
11246   [(set_attr "type" "ishift")
11247    (set_attr "mode" "DI")])
11249 ;; This pattern can't accept a variable shift count, since shifts by
11250 ;; zero don't affect the flags.  We assume that shifts by constant
11251 ;; zero are optimized away.
11252 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11253   [(set (reg FLAGS_REG)
11254         (compare
11255           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11256                        (match_operand:QI 2 "const1_operand" ""))
11257           (const_int 0)))
11258    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11259         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11260   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11261    && (TARGET_SHIFT1 || optimize_size)
11262    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11263   "shr{q}\t%0"
11264   [(set_attr "type" "ishift")
11265    (set (attr "length") 
11266      (if_then_else (match_operand:DI 0 "register_operand" "") 
11267         (const_string "2")
11268         (const_string "*")))])
11270 ;; This pattern can't accept a variable shift count, since shifts by
11271 ;; zero don't affect the flags.  We assume that shifts by constant
11272 ;; zero are optimized away.
11273 (define_insn "*lshrdi3_cmp_rex64"
11274   [(set (reg FLAGS_REG)
11275         (compare
11276           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11277                        (match_operand:QI 2 "const_int_operand" "e"))
11278           (const_int 0)))
11279    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11280         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11281   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11282    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11283   "shr{q}\t{%2, %0|%0, %2}"
11284   [(set_attr "type" "ishift")
11285    (set_attr "mode" "DI")])
11287 (define_insn "*lshrdi3_1"
11288   [(set (match_operand:DI 0 "register_operand" "=r")
11289         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11290                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11291    (clobber (reg:CC FLAGS_REG))]
11292   "!TARGET_64BIT"
11293   "#"
11294   [(set_attr "type" "multi")])
11296 ;; By default we don't ask for a scratch register, because when DImode
11297 ;; values are manipulated, registers are already at a premium.  But if
11298 ;; we have one handy, we won't turn it away.
11299 (define_peephole2
11300   [(match_scratch:SI 3 "r")
11301    (parallel [(set (match_operand:DI 0 "register_operand" "")
11302                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11303                                 (match_operand:QI 2 "nonmemory_operand" "")))
11304               (clobber (reg:CC FLAGS_REG))])
11305    (match_dup 3)]
11306   "!TARGET_64BIT && TARGET_CMOVE"
11307   [(const_int 0)]
11308   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11310 (define_split 
11311   [(set (match_operand:DI 0 "register_operand" "")
11312         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11313                      (match_operand:QI 2 "nonmemory_operand" "")))
11314    (clobber (reg:CC FLAGS_REG))]
11315   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11316   [(const_int 0)]
11317   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11319 (define_expand "lshrsi3"
11320   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11321         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11322                      (match_operand:QI 2 "nonmemory_operand" "")))
11323    (clobber (reg:CC FLAGS_REG))]
11324   ""
11325   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11327 (define_insn "*lshrsi3_1_one_bit"
11328   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11329         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11330                      (match_operand:QI 2 "const1_operand" "")))
11331    (clobber (reg:CC FLAGS_REG))]
11332   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11333    && (TARGET_SHIFT1 || optimize_size)"
11334   "shr{l}\t%0"
11335   [(set_attr "type" "ishift")
11336    (set (attr "length") 
11337      (if_then_else (match_operand:SI 0 "register_operand" "") 
11338         (const_string "2")
11339         (const_string "*")))])
11341 (define_insn "*lshrsi3_1_one_bit_zext"
11342   [(set (match_operand:DI 0 "register_operand" "=r")
11343         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11344                      (match_operand:QI 2 "const1_operand" "")))
11345    (clobber (reg:CC FLAGS_REG))]
11346   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11347    && (TARGET_SHIFT1 || optimize_size)"
11348   "shr{l}\t%k0"
11349   [(set_attr "type" "ishift")
11350    (set_attr "length" "2")])
11352 (define_insn "*lshrsi3_1"
11353   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11354         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11355                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11356    (clobber (reg:CC FLAGS_REG))]
11357   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11358   "@
11359    shr{l}\t{%2, %0|%0, %2}
11360    shr{l}\t{%b2, %0|%0, %b2}"
11361   [(set_attr "type" "ishift")
11362    (set_attr "mode" "SI")])
11364 (define_insn "*lshrsi3_1_zext"
11365   [(set (match_operand:DI 0 "register_operand" "=r,r")
11366         (zero_extend:DI
11367           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11368                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11369    (clobber (reg:CC FLAGS_REG))]
11370   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11371   "@
11372    shr{l}\t{%2, %k0|%k0, %2}
11373    shr{l}\t{%b2, %k0|%k0, %b2}"
11374   [(set_attr "type" "ishift")
11375    (set_attr "mode" "SI")])
11377 ;; This pattern can't accept a variable shift count, since shifts by
11378 ;; zero don't affect the flags.  We assume that shifts by constant
11379 ;; zero are optimized away.
11380 (define_insn "*lshrsi3_one_bit_cmp"
11381   [(set (reg FLAGS_REG)
11382         (compare
11383           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11384                        (match_operand:QI 2 "const1_operand" ""))
11385           (const_int 0)))
11386    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11387         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11388   "ix86_match_ccmode (insn, CCGOCmode)
11389    && (TARGET_SHIFT1 || optimize_size)
11390    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11391   "shr{l}\t%0"
11392   [(set_attr "type" "ishift")
11393    (set (attr "length") 
11394      (if_then_else (match_operand:SI 0 "register_operand" "") 
11395         (const_string "2")
11396         (const_string "*")))])
11398 (define_insn "*lshrsi3_cmp_one_bit_zext"
11399   [(set (reg FLAGS_REG)
11400         (compare
11401           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11402                        (match_operand:QI 2 "const1_operand" ""))
11403           (const_int 0)))
11404    (set (match_operand:DI 0 "register_operand" "=r")
11405         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11406   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11407    && (TARGET_SHIFT1 || optimize_size)
11408    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11409   "shr{l}\t%k0"
11410   [(set_attr "type" "ishift")
11411    (set_attr "length" "2")])
11413 ;; This pattern can't accept a variable shift count, since shifts by
11414 ;; zero don't affect the flags.  We assume that shifts by constant
11415 ;; zero are optimized away.
11416 (define_insn "*lshrsi3_cmp"
11417   [(set (reg FLAGS_REG)
11418         (compare
11419           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11420                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11421           (const_int 0)))
11422    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11423         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11424   "ix86_match_ccmode (insn, CCGOCmode)
11425    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11426   "shr{l}\t{%2, %0|%0, %2}"
11427   [(set_attr "type" "ishift")
11428    (set_attr "mode" "SI")])
11430 (define_insn "*lshrsi3_cmp_zext"
11431   [(set (reg FLAGS_REG)
11432         (compare
11433           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11434                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11435           (const_int 0)))
11436    (set (match_operand:DI 0 "register_operand" "=r")
11437         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11438   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11440   "shr{l}\t{%2, %k0|%k0, %2}"
11441   [(set_attr "type" "ishift")
11442    (set_attr "mode" "SI")])
11444 (define_expand "lshrhi3"
11445   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11446         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11447                      (match_operand:QI 2 "nonmemory_operand" "")))
11448    (clobber (reg:CC FLAGS_REG))]
11449   "TARGET_HIMODE_MATH"
11450   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11452 (define_insn "*lshrhi3_1_one_bit"
11453   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11454         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11455                      (match_operand:QI 2 "const1_operand" "")))
11456    (clobber (reg:CC FLAGS_REG))]
11457   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11458    && (TARGET_SHIFT1 || optimize_size)"
11459   "shr{w}\t%0"
11460   [(set_attr "type" "ishift")
11461    (set (attr "length") 
11462      (if_then_else (match_operand 0 "register_operand" "") 
11463         (const_string "2")
11464         (const_string "*")))])
11466 (define_insn "*lshrhi3_1"
11467   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11468         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11469                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11470    (clobber (reg:CC FLAGS_REG))]
11471   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11472   "@
11473    shr{w}\t{%2, %0|%0, %2}
11474    shr{w}\t{%b2, %0|%0, %b2}"
11475   [(set_attr "type" "ishift")
11476    (set_attr "mode" "HI")])
11478 ;; This pattern can't accept a variable shift count, since shifts by
11479 ;; zero don't affect the flags.  We assume that shifts by constant
11480 ;; zero are optimized away.
11481 (define_insn "*lshrhi3_one_bit_cmp"
11482   [(set (reg FLAGS_REG)
11483         (compare
11484           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11485                        (match_operand:QI 2 "const1_operand" ""))
11486           (const_int 0)))
11487    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11488         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11489   "ix86_match_ccmode (insn, CCGOCmode)
11490    && (TARGET_SHIFT1 || optimize_size)
11491    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11492   "shr{w}\t%0"
11493   [(set_attr "type" "ishift")
11494    (set (attr "length") 
11495      (if_then_else (match_operand:SI 0 "register_operand" "") 
11496         (const_string "2")
11497         (const_string "*")))])
11499 ;; This pattern can't accept a variable shift count, since shifts by
11500 ;; zero don't affect the flags.  We assume that shifts by constant
11501 ;; zero are optimized away.
11502 (define_insn "*lshrhi3_cmp"
11503   [(set (reg FLAGS_REG)
11504         (compare
11505           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11506                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11507           (const_int 0)))
11508    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11509         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11510   "ix86_match_ccmode (insn, CCGOCmode)
11511    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11512   "shr{w}\t{%2, %0|%0, %2}"
11513   [(set_attr "type" "ishift")
11514    (set_attr "mode" "HI")])
11516 (define_expand "lshrqi3"
11517   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11518         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11519                      (match_operand:QI 2 "nonmemory_operand" "")))
11520    (clobber (reg:CC FLAGS_REG))]
11521   "TARGET_QIMODE_MATH"
11522   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11524 (define_insn "*lshrqi3_1_one_bit"
11525   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11526         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11527                      (match_operand:QI 2 "const1_operand" "")))
11528    (clobber (reg:CC FLAGS_REG))]
11529   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11530    && (TARGET_SHIFT1 || optimize_size)"
11531   "shr{b}\t%0"
11532   [(set_attr "type" "ishift")
11533    (set (attr "length") 
11534      (if_then_else (match_operand 0 "register_operand" "") 
11535         (const_string "2")
11536         (const_string "*")))])
11538 (define_insn "*lshrqi3_1_one_bit_slp"
11539   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11540         (lshiftrt:QI (match_dup 0)
11541                      (match_operand:QI 1 "const1_operand" "")))
11542    (clobber (reg:CC FLAGS_REG))]
11543   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11544    && (TARGET_SHIFT1 || optimize_size)"
11545   "shr{b}\t%0"
11546   [(set_attr "type" "ishift1")
11547    (set (attr "length") 
11548      (if_then_else (match_operand 0 "register_operand" "") 
11549         (const_string "2")
11550         (const_string "*")))])
11552 (define_insn "*lshrqi3_1"
11553   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11554         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11555                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11556    (clobber (reg:CC FLAGS_REG))]
11557   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11558   "@
11559    shr{b}\t{%2, %0|%0, %2}
11560    shr{b}\t{%b2, %0|%0, %b2}"
11561   [(set_attr "type" "ishift")
11562    (set_attr "mode" "QI")])
11564 (define_insn "*lshrqi3_1_slp"
11565   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11566         (lshiftrt:QI (match_dup 0)
11567                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11568    (clobber (reg:CC FLAGS_REG))]
11569   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11570    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11571   "@
11572    shr{b}\t{%1, %0|%0, %1}
11573    shr{b}\t{%b1, %0|%0, %b1}"
11574   [(set_attr "type" "ishift1")
11575    (set_attr "mode" "QI")])
11577 ;; This pattern can't accept a variable shift count, since shifts by
11578 ;; zero don't affect the flags.  We assume that shifts by constant
11579 ;; zero are optimized away.
11580 (define_insn "*lshrqi2_one_bit_cmp"
11581   [(set (reg FLAGS_REG)
11582         (compare
11583           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11584                        (match_operand:QI 2 "const1_operand" ""))
11585           (const_int 0)))
11586    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11587         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11588   "ix86_match_ccmode (insn, CCGOCmode)
11589    && (TARGET_SHIFT1 || optimize_size)
11590    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11591   "shr{b}\t%0"
11592   [(set_attr "type" "ishift")
11593    (set (attr "length") 
11594      (if_then_else (match_operand:SI 0 "register_operand" "") 
11595         (const_string "2")
11596         (const_string "*")))])
11598 ;; This pattern can't accept a variable shift count, since shifts by
11599 ;; zero don't affect the flags.  We assume that shifts by constant
11600 ;; zero are optimized away.
11601 (define_insn "*lshrqi2_cmp"
11602   [(set (reg FLAGS_REG)
11603         (compare
11604           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11605                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11606           (const_int 0)))
11607    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11608         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11609   "ix86_match_ccmode (insn, CCGOCmode)
11610    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11611   "shr{b}\t{%2, %0|%0, %2}"
11612   [(set_attr "type" "ishift")
11613    (set_attr "mode" "QI")])
11615 ;; Rotate instructions
11617 (define_expand "rotldi3"
11618   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11619         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11620                    (match_operand:QI 2 "nonmemory_operand" "")))
11621    (clobber (reg:CC FLAGS_REG))]
11622   "TARGET_64BIT"
11623   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11625 (define_insn "*rotlsi3_1_one_bit_rex64"
11626   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11627         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11628                    (match_operand:QI 2 "const1_operand" "")))
11629    (clobber (reg:CC FLAGS_REG))]
11630   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11631    && (TARGET_SHIFT1 || optimize_size)"
11632   "rol{q}\t%0"
11633   [(set_attr "type" "rotate")
11634    (set (attr "length") 
11635      (if_then_else (match_operand:DI 0 "register_operand" "") 
11636         (const_string "2")
11637         (const_string "*")))])
11639 (define_insn "*rotldi3_1_rex64"
11640   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11641         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11642                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11643    (clobber (reg:CC FLAGS_REG))]
11644   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11645   "@
11646    rol{q}\t{%2, %0|%0, %2}
11647    rol{q}\t{%b2, %0|%0, %b2}"
11648   [(set_attr "type" "rotate")
11649    (set_attr "mode" "DI")])
11651 (define_expand "rotlsi3"
11652   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11653         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11654                    (match_operand:QI 2 "nonmemory_operand" "")))
11655    (clobber (reg:CC FLAGS_REG))]
11656   ""
11657   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11659 (define_insn "*rotlsi3_1_one_bit"
11660   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11661         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11662                    (match_operand:QI 2 "const1_operand" "")))
11663    (clobber (reg:CC FLAGS_REG))]
11664   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11665    && (TARGET_SHIFT1 || optimize_size)"
11666   "rol{l}\t%0"
11667   [(set_attr "type" "rotate")
11668    (set (attr "length") 
11669      (if_then_else (match_operand:SI 0 "register_operand" "") 
11670         (const_string "2")
11671         (const_string "*")))])
11673 (define_insn "*rotlsi3_1_one_bit_zext"
11674   [(set (match_operand:DI 0 "register_operand" "=r")
11675         (zero_extend:DI
11676           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11677                      (match_operand:QI 2 "const1_operand" ""))))
11678    (clobber (reg:CC FLAGS_REG))]
11679   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11680    && (TARGET_SHIFT1 || optimize_size)"
11681   "rol{l}\t%k0"
11682   [(set_attr "type" "rotate")
11683    (set_attr "length" "2")])
11685 (define_insn "*rotlsi3_1"
11686   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11687         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11688                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11689    (clobber (reg:CC FLAGS_REG))]
11690   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11691   "@
11692    rol{l}\t{%2, %0|%0, %2}
11693    rol{l}\t{%b2, %0|%0, %b2}"
11694   [(set_attr "type" "rotate")
11695    (set_attr "mode" "SI")])
11697 (define_insn "*rotlsi3_1_zext"
11698   [(set (match_operand:DI 0 "register_operand" "=r,r")
11699         (zero_extend:DI
11700           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11701                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11702    (clobber (reg:CC FLAGS_REG))]
11703   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11704   "@
11705    rol{l}\t{%2, %k0|%k0, %2}
11706    rol{l}\t{%b2, %k0|%k0, %b2}"
11707   [(set_attr "type" "rotate")
11708    (set_attr "mode" "SI")])
11710 (define_expand "rotlhi3"
11711   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11712         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11713                    (match_operand:QI 2 "nonmemory_operand" "")))
11714    (clobber (reg:CC FLAGS_REG))]
11715   "TARGET_HIMODE_MATH"
11716   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11718 (define_insn "*rotlhi3_1_one_bit"
11719   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11720         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11721                    (match_operand:QI 2 "const1_operand" "")))
11722    (clobber (reg:CC FLAGS_REG))]
11723   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11724    && (TARGET_SHIFT1 || optimize_size)"
11725   "rol{w}\t%0"
11726   [(set_attr "type" "rotate")
11727    (set (attr "length") 
11728      (if_then_else (match_operand 0 "register_operand" "") 
11729         (const_string "2")
11730         (const_string "*")))])
11732 (define_insn "*rotlhi3_1"
11733   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11734         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11735                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11736    (clobber (reg:CC FLAGS_REG))]
11737   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11738   "@
11739    rol{w}\t{%2, %0|%0, %2}
11740    rol{w}\t{%b2, %0|%0, %b2}"
11741   [(set_attr "type" "rotate")
11742    (set_attr "mode" "HI")])
11744 (define_expand "rotlqi3"
11745   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11746         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11747                    (match_operand:QI 2 "nonmemory_operand" "")))
11748    (clobber (reg:CC FLAGS_REG))]
11749   "TARGET_QIMODE_MATH"
11750   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11752 (define_insn "*rotlqi3_1_one_bit_slp"
11753   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11754         (rotate:QI (match_dup 0)
11755                    (match_operand:QI 1 "const1_operand" "")))
11756    (clobber (reg:CC FLAGS_REG))]
11757   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11758    && (TARGET_SHIFT1 || optimize_size)"
11759   "rol{b}\t%0"
11760   [(set_attr "type" "rotate1")
11761    (set (attr "length") 
11762      (if_then_else (match_operand 0 "register_operand" "") 
11763         (const_string "2")
11764         (const_string "*")))])
11766 (define_insn "*rotlqi3_1_one_bit"
11767   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11768         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11769                    (match_operand:QI 2 "const1_operand" "")))
11770    (clobber (reg:CC FLAGS_REG))]
11771   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11772    && (TARGET_SHIFT1 || optimize_size)"
11773   "rol{b}\t%0"
11774   [(set_attr "type" "rotate")
11775    (set (attr "length") 
11776      (if_then_else (match_operand 0 "register_operand" "") 
11777         (const_string "2")
11778         (const_string "*")))])
11780 (define_insn "*rotlqi3_1_slp"
11781   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11782         (rotate:QI (match_dup 0)
11783                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11784    (clobber (reg:CC FLAGS_REG))]
11785   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11786    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11787   "@
11788    rol{b}\t{%1, %0|%0, %1}
11789    rol{b}\t{%b1, %0|%0, %b1}"
11790   [(set_attr "type" "rotate1")
11791    (set_attr "mode" "QI")])
11793 (define_insn "*rotlqi3_1"
11794   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11795         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11796                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11797    (clobber (reg:CC FLAGS_REG))]
11798   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11799   "@
11800    rol{b}\t{%2, %0|%0, %2}
11801    rol{b}\t{%b2, %0|%0, %b2}"
11802   [(set_attr "type" "rotate")
11803    (set_attr "mode" "QI")])
11805 (define_expand "rotrdi3"
11806   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11807         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11808                      (match_operand:QI 2 "nonmemory_operand" "")))
11809    (clobber (reg:CC FLAGS_REG))]
11810   "TARGET_64BIT"
11811   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11813 (define_insn "*rotrdi3_1_one_bit_rex64"
11814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11815         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11816                      (match_operand:QI 2 "const1_operand" "")))
11817    (clobber (reg:CC FLAGS_REG))]
11818   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11819    && (TARGET_SHIFT1 || optimize_size)"
11820   "ror{q}\t%0"
11821   [(set_attr "type" "rotate")
11822    (set (attr "length") 
11823      (if_then_else (match_operand:DI 0 "register_operand" "") 
11824         (const_string "2")
11825         (const_string "*")))])
11827 (define_insn "*rotrdi3_1_rex64"
11828   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11829         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11830                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11833   "@
11834    ror{q}\t{%2, %0|%0, %2}
11835    ror{q}\t{%b2, %0|%0, %b2}"
11836   [(set_attr "type" "rotate")
11837    (set_attr "mode" "DI")])
11839 (define_expand "rotrsi3"
11840   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11841         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11842                      (match_operand:QI 2 "nonmemory_operand" "")))
11843    (clobber (reg:CC FLAGS_REG))]
11844   ""
11845   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11847 (define_insn "*rotrsi3_1_one_bit"
11848   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11849         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11850                      (match_operand:QI 2 "const1_operand" "")))
11851    (clobber (reg:CC FLAGS_REG))]
11852   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11853    && (TARGET_SHIFT1 || optimize_size)"
11854   "ror{l}\t%0"
11855   [(set_attr "type" "rotate")
11856    (set (attr "length") 
11857      (if_then_else (match_operand:SI 0 "register_operand" "") 
11858         (const_string "2")
11859         (const_string "*")))])
11861 (define_insn "*rotrsi3_1_one_bit_zext"
11862   [(set (match_operand:DI 0 "register_operand" "=r")
11863         (zero_extend:DI
11864           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11865                        (match_operand:QI 2 "const1_operand" ""))))
11866    (clobber (reg:CC FLAGS_REG))]
11867   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11868    && (TARGET_SHIFT1 || optimize_size)"
11869   "ror{l}\t%k0"
11870   [(set_attr "type" "rotate")
11871    (set (attr "length") 
11872      (if_then_else (match_operand:SI 0 "register_operand" "") 
11873         (const_string "2")
11874         (const_string "*")))])
11876 (define_insn "*rotrsi3_1"
11877   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11878         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11879                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11882   "@
11883    ror{l}\t{%2, %0|%0, %2}
11884    ror{l}\t{%b2, %0|%0, %b2}"
11885   [(set_attr "type" "rotate")
11886    (set_attr "mode" "SI")])
11888 (define_insn "*rotrsi3_1_zext"
11889   [(set (match_operand:DI 0 "register_operand" "=r,r")
11890         (zero_extend:DI
11891           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11892                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11893    (clobber (reg:CC FLAGS_REG))]
11894   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11895   "@
11896    ror{l}\t{%2, %k0|%k0, %2}
11897    ror{l}\t{%b2, %k0|%k0, %b2}"
11898   [(set_attr "type" "rotate")
11899    (set_attr "mode" "SI")])
11901 (define_expand "rotrhi3"
11902   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11903         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11904                      (match_operand:QI 2 "nonmemory_operand" "")))
11905    (clobber (reg:CC FLAGS_REG))]
11906   "TARGET_HIMODE_MATH"
11907   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11909 (define_insn "*rotrhi3_one_bit"
11910   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11911         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11912                      (match_operand:QI 2 "const1_operand" "")))
11913    (clobber (reg:CC FLAGS_REG))]
11914   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11915    && (TARGET_SHIFT1 || optimize_size)"
11916   "ror{w}\t%0"
11917   [(set_attr "type" "rotate")
11918    (set (attr "length") 
11919      (if_then_else (match_operand 0 "register_operand" "") 
11920         (const_string "2")
11921         (const_string "*")))])
11923 (define_insn "*rotrhi3"
11924   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11925         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11926                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11929   "@
11930    ror{w}\t{%2, %0|%0, %2}
11931    ror{w}\t{%b2, %0|%0, %b2}"
11932   [(set_attr "type" "rotate")
11933    (set_attr "mode" "HI")])
11935 (define_expand "rotrqi3"
11936   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11937         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11938                      (match_operand:QI 2 "nonmemory_operand" "")))
11939    (clobber (reg:CC FLAGS_REG))]
11940   "TARGET_QIMODE_MATH"
11941   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
11943 (define_insn "*rotrqi3_1_one_bit"
11944   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11945         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11946                      (match_operand:QI 2 "const1_operand" "")))
11947    (clobber (reg:CC FLAGS_REG))]
11948   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
11949    && (TARGET_SHIFT1 || optimize_size)"
11950   "ror{b}\t%0"
11951   [(set_attr "type" "rotate")
11952    (set (attr "length") 
11953      (if_then_else (match_operand 0 "register_operand" "") 
11954         (const_string "2")
11955         (const_string "*")))])
11957 (define_insn "*rotrqi3_1_one_bit_slp"
11958   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11959         (rotatert:QI (match_dup 0)
11960                      (match_operand:QI 1 "const1_operand" "")))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11963    && (TARGET_SHIFT1 || optimize_size)"
11964   "ror{b}\t%0"
11965   [(set_attr "type" "rotate1")
11966    (set (attr "length") 
11967      (if_then_else (match_operand 0 "register_operand" "") 
11968         (const_string "2")
11969         (const_string "*")))])
11971 (define_insn "*rotrqi3_1"
11972   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11973         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11974                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11975    (clobber (reg:CC FLAGS_REG))]
11976   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
11977   "@
11978    ror{b}\t{%2, %0|%0, %2}
11979    ror{b}\t{%b2, %0|%0, %b2}"
11980   [(set_attr "type" "rotate")
11981    (set_attr "mode" "QI")])
11983 (define_insn "*rotrqi3_1_slp"
11984   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11985         (rotatert:QI (match_dup 0)
11986                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11987    (clobber (reg:CC FLAGS_REG))]
11988   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11989    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11990   "@
11991    ror{b}\t{%1, %0|%0, %1}
11992    ror{b}\t{%b1, %0|%0, %b1}"
11993   [(set_attr "type" "rotate1")
11994    (set_attr "mode" "QI")])
11996 ;; Bit set / bit test instructions
11998 (define_expand "extv"
11999   [(set (match_operand:SI 0 "register_operand" "")
12000         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12001                          (match_operand:SI 2 "immediate_operand" "")
12002                          (match_operand:SI 3 "immediate_operand" "")))]
12003   ""
12005   /* Handle extractions from %ah et al.  */
12006   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12007     FAIL;
12009   /* From mips.md: extract_bit_field doesn't verify that our source
12010      matches the predicate, so check it again here.  */
12011   if (! ext_register_operand (operands[1], VOIDmode))
12012     FAIL;
12015 (define_expand "extzv"
12016   [(set (match_operand:SI 0 "register_operand" "")
12017         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12018                          (match_operand:SI 2 "immediate_operand" "")
12019                          (match_operand:SI 3 "immediate_operand" "")))]
12020   ""
12022   /* Handle extractions from %ah et al.  */
12023   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12024     FAIL;
12026   /* From mips.md: extract_bit_field doesn't verify that our source
12027      matches the predicate, so check it again here.  */
12028   if (! ext_register_operand (operands[1], VOIDmode))
12029     FAIL;
12032 (define_expand "insv"
12033   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12034                       (match_operand 1 "immediate_operand" "")
12035                       (match_operand 2 "immediate_operand" ""))
12036         (match_operand 3 "register_operand" ""))]
12037   ""
12039   /* Handle extractions from %ah et al.  */
12040   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12041     FAIL;
12043   /* From mips.md: insert_bit_field doesn't verify that our source
12044      matches the predicate, so check it again here.  */
12045   if (! ext_register_operand (operands[0], VOIDmode))
12046     FAIL;
12048   if (TARGET_64BIT)
12049     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12050   else
12051     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12053   DONE;
12056 ;; %%% bts, btr, btc, bt.
12057 ;; In general these instructions are *slow* when applied to memory,
12058 ;; since they enforce atomic operation.  When applied to registers,
12059 ;; it depends on the cpu implementation.  They're never faster than
12060 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12061 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12062 ;; within the instruction itself, so operating on bits in the high
12063 ;; 32-bits of a register becomes easier.
12065 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12066 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12067 ;; negdf respectively, so they can never be disabled entirely.
12069 (define_insn "*btsq"
12070   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12071                          (const_int 1)
12072                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12073         (const_int 1))
12074    (clobber (reg:CC FLAGS_REG))]
12075   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12076   "bts{q} %1,%0"
12077   [(set_attr "type" "alu1")])
12079 (define_insn "*btrq"
12080   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12081                          (const_int 1)
12082                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12083         (const_int 0))
12084    (clobber (reg:CC FLAGS_REG))]
12085   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12086   "btr{q} %1,%0"
12087   [(set_attr "type" "alu1")])
12089 (define_insn "*btcq"
12090   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12091                          (const_int 1)
12092                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12093         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12094    (clobber (reg:CC FLAGS_REG))]
12095   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12096   "btc{q} %1,%0"
12097   [(set_attr "type" "alu1")])
12099 ;; Allow Nocona to avoid these instructions if a register is available.
12101 (define_peephole2
12102   [(match_scratch:DI 2 "r")
12103    (parallel [(set (zero_extract:DI
12104                      (match_operand:DI 0 "register_operand" "")
12105                      (const_int 1)
12106                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12107                    (const_int 1))
12108               (clobber (reg:CC FLAGS_REG))])]
12109   "TARGET_64BIT && !TARGET_USE_BT"
12110   [(const_int 0)]
12112   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12113   rtx op1;
12115   if (HOST_BITS_PER_WIDE_INT >= 64)
12116     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12117   else if (i < HOST_BITS_PER_WIDE_INT)
12118     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12119   else
12120     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12122   op1 = immed_double_const (lo, hi, DImode);
12123   if (i >= 31)
12124     {
12125       emit_move_insn (operands[2], op1);
12126       op1 = operands[2];
12127     }
12129   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12130   DONE;
12133 (define_peephole2
12134   [(match_scratch:DI 2 "r")
12135    (parallel [(set (zero_extract:DI
12136                      (match_operand:DI 0 "register_operand" "")
12137                      (const_int 1)
12138                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12139                    (const_int 0))
12140               (clobber (reg:CC FLAGS_REG))])]
12141   "TARGET_64BIT && !TARGET_USE_BT"
12142   [(const_int 0)]
12144   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12145   rtx op1;
12147   if (HOST_BITS_PER_WIDE_INT >= 64)
12148     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12149   else if (i < HOST_BITS_PER_WIDE_INT)
12150     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12151   else
12152     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12154   op1 = immed_double_const (~lo, ~hi, DImode);
12155   if (i >= 32)
12156     {
12157       emit_move_insn (operands[2], op1);
12158       op1 = operands[2];
12159     }
12161   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12162   DONE;
12165 (define_peephole2
12166   [(match_scratch:DI 2 "r")
12167    (parallel [(set (zero_extract:DI
12168                      (match_operand:DI 0 "register_operand" "")
12169                      (const_int 1)
12170                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12171               (not:DI (zero_extract:DI
12172                         (match_dup 0) (const_int 1) (match_dup 1))))
12173               (clobber (reg:CC FLAGS_REG))])]
12174   "TARGET_64BIT && !TARGET_USE_BT"
12175   [(const_int 0)]
12177   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12178   rtx op1;
12180   if (HOST_BITS_PER_WIDE_INT >= 64)
12181     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12182   else if (i < HOST_BITS_PER_WIDE_INT)
12183     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12184   else
12185     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12187   op1 = immed_double_const (lo, hi, DImode);
12188   if (i >= 31)
12189     {
12190       emit_move_insn (operands[2], op1);
12191       op1 = operands[2];
12192     }
12194   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12195   DONE;
12198 ;; Store-flag instructions.
12200 ;; For all sCOND expanders, also expand the compare or test insn that
12201 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12203 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12204 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12205 ;; way, which can later delete the movzx if only QImode is needed.
12207 (define_expand "seq"
12208   [(set (match_operand:QI 0 "register_operand" "")
12209         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12210   ""
12211   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12213 (define_expand "sne"
12214   [(set (match_operand:QI 0 "register_operand" "")
12215         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12216   ""
12217   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12219 (define_expand "sgt"
12220   [(set (match_operand:QI 0 "register_operand" "")
12221         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12222   ""
12223   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12225 (define_expand "sgtu"
12226   [(set (match_operand:QI 0 "register_operand" "")
12227         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12228   ""
12229   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12231 (define_expand "slt"
12232   [(set (match_operand:QI 0 "register_operand" "")
12233         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12234   ""
12235   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12237 (define_expand "sltu"
12238   [(set (match_operand:QI 0 "register_operand" "")
12239         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12240   ""
12241   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12243 (define_expand "sge"
12244   [(set (match_operand:QI 0 "register_operand" "")
12245         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12246   ""
12247   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12249 (define_expand "sgeu"
12250   [(set (match_operand:QI 0 "register_operand" "")
12251         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12252   ""
12253   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12255 (define_expand "sle"
12256   [(set (match_operand:QI 0 "register_operand" "")
12257         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12258   ""
12259   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12261 (define_expand "sleu"
12262   [(set (match_operand:QI 0 "register_operand" "")
12263         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12264   ""
12265   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12267 (define_expand "sunordered"
12268   [(set (match_operand:QI 0 "register_operand" "")
12269         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12270   "TARGET_80387 || TARGET_SSE"
12271   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12273 (define_expand "sordered"
12274   [(set (match_operand:QI 0 "register_operand" "")
12275         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12276   "TARGET_80387"
12277   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12279 (define_expand "suneq"
12280   [(set (match_operand:QI 0 "register_operand" "")
12281         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12282   "TARGET_80387 || TARGET_SSE"
12283   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12285 (define_expand "sunge"
12286   [(set (match_operand:QI 0 "register_operand" "")
12287         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12288   "TARGET_80387 || TARGET_SSE"
12289   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12291 (define_expand "sungt"
12292   [(set (match_operand:QI 0 "register_operand" "")
12293         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12294   "TARGET_80387 || TARGET_SSE"
12295   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12297 (define_expand "sunle"
12298   [(set (match_operand:QI 0 "register_operand" "")
12299         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12300   "TARGET_80387 || TARGET_SSE"
12301   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12303 (define_expand "sunlt"
12304   [(set (match_operand:QI 0 "register_operand" "")
12305         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12306   "TARGET_80387 || TARGET_SSE"
12307   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12309 (define_expand "sltgt"
12310   [(set (match_operand:QI 0 "register_operand" "")
12311         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12312   "TARGET_80387 || TARGET_SSE"
12313   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12315 (define_insn "*setcc_1"
12316   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12317         (match_operator:QI 1 "ix86_comparison_operator"
12318           [(reg FLAGS_REG) (const_int 0)]))]
12319   ""
12320   "set%C1\t%0"
12321   [(set_attr "type" "setcc")
12322    (set_attr "mode" "QI")])
12324 (define_insn "*setcc_2"
12325   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12326         (match_operator:QI 1 "ix86_comparison_operator"
12327           [(reg FLAGS_REG) (const_int 0)]))]
12328   ""
12329   "set%C1\t%0"
12330   [(set_attr "type" "setcc")
12331    (set_attr "mode" "QI")])
12333 ;; In general it is not safe to assume too much about CCmode registers,
12334 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12335 ;; conditions this is safe on x86, so help combine not create
12337 ;;      seta    %al
12338 ;;      testb   %al, %al
12339 ;;      sete    %al
12341 (define_split 
12342   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12343         (ne:QI (match_operator 1 "ix86_comparison_operator"
12344                  [(reg FLAGS_REG) (const_int 0)])
12345             (const_int 0)))]
12346   ""
12347   [(set (match_dup 0) (match_dup 1))]
12349   PUT_MODE (operands[1], QImode);
12352 (define_split 
12353   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12354         (ne:QI (match_operator 1 "ix86_comparison_operator"
12355                  [(reg FLAGS_REG) (const_int 0)])
12356             (const_int 0)))]
12357   ""
12358   [(set (match_dup 0) (match_dup 1))]
12360   PUT_MODE (operands[1], QImode);
12363 (define_split 
12364   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12365         (eq:QI (match_operator 1 "ix86_comparison_operator"
12366                  [(reg FLAGS_REG) (const_int 0)])
12367             (const_int 0)))]
12368   ""
12369   [(set (match_dup 0) (match_dup 1))]
12371   rtx new_op1 = copy_rtx (operands[1]);
12372   operands[1] = new_op1;
12373   PUT_MODE (new_op1, QImode);
12374   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12375                                              GET_MODE (XEXP (new_op1, 0))));
12377   /* Make sure that (a) the CCmode we have for the flags is strong
12378      enough for the reversed compare or (b) we have a valid FP compare.  */
12379   if (! ix86_comparison_operator (new_op1, VOIDmode))
12380     FAIL;
12383 (define_split 
12384   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12385         (eq:QI (match_operator 1 "ix86_comparison_operator"
12386                  [(reg FLAGS_REG) (const_int 0)])
12387             (const_int 0)))]
12388   ""
12389   [(set (match_dup 0) (match_dup 1))]
12391   rtx new_op1 = copy_rtx (operands[1]);
12392   operands[1] = new_op1;
12393   PUT_MODE (new_op1, QImode);
12394   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12395                                              GET_MODE (XEXP (new_op1, 0))));
12397   /* Make sure that (a) the CCmode we have for the flags is strong
12398      enough for the reversed compare or (b) we have a valid FP compare.  */
12399   if (! ix86_comparison_operator (new_op1, VOIDmode))
12400     FAIL;
12403 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12404 ;; subsequent logical operations are used to imitate conditional moves.
12405 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12406 ;; it directly.  Further holding this value in pseudo register might bring
12407 ;; problem in implicit normalization in spill code.
12408 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12409 ;; instructions after reload by splitting the conditional move patterns.
12411 (define_insn "*sse_setccsf"
12412   [(set (match_operand:SF 0 "register_operand" "=x")
12413         (match_operator:SF 1 "sse_comparison_operator"
12414           [(match_operand:SF 2 "register_operand" "0")
12415            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12416   "TARGET_SSE && reload_completed"
12417   "cmp%D1ss\t{%3, %0|%0, %3}"
12418   [(set_attr "type" "ssecmp")
12419    (set_attr "mode" "SF")])
12421 (define_insn "*sse_setccdf"
12422   [(set (match_operand:DF 0 "register_operand" "=Y")
12423         (match_operator:DF 1 "sse_comparison_operator"
12424           [(match_operand:DF 2 "register_operand" "0")
12425            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12426   "TARGET_SSE2 && reload_completed"
12427   "cmp%D1sd\t{%3, %0|%0, %3}"
12428   [(set_attr "type" "ssecmp")
12429    (set_attr "mode" "DF")])
12431 ;; Basic conditional jump instructions.
12432 ;; We ignore the overflow flag for signed branch instructions.
12434 ;; For all bCOND expanders, also expand the compare or test insn that
12435 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12437 (define_expand "beq"
12438   [(set (pc)
12439         (if_then_else (match_dup 1)
12440                       (label_ref (match_operand 0 "" ""))
12441                       (pc)))]
12442   ""
12443   "ix86_expand_branch (EQ, operands[0]); DONE;")
12445 (define_expand "bne"
12446   [(set (pc)
12447         (if_then_else (match_dup 1)
12448                       (label_ref (match_operand 0 "" ""))
12449                       (pc)))]
12450   ""
12451   "ix86_expand_branch (NE, operands[0]); DONE;")
12453 (define_expand "bgt"
12454   [(set (pc)
12455         (if_then_else (match_dup 1)
12456                       (label_ref (match_operand 0 "" ""))
12457                       (pc)))]
12458   ""
12459   "ix86_expand_branch (GT, operands[0]); DONE;")
12461 (define_expand "bgtu"
12462   [(set (pc)
12463         (if_then_else (match_dup 1)
12464                       (label_ref (match_operand 0 "" ""))
12465                       (pc)))]
12466   ""
12467   "ix86_expand_branch (GTU, operands[0]); DONE;")
12469 (define_expand "blt"
12470   [(set (pc)
12471         (if_then_else (match_dup 1)
12472                       (label_ref (match_operand 0 "" ""))
12473                       (pc)))]
12474   ""
12475   "ix86_expand_branch (LT, operands[0]); DONE;")
12477 (define_expand "bltu"
12478   [(set (pc)
12479         (if_then_else (match_dup 1)
12480                       (label_ref (match_operand 0 "" ""))
12481                       (pc)))]
12482   ""
12483   "ix86_expand_branch (LTU, operands[0]); DONE;")
12485 (define_expand "bge"
12486   [(set (pc)
12487         (if_then_else (match_dup 1)
12488                       (label_ref (match_operand 0 "" ""))
12489                       (pc)))]
12490   ""
12491   "ix86_expand_branch (GE, operands[0]); DONE;")
12493 (define_expand "bgeu"
12494   [(set (pc)
12495         (if_then_else (match_dup 1)
12496                       (label_ref (match_operand 0 "" ""))
12497                       (pc)))]
12498   ""
12499   "ix86_expand_branch (GEU, operands[0]); DONE;")
12501 (define_expand "ble"
12502   [(set (pc)
12503         (if_then_else (match_dup 1)
12504                       (label_ref (match_operand 0 "" ""))
12505                       (pc)))]
12506   ""
12507   "ix86_expand_branch (LE, operands[0]); DONE;")
12509 (define_expand "bleu"
12510   [(set (pc)
12511         (if_then_else (match_dup 1)
12512                       (label_ref (match_operand 0 "" ""))
12513                       (pc)))]
12514   ""
12515   "ix86_expand_branch (LEU, operands[0]); DONE;")
12517 (define_expand "bunordered"
12518   [(set (pc)
12519         (if_then_else (match_dup 1)
12520                       (label_ref (match_operand 0 "" ""))
12521                       (pc)))]
12522   "TARGET_80387 || TARGET_SSE_MATH"
12523   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12525 (define_expand "bordered"
12526   [(set (pc)
12527         (if_then_else (match_dup 1)
12528                       (label_ref (match_operand 0 "" ""))
12529                       (pc)))]
12530   "TARGET_80387 || TARGET_SSE_MATH"
12531   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12533 (define_expand "buneq"
12534   [(set (pc)
12535         (if_then_else (match_dup 1)
12536                       (label_ref (match_operand 0 "" ""))
12537                       (pc)))]
12538   "TARGET_80387 || TARGET_SSE_MATH"
12539   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12541 (define_expand "bunge"
12542   [(set (pc)
12543         (if_then_else (match_dup 1)
12544                       (label_ref (match_operand 0 "" ""))
12545                       (pc)))]
12546   "TARGET_80387 || TARGET_SSE_MATH"
12547   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12549 (define_expand "bungt"
12550   [(set (pc)
12551         (if_then_else (match_dup 1)
12552                       (label_ref (match_operand 0 "" ""))
12553                       (pc)))]
12554   "TARGET_80387 || TARGET_SSE_MATH"
12555   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12557 (define_expand "bunle"
12558   [(set (pc)
12559         (if_then_else (match_dup 1)
12560                       (label_ref (match_operand 0 "" ""))
12561                       (pc)))]
12562   "TARGET_80387 || TARGET_SSE_MATH"
12563   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12565 (define_expand "bunlt"
12566   [(set (pc)
12567         (if_then_else (match_dup 1)
12568                       (label_ref (match_operand 0 "" ""))
12569                       (pc)))]
12570   "TARGET_80387 || TARGET_SSE_MATH"
12571   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12573 (define_expand "bltgt"
12574   [(set (pc)
12575         (if_then_else (match_dup 1)
12576                       (label_ref (match_operand 0 "" ""))
12577                       (pc)))]
12578   "TARGET_80387 || TARGET_SSE_MATH"
12579   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12581 (define_insn "*jcc_1"
12582   [(set (pc)
12583         (if_then_else (match_operator 1 "ix86_comparison_operator"
12584                                       [(reg FLAGS_REG) (const_int 0)])
12585                       (label_ref (match_operand 0 "" ""))
12586                       (pc)))]
12587   ""
12588   "%+j%C1\t%l0"
12589   [(set_attr "type" "ibr")
12590    (set_attr "modrm" "0")
12591    (set (attr "length")
12592            (if_then_else (and (ge (minus (match_dup 0) (pc))
12593                                   (const_int -126))
12594                               (lt (minus (match_dup 0) (pc))
12595                                   (const_int 128)))
12596              (const_int 2)
12597              (const_int 6)))])
12599 (define_insn "*jcc_2"
12600   [(set (pc)
12601         (if_then_else (match_operator 1 "ix86_comparison_operator"
12602                                       [(reg FLAGS_REG) (const_int 0)])
12603                       (pc)
12604                       (label_ref (match_operand 0 "" ""))))]
12605   ""
12606   "%+j%c1\t%l0"
12607   [(set_attr "type" "ibr")
12608    (set_attr "modrm" "0")
12609    (set (attr "length")
12610            (if_then_else (and (ge (minus (match_dup 0) (pc))
12611                                   (const_int -126))
12612                               (lt (minus (match_dup 0) (pc))
12613                                   (const_int 128)))
12614              (const_int 2)
12615              (const_int 6)))])
12617 ;; In general it is not safe to assume too much about CCmode registers,
12618 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12619 ;; conditions this is safe on x86, so help combine not create
12621 ;;      seta    %al
12622 ;;      testb   %al, %al
12623 ;;      je      Lfoo
12625 (define_split 
12626   [(set (pc)
12627         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12628                                       [(reg FLAGS_REG) (const_int 0)])
12629                           (const_int 0))
12630                       (label_ref (match_operand 1 "" ""))
12631                       (pc)))]
12632   ""
12633   [(set (pc)
12634         (if_then_else (match_dup 0)
12635                       (label_ref (match_dup 1))
12636                       (pc)))]
12638   PUT_MODE (operands[0], VOIDmode);
12640   
12641 (define_split 
12642   [(set (pc)
12643         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12644                                       [(reg FLAGS_REG) (const_int 0)])
12645                           (const_int 0))
12646                       (label_ref (match_operand 1 "" ""))
12647                       (pc)))]
12648   ""
12649   [(set (pc)
12650         (if_then_else (match_dup 0)
12651                       (label_ref (match_dup 1))
12652                       (pc)))]
12654   rtx new_op0 = copy_rtx (operands[0]);
12655   operands[0] = new_op0;
12656   PUT_MODE (new_op0, VOIDmode);
12657   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12658                                              GET_MODE (XEXP (new_op0, 0))));
12660   /* Make sure that (a) the CCmode we have for the flags is strong
12661      enough for the reversed compare or (b) we have a valid FP compare.  */
12662   if (! ix86_comparison_operator (new_op0, VOIDmode))
12663     FAIL;
12666 ;; Define combination compare-and-branch fp compare instructions to use
12667 ;; during early optimization.  Splitting the operation apart early makes
12668 ;; for bad code when we want to reverse the operation.
12670 (define_insn "*fp_jcc_1_mixed"
12671   [(set (pc)
12672         (if_then_else (match_operator 0 "comparison_operator"
12673                         [(match_operand 1 "register_operand" "f#x,x#f")
12674                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12675           (label_ref (match_operand 3 "" ""))
12676           (pc)))
12677    (clobber (reg:CCFP FPSR_REG))
12678    (clobber (reg:CCFP FLAGS_REG))]
12679   "TARGET_MIX_SSE_I387
12680    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12681    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12682    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12683   "#")
12685 (define_insn "*fp_jcc_1_sse"
12686   [(set (pc)
12687         (if_then_else (match_operator 0 "comparison_operator"
12688                         [(match_operand 1 "register_operand" "x")
12689                          (match_operand 2 "nonimmediate_operand" "xm")])
12690           (label_ref (match_operand 3 "" ""))
12691           (pc)))
12692    (clobber (reg:CCFP FPSR_REG))
12693    (clobber (reg:CCFP FLAGS_REG))]
12694   "TARGET_SSE_MATH
12695    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12696    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12697    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12698   "#")
12700 (define_insn "*fp_jcc_1_387"
12701   [(set (pc)
12702         (if_then_else (match_operator 0 "comparison_operator"
12703                         [(match_operand 1 "register_operand" "f")
12704                          (match_operand 2 "register_operand" "f")])
12705           (label_ref (match_operand 3 "" ""))
12706           (pc)))
12707    (clobber (reg:CCFP FPSR_REG))
12708    (clobber (reg:CCFP FLAGS_REG))]
12709   "TARGET_CMOVE && TARGET_80387
12710    && FLOAT_MODE_P (GET_MODE (operands[1]))
12711    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12712    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12713   "#")
12715 (define_insn "*fp_jcc_2_mixed"
12716   [(set (pc)
12717         (if_then_else (match_operator 0 "comparison_operator"
12718                         [(match_operand 1 "register_operand" "f#x,x#f")
12719                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12720           (pc)
12721           (label_ref (match_operand 3 "" ""))))
12722    (clobber (reg:CCFP FPSR_REG))
12723    (clobber (reg:CCFP FLAGS_REG))]
12724   "TARGET_MIX_SSE_I387
12725    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12726    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12727    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12728   "#")
12730 (define_insn "*fp_jcc_2_sse"
12731   [(set (pc)
12732         (if_then_else (match_operator 0 "comparison_operator"
12733                         [(match_operand 1 "register_operand" "x")
12734                          (match_operand 2 "nonimmediate_operand" "xm")])
12735           (pc)
12736           (label_ref (match_operand 3 "" ""))))
12737    (clobber (reg:CCFP FPSR_REG))
12738    (clobber (reg:CCFP FLAGS_REG))]
12739   "TARGET_SSE_MATH
12740    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12741    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12742    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12743   "#")
12745 (define_insn "*fp_jcc_2_387"
12746   [(set (pc)
12747         (if_then_else (match_operator 0 "comparison_operator"
12748                         [(match_operand 1 "register_operand" "f")
12749                          (match_operand 2 "register_operand" "f")])
12750           (pc)
12751           (label_ref (match_operand 3 "" ""))))
12752    (clobber (reg:CCFP FPSR_REG))
12753    (clobber (reg:CCFP FLAGS_REG))]
12754   "TARGET_CMOVE && TARGET_80387
12755    && FLOAT_MODE_P (GET_MODE (operands[1]))
12756    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12757    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12758   "#")
12760 (define_insn "*fp_jcc_3_387"
12761   [(set (pc)
12762         (if_then_else (match_operator 0 "comparison_operator"
12763                         [(match_operand 1 "register_operand" "f")
12764                          (match_operand 2 "nonimmediate_operand" "fm")])
12765           (label_ref (match_operand 3 "" ""))
12766           (pc)))
12767    (clobber (reg:CCFP FPSR_REG))
12768    (clobber (reg:CCFP FLAGS_REG))
12769    (clobber (match_scratch:HI 4 "=a"))]
12770   "TARGET_80387
12771    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12772    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12773    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12774    && SELECT_CC_MODE (GET_CODE (operands[0]),
12775                       operands[1], operands[2]) == CCFPmode
12776    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12777   "#")
12779 (define_insn "*fp_jcc_4_387"
12780   [(set (pc)
12781         (if_then_else (match_operator 0 "comparison_operator"
12782                         [(match_operand 1 "register_operand" "f")
12783                          (match_operand 2 "nonimmediate_operand" "fm")])
12784           (pc)
12785           (label_ref (match_operand 3 "" ""))))
12786    (clobber (reg:CCFP FPSR_REG))
12787    (clobber (reg:CCFP FLAGS_REG))
12788    (clobber (match_scratch:HI 4 "=a"))]
12789   "TARGET_80387
12790    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12791    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12792    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12793    && SELECT_CC_MODE (GET_CODE (operands[0]),
12794                       operands[1], operands[2]) == CCFPmode
12795    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12796   "#")
12798 (define_insn "*fp_jcc_5_387"
12799   [(set (pc)
12800         (if_then_else (match_operator 0 "comparison_operator"
12801                         [(match_operand 1 "register_operand" "f")
12802                          (match_operand 2 "register_operand" "f")])
12803           (label_ref (match_operand 3 "" ""))
12804           (pc)))
12805    (clobber (reg:CCFP FPSR_REG))
12806    (clobber (reg:CCFP FLAGS_REG))
12807    (clobber (match_scratch:HI 4 "=a"))]
12808   "TARGET_80387
12809    && FLOAT_MODE_P (GET_MODE (operands[1]))
12810    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12811    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12812   "#")
12814 (define_insn "*fp_jcc_6_387"
12815   [(set (pc)
12816         (if_then_else (match_operator 0 "comparison_operator"
12817                         [(match_operand 1 "register_operand" "f")
12818                          (match_operand 2 "register_operand" "f")])
12819           (pc)
12820           (label_ref (match_operand 3 "" ""))))
12821    (clobber (reg:CCFP FPSR_REG))
12822    (clobber (reg:CCFP FLAGS_REG))
12823    (clobber (match_scratch:HI 4 "=a"))]
12824   "TARGET_80387
12825    && FLOAT_MODE_P (GET_MODE (operands[1]))
12826    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12827    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12828   "#")
12830 (define_insn "*fp_jcc_7_387"
12831   [(set (pc)
12832         (if_then_else (match_operator 0 "comparison_operator"
12833                         [(match_operand 1 "register_operand" "f")
12834                          (match_operand 2 "const_double_operand" "C")])
12835           (label_ref (match_operand 3 "" ""))
12836           (pc)))
12837    (clobber (reg:CCFP FPSR_REG))
12838    (clobber (reg:CCFP FLAGS_REG))
12839    (clobber (match_scratch:HI 4 "=a"))]
12840   "TARGET_80387
12841    && FLOAT_MODE_P (GET_MODE (operands[1]))
12842    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
12843    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12844    && SELECT_CC_MODE (GET_CODE (operands[0]),
12845                       operands[1], operands[2]) == CCFPmode
12846    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12847   "#")
12849 ;; The order of operands in *fp_jcc_8 is forced by combine in
12850 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12851 ;; with a precedence over other operators and is always put in the first
12852 ;; place. Swap condition and operands to match ficom instruction.
12854 (define_insn "*fp_jcc_8_387"
12855   [(set (pc)
12856         (if_then_else (match_operator 0 "comparison_operator"
12857                         [(match_operator 1 "float_operator"
12858                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
12859                            (match_operand 3 "register_operand" "f,f")])
12860           (label_ref (match_operand 4 "" ""))
12861           (pc)))
12862    (clobber (reg:CCFP FPSR_REG))
12863    (clobber (reg:CCFP FLAGS_REG))
12864    (clobber (match_scratch:HI 5 "=a,a"))]
12865   "TARGET_80387 && TARGET_USE_FIOP
12866    && FLOAT_MODE_P (GET_MODE (operands[3]))
12867    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12868    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12869    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12870    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12871   "#")
12873 (define_split
12874   [(set (pc)
12875         (if_then_else (match_operator 0 "comparison_operator"
12876                         [(match_operand 1 "register_operand" "")
12877                          (match_operand 2 "nonimmediate_operand" "")])
12878           (match_operand 3 "" "")
12879           (match_operand 4 "" "")))
12880    (clobber (reg:CCFP FPSR_REG))
12881    (clobber (reg:CCFP FLAGS_REG))]
12882   "reload_completed"
12883   [(const_int 0)]
12885   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12886                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12887   DONE;
12890 (define_split
12891   [(set (pc)
12892         (if_then_else (match_operator 0 "comparison_operator"
12893                         [(match_operand 1 "register_operand" "")
12894                          (match_operand 2 "general_operand" "")])
12895           (match_operand 3 "" "")
12896           (match_operand 4 "" "")))
12897    (clobber (reg:CCFP FPSR_REG))
12898    (clobber (reg:CCFP FLAGS_REG))
12899    (clobber (match_scratch:HI 5 "=a"))]
12900   "reload_completed"
12901   [(const_int 0)]
12903   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12904                         operands[3], operands[4], operands[5], NULL_RTX);
12905   DONE;
12908 (define_split
12909   [(set (pc)
12910         (if_then_else (match_operator 0 "comparison_operator"
12911                         [(match_operator 1 "float_operator"
12912                            [(match_operand:SI 2 "memory_operand" "")])
12913                            (match_operand 3 "register_operand" "")])
12914           (match_operand 4 "" "")
12915           (match_operand 5 "" "")))
12916    (clobber (reg:CCFP FPSR_REG))
12917    (clobber (reg:CCFP FLAGS_REG))
12918    (clobber (match_scratch:HI 6 "=a"))]
12919   "reload_completed"
12920   [(const_int 0)]
12922   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12923   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12924                         operands[3], operands[7],
12925                         operands[4], operands[5], operands[6], NULL_RTX);
12926   DONE;
12929 ;; %%% Kill this when reload knows how to do it.
12930 (define_split
12931   [(set (pc)
12932         (if_then_else (match_operator 0 "comparison_operator"
12933                         [(match_operator 1 "float_operator"
12934                            [(match_operand:SI 2 "register_operand" "")])
12935                            (match_operand 3 "register_operand" "")])
12936           (match_operand 4 "" "")
12937           (match_operand 5 "" "")))
12938    (clobber (reg:CCFP FPSR_REG))
12939    (clobber (reg:CCFP FLAGS_REG))
12940    (clobber (match_scratch:HI 6 "=a"))]
12941   "reload_completed"
12942   [(const_int 0)]
12944   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12945   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
12946   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12947                         operands[3], operands[7],
12948                         operands[4], operands[5], operands[6], operands[2]);
12949   DONE;
12952 ;; Unconditional and other jump instructions
12954 (define_insn "jump"
12955   [(set (pc)
12956         (label_ref (match_operand 0 "" "")))]
12957   ""
12958   "jmp\t%l0"
12959   [(set_attr "type" "ibr")
12960    (set (attr "length")
12961            (if_then_else (and (ge (minus (match_dup 0) (pc))
12962                                   (const_int -126))
12963                               (lt (minus (match_dup 0) (pc))
12964                                   (const_int 128)))
12965              (const_int 2)
12966              (const_int 5)))
12967    (set_attr "modrm" "0")])
12969 (define_expand "indirect_jump"
12970   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
12971   ""
12972   "")
12974 (define_insn "*indirect_jump"
12975   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
12976   "!TARGET_64BIT"
12977   "jmp\t%A0"
12978   [(set_attr "type" "ibr")
12979    (set_attr "length_immediate" "0")])
12981 (define_insn "*indirect_jump_rtx64"
12982   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
12983   "TARGET_64BIT"
12984   "jmp\t%A0"
12985   [(set_attr "type" "ibr")
12986    (set_attr "length_immediate" "0")])
12988 (define_expand "tablejump"
12989   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
12990               (use (label_ref (match_operand 1 "" "")))])]
12991   ""
12993   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12994      relative.  Convert the relative address to an absolute address.  */
12995   if (flag_pic)
12996     {
12997       rtx op0, op1;
12998       enum rtx_code code;
13000       if (TARGET_64BIT)
13001         {
13002           code = PLUS;
13003           op0 = operands[0];
13004           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13005         }
13006       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13007         {
13008           code = PLUS;
13009           op0 = operands[0];
13010           op1 = pic_offset_table_rtx;
13011         }
13012       else
13013         {
13014           code = MINUS;
13015           op0 = pic_offset_table_rtx;
13016           op1 = operands[0];
13017         }
13019       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13020                                          OPTAB_DIRECT);
13021     }
13024 (define_insn "*tablejump_1"
13025   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13026    (use (label_ref (match_operand 1 "" "")))]
13027   "!TARGET_64BIT"
13028   "jmp\t%A0"
13029   [(set_attr "type" "ibr")
13030    (set_attr "length_immediate" "0")])
13032 (define_insn "*tablejump_1_rtx64"
13033   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13034    (use (label_ref (match_operand 1 "" "")))]
13035   "TARGET_64BIT"
13036   "jmp\t%A0"
13037   [(set_attr "type" "ibr")
13038    (set_attr "length_immediate" "0")])
13040 ;; Loop instruction
13042 ;; This is all complicated by the fact that since this is a jump insn
13043 ;; we must handle our own reloads.
13045 (define_expand "doloop_end"
13046   [(use (match_operand 0 "" ""))        ; loop pseudo
13047    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13048    (use (match_operand 2 "" ""))        ; max iterations
13049    (use (match_operand 3 "" ""))        ; loop level 
13050    (use (match_operand 4 "" ""))]       ; label
13051   "!TARGET_64BIT && TARGET_USE_LOOP"
13052   "                                 
13054   /* Only use cloop on innermost loops.  */
13055   if (INTVAL (operands[3]) > 1)
13056     FAIL;
13057   if (GET_MODE (operands[0]) != SImode)
13058     FAIL;
13059   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13060                                            operands[0]));
13061   DONE;
13064 (define_insn "doloop_end_internal"
13065   [(set (pc)
13066         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13067                           (const_int 1))
13068                       (label_ref (match_operand 0 "" ""))
13069                       (pc)))
13070    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13071         (plus:SI (match_dup 1)
13072                  (const_int -1)))
13073    (clobber (match_scratch:SI 3 "=X,X,r"))
13074    (clobber (reg:CC FLAGS_REG))]
13075   "!TARGET_64BIT && TARGET_USE_LOOP
13076    && (reload_in_progress || reload_completed
13077        || register_operand (operands[2], VOIDmode))"
13079   if (which_alternative != 0)
13080     return "#";
13081   if (get_attr_length (insn) == 2)
13082     return "%+loop\t%l0";
13083   else
13084     return "dec{l}\t%1\;%+jne\t%l0";
13086   [(set (attr "length")
13087         (if_then_else (and (eq_attr "alternative" "0")
13088                            (and (ge (minus (match_dup 0) (pc))
13089                                     (const_int -126))
13090                                 (lt (minus (match_dup 0) (pc))
13091                                     (const_int 128))))
13092                       (const_int 2)
13093                       (const_int 16)))
13094    ;; We don't know the type before shorten branches.  Optimistically expect
13095    ;; the loop instruction to match.
13096    (set (attr "type") (const_string "ibr"))])
13098 (define_split
13099   [(set (pc)
13100         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13101                           (const_int 1))
13102                       (match_operand 0 "" "")
13103                       (pc)))
13104    (set (match_dup 1)
13105         (plus:SI (match_dup 1)
13106                  (const_int -1)))
13107    (clobber (match_scratch:SI 2 ""))
13108    (clobber (reg:CC FLAGS_REG))]
13109   "!TARGET_64BIT && TARGET_USE_LOOP
13110    && reload_completed
13111    && REGNO (operands[1]) != 2"
13112   [(parallel [(set (reg:CCZ FLAGS_REG)
13113                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13114                                  (const_int 0)))
13115               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13116    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13117                            (match_dup 0)
13118                            (pc)))]
13119   "")
13120   
13121 (define_split
13122   [(set (pc)
13123         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13124                           (const_int 1))
13125                       (match_operand 0 "" "")
13126                       (pc)))
13127    (set (match_operand:SI 2 "nonimmediate_operand" "")
13128         (plus:SI (match_dup 1)
13129                  (const_int -1)))
13130    (clobber (match_scratch:SI 3 ""))
13131    (clobber (reg:CC FLAGS_REG))]
13132   "!TARGET_64BIT && TARGET_USE_LOOP
13133    && reload_completed
13134    && (! REG_P (operands[2])
13135        || ! rtx_equal_p (operands[1], operands[2]))"
13136   [(set (match_dup 3) (match_dup 1))
13137    (parallel [(set (reg:CCZ FLAGS_REG)
13138                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13139                                 (const_int 0)))
13140               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13141    (set (match_dup 2) (match_dup 3))
13142    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13143                            (match_dup 0)
13144                            (pc)))]
13145   "")
13147 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13149 (define_peephole2
13150   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13151    (set (match_operand:QI 1 "register_operand" "")
13152         (match_operator:QI 2 "ix86_comparison_operator"
13153           [(reg FLAGS_REG) (const_int 0)]))
13154    (set (match_operand 3 "q_regs_operand" "")
13155         (zero_extend (match_dup 1)))]
13156   "(peep2_reg_dead_p (3, operands[1])
13157     || operands_match_p (operands[1], operands[3]))
13158    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13159   [(set (match_dup 4) (match_dup 0))
13160    (set (strict_low_part (match_dup 5))
13161         (match_dup 2))]
13163   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13164   operands[5] = gen_lowpart (QImode, operands[3]);
13165   ix86_expand_clear (operands[3]);
13168 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13170 (define_peephole2
13171   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13172    (set (match_operand:QI 1 "register_operand" "")
13173         (match_operator:QI 2 "ix86_comparison_operator"
13174           [(reg FLAGS_REG) (const_int 0)]))
13175    (parallel [(set (match_operand 3 "q_regs_operand" "")
13176                    (zero_extend (match_dup 1)))
13177               (clobber (reg:CC FLAGS_REG))])]
13178   "(peep2_reg_dead_p (3, operands[1])
13179     || operands_match_p (operands[1], operands[3]))
13180    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13181   [(set (match_dup 4) (match_dup 0))
13182    (set (strict_low_part (match_dup 5))
13183         (match_dup 2))]
13185   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13186   operands[5] = gen_lowpart (QImode, operands[3]);
13187   ix86_expand_clear (operands[3]);
13190 ;; Call instructions.
13192 ;; The predicates normally associated with named expanders are not properly
13193 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13194 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13196 ;; Call subroutine returning no value.
13198 (define_expand "call_pop"
13199   [(parallel [(call (match_operand:QI 0 "" "")
13200                     (match_operand:SI 1 "" ""))
13201               (set (reg:SI SP_REG)
13202                    (plus:SI (reg:SI SP_REG)
13203                             (match_operand:SI 3 "" "")))])]
13204   "!TARGET_64BIT"
13206   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13207   DONE;
13210 (define_insn "*call_pop_0"
13211   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13212          (match_operand:SI 1 "" ""))
13213    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13214                             (match_operand:SI 2 "immediate_operand" "")))]
13215   "!TARGET_64BIT"
13217   if (SIBLING_CALL_P (insn))
13218     return "jmp\t%P0";
13219   else
13220     return "call\t%P0";
13222   [(set_attr "type" "call")])
13223   
13224 (define_insn "*call_pop_1"
13225   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13226          (match_operand:SI 1 "" ""))
13227    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13228                             (match_operand:SI 2 "immediate_operand" "i")))]
13229   "!TARGET_64BIT"
13231   if (constant_call_address_operand (operands[0], Pmode))
13232     {
13233       if (SIBLING_CALL_P (insn))
13234         return "jmp\t%P0";
13235       else
13236         return "call\t%P0";
13237     }
13238   if (SIBLING_CALL_P (insn))
13239     return "jmp\t%A0";
13240   else
13241     return "call\t%A0";
13243   [(set_attr "type" "call")])
13245 (define_expand "call"
13246   [(call (match_operand:QI 0 "" "")
13247          (match_operand 1 "" ""))
13248    (use (match_operand 2 "" ""))]
13249   ""
13251   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13252   DONE;
13255 (define_expand "sibcall"
13256   [(call (match_operand:QI 0 "" "")
13257          (match_operand 1 "" ""))
13258    (use (match_operand 2 "" ""))]
13259   ""
13261   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13262   DONE;
13265 (define_insn "*call_0"
13266   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13267          (match_operand 1 "" ""))]
13268   ""
13270   if (SIBLING_CALL_P (insn))
13271     return "jmp\t%P0";
13272   else
13273     return "call\t%P0";
13275   [(set_attr "type" "call")])
13277 (define_insn "*call_1"
13278   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13279          (match_operand 1 "" ""))]
13280   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13282   if (constant_call_address_operand (operands[0], Pmode))
13283     return "call\t%P0";
13284   return "call\t%A0";
13286   [(set_attr "type" "call")])
13288 (define_insn "*sibcall_1"
13289   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13290          (match_operand 1 "" ""))]
13291   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13293   if (constant_call_address_operand (operands[0], Pmode))
13294     return "jmp\t%P0";
13295   return "jmp\t%A0";
13297   [(set_attr "type" "call")])
13299 (define_insn "*call_1_rex64"
13300   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13301          (match_operand 1 "" ""))]
13302   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13304   if (constant_call_address_operand (operands[0], Pmode))
13305     return "call\t%P0";
13306   return "call\t%A0";
13308   [(set_attr "type" "call")])
13310 (define_insn "*sibcall_1_rex64"
13311   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13312          (match_operand 1 "" ""))]
13313   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13314   "jmp\t%P0"
13315   [(set_attr "type" "call")])
13317 (define_insn "*sibcall_1_rex64_v"
13318   [(call (mem:QI (reg:DI 40))
13319          (match_operand 0 "" ""))]
13320   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13321   "jmp\t*%%r11"
13322   [(set_attr "type" "call")])
13325 ;; Call subroutine, returning value in operand 0
13327 (define_expand "call_value_pop"
13328   [(parallel [(set (match_operand 0 "" "")
13329                    (call (match_operand:QI 1 "" "")
13330                          (match_operand:SI 2 "" "")))
13331               (set (reg:SI SP_REG)
13332                    (plus:SI (reg:SI SP_REG)
13333                             (match_operand:SI 4 "" "")))])]
13334   "!TARGET_64BIT"
13336   ix86_expand_call (operands[0], operands[1], operands[2],
13337                     operands[3], operands[4], 0);
13338   DONE;
13341 (define_expand "call_value"
13342   [(set (match_operand 0 "" "")
13343         (call (match_operand:QI 1 "" "")
13344               (match_operand:SI 2 "" "")))
13345    (use (match_operand:SI 3 "" ""))]
13346   ;; Operand 2 not used on the i386.
13347   ""
13349   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13350   DONE;
13353 (define_expand "sibcall_value"
13354   [(set (match_operand 0 "" "")
13355         (call (match_operand:QI 1 "" "")
13356               (match_operand:SI 2 "" "")))
13357    (use (match_operand:SI 3 "" ""))]
13358   ;; Operand 2 not used on the i386.
13359   ""
13361   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13362   DONE;
13365 ;; Call subroutine returning any type.
13367 (define_expand "untyped_call"
13368   [(parallel [(call (match_operand 0 "" "")
13369                     (const_int 0))
13370               (match_operand 1 "" "")
13371               (match_operand 2 "" "")])]
13372   ""
13374   int i;
13376   /* In order to give reg-stack an easier job in validating two
13377      coprocessor registers as containing a possible return value,
13378      simply pretend the untyped call returns a complex long double
13379      value.  */
13381   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13382                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13383                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13384                     NULL, 0);
13386   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13387     {
13388       rtx set = XVECEXP (operands[2], 0, i);
13389       emit_move_insn (SET_DEST (set), SET_SRC (set));
13390     }
13392   /* The optimizer does not know that the call sets the function value
13393      registers we stored in the result block.  We avoid problems by
13394      claiming that all hard registers are used and clobbered at this
13395      point.  */
13396   emit_insn (gen_blockage (const0_rtx));
13398   DONE;
13401 ;; Prologue and epilogue instructions
13403 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13404 ;; all of memory.  This blocks insns from being moved across this point.
13406 (define_insn "blockage"
13407   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13408   ""
13409   ""
13410   [(set_attr "length" "0")])
13412 ;; Insn emitted into the body of a function to return from a function.
13413 ;; This is only done if the function's epilogue is known to be simple.
13414 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13416 (define_expand "return"
13417   [(return)]
13418   "ix86_can_use_return_insn_p ()"
13420   if (current_function_pops_args)
13421     {
13422       rtx popc = GEN_INT (current_function_pops_args);
13423       emit_jump_insn (gen_return_pop_internal (popc));
13424       DONE;
13425     }
13428 (define_insn "return_internal"
13429   [(return)]
13430   "reload_completed"
13431   "ret"
13432   [(set_attr "length" "1")
13433    (set_attr "length_immediate" "0")
13434    (set_attr "modrm" "0")])
13436 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13437 ;; instruction Athlon and K8 have.
13439 (define_insn "return_internal_long"
13440   [(return)
13441    (unspec [(const_int 0)] UNSPEC_REP)]
13442   "reload_completed"
13443   "rep {;} ret"
13444   [(set_attr "length" "1")
13445    (set_attr "length_immediate" "0")
13446    (set_attr "prefix_rep" "1")
13447    (set_attr "modrm" "0")])
13449 (define_insn "return_pop_internal"
13450   [(return)
13451    (use (match_operand:SI 0 "const_int_operand" ""))]
13452   "reload_completed"
13453   "ret\t%0"
13454   [(set_attr "length" "3")
13455    (set_attr "length_immediate" "2")
13456    (set_attr "modrm" "0")])
13458 (define_insn "return_indirect_internal"
13459   [(return)
13460    (use (match_operand:SI 0 "register_operand" "r"))]
13461   "reload_completed"
13462   "jmp\t%A0"
13463   [(set_attr "type" "ibr")
13464    (set_attr "length_immediate" "0")])
13466 (define_insn "nop"
13467   [(const_int 0)]
13468   ""
13469   "nop"
13470   [(set_attr "length" "1")
13471    (set_attr "length_immediate" "0")
13472    (set_attr "modrm" "0")])
13474 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13475 ;; branch prediction penalty for the third jump in a 16-byte
13476 ;; block on K8.
13478 (define_insn "align"
13479   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13480   ""
13482 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13483   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13484 #else
13485   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13486      The align insn is used to avoid 3 jump instructions in the row to improve
13487      branch prediction and the benefits hardly outweight the cost of extra 8
13488      nops on the average inserted by full alignment pseudo operation.  */
13489 #endif
13490   return "";
13492   [(set_attr "length" "16")])
13494 (define_expand "prologue"
13495   [(const_int 1)]
13496   ""
13497   "ix86_expand_prologue (); DONE;")
13499 (define_insn "set_got"
13500   [(set (match_operand:SI 0 "register_operand" "=r")
13501         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13502    (clobber (reg:CC FLAGS_REG))]
13503   "!TARGET_64BIT"
13504   { return output_set_got (operands[0]); }
13505   [(set_attr "type" "multi")
13506    (set_attr "length" "12")])
13508 (define_expand "epilogue"
13509   [(const_int 1)]
13510   ""
13511   "ix86_expand_epilogue (1); DONE;")
13513 (define_expand "sibcall_epilogue"
13514   [(const_int 1)]
13515   ""
13516   "ix86_expand_epilogue (0); DONE;")
13518 (define_expand "eh_return"
13519   [(use (match_operand 0 "register_operand" ""))]
13520   ""
13522   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13524   /* Tricky bit: we write the address of the handler to which we will
13525      be returning into someone else's stack frame, one word below the
13526      stack address we wish to restore.  */
13527   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13528   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13529   tmp = gen_rtx_MEM (Pmode, tmp);
13530   emit_move_insn (tmp, ra);
13532   if (Pmode == SImode)
13533     emit_jump_insn (gen_eh_return_si (sa));
13534   else
13535     emit_jump_insn (gen_eh_return_di (sa));
13536   emit_barrier ();
13537   DONE;
13540 (define_insn_and_split "eh_return_si"
13541   [(set (pc) 
13542         (unspec [(match_operand:SI 0 "register_operand" "c")]
13543                  UNSPEC_EH_RETURN))]
13544   "!TARGET_64BIT"
13545   "#"
13546   "reload_completed"
13547   [(const_int 1)]
13548   "ix86_expand_epilogue (2); DONE;")
13550 (define_insn_and_split "eh_return_di"
13551   [(set (pc) 
13552         (unspec [(match_operand:DI 0 "register_operand" "c")]
13553                  UNSPEC_EH_RETURN))]
13554   "TARGET_64BIT"
13555   "#"
13556   "reload_completed"
13557   [(const_int 1)]
13558   "ix86_expand_epilogue (2); DONE;")
13560 (define_insn "leave"
13561   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13562    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13563    (clobber (mem:BLK (scratch)))]
13564   "!TARGET_64BIT"
13565   "leave"
13566   [(set_attr "type" "leave")])
13568 (define_insn "leave_rex64"
13569   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13570    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13571    (clobber (mem:BLK (scratch)))]
13572   "TARGET_64BIT"
13573   "leave"
13574   [(set_attr "type" "leave")])
13576 (define_expand "ffssi2"
13577   [(parallel
13578      [(set (match_operand:SI 0 "register_operand" "") 
13579            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13580       (clobber (match_scratch:SI 2 ""))
13581       (clobber (reg:CC FLAGS_REG))])]
13582   ""
13583   "")
13585 (define_insn_and_split "*ffs_cmove"
13586   [(set (match_operand:SI 0 "register_operand" "=r") 
13587         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13588    (clobber (match_scratch:SI 2 "=&r"))
13589    (clobber (reg:CC FLAGS_REG))]
13590   "TARGET_CMOVE"
13591   "#"
13592   "&& reload_completed"
13593   [(set (match_dup 2) (const_int -1))
13594    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13595               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13596    (set (match_dup 0) (if_then_else:SI
13597                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13598                         (match_dup 2)
13599                         (match_dup 0)))
13600    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13601               (clobber (reg:CC FLAGS_REG))])]
13602   "")
13604 (define_insn_and_split "*ffs_no_cmove"
13605   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13606         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13607    (clobber (match_scratch:SI 2 "=&q"))
13608    (clobber (reg:CC FLAGS_REG))]
13609   ""
13610   "#"
13611   "reload_completed"
13612   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13613               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13614    (set (strict_low_part (match_dup 3))
13615         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13616    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13617               (clobber (reg:CC FLAGS_REG))])
13618    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13619               (clobber (reg:CC FLAGS_REG))])
13620    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13621               (clobber (reg:CC FLAGS_REG))])]
13623   operands[3] = gen_lowpart (QImode, operands[2]);
13624   ix86_expand_clear (operands[2]);
13627 (define_insn "*ffssi_1"
13628   [(set (reg:CCZ FLAGS_REG)
13629         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13630                      (const_int 0)))
13631    (set (match_operand:SI 0 "register_operand" "=r")
13632         (ctz:SI (match_dup 1)))]
13633   ""
13634   "bsf{l}\t{%1, %0|%0, %1}"
13635   [(set_attr "prefix_0f" "1")])
13637 (define_expand "ffsdi2"
13638   [(parallel
13639      [(set (match_operand:DI 0 "register_operand" "") 
13640            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13641       (clobber (match_scratch:DI 2 ""))
13642       (clobber (reg:CC FLAGS_REG))])]
13643   "TARGET_64BIT && TARGET_CMOVE"
13644   "")
13646 (define_insn_and_split "*ffs_rex64"
13647   [(set (match_operand:DI 0 "register_operand" "=r") 
13648         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13649    (clobber (match_scratch:DI 2 "=&r"))
13650    (clobber (reg:CC FLAGS_REG))]
13651   "TARGET_64BIT && TARGET_CMOVE"
13652   "#"
13653   "&& reload_completed"
13654   [(set (match_dup 2) (const_int -1))
13655    (parallel [(set (reg:CCZ FLAGS_REG)
13656                    (compare:CCZ (match_dup 1) (const_int 0)))
13657               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13658    (set (match_dup 0) (if_then_else:DI
13659                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13660                         (match_dup 2)
13661                         (match_dup 0)))
13662    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13663               (clobber (reg:CC FLAGS_REG))])]
13664   "")
13666 (define_insn "*ffsdi_1"
13667   [(set (reg:CCZ FLAGS_REG)
13668         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13669                      (const_int 0)))
13670    (set (match_operand:DI 0 "register_operand" "=r")
13671         (ctz:DI (match_dup 1)))]
13672   "TARGET_64BIT"
13673   "bsf{q}\t{%1, %0|%0, %1}"
13674   [(set_attr "prefix_0f" "1")])
13676 (define_insn "ctzsi2"
13677   [(set (match_operand:SI 0 "register_operand" "=r")
13678         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13679    (clobber (reg:CC FLAGS_REG))]
13680   ""
13681   "bsf{l}\t{%1, %0|%0, %1}"
13682   [(set_attr "prefix_0f" "1")])
13684 (define_insn "ctzdi2"
13685   [(set (match_operand:DI 0 "register_operand" "=r")
13686         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13687    (clobber (reg:CC FLAGS_REG))]
13688   "TARGET_64BIT"
13689   "bsf{q}\t{%1, %0|%0, %1}"
13690   [(set_attr "prefix_0f" "1")])
13692 (define_expand "clzsi2"
13693   [(parallel
13694      [(set (match_operand:SI 0 "register_operand" "")
13695            (minus:SI (const_int 31)
13696                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13697       (clobber (reg:CC FLAGS_REG))])
13698    (parallel
13699      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13700       (clobber (reg:CC FLAGS_REG))])]
13701   ""
13702   "")
13704 (define_insn "*bsr"
13705   [(set (match_operand:SI 0 "register_operand" "=r")
13706         (minus:SI (const_int 31)
13707                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13708    (clobber (reg:CC FLAGS_REG))]
13709   ""
13710   "bsr{l}\t{%1, %0|%0, %1}"
13711   [(set_attr "prefix_0f" "1")])
13713 (define_expand "clzdi2"
13714   [(parallel
13715      [(set (match_operand:DI 0 "register_operand" "")
13716            (minus:DI (const_int 63)
13717                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13718       (clobber (reg:CC FLAGS_REG))])
13719    (parallel
13720      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13721       (clobber (reg:CC FLAGS_REG))])]
13722   "TARGET_64BIT"
13723   "")
13725 (define_insn "*bsr_rex64"
13726   [(set (match_operand:DI 0 "register_operand" "=r")
13727         (minus:DI (const_int 63)
13728                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13729    (clobber (reg:CC FLAGS_REG))]
13730   "TARGET_64BIT"
13731   "bsr{q}\t{%1, %0|%0, %1}"
13732   [(set_attr "prefix_0f" "1")])
13734 ;; Thread-local storage patterns for ELF.
13736 ;; Note that these code sequences must appear exactly as shown
13737 ;; in order to allow linker relaxation.
13739 (define_insn "*tls_global_dynamic_32_gnu"
13740   [(set (match_operand:SI 0 "register_operand" "=a")
13741         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13742                     (match_operand:SI 2 "tls_symbolic_operand" "")
13743                     (match_operand:SI 3 "call_insn_operand" "")]
13744                     UNSPEC_TLS_GD))
13745    (clobber (match_scratch:SI 4 "=d"))
13746    (clobber (match_scratch:SI 5 "=c"))
13747    (clobber (reg:CC FLAGS_REG))]
13748   "!TARGET_64BIT && TARGET_GNU_TLS"
13749   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13750   [(set_attr "type" "multi")
13751    (set_attr "length" "12")])
13753 (define_insn "*tls_global_dynamic_32_sun"
13754   [(set (match_operand:SI 0 "register_operand" "=a")
13755         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13756                     (match_operand:SI 2 "tls_symbolic_operand" "")
13757                     (match_operand:SI 3 "call_insn_operand" "")]
13758                     UNSPEC_TLS_GD))
13759    (clobber (match_scratch:SI 4 "=d"))
13760    (clobber (match_scratch:SI 5 "=c"))
13761    (clobber (reg:CC FLAGS_REG))]
13762   "!TARGET_64BIT && TARGET_SUN_TLS"
13763   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13764         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13765   [(set_attr "type" "multi")
13766    (set_attr "length" "14")])
13768 (define_expand "tls_global_dynamic_32"
13769   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13770                    (unspec:SI
13771                     [(match_dup 2)
13772                      (match_operand:SI 1 "tls_symbolic_operand" "")
13773                      (match_dup 3)]
13774                     UNSPEC_TLS_GD))
13775               (clobber (match_scratch:SI 4 ""))
13776               (clobber (match_scratch:SI 5 ""))
13777               (clobber (reg:CC FLAGS_REG))])]
13778   ""
13780   if (flag_pic)
13781     operands[2] = pic_offset_table_rtx;
13782   else
13783     {
13784       operands[2] = gen_reg_rtx (Pmode);
13785       emit_insn (gen_set_got (operands[2]));
13786     }
13787   operands[3] = ix86_tls_get_addr ();
13790 (define_insn "*tls_global_dynamic_64"
13791   [(set (match_operand:DI 0 "register_operand" "=a")
13792         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13793                       (match_operand:DI 3 "" "")))
13794    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13795               UNSPEC_TLS_GD)]
13796   "TARGET_64BIT"
13797   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13798   [(set_attr "type" "multi")
13799    (set_attr "length" "16")])
13801 (define_expand "tls_global_dynamic_64"
13802   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13803                    (call (mem:QI (match_dup 2)) (const_int 0)))
13804               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13805                          UNSPEC_TLS_GD)])]
13806   ""
13808   operands[2] = ix86_tls_get_addr ();
13811 (define_insn "*tls_local_dynamic_base_32_gnu"
13812   [(set (match_operand:SI 0 "register_operand" "=a")
13813         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13814                     (match_operand:SI 2 "call_insn_operand" "")]
13815                    UNSPEC_TLS_LD_BASE))
13816    (clobber (match_scratch:SI 3 "=d"))
13817    (clobber (match_scratch:SI 4 "=c"))
13818    (clobber (reg:CC FLAGS_REG))]
13819   "!TARGET_64BIT && TARGET_GNU_TLS"
13820   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13821   [(set_attr "type" "multi")
13822    (set_attr "length" "11")])
13824 (define_insn "*tls_local_dynamic_base_32_sun"
13825   [(set (match_operand:SI 0 "register_operand" "=a")
13826         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13827                     (match_operand:SI 2 "call_insn_operand" "")]
13828                    UNSPEC_TLS_LD_BASE))
13829    (clobber (match_scratch:SI 3 "=d"))
13830    (clobber (match_scratch:SI 4 "=c"))
13831    (clobber (reg:CC FLAGS_REG))]
13832   "!TARGET_64BIT && TARGET_SUN_TLS"
13833   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13834         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13835   [(set_attr "type" "multi")
13836    (set_attr "length" "13")])
13838 (define_expand "tls_local_dynamic_base_32"
13839   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13840                    (unspec:SI [(match_dup 1) (match_dup 2)]
13841                               UNSPEC_TLS_LD_BASE))
13842               (clobber (match_scratch:SI 3 ""))
13843               (clobber (match_scratch:SI 4 ""))
13844               (clobber (reg:CC FLAGS_REG))])]
13845   ""
13847   if (flag_pic)
13848     operands[1] = pic_offset_table_rtx;
13849   else
13850     {
13851       operands[1] = gen_reg_rtx (Pmode);
13852       emit_insn (gen_set_got (operands[1]));
13853     }
13854   operands[2] = ix86_tls_get_addr ();
13857 (define_insn "*tls_local_dynamic_base_64"
13858   [(set (match_operand:DI 0 "register_operand" "=a")
13859         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13860                       (match_operand:DI 2 "" "")))
13861    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13862   "TARGET_64BIT"
13863   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13864   [(set_attr "type" "multi")
13865    (set_attr "length" "12")])
13867 (define_expand "tls_local_dynamic_base_64"
13868   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13869                    (call (mem:QI (match_dup 1)) (const_int 0)))
13870               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13871   ""
13873   operands[1] = ix86_tls_get_addr ();
13876 ;; Local dynamic of a single variable is a lose.  Show combine how
13877 ;; to convert that back to global dynamic.
13879 (define_insn_and_split "*tls_local_dynamic_32_once"
13880   [(set (match_operand:SI 0 "register_operand" "=a")
13881         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13882                              (match_operand:SI 2 "call_insn_operand" "")]
13883                             UNSPEC_TLS_LD_BASE)
13884                  (const:SI (unspec:SI
13885                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13886                             UNSPEC_DTPOFF))))
13887    (clobber (match_scratch:SI 4 "=d"))
13888    (clobber (match_scratch:SI 5 "=c"))
13889    (clobber (reg:CC FLAGS_REG))]
13890   ""
13891   "#"
13892   ""
13893   [(parallel [(set (match_dup 0)
13894                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13895                               UNSPEC_TLS_GD))
13896               (clobber (match_dup 4))
13897               (clobber (match_dup 5))
13898               (clobber (reg:CC FLAGS_REG))])]
13899   "")
13901 ;; Load and add the thread base pointer from %gs:0.
13903 (define_insn "*load_tp_si"
13904   [(set (match_operand:SI 0 "register_operand" "=r")
13905         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13906   "!TARGET_64BIT"
13907   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13908   [(set_attr "type" "imov")
13909    (set_attr "modrm" "0")
13910    (set_attr "length" "7")
13911    (set_attr "memory" "load")
13912    (set_attr "imm_disp" "false")])
13914 (define_insn "*add_tp_si"
13915   [(set (match_operand:SI 0 "register_operand" "=r")
13916         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13917                  (match_operand:SI 1 "register_operand" "0")))
13918    (clobber (reg:CC FLAGS_REG))]
13919   "!TARGET_64BIT"
13920   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13921   [(set_attr "type" "alu")
13922    (set_attr "modrm" "0")
13923    (set_attr "length" "7")
13924    (set_attr "memory" "load")
13925    (set_attr "imm_disp" "false")])
13927 (define_insn "*load_tp_di"
13928   [(set (match_operand:DI 0 "register_operand" "=r")
13929         (unspec:DI [(const_int 0)] UNSPEC_TP))]
13930   "TARGET_64BIT"
13931   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13932   [(set_attr "type" "imov")
13933    (set_attr "modrm" "0")
13934    (set_attr "length" "7")
13935    (set_attr "memory" "load")
13936    (set_attr "imm_disp" "false")])
13938 (define_insn "*add_tp_di"
13939   [(set (match_operand:DI 0 "register_operand" "=r")
13940         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
13941                  (match_operand:DI 1 "register_operand" "0")))
13942    (clobber (reg:CC FLAGS_REG))]
13943   "TARGET_64BIT"
13944   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13945   [(set_attr "type" "alu")
13946    (set_attr "modrm" "0")
13947    (set_attr "length" "7")
13948    (set_attr "memory" "load")
13949    (set_attr "imm_disp" "false")])
13951 ;; These patterns match the binary 387 instructions for addM3, subM3,
13952 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13953 ;; SFmode.  The first is the normal insn, the second the same insn but
13954 ;; with one operand a conversion, and the third the same insn but with
13955 ;; the other operand a conversion.  The conversion may be SFmode or
13956 ;; SImode if the target mode DFmode, but only SImode if the target mode
13957 ;; is SFmode.
13959 ;; Gcc is slightly more smart about handling normal two address instructions
13960 ;; so use special patterns for add and mull.
13962 (define_insn "*fop_sf_comm_mixed"
13963   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13964         (match_operator:SF 3 "binary_fp_operator"
13965                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
13966                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13967   "TARGET_MIX_SSE_I387
13968    && COMMUTATIVE_ARITH_P (operands[3])
13969    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13970   "* return output_387_binary_op (insn, operands);"
13971   [(set (attr "type") 
13972         (if_then_else (eq_attr "alternative" "1")
13973            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13974               (const_string "ssemul")
13975               (const_string "sseadd"))
13976            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13977               (const_string "fmul")
13978               (const_string "fop"))))
13979    (set_attr "mode" "SF")])
13981 (define_insn "*fop_sf_comm_sse"
13982   [(set (match_operand:SF 0 "register_operand" "=x")
13983         (match_operator:SF 3 "binary_fp_operator"
13984                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13985                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13986   "TARGET_SSE_MATH
13987    && COMMUTATIVE_ARITH_P (operands[3])
13988    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13989   "* return output_387_binary_op (insn, operands);"
13990   [(set (attr "type") 
13991         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13992            (const_string "ssemul")
13993            (const_string "sseadd")))
13994    (set_attr "mode" "SF")])
13996 (define_insn "*fop_sf_comm_i387"
13997   [(set (match_operand:SF 0 "register_operand" "=f")
13998         (match_operator:SF 3 "binary_fp_operator"
13999                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14000                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14001   "TARGET_80387
14002    && COMMUTATIVE_ARITH_P (operands[3])
14003    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14004   "* return output_387_binary_op (insn, operands);"
14005   [(set (attr "type") 
14006         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14007            (const_string "fmul")
14008            (const_string "fop")))
14009    (set_attr "mode" "SF")])
14011 (define_insn "*fop_sf_1_mixed"
14012   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14013         (match_operator:SF 3 "binary_fp_operator"
14014                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14015                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14016   "TARGET_MIX_SSE_I387
14017    && !COMMUTATIVE_ARITH_P (operands[3])
14018    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14019   "* return output_387_binary_op (insn, operands);"
14020   [(set (attr "type") 
14021         (cond [(and (eq_attr "alternative" "2")
14022                     (match_operand:SF 3 "mult_operator" ""))
14023                  (const_string "ssemul")
14024                (and (eq_attr "alternative" "2")
14025                     (match_operand:SF 3 "div_operator" ""))
14026                  (const_string "ssediv")
14027                (eq_attr "alternative" "2")
14028                  (const_string "sseadd")
14029                (match_operand:SF 3 "mult_operator" "") 
14030                  (const_string "fmul")
14031                (match_operand:SF 3 "div_operator" "") 
14032                  (const_string "fdiv")
14033               ]
14034               (const_string "fop")))
14035    (set_attr "mode" "SF")])
14037 (define_insn "*fop_sf_1_sse"
14038   [(set (match_operand:SF 0 "register_operand" "=x")
14039         (match_operator:SF 3 "binary_fp_operator"
14040                         [(match_operand:SF 1 "register_operand" "0")
14041                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14042   "TARGET_SSE_MATH
14043    && !COMMUTATIVE_ARITH_P (operands[3])"
14044   "* return output_387_binary_op (insn, operands);"
14045   [(set (attr "type") 
14046         (cond [(match_operand:SF 3 "mult_operator" "")
14047                  (const_string "ssemul")
14048                (match_operand:SF 3 "div_operator" "")
14049                  (const_string "ssediv")
14050               ]
14051               (const_string "sseadd")))
14052    (set_attr "mode" "SF")])
14054 ;; This pattern is not fully shadowed by the pattern above.
14055 (define_insn "*fop_sf_1_i387"
14056   [(set (match_operand:SF 0 "register_operand" "=f,f")
14057         (match_operator:SF 3 "binary_fp_operator"
14058                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14059                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14060   "TARGET_80387 && !TARGET_SSE_MATH
14061    && !COMMUTATIVE_ARITH_P (operands[3])
14062    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14063   "* return output_387_binary_op (insn, operands);"
14064   [(set (attr "type") 
14065         (cond [(match_operand:SF 3 "mult_operator" "") 
14066                  (const_string "fmul")
14067                (match_operand:SF 3 "div_operator" "") 
14068                  (const_string "fdiv")
14069               ]
14070               (const_string "fop")))
14071    (set_attr "mode" "SF")])
14074 ;; ??? Add SSE splitters for these!
14075 (define_insn "*fop_sf_2_i387"
14076   [(set (match_operand:SF 0 "register_operand" "=f,f")
14077         (match_operator:SF 3 "binary_fp_operator"
14078           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14079            (match_operand:SF 2 "register_operand" "0,0")]))]
14080   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14081   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14082   [(set (attr "type") 
14083         (cond [(match_operand:SF 3 "mult_operator" "") 
14084                  (const_string "fmul")
14085                (match_operand:SF 3 "div_operator" "") 
14086                  (const_string "fdiv")
14087               ]
14088               (const_string "fop")))
14089    (set_attr "fp_int_src" "true")
14090    (set_attr "mode" "SI")])
14092 (define_insn "*fop_sf_3_i387"
14093   [(set (match_operand:SF 0 "register_operand" "=f,f")
14094         (match_operator:SF 3 "binary_fp_operator"
14095           [(match_operand:SF 1 "register_operand" "0,0")
14096            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14097   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14098   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14099   [(set (attr "type") 
14100         (cond [(match_operand:SF 3 "mult_operator" "") 
14101                  (const_string "fmul")
14102                (match_operand:SF 3 "div_operator" "") 
14103                  (const_string "fdiv")
14104               ]
14105               (const_string "fop")))
14106    (set_attr "fp_int_src" "true")
14107    (set_attr "mode" "SI")])
14109 (define_insn "*fop_df_comm_mixed"
14110   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14111         (match_operator:DF 3 "binary_fp_operator"
14112                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14113                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14114   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14115    && COMMUTATIVE_ARITH_P (operands[3])
14116    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14117   "* return output_387_binary_op (insn, operands);"
14118   [(set (attr "type") 
14119         (if_then_else (eq_attr "alternative" "1")
14120            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14121               (const_string "ssemul")
14122               (const_string "sseadd"))
14123            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14124               (const_string "fmul")
14125               (const_string "fop"))))
14126    (set_attr "mode" "DF")])
14128 (define_insn "*fop_df_comm_sse"
14129   [(set (match_operand:DF 0 "register_operand" "=Y")
14130         (match_operator:DF 3 "binary_fp_operator"
14131                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14132                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14133   "TARGET_SSE2 && TARGET_SSE_MATH
14134    && COMMUTATIVE_ARITH_P (operands[3])
14135    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14136   "* return output_387_binary_op (insn, operands);"
14137   [(set (attr "type") 
14138         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14139            (const_string "ssemul")
14140            (const_string "sseadd")))
14141    (set_attr "mode" "DF")])
14143 (define_insn "*fop_df_comm_i387"
14144   [(set (match_operand:DF 0 "register_operand" "=f")
14145         (match_operator:DF 3 "binary_fp_operator"
14146                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14147                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14148   "TARGET_80387
14149    && COMMUTATIVE_ARITH_P (operands[3])
14150    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14151   "* return output_387_binary_op (insn, operands);"
14152   [(set (attr "type") 
14153         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14154            (const_string "fmul")
14155            (const_string "fop")))
14156    (set_attr "mode" "DF")])
14158 (define_insn "*fop_df_1_mixed"
14159   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14160         (match_operator:DF 3 "binary_fp_operator"
14161                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14162                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14163   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14164    && !COMMUTATIVE_ARITH_P (operands[3])
14165    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14166   "* return output_387_binary_op (insn, operands);"
14167   [(set (attr "type") 
14168         (cond [(and (eq_attr "alternative" "2")
14169                     (match_operand:SF 3 "mult_operator" ""))
14170                  (const_string "ssemul")
14171                (and (eq_attr "alternative" "2")
14172                     (match_operand:SF 3 "div_operator" ""))
14173                  (const_string "ssediv")
14174                (eq_attr "alternative" "2")
14175                  (const_string "sseadd")
14176                (match_operand:DF 3 "mult_operator" "") 
14177                  (const_string "fmul")
14178                (match_operand:DF 3 "div_operator" "") 
14179                  (const_string "fdiv")
14180               ]
14181               (const_string "fop")))
14182    (set_attr "mode" "DF")])
14184 (define_insn "*fop_df_1_sse"
14185   [(set (match_operand:DF 0 "register_operand" "=Y")
14186         (match_operator:DF 3 "binary_fp_operator"
14187                         [(match_operand:DF 1 "register_operand" "0")
14188                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14189   "TARGET_SSE2 && TARGET_SSE_MATH
14190    && !COMMUTATIVE_ARITH_P (operands[3])"
14191   "* return output_387_binary_op (insn, operands);"
14192   [(set_attr "mode" "DF")
14193    (set (attr "type") 
14194         (cond [(match_operand:SF 3 "mult_operator" "")
14195                  (const_string "ssemul")
14196                (match_operand:SF 3 "div_operator" "")
14197                  (const_string "ssediv")
14198               ]
14199               (const_string "sseadd")))])
14201 ;; This pattern is not fully shadowed by the pattern above.
14202 (define_insn "*fop_df_1_i387"
14203   [(set (match_operand:DF 0 "register_operand" "=f,f")
14204         (match_operator:DF 3 "binary_fp_operator"
14205                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14206                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14207   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14208    && !COMMUTATIVE_ARITH_P (operands[3])
14209    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14210   "* return output_387_binary_op (insn, operands);"
14211   [(set (attr "type") 
14212         (cond [(match_operand:DF 3 "mult_operator" "") 
14213                  (const_string "fmul")
14214                (match_operand:DF 3 "div_operator" "")
14215                  (const_string "fdiv")
14216               ]
14217               (const_string "fop")))
14218    (set_attr "mode" "DF")])
14220 ;; ??? Add SSE splitters for these!
14221 (define_insn "*fop_df_2_i387"
14222   [(set (match_operand:DF 0 "register_operand" "=f,f")
14223         (match_operator:DF 3 "binary_fp_operator"
14224            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14225             (match_operand:DF 2 "register_operand" "0,0")]))]
14226   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14227   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14228   [(set (attr "type") 
14229         (cond [(match_operand:DF 3 "mult_operator" "") 
14230                  (const_string "fmul")
14231                (match_operand:DF 3 "div_operator" "") 
14232                  (const_string "fdiv")
14233               ]
14234               (const_string "fop")))
14235    (set_attr "fp_int_src" "true")
14236    (set_attr "mode" "SI")])
14238 (define_insn "*fop_df_3_i387"
14239   [(set (match_operand:DF 0 "register_operand" "=f,f")
14240         (match_operator:DF 3 "binary_fp_operator"
14241            [(match_operand:DF 1 "register_operand" "0,0")
14242             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14243   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14244   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14245   [(set (attr "type") 
14246         (cond [(match_operand:DF 3 "mult_operator" "") 
14247                  (const_string "fmul")
14248                (match_operand:DF 3 "div_operator" "") 
14249                  (const_string "fdiv")
14250               ]
14251               (const_string "fop")))
14252    (set_attr "fp_int_src" "true")
14253    (set_attr "mode" "SI")])
14255 (define_insn "*fop_df_4_i387"
14256   [(set (match_operand:DF 0 "register_operand" "=f,f")
14257         (match_operator:DF 3 "binary_fp_operator"
14258            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14259             (match_operand:DF 2 "register_operand" "0,f")]))]
14260   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14261    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14262   "* return output_387_binary_op (insn, operands);"
14263   [(set (attr "type") 
14264         (cond [(match_operand:DF 3 "mult_operator" "") 
14265                  (const_string "fmul")
14266                (match_operand:DF 3 "div_operator" "") 
14267                  (const_string "fdiv")
14268               ]
14269               (const_string "fop")))
14270    (set_attr "mode" "SF")])
14272 (define_insn "*fop_df_5_i387"
14273   [(set (match_operand:DF 0 "register_operand" "=f,f")
14274         (match_operator:DF 3 "binary_fp_operator"
14275           [(match_operand:DF 1 "register_operand" "0,f")
14276            (float_extend:DF
14277             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14278   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14279   "* return output_387_binary_op (insn, operands);"
14280   [(set (attr "type") 
14281         (cond [(match_operand:DF 3 "mult_operator" "") 
14282                  (const_string "fmul")
14283                (match_operand:DF 3 "div_operator" "") 
14284                  (const_string "fdiv")
14285               ]
14286               (const_string "fop")))
14287    (set_attr "mode" "SF")])
14289 (define_insn "*fop_df_6_i387"
14290   [(set (match_operand:DF 0 "register_operand" "=f,f")
14291         (match_operator:DF 3 "binary_fp_operator"
14292           [(float_extend:DF
14293             (match_operand:SF 1 "register_operand" "0,f"))
14294            (float_extend:DF
14295             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14296   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14297   "* return output_387_binary_op (insn, operands);"
14298   [(set (attr "type") 
14299         (cond [(match_operand:DF 3 "mult_operator" "") 
14300                  (const_string "fmul")
14301                (match_operand:DF 3 "div_operator" "") 
14302                  (const_string "fdiv")
14303               ]
14304               (const_string "fop")))
14305    (set_attr "mode" "SF")])
14307 (define_insn "*fop_xf_comm_i387"
14308   [(set (match_operand:XF 0 "register_operand" "=f")
14309         (match_operator:XF 3 "binary_fp_operator"
14310                         [(match_operand:XF 1 "register_operand" "%0")
14311                          (match_operand:XF 2 "register_operand" "f")]))]
14312   "TARGET_80387
14313    && COMMUTATIVE_ARITH_P (operands[3])"
14314   "* return output_387_binary_op (insn, operands);"
14315   [(set (attr "type") 
14316         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14317            (const_string "fmul")
14318            (const_string "fop")))
14319    (set_attr "mode" "XF")])
14321 (define_insn "*fop_xf_1_i387"
14322   [(set (match_operand:XF 0 "register_operand" "=f,f")
14323         (match_operator:XF 3 "binary_fp_operator"
14324                         [(match_operand:XF 1 "register_operand" "0,f")
14325                          (match_operand:XF 2 "register_operand" "f,0")]))]
14326   "TARGET_80387
14327    && !COMMUTATIVE_ARITH_P (operands[3])"
14328   "* return output_387_binary_op (insn, operands);"
14329   [(set (attr "type") 
14330         (cond [(match_operand:XF 3 "mult_operator" "") 
14331                  (const_string "fmul")
14332                (match_operand:XF 3 "div_operator" "") 
14333                  (const_string "fdiv")
14334               ]
14335               (const_string "fop")))
14336    (set_attr "mode" "XF")])
14338 (define_insn "*fop_xf_2_i387"
14339   [(set (match_operand:XF 0 "register_operand" "=f,f")
14340         (match_operator:XF 3 "binary_fp_operator"
14341            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14342             (match_operand:XF 2 "register_operand" "0,0")]))]
14343   "TARGET_80387 && TARGET_USE_FIOP"
14344   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14345   [(set (attr "type") 
14346         (cond [(match_operand:XF 3 "mult_operator" "") 
14347                  (const_string "fmul")
14348                (match_operand:XF 3 "div_operator" "") 
14349                  (const_string "fdiv")
14350               ]
14351               (const_string "fop")))
14352    (set_attr "fp_int_src" "true")
14353    (set_attr "mode" "SI")])
14355 (define_insn "*fop_xf_3_i387"
14356   [(set (match_operand:XF 0 "register_operand" "=f,f")
14357         (match_operator:XF 3 "binary_fp_operator"
14358           [(match_operand:XF 1 "register_operand" "0,0")
14359            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14360   "TARGET_80387 && TARGET_USE_FIOP"
14361   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14362   [(set (attr "type") 
14363         (cond [(match_operand:XF 3 "mult_operator" "") 
14364                  (const_string "fmul")
14365                (match_operand:XF 3 "div_operator" "") 
14366                  (const_string "fdiv")
14367               ]
14368               (const_string "fop")))
14369    (set_attr "fp_int_src" "true")
14370    (set_attr "mode" "SI")])
14372 (define_insn "*fop_xf_4_i387"
14373   [(set (match_operand:XF 0 "register_operand" "=f,f")
14374         (match_operator:XF 3 "binary_fp_operator"
14375            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14376             (match_operand:XF 2 "register_operand" "0,f")]))]
14377   "TARGET_80387"
14378   "* return output_387_binary_op (insn, operands);"
14379   [(set (attr "type") 
14380         (cond [(match_operand:XF 3 "mult_operator" "") 
14381                  (const_string "fmul")
14382                (match_operand:XF 3 "div_operator" "") 
14383                  (const_string "fdiv")
14384               ]
14385               (const_string "fop")))
14386    (set_attr "mode" "SF")])
14388 (define_insn "*fop_xf_5_i387"
14389   [(set (match_operand:XF 0 "register_operand" "=f,f")
14390         (match_operator:XF 3 "binary_fp_operator"
14391           [(match_operand:XF 1 "register_operand" "0,f")
14392            (float_extend:XF
14393             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14394   "TARGET_80387"
14395   "* return output_387_binary_op (insn, operands);"
14396   [(set (attr "type") 
14397         (cond [(match_operand:XF 3 "mult_operator" "") 
14398                  (const_string "fmul")
14399                (match_operand:XF 3 "div_operator" "") 
14400                  (const_string "fdiv")
14401               ]
14402               (const_string "fop")))
14403    (set_attr "mode" "SF")])
14405 (define_insn "*fop_xf_6_i387"
14406   [(set (match_operand:XF 0 "register_operand" "=f,f")
14407         (match_operator:XF 3 "binary_fp_operator"
14408           [(float_extend:XF
14409             (match_operand 1 "register_operand" "0,f"))
14410            (float_extend:XF
14411             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14412   "TARGET_80387"
14413   "* return output_387_binary_op (insn, operands);"
14414   [(set (attr "type") 
14415         (cond [(match_operand:XF 3 "mult_operator" "") 
14416                  (const_string "fmul")
14417                (match_operand:XF 3 "div_operator" "") 
14418                  (const_string "fdiv")
14419               ]
14420               (const_string "fop")))
14421    (set_attr "mode" "SF")])
14423 (define_split
14424   [(set (match_operand 0 "register_operand" "")
14425         (match_operator 3 "binary_fp_operator"
14426            [(float (match_operand:SI 1 "register_operand" ""))
14427             (match_operand 2 "register_operand" "")]))]
14428   "TARGET_80387 && reload_completed
14429    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14430   [(const_int 0)]
14432   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14433   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14434   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14435                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14436                                           GET_MODE (operands[3]),
14437                                           operands[4],
14438                                           operands[2])));
14439   ix86_free_from_memory (GET_MODE (operands[1]));
14440   DONE;
14443 (define_split
14444   [(set (match_operand 0 "register_operand" "")
14445         (match_operator 3 "binary_fp_operator"
14446            [(match_operand 1 "register_operand" "")
14447             (float (match_operand:SI 2 "register_operand" ""))]))]
14448   "TARGET_80387 && reload_completed
14449    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14450   [(const_int 0)]
14452   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14453   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14454   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14455                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14456                                           GET_MODE (operands[3]),
14457                                           operands[1],
14458                                           operands[4])));
14459   ix86_free_from_memory (GET_MODE (operands[2]));
14460   DONE;
14463 ;; FPU special functions.
14465 (define_expand "sqrtsf2"
14466   [(set (match_operand:SF 0 "register_operand" "")
14467         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14468   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14470   if (!TARGET_SSE_MATH)
14471     operands[1] = force_reg (SFmode, operands[1]);
14474 (define_insn "*sqrtsf2_mixed"
14475   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14476         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14477   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14478   "@
14479    fsqrt
14480    sqrtss\t{%1, %0|%0, %1}"
14481   [(set_attr "type" "fpspc,sse")
14482    (set_attr "mode" "SF,SF")
14483    (set_attr "athlon_decode" "direct,*")])
14485 (define_insn "*sqrtsf2_sse"
14486   [(set (match_operand:SF 0 "register_operand" "=x")
14487         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14488   "TARGET_SSE_MATH"
14489   "sqrtss\t{%1, %0|%0, %1}"
14490   [(set_attr "type" "sse")
14491    (set_attr "mode" "SF")
14492    (set_attr "athlon_decode" "*")])
14494 (define_insn "*sqrtsf2_i387"
14495   [(set (match_operand:SF 0 "register_operand" "=f")
14496         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14497   "TARGET_USE_FANCY_MATH_387"
14498   "fsqrt"
14499   [(set_attr "type" "fpspc")
14500    (set_attr "mode" "SF")
14501    (set_attr "athlon_decode" "direct")])
14503 (define_expand "sqrtdf2"
14504   [(set (match_operand:DF 0 "register_operand" "")
14505         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14506   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14508   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14509     operands[1] = force_reg (DFmode, operands[1]);
14512 (define_insn "*sqrtdf2_mixed"
14513   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14514         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14515   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14516   "@
14517    fsqrt
14518    sqrtsd\t{%1, %0|%0, %1}"
14519   [(set_attr "type" "fpspc,sse")
14520    (set_attr "mode" "DF,DF")
14521    (set_attr "athlon_decode" "direct,*")])
14523 (define_insn "*sqrtdf2_sse"
14524   [(set (match_operand:DF 0 "register_operand" "=Y")
14525         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14526   "TARGET_SSE2 && TARGET_SSE_MATH"
14527   "sqrtsd\t{%1, %0|%0, %1}"
14528   [(set_attr "type" "sse")
14529    (set_attr "mode" "DF")
14530    (set_attr "athlon_decode" "*")])
14532 (define_insn "*sqrtdf2_i387"
14533   [(set (match_operand:DF 0 "register_operand" "=f")
14534         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14535   "TARGET_USE_FANCY_MATH_387"
14536   "fsqrt"
14537   [(set_attr "type" "fpspc")
14538    (set_attr "mode" "DF")
14539    (set_attr "athlon_decode" "direct")])
14541 (define_insn "*sqrtextendsfdf2_i387"
14542   [(set (match_operand:DF 0 "register_operand" "=f")
14543         (sqrt:DF (float_extend:DF
14544                   (match_operand:SF 1 "register_operand" "0"))))]
14545   "TARGET_USE_FANCY_MATH_387
14546    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14547   "fsqrt"
14548   [(set_attr "type" "fpspc")
14549    (set_attr "mode" "DF")
14550    (set_attr "athlon_decode" "direct")])
14552 (define_insn "sqrtxf2"
14553   [(set (match_operand:XF 0 "register_operand" "=f")
14554         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14555   "TARGET_USE_FANCY_MATH_387 
14556    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14557   "fsqrt"
14558   [(set_attr "type" "fpspc")
14559    (set_attr "mode" "XF")
14560    (set_attr "athlon_decode" "direct")])
14562 (define_insn "*sqrtextendsfxf2_i387"
14563   [(set (match_operand:XF 0 "register_operand" "=f")
14564         (sqrt:XF (float_extend:XF
14565                   (match_operand:SF 1 "register_operand" "0"))))]
14566   "TARGET_USE_FANCY_MATH_387"
14567   "fsqrt"
14568   [(set_attr "type" "fpspc")
14569    (set_attr "mode" "XF")
14570    (set_attr "athlon_decode" "direct")])
14572 (define_insn "*sqrtextenddfxf2_i387"
14573   [(set (match_operand:XF 0 "register_operand" "=f")
14574         (sqrt:XF (float_extend:XF
14575                   (match_operand:DF 1 "register_operand" "0"))))]
14576   "TARGET_USE_FANCY_MATH_387"
14577   "fsqrt"
14578   [(set_attr "type" "fpspc")
14579    (set_attr "mode" "XF")
14580    (set_attr "athlon_decode" "direct")])
14582 (define_insn "fpremxf4"
14583   [(set (match_operand:XF 0 "register_operand" "=f")
14584         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14585                     (match_operand:XF 3 "register_operand" "1")]
14586                    UNSPEC_FPREM_F))
14587    (set (match_operand:XF 1 "register_operand" "=u")
14588         (unspec:XF [(match_dup 2) (match_dup 3)]
14589                    UNSPEC_FPREM_U))
14590    (set (reg:CCFP FPSR_REG)
14591         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14592   "TARGET_USE_FANCY_MATH_387
14593    && flag_unsafe_math_optimizations"
14594   "fprem"
14595   [(set_attr "type" "fpspc")
14596    (set_attr "mode" "XF")])
14598 (define_expand "fmodsf3"
14599   [(use (match_operand:SF 0 "register_operand" ""))
14600    (use (match_operand:SF 1 "register_operand" ""))
14601    (use (match_operand:SF 2 "register_operand" ""))]
14602   "TARGET_USE_FANCY_MATH_387
14603    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14604    && flag_unsafe_math_optimizations"
14606   rtx label = gen_label_rtx ();
14608   rtx op1 = gen_reg_rtx (XFmode);
14609   rtx op2 = gen_reg_rtx (XFmode);
14611   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14612   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14614   emit_label (label);
14616   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14617   ix86_emit_fp_unordered_jump (label);
14619   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14620   DONE;
14623 (define_expand "fmoddf3"
14624   [(use (match_operand:DF 0 "register_operand" ""))
14625    (use (match_operand:DF 1 "register_operand" ""))
14626    (use (match_operand:DF 2 "register_operand" ""))]
14627   "TARGET_USE_FANCY_MATH_387
14628    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14629    && flag_unsafe_math_optimizations"
14631   rtx label = gen_label_rtx ();
14633   rtx op1 = gen_reg_rtx (XFmode);
14634   rtx op2 = gen_reg_rtx (XFmode);
14636   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14637   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14639   emit_label (label);
14641   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14642   ix86_emit_fp_unordered_jump (label);
14644   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14645   DONE;
14648 (define_expand "fmodxf3"
14649   [(use (match_operand:XF 0 "register_operand" ""))
14650    (use (match_operand:XF 1 "register_operand" ""))
14651    (use (match_operand:XF 2 "register_operand" ""))]
14652   "TARGET_USE_FANCY_MATH_387
14653    && flag_unsafe_math_optimizations"
14655   rtx label = gen_label_rtx ();
14657   emit_label (label);
14659   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14660                            operands[1], operands[2]));
14661   ix86_emit_fp_unordered_jump (label);
14663   emit_move_insn (operands[0], operands[1]);
14664   DONE;
14667 (define_insn "fprem1xf4"
14668   [(set (match_operand:XF 0 "register_operand" "=f")
14669         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14670                     (match_operand:XF 3 "register_operand" "1")]
14671                    UNSPEC_FPREM1_F))
14672    (set (match_operand:XF 1 "register_operand" "=u")
14673         (unspec:XF [(match_dup 2) (match_dup 3)]
14674                    UNSPEC_FPREM1_U))
14675    (set (reg:CCFP FPSR_REG)
14676         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14677   "TARGET_USE_FANCY_MATH_387
14678    && flag_unsafe_math_optimizations"
14679   "fprem1"
14680   [(set_attr "type" "fpspc")
14681    (set_attr "mode" "XF")])
14683 (define_expand "dremsf3"
14684   [(use (match_operand:SF 0 "register_operand" ""))
14685    (use (match_operand:SF 1 "register_operand" ""))
14686    (use (match_operand:SF 2 "register_operand" ""))]
14687   "TARGET_USE_FANCY_MATH_387
14688    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14689    && flag_unsafe_math_optimizations"
14691   rtx label = gen_label_rtx ();
14693   rtx op1 = gen_reg_rtx (XFmode);
14694   rtx op2 = gen_reg_rtx (XFmode);
14696   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14697   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14699   emit_label (label);
14701   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14702   ix86_emit_fp_unordered_jump (label);
14704   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14705   DONE;
14708 (define_expand "dremdf3"
14709   [(use (match_operand:DF 0 "register_operand" ""))
14710    (use (match_operand:DF 1 "register_operand" ""))
14711    (use (match_operand:DF 2 "register_operand" ""))]
14712   "TARGET_USE_FANCY_MATH_387
14713    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14714    && flag_unsafe_math_optimizations"
14716   rtx label = gen_label_rtx ();
14718   rtx op1 = gen_reg_rtx (XFmode);
14719   rtx op2 = gen_reg_rtx (XFmode);
14721   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14722   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14724   emit_label (label);
14726   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14727   ix86_emit_fp_unordered_jump (label);
14729   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14730   DONE;
14733 (define_expand "dremxf3"
14734   [(use (match_operand:XF 0 "register_operand" ""))
14735    (use (match_operand:XF 1 "register_operand" ""))
14736    (use (match_operand:XF 2 "register_operand" ""))]
14737   "TARGET_USE_FANCY_MATH_387
14738    && flag_unsafe_math_optimizations"
14740   rtx label = gen_label_rtx ();
14742   emit_label (label);
14744   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14745                             operands[1], operands[2]));
14746   ix86_emit_fp_unordered_jump (label);
14748   emit_move_insn (operands[0], operands[1]);
14749   DONE;
14752 (define_insn "*sindf2"
14753   [(set (match_operand:DF 0 "register_operand" "=f")
14754         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14755   "TARGET_USE_FANCY_MATH_387
14756    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14757    && flag_unsafe_math_optimizations"
14758   "fsin"
14759   [(set_attr "type" "fpspc")
14760    (set_attr "mode" "DF")])
14762 (define_insn "*sinsf2"
14763   [(set (match_operand:SF 0 "register_operand" "=f")
14764         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14765   "TARGET_USE_FANCY_MATH_387
14766    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14767    && flag_unsafe_math_optimizations"
14768   "fsin"
14769   [(set_attr "type" "fpspc")
14770    (set_attr "mode" "SF")])
14772 (define_insn "*sinextendsfdf2"
14773   [(set (match_operand:DF 0 "register_operand" "=f")
14774         (unspec:DF [(float_extend:DF
14775                      (match_operand:SF 1 "register_operand" "0"))]
14776                    UNSPEC_SIN))]
14777   "TARGET_USE_FANCY_MATH_387
14778    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14779    && flag_unsafe_math_optimizations"
14780   "fsin"
14781   [(set_attr "type" "fpspc")
14782    (set_attr "mode" "DF")])
14784 (define_insn "*sinxf2"
14785   [(set (match_operand:XF 0 "register_operand" "=f")
14786         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14787   "TARGET_USE_FANCY_MATH_387
14788    && flag_unsafe_math_optimizations"
14789   "fsin"
14790   [(set_attr "type" "fpspc")
14791    (set_attr "mode" "XF")])
14793 (define_insn "*cosdf2"
14794   [(set (match_operand:DF 0 "register_operand" "=f")
14795         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14796   "TARGET_USE_FANCY_MATH_387
14797    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14798    && flag_unsafe_math_optimizations"
14799   "fcos"
14800   [(set_attr "type" "fpspc")
14801    (set_attr "mode" "DF")])
14803 (define_insn "*cossf2"
14804   [(set (match_operand:SF 0 "register_operand" "=f")
14805         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14806   "TARGET_USE_FANCY_MATH_387
14807    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14808    && flag_unsafe_math_optimizations"
14809   "fcos"
14810   [(set_attr "type" "fpspc")
14811    (set_attr "mode" "SF")])
14813 (define_insn "*cosextendsfdf2"
14814   [(set (match_operand:DF 0 "register_operand" "=f")
14815         (unspec:DF [(float_extend:DF
14816                      (match_operand:SF 1 "register_operand" "0"))]
14817                    UNSPEC_COS))]
14818   "TARGET_USE_FANCY_MATH_387
14819    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14820    && flag_unsafe_math_optimizations"
14821   "fcos"
14822   [(set_attr "type" "fpspc")
14823    (set_attr "mode" "DF")])
14825 (define_insn "*cosxf2"
14826   [(set (match_operand:XF 0 "register_operand" "=f")
14827         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14828   "TARGET_USE_FANCY_MATH_387
14829    && flag_unsafe_math_optimizations"
14830   "fcos"
14831   [(set_attr "type" "fpspc")
14832    (set_attr "mode" "XF")])
14834 ;; With sincos pattern defined, sin and cos builtin function will be
14835 ;; expanded to sincos pattern with one of its outputs left unused. 
14836 ;; Cse pass  will detected, if two sincos patterns can be combined,
14837 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14838 ;; depending on the unused output.
14840 (define_insn "sincosdf3"
14841   [(set (match_operand:DF 0 "register_operand" "=f")
14842         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14843                    UNSPEC_SINCOS_COS))
14844    (set (match_operand:DF 1 "register_operand" "=u")
14845         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14846   "TARGET_USE_FANCY_MATH_387
14847    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14848    && flag_unsafe_math_optimizations"
14849   "fsincos"
14850   [(set_attr "type" "fpspc")
14851    (set_attr "mode" "DF")])
14853 (define_split
14854   [(set (match_operand:DF 0 "register_operand" "")
14855         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14856                    UNSPEC_SINCOS_COS))
14857    (set (match_operand:DF 1 "register_operand" "")
14858         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14859   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14860    && !reload_completed && !reload_in_progress"
14861   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14862   "")
14864 (define_split
14865   [(set (match_operand:DF 0 "register_operand" "")
14866         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14867                    UNSPEC_SINCOS_COS))
14868    (set (match_operand:DF 1 "register_operand" "")
14869         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14870   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14871    && !reload_completed && !reload_in_progress"
14872   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14873   "")
14875 (define_insn "sincossf3"
14876   [(set (match_operand:SF 0 "register_operand" "=f")
14877         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14878                    UNSPEC_SINCOS_COS))
14879    (set (match_operand:SF 1 "register_operand" "=u")
14880         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14881   "TARGET_USE_FANCY_MATH_387
14882    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14883    && flag_unsafe_math_optimizations"
14884   "fsincos"
14885   [(set_attr "type" "fpspc")
14886    (set_attr "mode" "SF")])
14888 (define_split
14889   [(set (match_operand:SF 0 "register_operand" "")
14890         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14891                    UNSPEC_SINCOS_COS))
14892    (set (match_operand:SF 1 "register_operand" "")
14893         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14894   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14895    && !reload_completed && !reload_in_progress"
14896   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14897   "")
14899 (define_split
14900   [(set (match_operand:SF 0 "register_operand" "")
14901         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14902                    UNSPEC_SINCOS_COS))
14903    (set (match_operand:SF 1 "register_operand" "")
14904         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14905   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14906    && !reload_completed && !reload_in_progress"
14907   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14908   "")
14910 (define_insn "*sincosextendsfdf3"
14911   [(set (match_operand:DF 0 "register_operand" "=f")
14912         (unspec:DF [(float_extend:DF
14913                      (match_operand:SF 2 "register_operand" "0"))]
14914                    UNSPEC_SINCOS_COS))
14915    (set (match_operand:DF 1 "register_operand" "=u")
14916         (unspec:DF [(float_extend:DF
14917                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14918   "TARGET_USE_FANCY_MATH_387
14919    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14920    && flag_unsafe_math_optimizations"
14921   "fsincos"
14922   [(set_attr "type" "fpspc")
14923    (set_attr "mode" "DF")])
14925 (define_split
14926   [(set (match_operand:DF 0 "register_operand" "")
14927         (unspec:DF [(float_extend:DF
14928                      (match_operand:SF 2 "register_operand" ""))]
14929                    UNSPEC_SINCOS_COS))
14930    (set (match_operand:DF 1 "register_operand" "")
14931         (unspec:DF [(float_extend:DF
14932                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14933   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14934    && !reload_completed && !reload_in_progress"
14935   [(set (match_dup 1) (unspec:DF [(float_extend:DF
14936                                    (match_dup 2))] UNSPEC_SIN))]
14937   "")
14939 (define_split
14940   [(set (match_operand:DF 0 "register_operand" "")
14941         (unspec:DF [(float_extend:DF
14942                      (match_operand:SF 2 "register_operand" ""))]
14943                    UNSPEC_SINCOS_COS))
14944    (set (match_operand:DF 1 "register_operand" "")
14945         (unspec:DF [(float_extend:DF
14946                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14947   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14948    && !reload_completed && !reload_in_progress"
14949   [(set (match_dup 0) (unspec:DF [(float_extend:DF
14950                                    (match_dup 2))] UNSPEC_COS))]
14951   "")
14953 (define_insn "sincosxf3"
14954   [(set (match_operand:XF 0 "register_operand" "=f")
14955         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14956                    UNSPEC_SINCOS_COS))
14957    (set (match_operand:XF 1 "register_operand" "=u")
14958         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14959   "TARGET_USE_FANCY_MATH_387
14960    && flag_unsafe_math_optimizations"
14961   "fsincos"
14962   [(set_attr "type" "fpspc")
14963    (set_attr "mode" "XF")])
14965 (define_split
14966   [(set (match_operand:XF 0 "register_operand" "")
14967         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14968                    UNSPEC_SINCOS_COS))
14969    (set (match_operand:XF 1 "register_operand" "")
14970         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14971   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14972    && !reload_completed && !reload_in_progress"
14973   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
14974   "")
14976 (define_split
14977   [(set (match_operand:XF 0 "register_operand" "")
14978         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14979                    UNSPEC_SINCOS_COS))
14980    (set (match_operand:XF 1 "register_operand" "")
14981         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14982   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14983    && !reload_completed && !reload_in_progress"
14984   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
14985   "")
14987 (define_insn "*tandf3_1"
14988   [(set (match_operand:DF 0 "register_operand" "=f")
14989         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14990                    UNSPEC_TAN_ONE))
14991    (set (match_operand:DF 1 "register_operand" "=u")
14992         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
14993   "TARGET_USE_FANCY_MATH_387
14994    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14995    && flag_unsafe_math_optimizations"
14996   "fptan"
14997   [(set_attr "type" "fpspc")
14998    (set_attr "mode" "DF")])
15000 ;; optimize sequence: fptan
15001 ;;                    fstp    %st(0)
15002 ;;                    fld1
15003 ;; into fptan insn.
15005 (define_peephole2
15006   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15007                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15008                              UNSPEC_TAN_ONE))
15009              (set (match_operand:DF 1 "register_operand" "")
15010                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15011    (set (match_dup 0)
15012         (match_operand:DF 3 "immediate_operand" ""))]
15013   "standard_80387_constant_p (operands[3]) == 2"
15014   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15015              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15016   "")
15018 (define_expand "tandf2"
15019   [(parallel [(set (match_dup 2)
15020                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15021                               UNSPEC_TAN_ONE))
15022               (set (match_operand:DF 0 "register_operand" "")
15023                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15024   "TARGET_USE_FANCY_MATH_387
15025    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15026    && flag_unsafe_math_optimizations"
15028   operands[2] = gen_reg_rtx (DFmode);
15031 (define_insn "*tansf3_1"
15032   [(set (match_operand:SF 0 "register_operand" "=f")
15033         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15034                    UNSPEC_TAN_ONE))
15035    (set (match_operand:SF 1 "register_operand" "=u")
15036         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15037   "TARGET_USE_FANCY_MATH_387
15038    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15039    && flag_unsafe_math_optimizations"
15040   "fptan"
15041   [(set_attr "type" "fpspc")
15042    (set_attr "mode" "SF")])
15044 ;; optimize sequence: fptan
15045 ;;                    fstp    %st(0)
15046 ;;                    fld1
15047 ;; into fptan insn.
15049 (define_peephole2
15050   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15051                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15052                              UNSPEC_TAN_ONE))
15053              (set (match_operand:SF 1 "register_operand" "")
15054                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15055    (set (match_dup 0)
15056         (match_operand:SF 3 "immediate_operand" ""))]
15057   "standard_80387_constant_p (operands[3]) == 2"
15058   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15059              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15060   "")
15062 (define_expand "tansf2"
15063   [(parallel [(set (match_dup 2)
15064                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15065                               UNSPEC_TAN_ONE))
15066               (set (match_operand:SF 0 "register_operand" "")
15067                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15068   "TARGET_USE_FANCY_MATH_387
15069    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15070    && flag_unsafe_math_optimizations"
15072   operands[2] = gen_reg_rtx (SFmode);
15075 (define_insn "*tanxf3_1"
15076   [(set (match_operand:XF 0 "register_operand" "=f")
15077         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15078                    UNSPEC_TAN_ONE))
15079    (set (match_operand:XF 1 "register_operand" "=u")
15080         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15081   "TARGET_USE_FANCY_MATH_387
15082    && flag_unsafe_math_optimizations"
15083   "fptan"
15084   [(set_attr "type" "fpspc")
15085    (set_attr "mode" "XF")])
15087 ;; optimize sequence: fptan
15088 ;;                    fstp    %st(0)
15089 ;;                    fld1
15090 ;; into fptan insn.
15092 (define_peephole2
15093   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15094                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15095                              UNSPEC_TAN_ONE))
15096              (set (match_operand:XF 1 "register_operand" "")
15097                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15098    (set (match_dup 0)
15099         (match_operand:XF 3 "immediate_operand" ""))]
15100   "standard_80387_constant_p (operands[3]) == 2"
15101   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15102              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15103   "")
15105 (define_expand "tanxf2"
15106   [(parallel [(set (match_dup 2)
15107                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15108                               UNSPEC_TAN_ONE))
15109               (set (match_operand:XF 0 "register_operand" "")
15110                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15111   "TARGET_USE_FANCY_MATH_387
15112    && flag_unsafe_math_optimizations"
15114   operands[2] = gen_reg_rtx (XFmode);
15117 (define_insn "atan2df3_1"
15118   [(set (match_operand:DF 0 "register_operand" "=f")
15119         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15120                     (match_operand:DF 1 "register_operand" "u")]
15121                    UNSPEC_FPATAN))
15122    (clobber (match_scratch:DF 3 "=1"))]
15123   "TARGET_USE_FANCY_MATH_387
15124    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15125    && flag_unsafe_math_optimizations"
15126   "fpatan"
15127   [(set_attr "type" "fpspc")
15128    (set_attr "mode" "DF")])
15130 (define_expand "atan2df3"
15131   [(use (match_operand:DF 0 "register_operand" ""))
15132    (use (match_operand:DF 2 "register_operand" ""))
15133    (use (match_operand:DF 1 "register_operand" ""))]
15134   "TARGET_USE_FANCY_MATH_387
15135    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15136    && flag_unsafe_math_optimizations"
15138   rtx copy = gen_reg_rtx (DFmode);
15139   emit_move_insn (copy, operands[1]);
15140   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15141   DONE;
15144 (define_expand "atandf2"
15145   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15146                    (unspec:DF [(match_dup 2)
15147                                (match_operand:DF 1 "register_operand" "")]
15148                     UNSPEC_FPATAN))
15149               (clobber (match_scratch:DF 3 ""))])]
15150   "TARGET_USE_FANCY_MATH_387
15151    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15152    && flag_unsafe_math_optimizations"
15154   operands[2] = gen_reg_rtx (DFmode);
15155   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15158 (define_insn "atan2sf3_1"
15159   [(set (match_operand:SF 0 "register_operand" "=f")
15160         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15161                     (match_operand:SF 1 "register_operand" "u")]
15162                    UNSPEC_FPATAN))
15163    (clobber (match_scratch:SF 3 "=1"))]
15164   "TARGET_USE_FANCY_MATH_387
15165    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15166    && flag_unsafe_math_optimizations"
15167   "fpatan"
15168   [(set_attr "type" "fpspc")
15169    (set_attr "mode" "SF")])
15171 (define_expand "atan2sf3"
15172   [(use (match_operand:SF 0 "register_operand" ""))
15173    (use (match_operand:SF 2 "register_operand" ""))
15174    (use (match_operand:SF 1 "register_operand" ""))]
15175   "TARGET_USE_FANCY_MATH_387
15176    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15177    && flag_unsafe_math_optimizations"
15179   rtx copy = gen_reg_rtx (SFmode);
15180   emit_move_insn (copy, operands[1]);
15181   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15182   DONE;
15185 (define_expand "atansf2"
15186   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15187                    (unspec:SF [(match_dup 2)
15188                                (match_operand:SF 1 "register_operand" "")]
15189                     UNSPEC_FPATAN))
15190               (clobber (match_scratch:SF 3 ""))])]
15191   "TARGET_USE_FANCY_MATH_387
15192    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15193    && flag_unsafe_math_optimizations"
15195   operands[2] = gen_reg_rtx (SFmode);
15196   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15199 (define_insn "atan2xf3_1"
15200   [(set (match_operand:XF 0 "register_operand" "=f")
15201         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15202                     (match_operand:XF 1 "register_operand" "u")]
15203                    UNSPEC_FPATAN))
15204    (clobber (match_scratch:XF 3 "=1"))]
15205   "TARGET_USE_FANCY_MATH_387
15206    && flag_unsafe_math_optimizations"
15207   "fpatan"
15208   [(set_attr "type" "fpspc")
15209    (set_attr "mode" "XF")])
15211 (define_expand "atan2xf3"
15212   [(use (match_operand:XF 0 "register_operand" ""))
15213    (use (match_operand:XF 2 "register_operand" ""))
15214    (use (match_operand:XF 1 "register_operand" ""))]
15215   "TARGET_USE_FANCY_MATH_387
15216    && flag_unsafe_math_optimizations"
15218   rtx copy = gen_reg_rtx (XFmode);
15219   emit_move_insn (copy, operands[1]);
15220   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15221   DONE;
15224 (define_expand "atanxf2"
15225   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15226                    (unspec:XF [(match_dup 2)
15227                                (match_operand:XF 1 "register_operand" "")]
15228                     UNSPEC_FPATAN))
15229               (clobber (match_scratch:XF 3 ""))])]
15230   "TARGET_USE_FANCY_MATH_387
15231    && flag_unsafe_math_optimizations"
15233   operands[2] = gen_reg_rtx (XFmode);
15234   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15237 (define_expand "asindf2"
15238   [(set (match_dup 2)
15239         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15240    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15241    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15242    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15243    (parallel [(set (match_dup 7)
15244                    (unspec:XF [(match_dup 6) (match_dup 2)]
15245                               UNSPEC_FPATAN))
15246               (clobber (match_scratch:XF 8 ""))])
15247    (set (match_operand:DF 0 "register_operand" "")
15248         (float_truncate:DF (match_dup 7)))]
15249   "TARGET_USE_FANCY_MATH_387
15250    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15251    && flag_unsafe_math_optimizations"
15253   int i;
15255   for (i=2; i<8; i++)
15256     operands[i] = gen_reg_rtx (XFmode);
15258   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15261 (define_expand "asinsf2"
15262   [(set (match_dup 2)
15263         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15264    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15265    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15266    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15267    (parallel [(set (match_dup 7)
15268                    (unspec:XF [(match_dup 6) (match_dup 2)]
15269                               UNSPEC_FPATAN))
15270               (clobber (match_scratch:XF 8 ""))])
15271    (set (match_operand:SF 0 "register_operand" "")
15272         (float_truncate:SF (match_dup 7)))]
15273   "TARGET_USE_FANCY_MATH_387
15274    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15275    && flag_unsafe_math_optimizations"
15277   int i;
15279   for (i=2; i<8; i++)
15280     operands[i] = gen_reg_rtx (XFmode);
15282   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15285 (define_expand "asinxf2"
15286   [(set (match_dup 2)
15287         (mult:XF (match_operand:XF 1 "register_operand" "")
15288                  (match_dup 1)))
15289    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15290    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15291    (parallel [(set (match_operand:XF 0 "register_operand" "")
15292                    (unspec:XF [(match_dup 5) (match_dup 1)]
15293                               UNSPEC_FPATAN))
15294               (clobber (match_scratch:XF 6 ""))])]
15295   "TARGET_USE_FANCY_MATH_387
15296    && flag_unsafe_math_optimizations"
15298   int i;
15300   for (i=2; i<6; i++)
15301     operands[i] = gen_reg_rtx (XFmode);
15303   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15306 (define_expand "acosdf2"
15307   [(set (match_dup 2)
15308         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15309    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15310    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15311    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15312    (parallel [(set (match_dup 7)
15313                    (unspec:XF [(match_dup 2) (match_dup 6)]
15314                               UNSPEC_FPATAN))
15315               (clobber (match_scratch:XF 8 ""))])
15316    (set (match_operand:DF 0 "register_operand" "")
15317         (float_truncate:DF (match_dup 7)))]
15318   "TARGET_USE_FANCY_MATH_387
15319    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15320    && flag_unsafe_math_optimizations"
15322   int i;
15324   for (i=2; i<8; i++)
15325     operands[i] = gen_reg_rtx (XFmode);
15327   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15330 (define_expand "acossf2"
15331   [(set (match_dup 2)
15332         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15333    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15334    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15335    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15336    (parallel [(set (match_dup 7)
15337                    (unspec:XF [(match_dup 2) (match_dup 6)]
15338                               UNSPEC_FPATAN))
15339               (clobber (match_scratch:XF 8 ""))])
15340    (set (match_operand:SF 0 "register_operand" "")
15341         (float_truncate:SF (match_dup 7)))]
15342   "TARGET_USE_FANCY_MATH_387
15343    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15344    && flag_unsafe_math_optimizations"
15346   int i;
15348   for (i=2; i<8; i++)
15349     operands[i] = gen_reg_rtx (XFmode);
15351   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15354 (define_expand "acosxf2"
15355   [(set (match_dup 2)
15356         (mult:XF (match_operand:XF 1 "register_operand" "")
15357                  (match_dup 1)))
15358    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15359    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15360    (parallel [(set (match_operand:XF 0 "register_operand" "")
15361                    (unspec:XF [(match_dup 1) (match_dup 5)]
15362                               UNSPEC_FPATAN))
15363               (clobber (match_scratch:XF 6 ""))])]
15364   "TARGET_USE_FANCY_MATH_387
15365    && flag_unsafe_math_optimizations"
15367   int i;
15369   for (i=2; i<6; i++)
15370     operands[i] = gen_reg_rtx (XFmode);
15372   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15375 (define_insn "fyl2x_xf3"
15376   [(set (match_operand:XF 0 "register_operand" "=f")
15377         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15378                     (match_operand:XF 1 "register_operand" "u")]
15379                    UNSPEC_FYL2X))
15380    (clobber (match_scratch:XF 3 "=1"))]
15381   "TARGET_USE_FANCY_MATH_387
15382    && flag_unsafe_math_optimizations"
15383   "fyl2x"
15384   [(set_attr "type" "fpspc")
15385    (set_attr "mode" "XF")])
15387 (define_expand "logsf2"
15388   [(set (match_dup 2)
15389         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15390    (parallel [(set (match_dup 4)
15391                    (unspec:XF [(match_dup 2)
15392                                (match_dup 3)] UNSPEC_FYL2X))
15393               (clobber (match_scratch:XF 5 ""))])
15394    (set (match_operand:SF 0 "register_operand" "")
15395         (float_truncate:SF (match_dup 4)))]
15396   "TARGET_USE_FANCY_MATH_387
15397    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15398    && flag_unsafe_math_optimizations"
15400   rtx temp;
15402   operands[2] = gen_reg_rtx (XFmode);
15403   operands[3] = gen_reg_rtx (XFmode);
15404   operands[4] = gen_reg_rtx (XFmode);
15406   temp = standard_80387_constant_rtx (4); /* fldln2 */
15407   emit_move_insn (operands[3], temp);
15410 (define_expand "logdf2"
15411   [(set (match_dup 2)
15412         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15413    (parallel [(set (match_dup 4)
15414                    (unspec:XF [(match_dup 2)
15415                                (match_dup 3)] UNSPEC_FYL2X))
15416               (clobber (match_scratch:XF 5 ""))])
15417    (set (match_operand:DF 0 "register_operand" "")
15418         (float_truncate:DF (match_dup 4)))]
15419   "TARGET_USE_FANCY_MATH_387
15420    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15421    && flag_unsafe_math_optimizations"
15423   rtx temp;
15425   operands[2] = gen_reg_rtx (XFmode);
15426   operands[3] = gen_reg_rtx (XFmode);
15427   operands[4] = gen_reg_rtx (XFmode);
15429   temp = standard_80387_constant_rtx (4); /* fldln2 */
15430   emit_move_insn (operands[3], temp);
15433 (define_expand "logxf2"
15434   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15435                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15436                                (match_dup 2)] UNSPEC_FYL2X))
15437               (clobber (match_scratch:XF 3 ""))])]
15438   "TARGET_USE_FANCY_MATH_387
15439    && flag_unsafe_math_optimizations"
15441   rtx temp;
15443   operands[2] = gen_reg_rtx (XFmode);
15444   temp = standard_80387_constant_rtx (4); /* fldln2 */
15445   emit_move_insn (operands[2], temp);
15448 (define_expand "log10sf2"
15449   [(set (match_dup 2)
15450         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15451    (parallel [(set (match_dup 4)
15452                    (unspec:XF [(match_dup 2)
15453                                (match_dup 3)] UNSPEC_FYL2X))
15454               (clobber (match_scratch:XF 5 ""))])
15455    (set (match_operand:SF 0 "register_operand" "")
15456         (float_truncate:SF (match_dup 4)))]
15457   "TARGET_USE_FANCY_MATH_387
15458    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15459    && flag_unsafe_math_optimizations"
15461   rtx temp;
15463   operands[2] = gen_reg_rtx (XFmode);
15464   operands[3] = gen_reg_rtx (XFmode);
15465   operands[4] = gen_reg_rtx (XFmode);
15467   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15468   emit_move_insn (operands[3], temp);
15471 (define_expand "log10df2"
15472   [(set (match_dup 2)
15473         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15474    (parallel [(set (match_dup 4)
15475                    (unspec:XF [(match_dup 2)
15476                                (match_dup 3)] UNSPEC_FYL2X))
15477               (clobber (match_scratch:XF 5 ""))])
15478    (set (match_operand:DF 0 "register_operand" "")
15479         (float_truncate:DF (match_dup 4)))]
15480   "TARGET_USE_FANCY_MATH_387
15481    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15482    && flag_unsafe_math_optimizations"
15484   rtx temp;
15486   operands[2] = gen_reg_rtx (XFmode);
15487   operands[3] = gen_reg_rtx (XFmode);
15488   operands[4] = gen_reg_rtx (XFmode);
15490   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15491   emit_move_insn (operands[3], temp);
15494 (define_expand "log10xf2"
15495   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15496                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15497                                (match_dup 2)] UNSPEC_FYL2X))
15498               (clobber (match_scratch:XF 3 ""))])]
15499   "TARGET_USE_FANCY_MATH_387
15500    && flag_unsafe_math_optimizations"
15502   rtx temp;
15504   operands[2] = gen_reg_rtx (XFmode);
15505   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15506   emit_move_insn (operands[2], temp);
15509 (define_expand "log2sf2"
15510   [(set (match_dup 2)
15511         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15512    (parallel [(set (match_dup 4)
15513                    (unspec:XF [(match_dup 2)
15514                                (match_dup 3)] UNSPEC_FYL2X))
15515               (clobber (match_scratch:XF 5 ""))])
15516    (set (match_operand:SF 0 "register_operand" "")
15517         (float_truncate:SF (match_dup 4)))]
15518   "TARGET_USE_FANCY_MATH_387
15519    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15520    && flag_unsafe_math_optimizations"
15522   operands[2] = gen_reg_rtx (XFmode);
15523   operands[3] = gen_reg_rtx (XFmode);
15524   operands[4] = gen_reg_rtx (XFmode);
15526   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15529 (define_expand "log2df2"
15530   [(set (match_dup 2)
15531         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15532    (parallel [(set (match_dup 4)
15533                    (unspec:XF [(match_dup 2)
15534                                (match_dup 3)] UNSPEC_FYL2X))
15535               (clobber (match_scratch:XF 5 ""))])
15536    (set (match_operand:DF 0 "register_operand" "")
15537         (float_truncate:DF (match_dup 4)))]
15538   "TARGET_USE_FANCY_MATH_387
15539    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15540    && flag_unsafe_math_optimizations"
15542   operands[2] = gen_reg_rtx (XFmode);
15543   operands[3] = gen_reg_rtx (XFmode);
15544   operands[4] = gen_reg_rtx (XFmode);
15546   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15549 (define_expand "log2xf2"
15550   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15551                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15552                                (match_dup 2)] UNSPEC_FYL2X))
15553               (clobber (match_scratch:XF 3 ""))])]
15554   "TARGET_USE_FANCY_MATH_387
15555    && flag_unsafe_math_optimizations"
15557   operands[2] = gen_reg_rtx (XFmode);
15558   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15561 (define_insn "fyl2xp1_xf3"
15562   [(set (match_operand:XF 0 "register_operand" "=f")
15563         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15564                     (match_operand:XF 1 "register_operand" "u")]
15565                    UNSPEC_FYL2XP1))
15566    (clobber (match_scratch:XF 3 "=1"))]
15567   "TARGET_USE_FANCY_MATH_387
15568    && flag_unsafe_math_optimizations"
15569   "fyl2xp1"
15570   [(set_attr "type" "fpspc")
15571    (set_attr "mode" "XF")])
15573 (define_expand "log1psf2"
15574   [(use (match_operand:SF 0 "register_operand" ""))
15575    (use (match_operand:SF 1 "register_operand" ""))]
15576   "TARGET_USE_FANCY_MATH_387
15577    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15578    && flag_unsafe_math_optimizations"
15580   rtx op0 = gen_reg_rtx (XFmode);
15581   rtx op1 = gen_reg_rtx (XFmode);
15583   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15584   ix86_emit_i387_log1p (op0, op1);
15585   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15586   DONE;
15589 (define_expand "log1pdf2"
15590   [(use (match_operand:DF 0 "register_operand" ""))
15591    (use (match_operand:DF 1 "register_operand" ""))]
15592   "TARGET_USE_FANCY_MATH_387
15593    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15594    && flag_unsafe_math_optimizations"
15596   rtx op0 = gen_reg_rtx (XFmode);
15597   rtx op1 = gen_reg_rtx (XFmode);
15599   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15600   ix86_emit_i387_log1p (op0, op1);
15601   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15602   DONE;
15605 (define_expand "log1pxf2"
15606   [(use (match_operand:XF 0 "register_operand" ""))
15607    (use (match_operand:XF 1 "register_operand" ""))]
15608   "TARGET_USE_FANCY_MATH_387
15609    && flag_unsafe_math_optimizations"
15611   ix86_emit_i387_log1p (operands[0], operands[1]);
15612   DONE;
15615 (define_insn "*fxtractxf3"
15616   [(set (match_operand:XF 0 "register_operand" "=f")
15617         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15618                    UNSPEC_XTRACT_FRACT))
15619    (set (match_operand:XF 1 "register_operand" "=u")
15620         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15621   "TARGET_USE_FANCY_MATH_387
15622    && flag_unsafe_math_optimizations"
15623   "fxtract"
15624   [(set_attr "type" "fpspc")
15625    (set_attr "mode" "XF")])
15627 (define_expand "logbsf2"
15628   [(set (match_dup 2)
15629         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15630    (parallel [(set (match_dup 3)
15631                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15632               (set (match_dup 4)
15633                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15634    (set (match_operand:SF 0 "register_operand" "")
15635         (float_truncate:SF (match_dup 4)))]
15636   "TARGET_USE_FANCY_MATH_387
15637    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15638    && flag_unsafe_math_optimizations"
15640   operands[2] = gen_reg_rtx (XFmode);
15641   operands[3] = gen_reg_rtx (XFmode);
15642   operands[4] = gen_reg_rtx (XFmode);
15645 (define_expand "logbdf2"
15646   [(set (match_dup 2)
15647         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15648    (parallel [(set (match_dup 3)
15649                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15650               (set (match_dup 4)
15651                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15652    (set (match_operand:DF 0 "register_operand" "")
15653         (float_truncate:DF (match_dup 4)))]
15654   "TARGET_USE_FANCY_MATH_387
15655    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15656    && flag_unsafe_math_optimizations"
15658   operands[2] = gen_reg_rtx (XFmode);
15659   operands[3] = gen_reg_rtx (XFmode);
15660   operands[4] = gen_reg_rtx (XFmode);
15663 (define_expand "logbxf2"
15664   [(parallel [(set (match_dup 2)
15665                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15666                               UNSPEC_XTRACT_FRACT))
15667               (set (match_operand:XF 0 "register_operand" "")
15668                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15669   "TARGET_USE_FANCY_MATH_387
15670    && flag_unsafe_math_optimizations"
15672   operands[2] = gen_reg_rtx (XFmode);
15675 (define_expand "ilogbsi2"
15676   [(parallel [(set (match_dup 2)
15677                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15678                               UNSPEC_XTRACT_FRACT))
15679               (set (match_operand:XF 3 "register_operand" "")
15680                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15681    (parallel [(set (match_operand:SI 0 "register_operand" "")
15682                    (fix:SI (match_dup 3)))
15683               (clobber (reg:CC FLAGS_REG))])]
15684   "TARGET_USE_FANCY_MATH_387
15685    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15686    && flag_unsafe_math_optimizations"
15688   operands[2] = gen_reg_rtx (XFmode);
15689   operands[3] = gen_reg_rtx (XFmode);
15692 (define_insn "*f2xm1xf2"
15693   [(set (match_operand:XF 0 "register_operand" "=f")
15694         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15695          UNSPEC_F2XM1))]
15696   "TARGET_USE_FANCY_MATH_387
15697    && flag_unsafe_math_optimizations"
15698   "f2xm1"
15699   [(set_attr "type" "fpspc")
15700    (set_attr "mode" "XF")])
15702 (define_insn "*fscalexf4"
15703   [(set (match_operand:XF 0 "register_operand" "=f")
15704         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15705                     (match_operand:XF 3 "register_operand" "1")]
15706                    UNSPEC_FSCALE_FRACT))
15707    (set (match_operand:XF 1 "register_operand" "=u")
15708         (unspec:XF [(match_dup 2) (match_dup 3)]
15709                    UNSPEC_FSCALE_EXP))]
15710   "TARGET_USE_FANCY_MATH_387
15711    && flag_unsafe_math_optimizations"
15712   "fscale"
15713   [(set_attr "type" "fpspc")
15714    (set_attr "mode" "XF")])
15716 (define_expand "expsf2"
15717   [(set (match_dup 2)
15718         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15719    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15720    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15721    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15722    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15723    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15724    (parallel [(set (match_dup 10)
15725                    (unspec:XF [(match_dup 9) (match_dup 5)]
15726                               UNSPEC_FSCALE_FRACT))
15727               (set (match_dup 11)
15728                    (unspec:XF [(match_dup 9) (match_dup 5)]
15729                               UNSPEC_FSCALE_EXP))])
15730    (set (match_operand:SF 0 "register_operand" "")
15731         (float_truncate:SF (match_dup 10)))]
15732   "TARGET_USE_FANCY_MATH_387
15733    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15734    && flag_unsafe_math_optimizations"
15736   rtx temp;
15737   int i;
15739   for (i=2; i<12; i++)
15740     operands[i] = gen_reg_rtx (XFmode);
15741   temp = standard_80387_constant_rtx (5); /* fldl2e */
15742   emit_move_insn (operands[3], temp);
15743   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15746 (define_expand "expdf2"
15747   [(set (match_dup 2)
15748         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15749    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15750    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15751    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15752    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15753    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15754    (parallel [(set (match_dup 10)
15755                    (unspec:XF [(match_dup 9) (match_dup 5)]
15756                               UNSPEC_FSCALE_FRACT))
15757               (set (match_dup 11)
15758                    (unspec:XF [(match_dup 9) (match_dup 5)]
15759                               UNSPEC_FSCALE_EXP))])
15760    (set (match_operand:DF 0 "register_operand" "")
15761         (float_truncate:DF (match_dup 10)))]
15762   "TARGET_USE_FANCY_MATH_387
15763    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15764    && flag_unsafe_math_optimizations"
15766   rtx temp;
15767   int i;
15769   for (i=2; i<12; i++)
15770     operands[i] = gen_reg_rtx (XFmode);
15771   temp = standard_80387_constant_rtx (5); /* fldl2e */
15772   emit_move_insn (operands[3], temp);
15773   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15776 (define_expand "expxf2"
15777   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15778                                (match_dup 2)))
15779    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15780    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15781    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15782    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15783    (parallel [(set (match_operand:XF 0 "register_operand" "")
15784                    (unspec:XF [(match_dup 8) (match_dup 4)]
15785                               UNSPEC_FSCALE_FRACT))
15786               (set (match_dup 9)
15787                    (unspec:XF [(match_dup 8) (match_dup 4)]
15788                               UNSPEC_FSCALE_EXP))])]
15789   "TARGET_USE_FANCY_MATH_387
15790    && flag_unsafe_math_optimizations"
15792   rtx temp;
15793   int i;
15795   for (i=2; i<10; i++)
15796     operands[i] = gen_reg_rtx (XFmode);
15797   temp = standard_80387_constant_rtx (5); /* fldl2e */
15798   emit_move_insn (operands[2], temp);
15799   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15802 (define_expand "exp10sf2"
15803   [(set (match_dup 2)
15804         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15805    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15806    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15807    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15808    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15809    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15810    (parallel [(set (match_dup 10)
15811                    (unspec:XF [(match_dup 9) (match_dup 5)]
15812                               UNSPEC_FSCALE_FRACT))
15813               (set (match_dup 11)
15814                    (unspec:XF [(match_dup 9) (match_dup 5)]
15815                               UNSPEC_FSCALE_EXP))])
15816    (set (match_operand:SF 0 "register_operand" "")
15817         (float_truncate:SF (match_dup 10)))]
15818   "TARGET_USE_FANCY_MATH_387
15819    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15820    && flag_unsafe_math_optimizations"
15822   rtx temp;
15823   int i;
15825   for (i=2; i<12; i++)
15826     operands[i] = gen_reg_rtx (XFmode);
15827   temp = standard_80387_constant_rtx (6); /* fldl2t */
15828   emit_move_insn (operands[3], temp);
15829   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15832 (define_expand "exp10df2"
15833   [(set (match_dup 2)
15834         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15835    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15836    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15837    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15838    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15839    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15840    (parallel [(set (match_dup 10)
15841                    (unspec:XF [(match_dup 9) (match_dup 5)]
15842                               UNSPEC_FSCALE_FRACT))
15843               (set (match_dup 11)
15844                    (unspec:XF [(match_dup 9) (match_dup 5)]
15845                               UNSPEC_FSCALE_EXP))])
15846    (set (match_operand:DF 0 "register_operand" "")
15847         (float_truncate:DF (match_dup 10)))]
15848   "TARGET_USE_FANCY_MATH_387
15849    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15850    && flag_unsafe_math_optimizations"
15852   rtx temp;
15853   int i;
15855   for (i=2; i<12; i++)
15856     operands[i] = gen_reg_rtx (XFmode);
15857   temp = standard_80387_constant_rtx (6); /* fldl2t */
15858   emit_move_insn (operands[3], temp);
15859   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15862 (define_expand "exp10xf2"
15863   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15864                                (match_dup 2)))
15865    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15866    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15867    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15868    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15869    (parallel [(set (match_operand:XF 0 "register_operand" "")
15870                    (unspec:XF [(match_dup 8) (match_dup 4)]
15871                               UNSPEC_FSCALE_FRACT))
15872               (set (match_dup 9)
15873                    (unspec:XF [(match_dup 8) (match_dup 4)]
15874                               UNSPEC_FSCALE_EXP))])]
15875   "TARGET_USE_FANCY_MATH_387
15876    && flag_unsafe_math_optimizations"
15878   rtx temp;
15879   int i;
15881   for (i=2; i<10; i++)
15882     operands[i] = gen_reg_rtx (XFmode);
15883   temp = standard_80387_constant_rtx (6); /* fldl2t */
15884   emit_move_insn (operands[2], temp);
15885   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15888 (define_expand "exp2sf2"
15889   [(set (match_dup 2)
15890         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15891    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15892    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15893    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15894    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15895    (parallel [(set (match_dup 8)
15896                    (unspec:XF [(match_dup 7) (match_dup 3)]
15897                               UNSPEC_FSCALE_FRACT))
15898               (set (match_dup 9)
15899                    (unspec:XF [(match_dup 7) (match_dup 3)]
15900                               UNSPEC_FSCALE_EXP))])
15901    (set (match_operand:SF 0 "register_operand" "")
15902         (float_truncate:SF (match_dup 8)))]
15903   "TARGET_USE_FANCY_MATH_387
15904    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15905    && flag_unsafe_math_optimizations"
15907   int i;
15909   for (i=2; i<10; i++)
15910     operands[i] = gen_reg_rtx (XFmode);
15911   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15914 (define_expand "exp2df2"
15915   [(set (match_dup 2)
15916         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15917    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15918    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15919    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15920    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15921    (parallel [(set (match_dup 8)
15922                    (unspec:XF [(match_dup 7) (match_dup 3)]
15923                               UNSPEC_FSCALE_FRACT))
15924               (set (match_dup 9)
15925                    (unspec:XF [(match_dup 7) (match_dup 3)]
15926                               UNSPEC_FSCALE_EXP))])
15927    (set (match_operand:DF 0 "register_operand" "")
15928         (float_truncate:DF (match_dup 8)))]
15929   "TARGET_USE_FANCY_MATH_387
15930    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15931    && flag_unsafe_math_optimizations"
15933   int i;
15935   for (i=2; i<10; i++)
15936     operands[i] = gen_reg_rtx (XFmode);
15937   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15940 (define_expand "exp2xf2"
15941   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15942    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15943    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15944    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15945    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15946    (parallel [(set (match_operand:XF 0 "register_operand" "")
15947                    (unspec:XF [(match_dup 7) (match_dup 3)]
15948                               UNSPEC_FSCALE_FRACT))
15949               (set (match_dup 8)
15950                    (unspec:XF [(match_dup 7) (match_dup 3)]
15951                               UNSPEC_FSCALE_EXP))])]
15952   "TARGET_USE_FANCY_MATH_387
15953    && flag_unsafe_math_optimizations"
15955   int i;
15957   for (i=2; i<9; i++)
15958     operands[i] = gen_reg_rtx (XFmode);
15959   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15962 (define_expand "expm1df2"
15963   [(set (match_dup 2)
15964         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15965    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15966    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15967    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15968    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15969    (parallel [(set (match_dup 8)
15970                    (unspec:XF [(match_dup 7) (match_dup 5)]
15971                               UNSPEC_FSCALE_FRACT))
15972                    (set (match_dup 9)
15973                    (unspec:XF [(match_dup 7) (match_dup 5)]
15974                               UNSPEC_FSCALE_EXP))])
15975    (parallel [(set (match_dup 11)
15976                    (unspec:XF [(match_dup 10) (match_dup 9)]
15977                               UNSPEC_FSCALE_FRACT))
15978               (set (match_dup 12)
15979                    (unspec:XF [(match_dup 10) (match_dup 9)]
15980                               UNSPEC_FSCALE_EXP))])
15981    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15982    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15983    (set (match_operand:DF 0 "register_operand" "")
15984         (float_truncate:DF (match_dup 14)))]
15985   "TARGET_USE_FANCY_MATH_387
15986    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15987    && flag_unsafe_math_optimizations"
15989   rtx temp;
15990   int i;
15992   for (i=2; i<15; i++)
15993     operands[i] = gen_reg_rtx (XFmode);
15994   temp = standard_80387_constant_rtx (5); /* fldl2e */
15995   emit_move_insn (operands[3], temp);
15996   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
15999 (define_expand "expm1sf2"
16000   [(set (match_dup 2)
16001         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16002    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16003    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16004    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16005    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16006    (parallel [(set (match_dup 8)
16007                    (unspec:XF [(match_dup 7) (match_dup 5)]
16008                               UNSPEC_FSCALE_FRACT))
16009                    (set (match_dup 9)
16010                    (unspec:XF [(match_dup 7) (match_dup 5)]
16011                               UNSPEC_FSCALE_EXP))])
16012    (parallel [(set (match_dup 11)
16013                    (unspec:XF [(match_dup 10) (match_dup 9)]
16014                               UNSPEC_FSCALE_FRACT))
16015               (set (match_dup 12)
16016                    (unspec:XF [(match_dup 10) (match_dup 9)]
16017                               UNSPEC_FSCALE_EXP))])
16018    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16019    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16020    (set (match_operand:SF 0 "register_operand" "")
16021         (float_truncate:SF (match_dup 14)))]
16022   "TARGET_USE_FANCY_MATH_387
16023    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16024    && flag_unsafe_math_optimizations"
16026   rtx temp;
16027   int i;
16029   for (i=2; i<15; i++)
16030     operands[i] = gen_reg_rtx (XFmode);
16031   temp = standard_80387_constant_rtx (5); /* fldl2e */
16032   emit_move_insn (operands[3], temp);
16033   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16036 (define_expand "expm1xf2"
16037   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16038                                (match_dup 2)))
16039    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16040    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16041    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16042    (parallel [(set (match_dup 7)
16043                    (unspec:XF [(match_dup 6) (match_dup 4)]
16044                               UNSPEC_FSCALE_FRACT))
16045                    (set (match_dup 8)
16046                    (unspec:XF [(match_dup 6) (match_dup 4)]
16047                               UNSPEC_FSCALE_EXP))])
16048    (parallel [(set (match_dup 10)
16049                    (unspec:XF [(match_dup 9) (match_dup 8)]
16050                               UNSPEC_FSCALE_FRACT))
16051               (set (match_dup 11)
16052                    (unspec:XF [(match_dup 9) (match_dup 8)]
16053                               UNSPEC_FSCALE_EXP))])
16054    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16055    (set (match_operand:XF 0 "register_operand" "")
16056         (plus:XF (match_dup 12) (match_dup 7)))]
16057   "TARGET_USE_FANCY_MATH_387
16058    && flag_unsafe_math_optimizations"
16060   rtx temp;
16061   int i;
16063   for (i=2; i<13; i++)
16064     operands[i] = gen_reg_rtx (XFmode);
16065   temp = standard_80387_constant_rtx (5); /* fldl2e */
16066   emit_move_insn (operands[2], temp);
16067   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16071 (define_insn "frndintxf2"
16072   [(set (match_operand:XF 0 "register_operand" "=f")
16073         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16074          UNSPEC_FRNDINT))]
16075   "TARGET_USE_FANCY_MATH_387
16076    && flag_unsafe_math_optimizations"
16077   "frndint"
16078   [(set_attr "type" "fpspc")
16079    (set_attr "mode" "XF")])
16081 (define_expand "rintdf2"
16082   [(use (match_operand:DF 0 "register_operand" ""))
16083    (use (match_operand:DF 1 "register_operand" ""))]
16084   "TARGET_USE_FANCY_MATH_387
16085    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16086    && flag_unsafe_math_optimizations"
16088   rtx op0 = gen_reg_rtx (XFmode);
16089   rtx op1 = gen_reg_rtx (XFmode);
16091   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16092   emit_insn (gen_frndintxf2 (op0, op1));
16094   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16095   DONE;
16098 (define_expand "rintsf2"
16099   [(use (match_operand:SF 0 "register_operand" ""))
16100    (use (match_operand:SF 1 "register_operand" ""))]
16101   "TARGET_USE_FANCY_MATH_387
16102    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16103    && flag_unsafe_math_optimizations"
16105   rtx op0 = gen_reg_rtx (XFmode);
16106   rtx op1 = gen_reg_rtx (XFmode);
16108   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16109   emit_insn (gen_frndintxf2 (op0, op1));
16111   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16112   DONE;
16115 (define_expand "rintxf2"
16116   [(use (match_operand:XF 0 "register_operand" ""))
16117    (use (match_operand:XF 1 "register_operand" ""))]
16118   "TARGET_USE_FANCY_MATH_387
16119    && flag_unsafe_math_optimizations"
16121   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16122   DONE;
16125 (define_insn "frndintxf2_floor"
16126   [(set (match_operand:XF 0 "register_operand" "=f")
16127         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16128          UNSPEC_FRNDINT_FLOOR))
16129    (use (match_operand:HI 2 "memory_operand" "m"))
16130    (use (match_operand:HI 3 "memory_operand" "m"))]
16131   "TARGET_USE_FANCY_MATH_387
16132    && flag_unsafe_math_optimizations"
16133   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16134   [(set_attr "type" "frndint")
16135    (set_attr "i387_cw" "floor")
16136    (set_attr "mode" "XF")])
16138 (define_expand "floordf2"
16139   [(use (match_operand:DF 0 "register_operand" ""))
16140    (use (match_operand:DF 1 "register_operand" ""))]
16141   "TARGET_USE_FANCY_MATH_387
16142    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16143    && flag_unsafe_math_optimizations"
16145   rtx op0 = gen_reg_rtx (XFmode);
16146   rtx op1 = gen_reg_rtx (XFmode);
16147   rtx op2 = assign_386_stack_local (HImode, 1);
16148   rtx op3 = assign_386_stack_local (HImode, 2);
16149         
16150   ix86_optimize_mode_switching = 1;
16152   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16153   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16155   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16156   DONE;
16159 (define_expand "floorsf2"
16160   [(use (match_operand:SF 0 "register_operand" ""))
16161    (use (match_operand:SF 1 "register_operand" ""))]
16162   "TARGET_USE_FANCY_MATH_387
16163    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16164    && flag_unsafe_math_optimizations"
16166   rtx op0 = gen_reg_rtx (XFmode);
16167   rtx op1 = gen_reg_rtx (XFmode);
16168   rtx op2 = assign_386_stack_local (HImode, 1);
16169   rtx op3 = assign_386_stack_local (HImode, 2);
16170         
16171   ix86_optimize_mode_switching = 1;
16173   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16174   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16176   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16177   DONE;
16180 (define_expand "floorxf2"
16181   [(use (match_operand:XF 0 "register_operand" ""))
16182    (use (match_operand:XF 1 "register_operand" ""))]
16183   "TARGET_USE_FANCY_MATH_387
16184    && flag_unsafe_math_optimizations"
16186   rtx op2 = assign_386_stack_local (HImode, 1);
16187   rtx op3 = assign_386_stack_local (HImode, 2);
16188         
16189   ix86_optimize_mode_switching = 1;
16191   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16192   DONE;
16195 (define_insn "frndintxf2_ceil"
16196   [(set (match_operand:XF 0 "register_operand" "=f")
16197         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16198          UNSPEC_FRNDINT_CEIL))
16199    (use (match_operand:HI 2 "memory_operand" "m"))
16200    (use (match_operand:HI 3 "memory_operand" "m"))]
16201   "TARGET_USE_FANCY_MATH_387
16202    && flag_unsafe_math_optimizations"
16203   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16204   [(set_attr "type" "frndint")
16205    (set_attr "i387_cw" "ceil")
16206    (set_attr "mode" "XF")])
16208 (define_expand "ceildf2"
16209   [(use (match_operand:DF 0 "register_operand" ""))
16210    (use (match_operand:DF 1 "register_operand" ""))]
16211   "TARGET_USE_FANCY_MATH_387
16212    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16213    && flag_unsafe_math_optimizations"
16215   rtx op0 = gen_reg_rtx (XFmode);
16216   rtx op1 = gen_reg_rtx (XFmode);
16217   rtx op2 = assign_386_stack_local (HImode, 1);
16218   rtx op3 = assign_386_stack_local (HImode, 2);
16219         
16220   ix86_optimize_mode_switching = 1;
16222   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16223   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16225   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16226   DONE;
16229 (define_expand "ceilsf2"
16230   [(use (match_operand:SF 0 "register_operand" ""))
16231    (use (match_operand:SF 1 "register_operand" ""))]
16232   "TARGET_USE_FANCY_MATH_387
16233    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16234    && flag_unsafe_math_optimizations"
16236   rtx op0 = gen_reg_rtx (XFmode);
16237   rtx op1 = gen_reg_rtx (XFmode);
16238   rtx op2 = assign_386_stack_local (HImode, 1);
16239   rtx op3 = assign_386_stack_local (HImode, 2);
16240         
16241   ix86_optimize_mode_switching = 1;
16243   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16244   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16246   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16247   DONE;
16250 (define_expand "ceilxf2"
16251   [(use (match_operand:XF 0 "register_operand" ""))
16252    (use (match_operand:XF 1 "register_operand" ""))]
16253   "TARGET_USE_FANCY_MATH_387
16254    && flag_unsafe_math_optimizations"
16256   rtx op2 = assign_386_stack_local (HImode, 1);
16257   rtx op3 = assign_386_stack_local (HImode, 2);
16258         
16259   ix86_optimize_mode_switching = 1;
16261   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16262   DONE;
16265 (define_insn "frndintxf2_trunc"
16266   [(set (match_operand:XF 0 "register_operand" "=f")
16267         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16268          UNSPEC_FRNDINT_TRUNC))
16269    (use (match_operand:HI 2 "memory_operand" "m"))
16270    (use (match_operand:HI 3 "memory_operand" "m"))]
16271   "TARGET_USE_FANCY_MATH_387
16272    && flag_unsafe_math_optimizations"
16273   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16274   [(set_attr "type" "frndint")
16275    (set_attr "i387_cw" "trunc")
16276    (set_attr "mode" "XF")])
16278 (define_expand "btruncdf2"
16279   [(use (match_operand:DF 0 "register_operand" ""))
16280    (use (match_operand:DF 1 "register_operand" ""))]
16281   "TARGET_USE_FANCY_MATH_387
16282    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16283    && flag_unsafe_math_optimizations"
16285   rtx op0 = gen_reg_rtx (XFmode);
16286   rtx op1 = gen_reg_rtx (XFmode);
16287   rtx op2 = assign_386_stack_local (HImode, 1);
16288   rtx op3 = assign_386_stack_local (HImode, 2);
16289         
16290   ix86_optimize_mode_switching = 1;
16292   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16293   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16295   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16296   DONE;
16299 (define_expand "btruncsf2"
16300   [(use (match_operand:SF 0 "register_operand" ""))
16301    (use (match_operand:SF 1 "register_operand" ""))]
16302   "TARGET_USE_FANCY_MATH_387
16303    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16304    && flag_unsafe_math_optimizations"
16306   rtx op0 = gen_reg_rtx (XFmode);
16307   rtx op1 = gen_reg_rtx (XFmode);
16308   rtx op2 = assign_386_stack_local (HImode, 1);
16309   rtx op3 = assign_386_stack_local (HImode, 2);
16310         
16311   ix86_optimize_mode_switching = 1;
16313   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16314   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16316   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16317   DONE;
16320 (define_expand "btruncxf2"
16321   [(use (match_operand:XF 0 "register_operand" ""))
16322    (use (match_operand:XF 1 "register_operand" ""))]
16323   "TARGET_USE_FANCY_MATH_387
16324    && flag_unsafe_math_optimizations"
16326   rtx op2 = assign_386_stack_local (HImode, 1);
16327   rtx op3 = assign_386_stack_local (HImode, 2);
16328         
16329   ix86_optimize_mode_switching = 1;
16331   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16332   DONE;
16335 (define_insn "frndintxf2_mask_pm"
16336   [(set (match_operand:XF 0 "register_operand" "=f")
16337         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16338          UNSPEC_FRNDINT_MASK_PM))
16339    (use (match_operand:HI 2 "memory_operand" "m"))
16340    (use (match_operand:HI 3 "memory_operand" "m"))]
16341   "TARGET_USE_FANCY_MATH_387
16342    && flag_unsafe_math_optimizations"
16343   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16344   [(set_attr "type" "frndint")
16345    (set_attr "i387_cw" "mask_pm")
16346    (set_attr "mode" "XF")])
16348 (define_expand "nearbyintdf2"
16349   [(use (match_operand:DF 0 "register_operand" ""))
16350    (use (match_operand:DF 1 "register_operand" ""))]
16351   "TARGET_USE_FANCY_MATH_387
16352    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16353    && flag_unsafe_math_optimizations"
16355   rtx op0 = gen_reg_rtx (XFmode);
16356   rtx op1 = gen_reg_rtx (XFmode);
16357   rtx op2 = assign_386_stack_local (HImode, 1);
16358   rtx op3 = assign_386_stack_local (HImode, 2);
16359         
16360   ix86_optimize_mode_switching = 1;
16362   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16363   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16365   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16366   DONE;
16369 (define_expand "nearbyintsf2"
16370   [(use (match_operand:SF 0 "register_operand" ""))
16371    (use (match_operand:SF 1 "register_operand" ""))]
16372   "TARGET_USE_FANCY_MATH_387
16373    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16374    && flag_unsafe_math_optimizations"
16376   rtx op0 = gen_reg_rtx (XFmode);
16377   rtx op1 = gen_reg_rtx (XFmode);
16378   rtx op2 = assign_386_stack_local (HImode, 1);
16379   rtx op3 = assign_386_stack_local (HImode, 2);
16380         
16381   ix86_optimize_mode_switching = 1;
16383   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16384   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16386   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16387   DONE;
16390 (define_expand "nearbyintxf2"
16391   [(use (match_operand:XF 0 "register_operand" ""))
16392    (use (match_operand:XF 1 "register_operand" ""))]
16393   "TARGET_USE_FANCY_MATH_387
16394    && flag_unsafe_math_optimizations"
16396   rtx op2 = assign_386_stack_local (HImode, 1);
16397   rtx op3 = assign_386_stack_local (HImode, 2);
16398         
16399   ix86_optimize_mode_switching = 1;
16401   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16402                                      op2, op3));
16403   DONE;
16407 ;; Block operation instructions
16409 (define_insn "cld"
16410  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16411  ""
16412  "cld"
16413   [(set_attr "type" "cld")])
16415 (define_expand "movmemsi"
16416   [(use (match_operand:BLK 0 "memory_operand" ""))
16417    (use (match_operand:BLK 1 "memory_operand" ""))
16418    (use (match_operand:SI 2 "nonmemory_operand" ""))
16419    (use (match_operand:SI 3 "const_int_operand" ""))]
16420   "! optimize_size"
16422  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16423    DONE;
16424  else
16425    FAIL;
16428 (define_expand "movmemdi"
16429   [(use (match_operand:BLK 0 "memory_operand" ""))
16430    (use (match_operand:BLK 1 "memory_operand" ""))
16431    (use (match_operand:DI 2 "nonmemory_operand" ""))
16432    (use (match_operand:DI 3 "const_int_operand" ""))]
16433   "TARGET_64BIT"
16435  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16436    DONE;
16437  else
16438    FAIL;
16441 ;; Most CPUs don't like single string operations
16442 ;; Handle this case here to simplify previous expander.
16444 (define_expand "strmov"
16445   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16446    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16447    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16448               (clobber (reg:CC FLAGS_REG))])
16449    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16450               (clobber (reg:CC FLAGS_REG))])]
16451   ""
16453   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16455   /* If .md ever supports :P for Pmode, these can be directly
16456      in the pattern above.  */
16457   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16458   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16460   if (TARGET_SINGLE_STRINGOP || optimize_size)
16461     {
16462       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16463                                       operands[2], operands[3],
16464                                       operands[5], operands[6]));
16465       DONE;
16466     }
16468   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16471 (define_expand "strmov_singleop"
16472   [(parallel [(set (match_operand 1 "memory_operand" "")
16473                    (match_operand 3 "memory_operand" ""))
16474               (set (match_operand 0 "register_operand" "")
16475                    (match_operand 4 "" ""))
16476               (set (match_operand 2 "register_operand" "")
16477                    (match_operand 5 "" ""))
16478               (use (reg:SI DIRFLAG_REG))])]
16479   "TARGET_SINGLE_STRINGOP || optimize_size"
16480   "")
16482 (define_insn "*strmovdi_rex_1"
16483   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16484         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16485    (set (match_operand:DI 0 "register_operand" "=D")
16486         (plus:DI (match_dup 2)
16487                  (const_int 8)))
16488    (set (match_operand:DI 1 "register_operand" "=S")
16489         (plus:DI (match_dup 3)
16490                  (const_int 8)))
16491    (use (reg:SI DIRFLAG_REG))]
16492   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16493   "movsq"
16494   [(set_attr "type" "str")
16495    (set_attr "mode" "DI")
16496    (set_attr "memory" "both")])
16498 (define_insn "*strmovsi_1"
16499   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16500         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16501    (set (match_operand:SI 0 "register_operand" "=D")
16502         (plus:SI (match_dup 2)
16503                  (const_int 4)))
16504    (set (match_operand:SI 1 "register_operand" "=S")
16505         (plus:SI (match_dup 3)
16506                  (const_int 4)))
16507    (use (reg:SI DIRFLAG_REG))]
16508   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16509   "{movsl|movsd}"
16510   [(set_attr "type" "str")
16511    (set_attr "mode" "SI")
16512    (set_attr "memory" "both")])
16514 (define_insn "*strmovsi_rex_1"
16515   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16516         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16517    (set (match_operand:DI 0 "register_operand" "=D")
16518         (plus:DI (match_dup 2)
16519                  (const_int 4)))
16520    (set (match_operand:DI 1 "register_operand" "=S")
16521         (plus:DI (match_dup 3)
16522                  (const_int 4)))
16523    (use (reg:SI DIRFLAG_REG))]
16524   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16525   "{movsl|movsd}"
16526   [(set_attr "type" "str")
16527    (set_attr "mode" "SI")
16528    (set_attr "memory" "both")])
16530 (define_insn "*strmovhi_1"
16531   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16532         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16533    (set (match_operand:SI 0 "register_operand" "=D")
16534         (plus:SI (match_dup 2)
16535                  (const_int 2)))
16536    (set (match_operand:SI 1 "register_operand" "=S")
16537         (plus:SI (match_dup 3)
16538                  (const_int 2)))
16539    (use (reg:SI DIRFLAG_REG))]
16540   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16541   "movsw"
16542   [(set_attr "type" "str")
16543    (set_attr "memory" "both")
16544    (set_attr "mode" "HI")])
16546 (define_insn "*strmovhi_rex_1"
16547   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16548         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16549    (set (match_operand:DI 0 "register_operand" "=D")
16550         (plus:DI (match_dup 2)
16551                  (const_int 2)))
16552    (set (match_operand:DI 1 "register_operand" "=S")
16553         (plus:DI (match_dup 3)
16554                  (const_int 2)))
16555    (use (reg:SI DIRFLAG_REG))]
16556   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16557   "movsw"
16558   [(set_attr "type" "str")
16559    (set_attr "memory" "both")
16560    (set_attr "mode" "HI")])
16562 (define_insn "*strmovqi_1"
16563   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16564         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16565    (set (match_operand:SI 0 "register_operand" "=D")
16566         (plus:SI (match_dup 2)
16567                  (const_int 1)))
16568    (set (match_operand:SI 1 "register_operand" "=S")
16569         (plus:SI (match_dup 3)
16570                  (const_int 1)))
16571    (use (reg:SI DIRFLAG_REG))]
16572   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16573   "movsb"
16574   [(set_attr "type" "str")
16575    (set_attr "memory" "both")
16576    (set_attr "mode" "QI")])
16578 (define_insn "*strmovqi_rex_1"
16579   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16580         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16581    (set (match_operand:DI 0 "register_operand" "=D")
16582         (plus:DI (match_dup 2)
16583                  (const_int 1)))
16584    (set (match_operand:DI 1 "register_operand" "=S")
16585         (plus:DI (match_dup 3)
16586                  (const_int 1)))
16587    (use (reg:SI DIRFLAG_REG))]
16588   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16589   "movsb"
16590   [(set_attr "type" "str")
16591    (set_attr "memory" "both")
16592    (set_attr "mode" "QI")])
16594 (define_expand "rep_mov"
16595   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16596               (set (match_operand 0 "register_operand" "")
16597                    (match_operand 5 "" ""))
16598               (set (match_operand 2 "register_operand" "")
16599                    (match_operand 6 "" ""))
16600               (set (match_operand 1 "memory_operand" "")
16601                    (match_operand 3 "memory_operand" ""))
16602               (use (match_dup 4))
16603               (use (reg:SI DIRFLAG_REG))])]
16604   ""
16605   "")
16607 (define_insn "*rep_movdi_rex64"
16608   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16609    (set (match_operand:DI 0 "register_operand" "=D") 
16610         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16611                             (const_int 3))
16612                  (match_operand:DI 3 "register_operand" "0")))
16613    (set (match_operand:DI 1 "register_operand" "=S") 
16614         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16615                  (match_operand:DI 4 "register_operand" "1")))
16616    (set (mem:BLK (match_dup 3))
16617         (mem:BLK (match_dup 4)))
16618    (use (match_dup 5))
16619    (use (reg:SI DIRFLAG_REG))]
16620   "TARGET_64BIT"
16621   "{rep\;movsq|rep movsq}"
16622   [(set_attr "type" "str")
16623    (set_attr "prefix_rep" "1")
16624    (set_attr "memory" "both")
16625    (set_attr "mode" "DI")])
16627 (define_insn "*rep_movsi"
16628   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16629    (set (match_operand:SI 0 "register_operand" "=D") 
16630         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16631                             (const_int 2))
16632                  (match_operand:SI 3 "register_operand" "0")))
16633    (set (match_operand:SI 1 "register_operand" "=S") 
16634         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16635                  (match_operand:SI 4 "register_operand" "1")))
16636    (set (mem:BLK (match_dup 3))
16637         (mem:BLK (match_dup 4)))
16638    (use (match_dup 5))
16639    (use (reg:SI DIRFLAG_REG))]
16640   "!TARGET_64BIT"
16641   "{rep\;movsl|rep movsd}"
16642   [(set_attr "type" "str")
16643    (set_attr "prefix_rep" "1")
16644    (set_attr "memory" "both")
16645    (set_attr "mode" "SI")])
16647 (define_insn "*rep_movsi_rex64"
16648   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16649    (set (match_operand:DI 0 "register_operand" "=D") 
16650         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16651                             (const_int 2))
16652                  (match_operand:DI 3 "register_operand" "0")))
16653    (set (match_operand:DI 1 "register_operand" "=S") 
16654         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16655                  (match_operand:DI 4 "register_operand" "1")))
16656    (set (mem:BLK (match_dup 3))
16657         (mem:BLK (match_dup 4)))
16658    (use (match_dup 5))
16659    (use (reg:SI DIRFLAG_REG))]
16660   "TARGET_64BIT"
16661   "{rep\;movsl|rep movsd}"
16662   [(set_attr "type" "str")
16663    (set_attr "prefix_rep" "1")
16664    (set_attr "memory" "both")
16665    (set_attr "mode" "SI")])
16667 (define_insn "*rep_movqi"
16668   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16669    (set (match_operand:SI 0 "register_operand" "=D") 
16670         (plus:SI (match_operand:SI 3 "register_operand" "0")
16671                  (match_operand:SI 5 "register_operand" "2")))
16672    (set (match_operand:SI 1 "register_operand" "=S") 
16673         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16674    (set (mem:BLK (match_dup 3))
16675         (mem:BLK (match_dup 4)))
16676    (use (match_dup 5))
16677    (use (reg:SI DIRFLAG_REG))]
16678   "!TARGET_64BIT"
16679   "{rep\;movsb|rep movsb}"
16680   [(set_attr "type" "str")
16681    (set_attr "prefix_rep" "1")
16682    (set_attr "memory" "both")
16683    (set_attr "mode" "SI")])
16685 (define_insn "*rep_movqi_rex64"
16686   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16687    (set (match_operand:DI 0 "register_operand" "=D") 
16688         (plus:DI (match_operand:DI 3 "register_operand" "0")
16689                  (match_operand:DI 5 "register_operand" "2")))
16690    (set (match_operand:DI 1 "register_operand" "=S") 
16691         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16692    (set (mem:BLK (match_dup 3))
16693         (mem:BLK (match_dup 4)))
16694    (use (match_dup 5))
16695    (use (reg:SI DIRFLAG_REG))]
16696   "TARGET_64BIT"
16697   "{rep\;movsb|rep movsb}"
16698   [(set_attr "type" "str")
16699    (set_attr "prefix_rep" "1")
16700    (set_attr "memory" "both")
16701    (set_attr "mode" "SI")])
16703 (define_expand "clrmemsi"
16704    [(use (match_operand:BLK 0 "memory_operand" ""))
16705     (use (match_operand:SI 1 "nonmemory_operand" ""))
16706     (use (match_operand 2 "const_int_operand" ""))]
16707   ""
16709  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16710    DONE;
16711  else
16712    FAIL;
16715 (define_expand "clrmemdi"
16716    [(use (match_operand:BLK 0 "memory_operand" ""))
16717     (use (match_operand:DI 1 "nonmemory_operand" ""))
16718     (use (match_operand 2 "const_int_operand" ""))]
16719   "TARGET_64BIT"
16721  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16722    DONE;
16723  else
16724    FAIL;
16727 ;; Most CPUs don't like single string operations
16728 ;; Handle this case here to simplify previous expander.
16730 (define_expand "strset"
16731   [(set (match_operand 1 "memory_operand" "")
16732         (match_operand 2 "register_operand" ""))
16733    (parallel [(set (match_operand 0 "register_operand" "")
16734                    (match_dup 3))
16735               (clobber (reg:CC FLAGS_REG))])]
16736   ""
16738   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16739     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16741   /* If .md ever supports :P for Pmode, this can be directly
16742      in the pattern above.  */
16743   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16744                               GEN_INT (GET_MODE_SIZE (GET_MODE
16745                                                       (operands[2]))));
16746   if (TARGET_SINGLE_STRINGOP || optimize_size)
16747     {
16748       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16749                                       operands[3]));
16750       DONE;
16751     }
16754 (define_expand "strset_singleop"
16755   [(parallel [(set (match_operand 1 "memory_operand" "")
16756                    (match_operand 2 "register_operand" ""))
16757               (set (match_operand 0 "register_operand" "")
16758                    (match_operand 3 "" ""))
16759               (use (reg:SI DIRFLAG_REG))])]
16760   "TARGET_SINGLE_STRINGOP || optimize_size"
16761   "")
16763 (define_insn "*strsetdi_rex_1"
16764   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16765         (match_operand:DI 2 "register_operand" "a"))
16766    (set (match_operand:DI 0 "register_operand" "=D")
16767         (plus:DI (match_dup 1)
16768                  (const_int 8)))
16769    (use (reg:SI DIRFLAG_REG))]
16770   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16771   "stosq"
16772   [(set_attr "type" "str")
16773    (set_attr "memory" "store")
16774    (set_attr "mode" "DI")])
16776 (define_insn "*strsetsi_1"
16777   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16778         (match_operand:SI 2 "register_operand" "a"))
16779    (set (match_operand:SI 0 "register_operand" "=D")
16780         (plus:SI (match_dup 1)
16781                  (const_int 4)))
16782    (use (reg:SI DIRFLAG_REG))]
16783   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16784   "{stosl|stosd}"
16785   [(set_attr "type" "str")
16786    (set_attr "memory" "store")
16787    (set_attr "mode" "SI")])
16789 (define_insn "*strsetsi_rex_1"
16790   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16791         (match_operand:SI 2 "register_operand" "a"))
16792    (set (match_operand:DI 0 "register_operand" "=D")
16793         (plus:DI (match_dup 1)
16794                  (const_int 4)))
16795    (use (reg:SI DIRFLAG_REG))]
16796   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16797   "{stosl|stosd}"
16798   [(set_attr "type" "str")
16799    (set_attr "memory" "store")
16800    (set_attr "mode" "SI")])
16802 (define_insn "*strsethi_1"
16803   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16804         (match_operand:HI 2 "register_operand" "a"))
16805    (set (match_operand:SI 0 "register_operand" "=D")
16806         (plus:SI (match_dup 1)
16807                  (const_int 2)))
16808    (use (reg:SI DIRFLAG_REG))]
16809   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16810   "stosw"
16811   [(set_attr "type" "str")
16812    (set_attr "memory" "store")
16813    (set_attr "mode" "HI")])
16815 (define_insn "*strsethi_rex_1"
16816   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16817         (match_operand:HI 2 "register_operand" "a"))
16818    (set (match_operand:DI 0 "register_operand" "=D")
16819         (plus:DI (match_dup 1)
16820                  (const_int 2)))
16821    (use (reg:SI DIRFLAG_REG))]
16822   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16823   "stosw"
16824   [(set_attr "type" "str")
16825    (set_attr "memory" "store")
16826    (set_attr "mode" "HI")])
16828 (define_insn "*strsetqi_1"
16829   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16830         (match_operand:QI 2 "register_operand" "a"))
16831    (set (match_operand:SI 0 "register_operand" "=D")
16832         (plus:SI (match_dup 1)
16833                  (const_int 1)))
16834    (use (reg:SI DIRFLAG_REG))]
16835   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16836   "stosb"
16837   [(set_attr "type" "str")
16838    (set_attr "memory" "store")
16839    (set_attr "mode" "QI")])
16841 (define_insn "*strsetqi_rex_1"
16842   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16843         (match_operand:QI 2 "register_operand" "a"))
16844    (set (match_operand:DI 0 "register_operand" "=D")
16845         (plus:DI (match_dup 1)
16846                  (const_int 1)))
16847    (use (reg:SI DIRFLAG_REG))]
16848   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16849   "stosb"
16850   [(set_attr "type" "str")
16851    (set_attr "memory" "store")
16852    (set_attr "mode" "QI")])
16854 (define_expand "rep_stos"
16855   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16856               (set (match_operand 0 "register_operand" "")
16857                    (match_operand 4 "" ""))
16858               (set (match_operand 2 "memory_operand" "") (const_int 0))
16859               (use (match_operand 3 "register_operand" ""))
16860               (use (match_dup 1))
16861               (use (reg:SI DIRFLAG_REG))])]
16862   ""
16863   "")
16865 (define_insn "*rep_stosdi_rex64"
16866   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16867    (set (match_operand:DI 0 "register_operand" "=D") 
16868         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16869                             (const_int 3))
16870                  (match_operand:DI 3 "register_operand" "0")))
16871    (set (mem:BLK (match_dup 3))
16872         (const_int 0))
16873    (use (match_operand:DI 2 "register_operand" "a"))
16874    (use (match_dup 4))
16875    (use (reg:SI DIRFLAG_REG))]
16876   "TARGET_64BIT"
16877   "{rep\;stosq|rep stosq}"
16878   [(set_attr "type" "str")
16879    (set_attr "prefix_rep" "1")
16880    (set_attr "memory" "store")
16881    (set_attr "mode" "DI")])
16883 (define_insn "*rep_stossi"
16884   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16885    (set (match_operand:SI 0 "register_operand" "=D") 
16886         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16887                             (const_int 2))
16888                  (match_operand:SI 3 "register_operand" "0")))
16889    (set (mem:BLK (match_dup 3))
16890         (const_int 0))
16891    (use (match_operand:SI 2 "register_operand" "a"))
16892    (use (match_dup 4))
16893    (use (reg:SI DIRFLAG_REG))]
16894   "!TARGET_64BIT"
16895   "{rep\;stosl|rep stosd}"
16896   [(set_attr "type" "str")
16897    (set_attr "prefix_rep" "1")
16898    (set_attr "memory" "store")
16899    (set_attr "mode" "SI")])
16901 (define_insn "*rep_stossi_rex64"
16902   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16903    (set (match_operand:DI 0 "register_operand" "=D") 
16904         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16905                             (const_int 2))
16906                  (match_operand:DI 3 "register_operand" "0")))
16907    (set (mem:BLK (match_dup 3))
16908         (const_int 0))
16909    (use (match_operand:SI 2 "register_operand" "a"))
16910    (use (match_dup 4))
16911    (use (reg:SI DIRFLAG_REG))]
16912   "TARGET_64BIT"
16913   "{rep\;stosl|rep stosd}"
16914   [(set_attr "type" "str")
16915    (set_attr "prefix_rep" "1")
16916    (set_attr "memory" "store")
16917    (set_attr "mode" "SI")])
16919 (define_insn "*rep_stosqi"
16920   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16921    (set (match_operand:SI 0 "register_operand" "=D") 
16922         (plus:SI (match_operand:SI 3 "register_operand" "0")
16923                  (match_operand:SI 4 "register_operand" "1")))
16924    (set (mem:BLK (match_dup 3))
16925         (const_int 0))
16926    (use (match_operand:QI 2 "register_operand" "a"))
16927    (use (match_dup 4))
16928    (use (reg:SI DIRFLAG_REG))]
16929   "!TARGET_64BIT"
16930   "{rep\;stosb|rep stosb}"
16931   [(set_attr "type" "str")
16932    (set_attr "prefix_rep" "1")
16933    (set_attr "memory" "store")
16934    (set_attr "mode" "QI")])
16936 (define_insn "*rep_stosqi_rex64"
16937   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16938    (set (match_operand:DI 0 "register_operand" "=D") 
16939         (plus:DI (match_operand:DI 3 "register_operand" "0")
16940                  (match_operand:DI 4 "register_operand" "1")))
16941    (set (mem:BLK (match_dup 3))
16942         (const_int 0))
16943    (use (match_operand:QI 2 "register_operand" "a"))
16944    (use (match_dup 4))
16945    (use (reg:SI DIRFLAG_REG))]
16946   "TARGET_64BIT"
16947   "{rep\;stosb|rep stosb}"
16948   [(set_attr "type" "str")
16949    (set_attr "prefix_rep" "1")
16950    (set_attr "memory" "store")
16951    (set_attr "mode" "QI")])
16953 (define_expand "cmpstrsi"
16954   [(set (match_operand:SI 0 "register_operand" "")
16955         (compare:SI (match_operand:BLK 1 "general_operand" "")
16956                     (match_operand:BLK 2 "general_operand" "")))
16957    (use (match_operand 3 "general_operand" ""))
16958    (use (match_operand 4 "immediate_operand" ""))]
16959   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16961   rtx addr1, addr2, out, outlow, count, countreg, align;
16963   /* Can't use this if the user has appropriated esi or edi.  */
16964   if (global_regs[4] || global_regs[5])
16965     FAIL;
16967   out = operands[0];
16968   if (GET_CODE (out) != REG)
16969     out = gen_reg_rtx (SImode);
16971   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16972   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16973   if (addr1 != XEXP (operands[1], 0))
16974     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16975   if (addr2 != XEXP (operands[2], 0))
16976     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16978   count = operands[3];
16979   countreg = ix86_zero_extend_to_Pmode (count);
16981   /* %%% Iff we are testing strict equality, we can use known alignment
16982      to good advantage.  This may be possible with combine, particularly
16983      once cc0 is dead.  */
16984   align = operands[4];
16986   emit_insn (gen_cld ());
16987   if (GET_CODE (count) == CONST_INT)
16988     {
16989       if (INTVAL (count) == 0)
16990         {
16991           emit_move_insn (operands[0], const0_rtx);
16992           DONE;
16993         }
16994       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16995                                     operands[1], operands[2]));
16996     }
16997   else
16998     {
16999       if (TARGET_64BIT)
17000         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17001       else
17002         emit_insn (gen_cmpsi_1 (countreg, countreg));
17003       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17004                                  operands[1], operands[2]));
17005     }
17007   outlow = gen_lowpart (QImode, out);
17008   emit_insn (gen_cmpintqi (outlow));
17009   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17011   if (operands[0] != out)
17012     emit_move_insn (operands[0], out);
17014   DONE;
17017 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17019 (define_expand "cmpintqi"
17020   [(set (match_dup 1)
17021         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17022    (set (match_dup 2)
17023         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17024    (parallel [(set (match_operand:QI 0 "register_operand" "")
17025                    (minus:QI (match_dup 1)
17026                              (match_dup 2)))
17027               (clobber (reg:CC FLAGS_REG))])]
17028   ""
17029   "operands[1] = gen_reg_rtx (QImode);
17030    operands[2] = gen_reg_rtx (QImode);")
17032 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17033 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17035 (define_expand "cmpstrqi_nz_1"
17036   [(parallel [(set (reg:CC FLAGS_REG)
17037                    (compare:CC (match_operand 4 "memory_operand" "")
17038                                (match_operand 5 "memory_operand" "")))
17039               (use (match_operand 2 "register_operand" ""))
17040               (use (match_operand:SI 3 "immediate_operand" ""))
17041               (use (reg:SI DIRFLAG_REG))
17042               (clobber (match_operand 0 "register_operand" ""))
17043               (clobber (match_operand 1 "register_operand" ""))
17044               (clobber (match_dup 2))])]
17045   ""
17046   "")
17048 (define_insn "*cmpstrqi_nz_1"
17049   [(set (reg:CC FLAGS_REG)
17050         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17051                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17052    (use (match_operand:SI 6 "register_operand" "2"))
17053    (use (match_operand:SI 3 "immediate_operand" "i"))
17054    (use (reg:SI DIRFLAG_REG))
17055    (clobber (match_operand:SI 0 "register_operand" "=S"))
17056    (clobber (match_operand:SI 1 "register_operand" "=D"))
17057    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17058   "!TARGET_64BIT"
17059   "repz{\;| }cmpsb"
17060   [(set_attr "type" "str")
17061    (set_attr "mode" "QI")
17062    (set_attr "prefix_rep" "1")])
17064 (define_insn "*cmpstrqi_nz_rex_1"
17065   [(set (reg:CC FLAGS_REG)
17066         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17067                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17068    (use (match_operand:DI 6 "register_operand" "2"))
17069    (use (match_operand:SI 3 "immediate_operand" "i"))
17070    (use (reg:SI DIRFLAG_REG))
17071    (clobber (match_operand:DI 0 "register_operand" "=S"))
17072    (clobber (match_operand:DI 1 "register_operand" "=D"))
17073    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17074   "TARGET_64BIT"
17075   "repz{\;| }cmpsb"
17076   [(set_attr "type" "str")
17077    (set_attr "mode" "QI")
17078    (set_attr "prefix_rep" "1")])
17080 ;; The same, but the count is not known to not be zero.
17082 (define_expand "cmpstrqi_1"
17083   [(parallel [(set (reg:CC FLAGS_REG)
17084                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17085                                      (const_int 0))
17086                   (compare:CC (match_operand 4 "memory_operand" "")
17087                               (match_operand 5 "memory_operand" ""))
17088                   (const_int 0)))
17089               (use (match_operand:SI 3 "immediate_operand" ""))
17090               (use (reg:CC FLAGS_REG))
17091               (use (reg:SI DIRFLAG_REG))
17092               (clobber (match_operand 0 "register_operand" ""))
17093               (clobber (match_operand 1 "register_operand" ""))
17094               (clobber (match_dup 2))])]
17095   ""
17096   "")
17098 (define_insn "*cmpstrqi_1"
17099   [(set (reg:CC FLAGS_REG)
17100         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17101                              (const_int 0))
17102           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17103                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17104           (const_int 0)))
17105    (use (match_operand:SI 3 "immediate_operand" "i"))
17106    (use (reg:CC FLAGS_REG))
17107    (use (reg:SI DIRFLAG_REG))
17108    (clobber (match_operand:SI 0 "register_operand" "=S"))
17109    (clobber (match_operand:SI 1 "register_operand" "=D"))
17110    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17111   "!TARGET_64BIT"
17112   "repz{\;| }cmpsb"
17113   [(set_attr "type" "str")
17114    (set_attr "mode" "QI")
17115    (set_attr "prefix_rep" "1")])
17117 (define_insn "*cmpstrqi_rex_1"
17118   [(set (reg:CC FLAGS_REG)
17119         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17120                              (const_int 0))
17121           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17122                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17123           (const_int 0)))
17124    (use (match_operand:SI 3 "immediate_operand" "i"))
17125    (use (reg:CC FLAGS_REG))
17126    (use (reg:SI DIRFLAG_REG))
17127    (clobber (match_operand:DI 0 "register_operand" "=S"))
17128    (clobber (match_operand:DI 1 "register_operand" "=D"))
17129    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17130   "TARGET_64BIT"
17131   "repz{\;| }cmpsb"
17132   [(set_attr "type" "str")
17133    (set_attr "mode" "QI")
17134    (set_attr "prefix_rep" "1")])
17136 (define_expand "strlensi"
17137   [(set (match_operand:SI 0 "register_operand" "")
17138         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17139                     (match_operand:QI 2 "immediate_operand" "")
17140                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17141   ""
17143  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17144    DONE;
17145  else
17146    FAIL;
17149 (define_expand "strlendi"
17150   [(set (match_operand:DI 0 "register_operand" "")
17151         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17152                     (match_operand:QI 2 "immediate_operand" "")
17153                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17154   ""
17156  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17157    DONE;
17158  else
17159    FAIL;
17162 (define_expand "strlenqi_1"
17163   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17164               (use (reg:SI DIRFLAG_REG))
17165               (clobber (match_operand 1 "register_operand" ""))
17166               (clobber (reg:CC FLAGS_REG))])]
17167   ""
17168   "")
17170 (define_insn "*strlenqi_1"
17171   [(set (match_operand:SI 0 "register_operand" "=&c")
17172         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17173                     (match_operand:QI 2 "register_operand" "a")
17174                     (match_operand:SI 3 "immediate_operand" "i")
17175                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17176    (use (reg:SI DIRFLAG_REG))
17177    (clobber (match_operand:SI 1 "register_operand" "=D"))
17178    (clobber (reg:CC FLAGS_REG))]
17179   "!TARGET_64BIT"
17180   "repnz{\;| }scasb"
17181   [(set_attr "type" "str")
17182    (set_attr "mode" "QI")
17183    (set_attr "prefix_rep" "1")])
17185 (define_insn "*strlenqi_rex_1"
17186   [(set (match_operand:DI 0 "register_operand" "=&c")
17187         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17188                     (match_operand:QI 2 "register_operand" "a")
17189                     (match_operand:DI 3 "immediate_operand" "i")
17190                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17191    (use (reg:SI DIRFLAG_REG))
17192    (clobber (match_operand:DI 1 "register_operand" "=D"))
17193    (clobber (reg:CC FLAGS_REG))]
17194   "TARGET_64BIT"
17195   "repnz{\;| }scasb"
17196   [(set_attr "type" "str")
17197    (set_attr "mode" "QI")
17198    (set_attr "prefix_rep" "1")])
17200 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17201 ;; handled in combine, but it is not currently up to the task.
17202 ;; When used for their truth value, the cmpstr* expanders generate
17203 ;; code like this:
17205 ;;   repz cmpsb
17206 ;;   seta       %al
17207 ;;   setb       %dl
17208 ;;   cmpb       %al, %dl
17209 ;;   jcc        label
17211 ;; The intermediate three instructions are unnecessary.
17213 ;; This one handles cmpstr*_nz_1...
17214 (define_peephole2
17215   [(parallel[
17216      (set (reg:CC FLAGS_REG)
17217           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17218                       (mem:BLK (match_operand 5 "register_operand" ""))))
17219      (use (match_operand 6 "register_operand" ""))
17220      (use (match_operand:SI 3 "immediate_operand" ""))
17221      (use (reg:SI DIRFLAG_REG))
17222      (clobber (match_operand 0 "register_operand" ""))
17223      (clobber (match_operand 1 "register_operand" ""))
17224      (clobber (match_operand 2 "register_operand" ""))])
17225    (set (match_operand:QI 7 "register_operand" "")
17226         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17227    (set (match_operand:QI 8 "register_operand" "")
17228         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17229    (set (reg FLAGS_REG)
17230         (compare (match_dup 7) (match_dup 8)))
17231   ]
17232   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17233   [(parallel[
17234      (set (reg:CC FLAGS_REG)
17235           (compare:CC (mem:BLK (match_dup 4))
17236                       (mem:BLK (match_dup 5))))
17237      (use (match_dup 6))
17238      (use (match_dup 3))
17239      (use (reg:SI DIRFLAG_REG))
17240      (clobber (match_dup 0))
17241      (clobber (match_dup 1))
17242      (clobber (match_dup 2))])]
17243   "")
17245 ;; ...and this one handles cmpstr*_1.
17246 (define_peephole2
17247   [(parallel[
17248      (set (reg:CC FLAGS_REG)
17249           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17250                                (const_int 0))
17251             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17252                         (mem:BLK (match_operand 5 "register_operand" "")))
17253             (const_int 0)))
17254      (use (match_operand:SI 3 "immediate_operand" ""))
17255      (use (reg:CC FLAGS_REG))
17256      (use (reg:SI DIRFLAG_REG))
17257      (clobber (match_operand 0 "register_operand" ""))
17258      (clobber (match_operand 1 "register_operand" ""))
17259      (clobber (match_operand 2 "register_operand" ""))])
17260    (set (match_operand:QI 7 "register_operand" "")
17261         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17262    (set (match_operand:QI 8 "register_operand" "")
17263         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17264    (set (reg FLAGS_REG)
17265         (compare (match_dup 7) (match_dup 8)))
17266   ]
17267   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17268   [(parallel[
17269      (set (reg:CC FLAGS_REG)
17270           (if_then_else:CC (ne (match_dup 6)
17271                                (const_int 0))
17272             (compare:CC (mem:BLK (match_dup 4))
17273                         (mem:BLK (match_dup 5)))
17274             (const_int 0)))
17275      (use (match_dup 3))
17276      (use (reg:CC FLAGS_REG))
17277      (use (reg:SI DIRFLAG_REG))
17278      (clobber (match_dup 0))
17279      (clobber (match_dup 1))
17280      (clobber (match_dup 2))])]
17281   "")
17285 ;; Conditional move instructions.
17287 (define_expand "movdicc"
17288   [(set (match_operand:DI 0 "register_operand" "")
17289         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17290                          (match_operand:DI 2 "general_operand" "")
17291                          (match_operand:DI 3 "general_operand" "")))]
17292   "TARGET_64BIT"
17293   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17295 (define_insn "x86_movdicc_0_m1_rex64"
17296   [(set (match_operand:DI 0 "register_operand" "=r")
17297         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17298           (const_int -1)
17299           (const_int 0)))
17300    (clobber (reg:CC FLAGS_REG))]
17301   "TARGET_64BIT"
17302   "sbb{q}\t%0, %0"
17303   ; Since we don't have the proper number of operands for an alu insn,
17304   ; fill in all the blanks.
17305   [(set_attr "type" "alu")
17306    (set_attr "pent_pair" "pu")
17307    (set_attr "memory" "none")
17308    (set_attr "imm_disp" "false")
17309    (set_attr "mode" "DI")
17310    (set_attr "length_immediate" "0")])
17312 (define_insn "*movdicc_c_rex64"
17313   [(set (match_operand:DI 0 "register_operand" "=r,r")
17314         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17315                                 [(reg FLAGS_REG) (const_int 0)])
17316                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17317                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17318   "TARGET_64BIT && TARGET_CMOVE
17319    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17320   "@
17321    cmov%O2%C1\t{%2, %0|%0, %2}
17322    cmov%O2%c1\t{%3, %0|%0, %3}"
17323   [(set_attr "type" "icmov")
17324    (set_attr "mode" "DI")])
17326 (define_expand "movsicc"
17327   [(set (match_operand:SI 0 "register_operand" "")
17328         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17329                          (match_operand:SI 2 "general_operand" "")
17330                          (match_operand:SI 3 "general_operand" "")))]
17331   ""
17332   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17334 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17335 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17336 ;; So just document what we're doing explicitly.
17338 (define_insn "x86_movsicc_0_m1"
17339   [(set (match_operand:SI 0 "register_operand" "=r")
17340         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17341           (const_int -1)
17342           (const_int 0)))
17343    (clobber (reg:CC FLAGS_REG))]
17344   ""
17345   "sbb{l}\t%0, %0"
17346   ; Since we don't have the proper number of operands for an alu insn,
17347   ; fill in all the blanks.
17348   [(set_attr "type" "alu")
17349    (set_attr "pent_pair" "pu")
17350    (set_attr "memory" "none")
17351    (set_attr "imm_disp" "false")
17352    (set_attr "mode" "SI")
17353    (set_attr "length_immediate" "0")])
17355 (define_insn "*movsicc_noc"
17356   [(set (match_operand:SI 0 "register_operand" "=r,r")
17357         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17358                                 [(reg FLAGS_REG) (const_int 0)])
17359                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17360                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17361   "TARGET_CMOVE
17362    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17363   "@
17364    cmov%O2%C1\t{%2, %0|%0, %2}
17365    cmov%O2%c1\t{%3, %0|%0, %3}"
17366   [(set_attr "type" "icmov")
17367    (set_attr "mode" "SI")])
17369 (define_expand "movhicc"
17370   [(set (match_operand:HI 0 "register_operand" "")
17371         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17372                          (match_operand:HI 2 "general_operand" "")
17373                          (match_operand:HI 3 "general_operand" "")))]
17374   "TARGET_HIMODE_MATH"
17375   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17377 (define_insn "*movhicc_noc"
17378   [(set (match_operand:HI 0 "register_operand" "=r,r")
17379         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17380                                 [(reg FLAGS_REG) (const_int 0)])
17381                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17382                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17383   "TARGET_CMOVE
17384    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17385   "@
17386    cmov%O2%C1\t{%2, %0|%0, %2}
17387    cmov%O2%c1\t{%3, %0|%0, %3}"
17388   [(set_attr "type" "icmov")
17389    (set_attr "mode" "HI")])
17391 (define_expand "movqicc"
17392   [(set (match_operand:QI 0 "register_operand" "")
17393         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17394                          (match_operand:QI 2 "general_operand" "")
17395                          (match_operand:QI 3 "general_operand" "")))]
17396   "TARGET_QIMODE_MATH"
17397   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17399 (define_insn_and_split "*movqicc_noc"
17400   [(set (match_operand:QI 0 "register_operand" "=r,r")
17401         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17402                                 [(match_operand 4 "flags_reg_operand" "")
17403                                  (const_int 0)])
17404                       (match_operand:QI 2 "register_operand" "r,0")
17405                       (match_operand:QI 3 "register_operand" "0,r")))]
17406   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17407   "#"
17408   "&& reload_completed"
17409   [(set (match_dup 0)
17410         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17411                       (match_dup 2)
17412                       (match_dup 3)))]
17413   "operands[0] = gen_lowpart (SImode, operands[0]);
17414    operands[2] = gen_lowpart (SImode, operands[2]);
17415    operands[3] = gen_lowpart (SImode, operands[3]);"
17416   [(set_attr "type" "icmov")
17417    (set_attr "mode" "SI")])
17419 (define_expand "movsfcc"
17420   [(set (match_operand:SF 0 "register_operand" "")
17421         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17422                          (match_operand:SF 2 "register_operand" "")
17423                          (match_operand:SF 3 "register_operand" "")))]
17424   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17425   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17427 ;; These versions of min/max are aware of the instruction's behavior
17428 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17429 ;; should have used the smin/smax expanders in the first place.
17430 (define_insn "*movsfcc_1_sse_min"
17431   [(set (match_operand:SF 0 "register_operand" "=x")
17432         (if_then_else:SF
17433           (lt:SF (match_operand:SF 1 "register_operand" "0")
17434                  (match_operand:SF 2 "nonimmediate_operand" "xm"))
17435           (match_dup 1)
17436           (match_dup 2)))]
17437   "TARGET_SSE_MATH"
17438   "minss\t{%2, %0|%0, %2}"
17439   [(set_attr "type" "sseadd")
17440    (set_attr "mode" "SF")])
17442 (define_insn "*movsfcc_1_sse_max"
17443   [(set (match_operand:SF 0 "register_operand" "=x")
17444         (if_then_else:SF
17445           (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
17446                  (match_operand:SF 1 "nonimmediate_operand" "0"))
17447           (match_dup 1)
17448           (match_dup 2)))]
17449   "TARGET_SSE_MATH"
17450   "maxss\t{%2, %0|%0, %2}"
17451   [(set_attr "type" "sseadd")
17452    (set_attr "mode" "SF")])
17454 (define_insn_and_split "*movsfcc_1_sse"
17455   [(set (match_operand:SF 0 "register_operand" "=x,x,x")
17456         (if_then_else:SF
17457           (match_operator:SF 4 "sse_comparison_operator"
17458             [(match_operand:SF 5 "register_operand" "0,0,0")
17459              (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
17460           (match_operand:SF 2 "reg_or_0_operand" "C,x,x")
17461           (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
17462    (clobber (match_scratch:V4SF 1 "=&x,&x,&x"))]
17463   "TARGET_SSE_MATH"
17464   "#"
17465   "&& reload_completed"
17466   [(const_int 0)]
17468   ix86_split_sse_movcc (operands);
17469   DONE;
17472 (define_insn "*movsfcc_1_387"
17473   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17474         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17475                                 [(reg FLAGS_REG) (const_int 0)])
17476                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17477                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17478   "TARGET_80387 && TARGET_CMOVE
17479    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17480   "@
17481    fcmov%F1\t{%2, %0|%0, %2}
17482    fcmov%f1\t{%3, %0|%0, %3}
17483    cmov%O2%C1\t{%2, %0|%0, %2}
17484    cmov%O2%c1\t{%3, %0|%0, %3}"
17485   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17486    (set_attr "mode" "SF,SF,SI,SI")])
17488 (define_expand "movdfcc"
17489   [(set (match_operand:DF 0 "register_operand" "")
17490         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17491                          (match_operand:DF 2 "register_operand" "")
17492                          (match_operand:DF 3 "register_operand" "")))]
17493   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17494   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17496 ;; These versions of min/max are aware of the instruction's behavior
17497 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17498 ;; should have used the smin/smax expanders in the first place.
17499 (define_insn "*movdfcc_1_sse_min"
17500   [(set (match_operand:DF 0 "register_operand" "=x")
17501         (if_then_else:DF
17502           (lt:DF (match_operand:DF 1 "register_operand" "0")
17503                  (match_operand:DF 2 "nonimmediate_operand" "xm"))
17504           (match_dup 1)
17505           (match_dup 2)))]
17506   "TARGET_SSE2 && TARGET_SSE_MATH"
17507   "minsd\t{%2, %0|%0, %2}"
17508   [(set_attr "type" "sseadd")
17509    (set_attr "mode" "DF")])
17511 (define_insn "*movdfcc_1_sse_max"
17512   [(set (match_operand:DF 0 "register_operand" "=x")
17513         (if_then_else:DF
17514           (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
17515                  (match_operand:DF 1 "nonimmediate_operand" "0"))
17516           (match_dup 1)
17517           (match_dup 2)))]
17518   "TARGET_SSE2 && TARGET_SSE_MATH"
17519   "maxsd\t{%2, %0|%0, %2}"
17520   [(set_attr "type" "sseadd")
17521    (set_attr "mode" "DF")])
17523 (define_insn_and_split "*movdfcc_1_sse"
17524   [(set (match_operand:DF 0 "register_operand" "=x,x,x")
17525         (if_then_else:DF
17526           (match_operator:DF 4 "sse_comparison_operator"
17527             [(match_operand:DF 5 "register_operand" "0,0,0")
17528              (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
17529           (match_operand:DF 2 "reg_or_0_operand" "C,x,x")
17530           (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
17531    (clobber (match_scratch:V2DF 1 "=&x,&x,&x"))]
17532   "TARGET_SSE2 && TARGET_SSE_MATH"
17533   "#"
17534   "&& reload_completed"
17535   [(const_int 0)]
17537   ix86_split_sse_movcc (operands);
17538   DONE;
17541 (define_insn "*movdfcc_1"
17542   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17543         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17544                                 [(reg FLAGS_REG) (const_int 0)])
17545                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17546                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17547   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17548    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17549   "@
17550    fcmov%F1\t{%2, %0|%0, %2}
17551    fcmov%f1\t{%3, %0|%0, %3}
17552    #
17553    #"
17554   [(set_attr "type" "fcmov,fcmov,multi,multi")
17555    (set_attr "mode" "DF")])
17557 (define_insn "*movdfcc_1_rex64"
17558   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17559         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17560                                 [(reg FLAGS_REG) (const_int 0)])
17561                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17562                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17563   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17564    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17565   "@
17566    fcmov%F1\t{%2, %0|%0, %2}
17567    fcmov%f1\t{%3, %0|%0, %3}
17568    cmov%O2%C1\t{%2, %0|%0, %2}
17569    cmov%O2%c1\t{%3, %0|%0, %3}"
17570   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17571    (set_attr "mode" "DF")])
17573 (define_split
17574   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17575         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17576                                 [(match_operand 4 "flags_reg_operand" "")
17577                                  (const_int 0)])
17578                       (match_operand:DF 2 "nonimmediate_operand" "")
17579                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17580   "!TARGET_64BIT && reload_completed"
17581   [(set (match_dup 2)
17582         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17583                       (match_dup 5)
17584                       (match_dup 7)))
17585    (set (match_dup 3)
17586         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17587                       (match_dup 6)
17588                       (match_dup 8)))]
17589   "split_di (operands+2, 1, operands+5, operands+6);
17590    split_di (operands+3, 1, operands+7, operands+8);
17591    split_di (operands, 1, operands+2, operands+3);")
17593 (define_expand "movxfcc"
17594   [(set (match_operand:XF 0 "register_operand" "")
17595         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17596                          (match_operand:XF 2 "register_operand" "")
17597                          (match_operand:XF 3 "register_operand" "")))]
17598   "TARGET_80387 && TARGET_CMOVE"
17599   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17601 (define_insn "*movxfcc_1"
17602   [(set (match_operand:XF 0 "register_operand" "=f,f")
17603         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17604                                 [(reg FLAGS_REG) (const_int 0)])
17605                       (match_operand:XF 2 "register_operand" "f,0")
17606                       (match_operand:XF 3 "register_operand" "0,f")))]
17607   "TARGET_80387 && TARGET_CMOVE"
17608   "@
17609    fcmov%F1\t{%2, %0|%0, %2}
17610    fcmov%f1\t{%3, %0|%0, %3}"
17611   [(set_attr "type" "fcmov")
17612    (set_attr "mode" "XF")])
17614 ;; These versions of the min/max patterns are intentionally ignorant of
17615 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17616 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17617 ;; are undefined in this condition, we're certain this is correct.
17619 (define_insn "sminsf3"
17620   [(set (match_operand:SF 0 "register_operand" "=x")
17621         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17622                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17623   "TARGET_SSE_MATH"
17624   "minss\t{%2, %0|%0, %2}"
17625   [(set_attr "type" "sseadd")
17626    (set_attr "mode" "SF")])
17628 (define_insn "smaxsf3"
17629   [(set (match_operand:SF 0 "register_operand" "=x")
17630         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17631                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17632   "TARGET_SSE_MATH"
17633   "maxss\t{%2, %0|%0, %2}"
17634   [(set_attr "type" "sseadd")
17635    (set_attr "mode" "SF")])
17637 (define_insn "smindf3"
17638   [(set (match_operand:DF 0 "register_operand" "=x")
17639         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17640                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17641   "TARGET_SSE2 && TARGET_SSE_MATH"
17642   "minsd\t{%2, %0|%0, %2}"
17643   [(set_attr "type" "sseadd")
17644    (set_attr "mode" "DF")])
17646 (define_insn "smaxdf3"
17647   [(set (match_operand:DF 0 "register_operand" "=x")
17648         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17649                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17650   "TARGET_SSE2 && TARGET_SSE_MATH"
17651   "maxsd\t{%2, %0|%0, %2}"
17652   [(set_attr "type" "sseadd")
17653    (set_attr "mode" "DF")])
17655 ;; Conditional addition patterns
17656 (define_expand "addqicc"
17657   [(match_operand:QI 0 "register_operand" "")
17658    (match_operand 1 "comparison_operator" "")
17659    (match_operand:QI 2 "register_operand" "")
17660    (match_operand:QI 3 "const_int_operand" "")]
17661   ""
17662   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17664 (define_expand "addhicc"
17665   [(match_operand:HI 0 "register_operand" "")
17666    (match_operand 1 "comparison_operator" "")
17667    (match_operand:HI 2 "register_operand" "")
17668    (match_operand:HI 3 "const_int_operand" "")]
17669   ""
17670   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17672 (define_expand "addsicc"
17673   [(match_operand:SI 0 "register_operand" "")
17674    (match_operand 1 "comparison_operator" "")
17675    (match_operand:SI 2 "register_operand" "")
17676    (match_operand:SI 3 "const_int_operand" "")]
17677   ""
17678   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17680 (define_expand "adddicc"
17681   [(match_operand:DI 0 "register_operand" "")
17682    (match_operand 1 "comparison_operator" "")
17683    (match_operand:DI 2 "register_operand" "")
17684    (match_operand:DI 3 "const_int_operand" "")]
17685   "TARGET_64BIT"
17686   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17689 ;; Misc patterns (?)
17691 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17692 ;; Otherwise there will be nothing to keep
17693 ;; 
17694 ;; [(set (reg ebp) (reg esp))]
17695 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17696 ;;  (clobber (eflags)]
17697 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17699 ;; in proper program order.
17700 (define_insn "pro_epilogue_adjust_stack_1"
17701   [(set (match_operand:SI 0 "register_operand" "=r,r")
17702         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17703                  (match_operand:SI 2 "immediate_operand" "i,i")))
17704    (clobber (reg:CC FLAGS_REG))
17705    (clobber (mem:BLK (scratch)))]
17706   "!TARGET_64BIT"
17708   switch (get_attr_type (insn))
17709     {
17710     case TYPE_IMOV:
17711       return "mov{l}\t{%1, %0|%0, %1}";
17713     case TYPE_ALU:
17714       if (GET_CODE (operands[2]) == CONST_INT
17715           && (INTVAL (operands[2]) == 128
17716               || (INTVAL (operands[2]) < 0
17717                   && INTVAL (operands[2]) != -128)))
17718         {
17719           operands[2] = GEN_INT (-INTVAL (operands[2]));
17720           return "sub{l}\t{%2, %0|%0, %2}";
17721         }
17722       return "add{l}\t{%2, %0|%0, %2}";
17724     case TYPE_LEA:
17725       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17726       return "lea{l}\t{%a2, %0|%0, %a2}";
17728     default:
17729       abort ();
17730     }
17732   [(set (attr "type")
17733         (cond [(eq_attr "alternative" "0")
17734                  (const_string "alu")
17735                (match_operand:SI 2 "const0_operand" "")
17736                  (const_string "imov")
17737               ]
17738               (const_string "lea")))
17739    (set_attr "mode" "SI")])
17741 (define_insn "pro_epilogue_adjust_stack_rex64"
17742   [(set (match_operand:DI 0 "register_operand" "=r,r")
17743         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17744                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17745    (clobber (reg:CC FLAGS_REG))
17746    (clobber (mem:BLK (scratch)))]
17747   "TARGET_64BIT"
17749   switch (get_attr_type (insn))
17750     {
17751     case TYPE_IMOV:
17752       return "mov{q}\t{%1, %0|%0, %1}";
17754     case TYPE_ALU:
17755       if (GET_CODE (operands[2]) == CONST_INT
17756           /* Avoid overflows.  */
17757           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17758           && (INTVAL (operands[2]) == 128
17759               || (INTVAL (operands[2]) < 0
17760                   && INTVAL (operands[2]) != -128)))
17761         {
17762           operands[2] = GEN_INT (-INTVAL (operands[2]));
17763           return "sub{q}\t{%2, %0|%0, %2}";
17764         }
17765       return "add{q}\t{%2, %0|%0, %2}";
17767     case TYPE_LEA:
17768       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17769       return "lea{q}\t{%a2, %0|%0, %a2}";
17771     default:
17772       abort ();
17773     }
17775   [(set (attr "type")
17776         (cond [(eq_attr "alternative" "0")
17777                  (const_string "alu")
17778                (match_operand:DI 2 "const0_operand" "")
17779                  (const_string "imov")
17780               ]
17781               (const_string "lea")))
17782    (set_attr "mode" "DI")])
17784 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17785   [(set (match_operand:DI 0 "register_operand" "=r,r")
17786         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17787                  (match_operand:DI 3 "immediate_operand" "i,i")))
17788    (use (match_operand:DI 2 "register_operand" "r,r"))
17789    (clobber (reg:CC FLAGS_REG))
17790    (clobber (mem:BLK (scratch)))]
17791   "TARGET_64BIT"
17793   switch (get_attr_type (insn))
17794     {
17795     case TYPE_ALU:
17796       return "add{q}\t{%2, %0|%0, %2}";
17798     case TYPE_LEA:
17799       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17800       return "lea{q}\t{%a2, %0|%0, %a2}";
17802     default:
17803       abort ();
17804     }
17806   [(set_attr "type" "alu,lea")
17807    (set_attr "mode" "DI")])
17809 (define_expand "allocate_stack_worker"
17810   [(match_operand:SI 0 "register_operand" "")]
17811   "TARGET_STACK_PROBE"
17813   if (reload_completed)
17814     {
17815       if (TARGET_64BIT)
17816         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17817       else
17818         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17819     }
17820   else
17821     {
17822       if (TARGET_64BIT)
17823         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17824       else
17825         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17826     }
17827   DONE;
17830 (define_insn "allocate_stack_worker_1"
17831   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17832     UNSPECV_STACK_PROBE)
17833    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
17834    (clobber (match_scratch:SI 1 "=0"))
17835    (clobber (reg:CC FLAGS_REG))]
17836   "!TARGET_64BIT && TARGET_STACK_PROBE"
17837   "call\t__alloca"
17838   [(set_attr "type" "multi")
17839    (set_attr "length" "5")])
17841 (define_expand "allocate_stack_worker_postreload"
17842   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17843                                     UNSPECV_STACK_PROBE)
17844               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
17845               (clobber (match_dup 0))
17846               (clobber (reg:CC FLAGS_REG))])]
17847   ""
17848   "")
17850 (define_insn "allocate_stack_worker_rex64"
17851   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17852     UNSPECV_STACK_PROBE)
17853    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
17854    (clobber (match_scratch:DI 1 "=0"))
17855    (clobber (reg:CC FLAGS_REG))]
17856   "TARGET_64BIT && TARGET_STACK_PROBE"
17857   "call\t__alloca"
17858   [(set_attr "type" "multi")
17859    (set_attr "length" "5")])
17861 (define_expand "allocate_stack_worker_rex64_postreload"
17862   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17863                                     UNSPECV_STACK_PROBE)
17864               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
17865               (clobber (match_dup 0))
17866               (clobber (reg:CC FLAGS_REG))])]
17867   ""
17868   "")
17870 (define_expand "allocate_stack"
17871   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17872                    (minus:SI (reg:SI SP_REG)
17873                              (match_operand:SI 1 "general_operand" "")))
17874               (clobber (reg:CC FLAGS_REG))])
17875    (parallel [(set (reg:SI SP_REG)
17876                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
17877               (clobber (reg:CC FLAGS_REG))])]
17878   "TARGET_STACK_PROBE"
17880 #ifdef CHECK_STACK_LIMIT
17881   if (GET_CODE (operands[1]) == CONST_INT
17882       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17883     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17884                            operands[1]));
17885   else 
17886 #endif
17887     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17888                                                             operands[1])));
17890   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17891   DONE;
17894 (define_expand "builtin_setjmp_receiver"
17895   [(label_ref (match_operand 0 "" ""))]
17896   "!TARGET_64BIT && flag_pic"
17898   emit_insn (gen_set_got (pic_offset_table_rtx));
17899   DONE;
17902 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17904 (define_split
17905   [(set (match_operand 0 "register_operand" "")
17906         (match_operator 3 "promotable_binary_operator"
17907            [(match_operand 1 "register_operand" "")
17908             (match_operand 2 "aligned_operand" "")]))
17909    (clobber (reg:CC FLAGS_REG))]
17910   "! TARGET_PARTIAL_REG_STALL && reload_completed
17911    && ((GET_MODE (operands[0]) == HImode 
17912         && ((!optimize_size && !TARGET_FAST_PREFIX)
17913             || GET_CODE (operands[2]) != CONST_INT
17914             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17915        || (GET_MODE (operands[0]) == QImode 
17916            && (TARGET_PROMOTE_QImode || optimize_size)))"
17917   [(parallel [(set (match_dup 0)
17918                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17919               (clobber (reg:CC FLAGS_REG))])]
17920   "operands[0] = gen_lowpart (SImode, operands[0]);
17921    operands[1] = gen_lowpart (SImode, operands[1]);
17922    if (GET_CODE (operands[3]) != ASHIFT)
17923      operands[2] = gen_lowpart (SImode, operands[2]);
17924    PUT_MODE (operands[3], SImode);")
17926 ; Promote the QImode tests, as i386 has encoding of the AND
17927 ; instruction with 32-bit sign-extended immediate and thus the
17928 ; instruction size is unchanged, except in the %eax case for
17929 ; which it is increased by one byte, hence the ! optimize_size.
17930 (define_split
17931   [(set (match_operand 0 "flags_reg_operand" "")
17932         (match_operator 2 "compare_operator"
17933           [(and (match_operand 3 "aligned_operand" "")
17934                 (match_operand 4 "const_int_operand" ""))
17935            (const_int 0)]))
17936    (set (match_operand 1 "register_operand" "")
17937         (and (match_dup 3) (match_dup 4)))]
17938   "! TARGET_PARTIAL_REG_STALL && reload_completed
17939    /* Ensure that the operand will remain sign-extended immediate.  */
17940    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
17941    && ! optimize_size
17942    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17943        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
17944   [(parallel [(set (match_dup 0)
17945                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17946                                     (const_int 0)]))
17947               (set (match_dup 1)
17948                    (and:SI (match_dup 3) (match_dup 4)))])]
17950   operands[4]
17951     = gen_int_mode (INTVAL (operands[4])
17952                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17953   operands[1] = gen_lowpart (SImode, operands[1]);
17954   operands[3] = gen_lowpart (SImode, operands[3]);
17957 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17958 ; the TEST instruction with 32-bit sign-extended immediate and thus
17959 ; the instruction size would at least double, which is not what we
17960 ; want even with ! optimize_size.
17961 (define_split
17962   [(set (match_operand 0 "flags_reg_operand" "")
17963         (match_operator 1 "compare_operator"
17964           [(and (match_operand:HI 2 "aligned_operand" "")
17965                 (match_operand:HI 3 "const_int_operand" ""))
17966            (const_int 0)]))]
17967   "! TARGET_PARTIAL_REG_STALL && reload_completed
17968    /* Ensure that the operand will remain sign-extended immediate.  */
17969    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
17970    && ! TARGET_FAST_PREFIX
17971    && ! optimize_size"
17972   [(set (match_dup 0)
17973         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17974                          (const_int 0)]))]
17976   operands[3]
17977     = gen_int_mode (INTVAL (operands[3])
17978                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17979   operands[2] = gen_lowpart (SImode, operands[2]);
17982 (define_split
17983   [(set (match_operand 0 "register_operand" "")
17984         (neg (match_operand 1 "register_operand" "")))
17985    (clobber (reg:CC FLAGS_REG))]
17986   "! TARGET_PARTIAL_REG_STALL && reload_completed
17987    && (GET_MODE (operands[0]) == HImode
17988        || (GET_MODE (operands[0]) == QImode 
17989            && (TARGET_PROMOTE_QImode || optimize_size)))"
17990   [(parallel [(set (match_dup 0)
17991                    (neg:SI (match_dup 1)))
17992               (clobber (reg:CC FLAGS_REG))])]
17993   "operands[0] = gen_lowpart (SImode, operands[0]);
17994    operands[1] = gen_lowpart (SImode, operands[1]);")
17996 (define_split
17997   [(set (match_operand 0 "register_operand" "")
17998         (not (match_operand 1 "register_operand" "")))]
17999   "! TARGET_PARTIAL_REG_STALL && reload_completed
18000    && (GET_MODE (operands[0]) == HImode
18001        || (GET_MODE (operands[0]) == QImode 
18002            && (TARGET_PROMOTE_QImode || optimize_size)))"
18003   [(set (match_dup 0)
18004         (not:SI (match_dup 1)))]
18005   "operands[0] = gen_lowpart (SImode, operands[0]);
18006    operands[1] = gen_lowpart (SImode, operands[1]);")
18008 (define_split 
18009   [(set (match_operand 0 "register_operand" "")
18010         (if_then_else (match_operator 1 "comparison_operator" 
18011                                 [(reg FLAGS_REG) (const_int 0)])
18012                       (match_operand 2 "register_operand" "")
18013                       (match_operand 3 "register_operand" "")))]
18014   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18015    && (GET_MODE (operands[0]) == HImode
18016        || (GET_MODE (operands[0]) == QImode 
18017            && (TARGET_PROMOTE_QImode || optimize_size)))"
18018   [(set (match_dup 0)
18019         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18020   "operands[0] = gen_lowpart (SImode, operands[0]);
18021    operands[2] = gen_lowpart (SImode, operands[2]);
18022    operands[3] = gen_lowpart (SImode, operands[3]);")
18023                         
18025 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18026 ;; transform a complex memory operation into two memory to register operations.
18028 ;; Don't push memory operands
18029 (define_peephole2
18030   [(set (match_operand:SI 0 "push_operand" "")
18031         (match_operand:SI 1 "memory_operand" ""))
18032    (match_scratch:SI 2 "r")]
18033   "! optimize_size && ! TARGET_PUSH_MEMORY"
18034   [(set (match_dup 2) (match_dup 1))
18035    (set (match_dup 0) (match_dup 2))]
18036   "")
18038 (define_peephole2
18039   [(set (match_operand:DI 0 "push_operand" "")
18040         (match_operand:DI 1 "memory_operand" ""))
18041    (match_scratch:DI 2 "r")]
18042   "! optimize_size && ! TARGET_PUSH_MEMORY"
18043   [(set (match_dup 2) (match_dup 1))
18044    (set (match_dup 0) (match_dup 2))]
18045   "")
18047 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18048 ;; SImode pushes.
18049 (define_peephole2
18050   [(set (match_operand:SF 0 "push_operand" "")
18051         (match_operand:SF 1 "memory_operand" ""))
18052    (match_scratch:SF 2 "r")]
18053   "! optimize_size && ! TARGET_PUSH_MEMORY"
18054   [(set (match_dup 2) (match_dup 1))
18055    (set (match_dup 0) (match_dup 2))]
18056   "")
18058 (define_peephole2
18059   [(set (match_operand:HI 0 "push_operand" "")
18060         (match_operand:HI 1 "memory_operand" ""))
18061    (match_scratch:HI 2 "r")]
18062   "! optimize_size && ! TARGET_PUSH_MEMORY"
18063   [(set (match_dup 2) (match_dup 1))
18064    (set (match_dup 0) (match_dup 2))]
18065   "")
18067 (define_peephole2
18068   [(set (match_operand:QI 0 "push_operand" "")
18069         (match_operand:QI 1 "memory_operand" ""))
18070    (match_scratch:QI 2 "q")]
18071   "! optimize_size && ! TARGET_PUSH_MEMORY"
18072   [(set (match_dup 2) (match_dup 1))
18073    (set (match_dup 0) (match_dup 2))]
18074   "")
18076 ;; Don't move an immediate directly to memory when the instruction
18077 ;; gets too big.
18078 (define_peephole2
18079   [(match_scratch:SI 1 "r")
18080    (set (match_operand:SI 0 "memory_operand" "")
18081         (const_int 0))]
18082   "! optimize_size
18083    && ! TARGET_USE_MOV0
18084    && TARGET_SPLIT_LONG_MOVES
18085    && get_attr_length (insn) >= ix86_cost->large_insn
18086    && peep2_regno_dead_p (0, FLAGS_REG)"
18087   [(parallel [(set (match_dup 1) (const_int 0))
18088               (clobber (reg:CC FLAGS_REG))])
18089    (set (match_dup 0) (match_dup 1))]
18090   "")
18092 (define_peephole2
18093   [(match_scratch:HI 1 "r")
18094    (set (match_operand:HI 0 "memory_operand" "")
18095         (const_int 0))]
18096   "! optimize_size
18097    && ! TARGET_USE_MOV0
18098    && TARGET_SPLIT_LONG_MOVES
18099    && get_attr_length (insn) >= ix86_cost->large_insn
18100    && peep2_regno_dead_p (0, FLAGS_REG)"
18101   [(parallel [(set (match_dup 2) (const_int 0))
18102               (clobber (reg:CC FLAGS_REG))])
18103    (set (match_dup 0) (match_dup 1))]
18104   "operands[2] = gen_lowpart (SImode, operands[1]);")
18106 (define_peephole2
18107   [(match_scratch:QI 1 "q")
18108    (set (match_operand:QI 0 "memory_operand" "")
18109         (const_int 0))]
18110   "! optimize_size
18111    && ! TARGET_USE_MOV0
18112    && TARGET_SPLIT_LONG_MOVES
18113    && get_attr_length (insn) >= ix86_cost->large_insn
18114    && peep2_regno_dead_p (0, FLAGS_REG)"
18115   [(parallel [(set (match_dup 2) (const_int 0))
18116               (clobber (reg:CC FLAGS_REG))])
18117    (set (match_dup 0) (match_dup 1))]
18118   "operands[2] = gen_lowpart (SImode, operands[1]);")
18120 (define_peephole2
18121   [(match_scratch:SI 2 "r")
18122    (set (match_operand:SI 0 "memory_operand" "")
18123         (match_operand:SI 1 "immediate_operand" ""))]
18124   "! optimize_size
18125    && get_attr_length (insn) >= ix86_cost->large_insn
18126    && TARGET_SPLIT_LONG_MOVES"
18127   [(set (match_dup 2) (match_dup 1))
18128    (set (match_dup 0) (match_dup 2))]
18129   "")
18131 (define_peephole2
18132   [(match_scratch:HI 2 "r")
18133    (set (match_operand:HI 0 "memory_operand" "")
18134         (match_operand:HI 1 "immediate_operand" ""))]
18135   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18136   && TARGET_SPLIT_LONG_MOVES"
18137   [(set (match_dup 2) (match_dup 1))
18138    (set (match_dup 0) (match_dup 2))]
18139   "")
18141 (define_peephole2
18142   [(match_scratch:QI 2 "q")
18143    (set (match_operand:QI 0 "memory_operand" "")
18144         (match_operand:QI 1 "immediate_operand" ""))]
18145   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18146   && TARGET_SPLIT_LONG_MOVES"
18147   [(set (match_dup 2) (match_dup 1))
18148    (set (match_dup 0) (match_dup 2))]
18149   "")
18151 ;; Don't compare memory with zero, load and use a test instead.
18152 (define_peephole2
18153   [(set (match_operand 0 "flags_reg_operand" "")
18154         (match_operator 1 "compare_operator"
18155           [(match_operand:SI 2 "memory_operand" "")
18156            (const_int 0)]))
18157    (match_scratch:SI 3 "r")]
18158   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18159   [(set (match_dup 3) (match_dup 2))
18160    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18161   "")
18163 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18164 ;; Don't split NOTs with a displacement operand, because resulting XOR
18165 ;; will not be pairable anyway.
18167 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18168 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18169 ;; so this split helps here as well.
18171 ;; Note: Can't do this as a regular split because we can't get proper
18172 ;; lifetime information then.
18174 (define_peephole2
18175   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18176         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18177   "!optimize_size
18178    && peep2_regno_dead_p (0, FLAGS_REG)
18179    && ((TARGET_PENTIUM 
18180         && (GET_CODE (operands[0]) != MEM
18181             || !memory_displacement_operand (operands[0], SImode)))
18182        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18183   [(parallel [(set (match_dup 0)
18184                    (xor:SI (match_dup 1) (const_int -1)))
18185               (clobber (reg:CC FLAGS_REG))])]
18186   "")
18188 (define_peephole2
18189   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18190         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18191   "!optimize_size
18192    && peep2_regno_dead_p (0, FLAGS_REG)
18193    && ((TARGET_PENTIUM 
18194         && (GET_CODE (operands[0]) != MEM
18195             || !memory_displacement_operand (operands[0], HImode)))
18196        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18197   [(parallel [(set (match_dup 0)
18198                    (xor:HI (match_dup 1) (const_int -1)))
18199               (clobber (reg:CC FLAGS_REG))])]
18200   "")
18202 (define_peephole2
18203   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18204         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18205   "!optimize_size
18206    && peep2_regno_dead_p (0, FLAGS_REG)
18207    && ((TARGET_PENTIUM 
18208         && (GET_CODE (operands[0]) != MEM
18209             || !memory_displacement_operand (operands[0], QImode)))
18210        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18211   [(parallel [(set (match_dup 0)
18212                    (xor:QI (match_dup 1) (const_int -1)))
18213               (clobber (reg:CC FLAGS_REG))])]
18214   "")
18216 ;; Non pairable "test imm, reg" instructions can be translated to
18217 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18218 ;; byte opcode instead of two, have a short form for byte operands),
18219 ;; so do it for other CPUs as well.  Given that the value was dead,
18220 ;; this should not create any new dependencies.  Pass on the sub-word
18221 ;; versions if we're concerned about partial register stalls.
18223 (define_peephole2
18224   [(set (match_operand 0 "flags_reg_operand" "")
18225         (match_operator 1 "compare_operator"
18226           [(and:SI (match_operand:SI 2 "register_operand" "")
18227                    (match_operand:SI 3 "immediate_operand" ""))
18228            (const_int 0)]))]
18229   "ix86_match_ccmode (insn, CCNOmode)
18230    && (true_regnum (operands[2]) != 0
18231        || (GET_CODE (operands[3]) == CONST_INT
18232            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18233    && peep2_reg_dead_p (1, operands[2])"
18234   [(parallel
18235      [(set (match_dup 0)
18236            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18237                             (const_int 0)]))
18238       (set (match_dup 2)
18239            (and:SI (match_dup 2) (match_dup 3)))])]
18240   "")
18242 ;; We don't need to handle HImode case, because it will be promoted to SImode
18243 ;; on ! TARGET_PARTIAL_REG_STALL
18245 (define_peephole2
18246   [(set (match_operand 0 "flags_reg_operand" "")
18247         (match_operator 1 "compare_operator"
18248           [(and:QI (match_operand:QI 2 "register_operand" "")
18249                    (match_operand:QI 3 "immediate_operand" ""))
18250            (const_int 0)]))]
18251   "! TARGET_PARTIAL_REG_STALL
18252    && ix86_match_ccmode (insn, CCNOmode)
18253    && true_regnum (operands[2]) != 0
18254    && peep2_reg_dead_p (1, operands[2])"
18255   [(parallel
18256      [(set (match_dup 0)
18257            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18258                             (const_int 0)]))
18259       (set (match_dup 2)
18260            (and:QI (match_dup 2) (match_dup 3)))])]
18261   "")
18263 (define_peephole2
18264   [(set (match_operand 0 "flags_reg_operand" "")
18265         (match_operator 1 "compare_operator"
18266           [(and:SI
18267              (zero_extract:SI
18268                (match_operand 2 "ext_register_operand" "")
18269                (const_int 8)
18270                (const_int 8))
18271              (match_operand 3 "const_int_operand" ""))
18272            (const_int 0)]))]
18273   "! TARGET_PARTIAL_REG_STALL
18274    && ix86_match_ccmode (insn, CCNOmode)
18275    && true_regnum (operands[2]) != 0
18276    && peep2_reg_dead_p (1, operands[2])"
18277   [(parallel [(set (match_dup 0)
18278                    (match_op_dup 1
18279                      [(and:SI
18280                         (zero_extract:SI
18281                           (match_dup 2)
18282                           (const_int 8)
18283                           (const_int 8))
18284                         (match_dup 3))
18285                       (const_int 0)]))
18286               (set (zero_extract:SI (match_dup 2)
18287                                     (const_int 8)
18288                                     (const_int 8))
18289                    (and:SI 
18290                      (zero_extract:SI
18291                        (match_dup 2)
18292                        (const_int 8)
18293                        (const_int 8))
18294                      (match_dup 3)))])]
18295   "")
18297 ;; Don't do logical operations with memory inputs.
18298 (define_peephole2
18299   [(match_scratch:SI 2 "r")
18300    (parallel [(set (match_operand:SI 0 "register_operand" "")
18301                    (match_operator:SI 3 "arith_or_logical_operator"
18302                      [(match_dup 0)
18303                       (match_operand:SI 1 "memory_operand" "")]))
18304               (clobber (reg:CC FLAGS_REG))])]
18305   "! optimize_size && ! TARGET_READ_MODIFY"
18306   [(set (match_dup 2) (match_dup 1))
18307    (parallel [(set (match_dup 0)
18308                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18309               (clobber (reg:CC FLAGS_REG))])]
18310   "")
18312 (define_peephole2
18313   [(match_scratch:SI 2 "r")
18314    (parallel [(set (match_operand:SI 0 "register_operand" "")
18315                    (match_operator:SI 3 "arith_or_logical_operator"
18316                      [(match_operand:SI 1 "memory_operand" "")
18317                       (match_dup 0)]))
18318               (clobber (reg:CC FLAGS_REG))])]
18319   "! optimize_size && ! TARGET_READ_MODIFY"
18320   [(set (match_dup 2) (match_dup 1))
18321    (parallel [(set (match_dup 0)
18322                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18323               (clobber (reg:CC FLAGS_REG))])]
18324   "")
18326 ; Don't do logical operations with memory outputs
18328 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18329 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18330 ; the same decoder scheduling characteristics as the original.
18332 (define_peephole2
18333   [(match_scratch:SI 2 "r")
18334    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18335                    (match_operator:SI 3 "arith_or_logical_operator"
18336                      [(match_dup 0)
18337                       (match_operand:SI 1 "nonmemory_operand" "")]))
18338               (clobber (reg:CC FLAGS_REG))])]
18339   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18340   [(set (match_dup 2) (match_dup 0))
18341    (parallel [(set (match_dup 2)
18342                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18343               (clobber (reg:CC FLAGS_REG))])
18344    (set (match_dup 0) (match_dup 2))]
18345   "")
18347 (define_peephole2
18348   [(match_scratch:SI 2 "r")
18349    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18350                    (match_operator:SI 3 "arith_or_logical_operator"
18351                      [(match_operand:SI 1 "nonmemory_operand" "")
18352                       (match_dup 0)]))
18353               (clobber (reg:CC FLAGS_REG))])]
18354   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18355   [(set (match_dup 2) (match_dup 0))
18356    (parallel [(set (match_dup 2)
18357                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18358               (clobber (reg:CC FLAGS_REG))])
18359    (set (match_dup 0) (match_dup 2))]
18360   "")
18362 ;; Attempt to always use XOR for zeroing registers.
18363 (define_peephole2
18364   [(set (match_operand 0 "register_operand" "")
18365         (const_int 0))]
18366   "(GET_MODE (operands[0]) == QImode
18367     || GET_MODE (operands[0]) == HImode
18368     || GET_MODE (operands[0]) == SImode
18369     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18370    && (! TARGET_USE_MOV0 || optimize_size)
18371    && GENERAL_REG_P (operands[0])
18372    && peep2_regno_dead_p (0, FLAGS_REG)"
18373   [(parallel [(set (match_dup 0) (const_int 0))
18374               (clobber (reg:CC FLAGS_REG))])]
18375   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18376                               operands[0]);")
18378 (define_peephole2
18379   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18380         (const_int 0))]
18381   "(GET_MODE (operands[0]) == QImode
18382     || GET_MODE (operands[0]) == HImode)
18383    && (! TARGET_USE_MOV0 || optimize_size)
18384    && peep2_regno_dead_p (0, FLAGS_REG)"
18385   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18386               (clobber (reg:CC FLAGS_REG))])])
18388 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18389 (define_peephole2
18390   [(set (match_operand 0 "register_operand" "")
18391         (const_int -1))]
18392   "(GET_MODE (operands[0]) == HImode
18393     || GET_MODE (operands[0]) == SImode 
18394     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18395    && (optimize_size || TARGET_PENTIUM)
18396    && peep2_regno_dead_p (0, FLAGS_REG)"
18397   [(parallel [(set (match_dup 0) (const_int -1))
18398               (clobber (reg:CC FLAGS_REG))])]
18399   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18400                               operands[0]);")
18402 ;; Attempt to convert simple leas to adds. These can be created by
18403 ;; move expanders.
18404 (define_peephole2
18405   [(set (match_operand:SI 0 "register_operand" "")
18406         (plus:SI (match_dup 0)
18407                  (match_operand:SI 1 "nonmemory_operand" "")))]
18408   "peep2_regno_dead_p (0, FLAGS_REG)"
18409   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18410               (clobber (reg:CC FLAGS_REG))])]
18411   "")
18413 (define_peephole2
18414   [(set (match_operand:SI 0 "register_operand" "")
18415         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18416                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18417   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18418   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18419               (clobber (reg:CC FLAGS_REG))])]
18420   "operands[2] = gen_lowpart (SImode, operands[2]);")
18422 (define_peephole2
18423   [(set (match_operand:DI 0 "register_operand" "")
18424         (plus:DI (match_dup 0)
18425                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18426   "peep2_regno_dead_p (0, FLAGS_REG)"
18427   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18428               (clobber (reg:CC FLAGS_REG))])]
18429   "")
18431 (define_peephole2
18432   [(set (match_operand:SI 0 "register_operand" "")
18433         (mult:SI (match_dup 0)
18434                  (match_operand:SI 1 "const_int_operand" "")))]
18435   "exact_log2 (INTVAL (operands[1])) >= 0
18436    && peep2_regno_dead_p (0, FLAGS_REG)"
18437   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18438               (clobber (reg:CC FLAGS_REG))])]
18439   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18441 (define_peephole2
18442   [(set (match_operand:DI 0 "register_operand" "")
18443         (mult:DI (match_dup 0)
18444                  (match_operand:DI 1 "const_int_operand" "")))]
18445   "exact_log2 (INTVAL (operands[1])) >= 0
18446    && peep2_regno_dead_p (0, FLAGS_REG)"
18447   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18448               (clobber (reg:CC FLAGS_REG))])]
18449   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18451 (define_peephole2
18452   [(set (match_operand:SI 0 "register_operand" "")
18453         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18454                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18455   "exact_log2 (INTVAL (operands[2])) >= 0
18456    && REGNO (operands[0]) == REGNO (operands[1])
18457    && peep2_regno_dead_p (0, FLAGS_REG)"
18458   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18459               (clobber (reg:CC FLAGS_REG))])]
18460   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18462 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18463 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18464 ;; many CPUs it is also faster, since special hardware to avoid esp
18465 ;; dependencies is present.
18467 ;; While some of these conversions may be done using splitters, we use peepholes
18468 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18470 ;; Convert prologue esp subtractions to push.
18471 ;; We need register to push.  In order to keep verify_flow_info happy we have
18472 ;; two choices
18473 ;; - use scratch and clobber it in order to avoid dependencies
18474 ;; - use already live register
18475 ;; We can't use the second way right now, since there is no reliable way how to
18476 ;; verify that given register is live.  First choice will also most likely in
18477 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18478 ;; call clobbered registers are dead.  We may want to use base pointer as an
18479 ;; alternative when no register is available later.
18481 (define_peephole2
18482   [(match_scratch:SI 0 "r")
18483    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18484               (clobber (reg:CC FLAGS_REG))
18485               (clobber (mem:BLK (scratch)))])]
18486   "optimize_size || !TARGET_SUB_ESP_4"
18487   [(clobber (match_dup 0))
18488    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18489               (clobber (mem:BLK (scratch)))])])
18491 (define_peephole2
18492   [(match_scratch:SI 0 "r")
18493    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18494               (clobber (reg:CC FLAGS_REG))
18495               (clobber (mem:BLK (scratch)))])]
18496   "optimize_size || !TARGET_SUB_ESP_8"
18497   [(clobber (match_dup 0))
18498    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18499    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18500               (clobber (mem:BLK (scratch)))])])
18502 ;; Convert esp subtractions to push.
18503 (define_peephole2
18504   [(match_scratch:SI 0 "r")
18505    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18506               (clobber (reg:CC FLAGS_REG))])]
18507   "optimize_size || !TARGET_SUB_ESP_4"
18508   [(clobber (match_dup 0))
18509    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18511 (define_peephole2
18512   [(match_scratch:SI 0 "r")
18513    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18514               (clobber (reg:CC FLAGS_REG))])]
18515   "optimize_size || !TARGET_SUB_ESP_8"
18516   [(clobber (match_dup 0))
18517    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18518    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18520 ;; Convert epilogue deallocator to pop.
18521 (define_peephole2
18522   [(match_scratch:SI 0 "r")
18523    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18524               (clobber (reg:CC FLAGS_REG))
18525               (clobber (mem:BLK (scratch)))])]
18526   "optimize_size || !TARGET_ADD_ESP_4"
18527   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18528               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18529               (clobber (mem:BLK (scratch)))])]
18530   "")
18532 ;; Two pops case is tricky, since pop causes dependency on destination register.
18533 ;; We use two registers if available.
18534 (define_peephole2
18535   [(match_scratch:SI 0 "r")
18536    (match_scratch:SI 1 "r")
18537    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18538               (clobber (reg:CC FLAGS_REG))
18539               (clobber (mem:BLK (scratch)))])]
18540   "optimize_size || !TARGET_ADD_ESP_8"
18541   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18542               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18543               (clobber (mem:BLK (scratch)))])
18544    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18545               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18546   "")
18548 (define_peephole2
18549   [(match_scratch:SI 0 "r")
18550    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18551               (clobber (reg:CC FLAGS_REG))
18552               (clobber (mem:BLK (scratch)))])]
18553   "optimize_size"
18554   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18555               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18556               (clobber (mem:BLK (scratch)))])
18557    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18558               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18559   "")
18561 ;; Convert esp additions to pop.
18562 (define_peephole2
18563   [(match_scratch:SI 0 "r")
18564    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18565               (clobber (reg:CC FLAGS_REG))])]
18566   ""
18567   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18568               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18569   "")
18571 ;; Two pops case is tricky, since pop causes dependency on destination register.
18572 ;; We use two registers if available.
18573 (define_peephole2
18574   [(match_scratch:SI 0 "r")
18575    (match_scratch:SI 1 "r")
18576    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18577               (clobber (reg:CC FLAGS_REG))])]
18578   ""
18579   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18580               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18581    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18582               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18583   "")
18585 (define_peephole2
18586   [(match_scratch:SI 0 "r")
18587    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18588               (clobber (reg:CC FLAGS_REG))])]
18589   "optimize_size"
18590   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18591               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18592    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18593               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18594   "")
18596 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18597 ;; required and register dies.  Similarly for 128 to plus -128.
18598 (define_peephole2
18599   [(set (match_operand 0 "flags_reg_operand" "")
18600         (match_operator 1 "compare_operator"
18601           [(match_operand 2 "register_operand" "")
18602            (match_operand 3 "const_int_operand" "")]))]
18603   "(INTVAL (operands[3]) == -1
18604     || INTVAL (operands[3]) == 1
18605     || INTVAL (operands[3]) == 128)
18606    && ix86_match_ccmode (insn, CCGCmode)
18607    && peep2_reg_dead_p (1, operands[2])"
18608   [(parallel [(set (match_dup 0)
18609                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18610               (clobber (match_dup 2))])]
18611   "")
18613 (define_peephole2
18614   [(match_scratch:DI 0 "r")
18615    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18616               (clobber (reg:CC FLAGS_REG))
18617               (clobber (mem:BLK (scratch)))])]
18618   "optimize_size || !TARGET_SUB_ESP_4"
18619   [(clobber (match_dup 0))
18620    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18621               (clobber (mem:BLK (scratch)))])])
18623 (define_peephole2
18624   [(match_scratch:DI 0 "r")
18625    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18626               (clobber (reg:CC FLAGS_REG))
18627               (clobber (mem:BLK (scratch)))])]
18628   "optimize_size || !TARGET_SUB_ESP_8"
18629   [(clobber (match_dup 0))
18630    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18631    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18632               (clobber (mem:BLK (scratch)))])])
18634 ;; Convert esp subtractions to push.
18635 (define_peephole2
18636   [(match_scratch:DI 0 "r")
18637    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18638               (clobber (reg:CC FLAGS_REG))])]
18639   "optimize_size || !TARGET_SUB_ESP_4"
18640   [(clobber (match_dup 0))
18641    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18643 (define_peephole2
18644   [(match_scratch:DI 0 "r")
18645    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18646               (clobber (reg:CC FLAGS_REG))])]
18647   "optimize_size || !TARGET_SUB_ESP_8"
18648   [(clobber (match_dup 0))
18649    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18650    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18652 ;; Convert epilogue deallocator to pop.
18653 (define_peephole2
18654   [(match_scratch:DI 0 "r")
18655    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18656               (clobber (reg:CC FLAGS_REG))
18657               (clobber (mem:BLK (scratch)))])]
18658   "optimize_size || !TARGET_ADD_ESP_4"
18659   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18660               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18661               (clobber (mem:BLK (scratch)))])]
18662   "")
18664 ;; Two pops case is tricky, since pop causes dependency on destination register.
18665 ;; We use two registers if available.
18666 (define_peephole2
18667   [(match_scratch:DI 0 "r")
18668    (match_scratch:DI 1 "r")
18669    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18670               (clobber (reg:CC FLAGS_REG))
18671               (clobber (mem:BLK (scratch)))])]
18672   "optimize_size || !TARGET_ADD_ESP_8"
18673   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18674               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18675               (clobber (mem:BLK (scratch)))])
18676    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18677               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18678   "")
18680 (define_peephole2
18681   [(match_scratch:DI 0 "r")
18682    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18683               (clobber (reg:CC FLAGS_REG))
18684               (clobber (mem:BLK (scratch)))])]
18685   "optimize_size"
18686   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18687               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18688               (clobber (mem:BLK (scratch)))])
18689    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18690               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18691   "")
18693 ;; Convert esp additions to pop.
18694 (define_peephole2
18695   [(match_scratch:DI 0 "r")
18696    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18697               (clobber (reg:CC FLAGS_REG))])]
18698   ""
18699   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18700               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18701   "")
18703 ;; Two pops case is tricky, since pop causes dependency on destination register.
18704 ;; We use two registers if available.
18705 (define_peephole2
18706   [(match_scratch:DI 0 "r")
18707    (match_scratch:DI 1 "r")
18708    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18709               (clobber (reg:CC FLAGS_REG))])]
18710   ""
18711   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18712               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18713    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18714               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18715   "")
18717 (define_peephole2
18718   [(match_scratch:DI 0 "r")
18719    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18720               (clobber (reg:CC FLAGS_REG))])]
18721   "optimize_size"
18722   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18723               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18724    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18725               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18726   "")
18728 ;; Convert imul by three, five and nine into lea
18729 (define_peephole2
18730   [(parallel
18731     [(set (match_operand:SI 0 "register_operand" "")
18732           (mult:SI (match_operand:SI 1 "register_operand" "")
18733                    (match_operand:SI 2 "const_int_operand" "")))
18734      (clobber (reg:CC FLAGS_REG))])]
18735   "INTVAL (operands[2]) == 3
18736    || INTVAL (operands[2]) == 5
18737    || INTVAL (operands[2]) == 9"
18738   [(set (match_dup 0)
18739         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18740                  (match_dup 1)))]
18741   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18743 (define_peephole2
18744   [(parallel
18745     [(set (match_operand:SI 0 "register_operand" "")
18746           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18747                    (match_operand:SI 2 "const_int_operand" "")))
18748      (clobber (reg:CC FLAGS_REG))])]
18749   "!optimize_size 
18750    && (INTVAL (operands[2]) == 3
18751        || INTVAL (operands[2]) == 5
18752        || INTVAL (operands[2]) == 9)"
18753   [(set (match_dup 0) (match_dup 1))
18754    (set (match_dup 0)
18755         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18756                  (match_dup 0)))]
18757   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18759 (define_peephole2
18760   [(parallel
18761     [(set (match_operand:DI 0 "register_operand" "")
18762           (mult:DI (match_operand:DI 1 "register_operand" "")
18763                    (match_operand:DI 2 "const_int_operand" "")))
18764      (clobber (reg:CC FLAGS_REG))])]
18765   "TARGET_64BIT
18766    && (INTVAL (operands[2]) == 3
18767        || INTVAL (operands[2]) == 5
18768        || INTVAL (operands[2]) == 9)"
18769   [(set (match_dup 0)
18770         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18771                  (match_dup 1)))]
18772   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18774 (define_peephole2
18775   [(parallel
18776     [(set (match_operand:DI 0 "register_operand" "")
18777           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18778                    (match_operand:DI 2 "const_int_operand" "")))
18779      (clobber (reg:CC FLAGS_REG))])]
18780   "TARGET_64BIT
18781    && !optimize_size 
18782    && (INTVAL (operands[2]) == 3
18783        || INTVAL (operands[2]) == 5
18784        || INTVAL (operands[2]) == 9)"
18785   [(set (match_dup 0) (match_dup 1))
18786    (set (match_dup 0)
18787         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18788                  (match_dup 0)))]
18789   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18791 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18792 ;; imul $32bit_imm, reg, reg is direct decoded.
18793 (define_peephole2
18794   [(match_scratch:DI 3 "r")
18795    (parallel [(set (match_operand:DI 0 "register_operand" "")
18796                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18797                             (match_operand:DI 2 "immediate_operand" "")))
18798               (clobber (reg:CC FLAGS_REG))])]
18799   "TARGET_K8 && !optimize_size
18800    && (GET_CODE (operands[2]) != CONST_INT
18801        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18802   [(set (match_dup 3) (match_dup 1))
18803    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18804               (clobber (reg:CC FLAGS_REG))])]
18807 (define_peephole2
18808   [(match_scratch:SI 3 "r")
18809    (parallel [(set (match_operand:SI 0 "register_operand" "")
18810                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18811                             (match_operand:SI 2 "immediate_operand" "")))
18812               (clobber (reg:CC FLAGS_REG))])]
18813   "TARGET_K8 && !optimize_size
18814    && (GET_CODE (operands[2]) != CONST_INT
18815        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18816   [(set (match_dup 3) (match_dup 1))
18817    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18818               (clobber (reg:CC FLAGS_REG))])]
18821 (define_peephole2
18822   [(match_scratch:SI 3 "r")
18823    (parallel [(set (match_operand:DI 0 "register_operand" "")
18824                    (zero_extend:DI
18825                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18826                               (match_operand:SI 2 "immediate_operand" ""))))
18827               (clobber (reg:CC FLAGS_REG))])]
18828   "TARGET_K8 && !optimize_size
18829    && (GET_CODE (operands[2]) != CONST_INT
18830        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18831   [(set (match_dup 3) (match_dup 1))
18832    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18833               (clobber (reg:CC FLAGS_REG))])]
18836 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18837 ;; Convert it into imul reg, reg
18838 ;; It would be better to force assembler to encode instruction using long
18839 ;; immediate, but there is apparently no way to do so.
18840 (define_peephole2
18841   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18842                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18843                             (match_operand:DI 2 "const_int_operand" "")))
18844               (clobber (reg:CC FLAGS_REG))])
18845    (match_scratch:DI 3 "r")]
18846   "TARGET_K8 && !optimize_size
18847    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18848   [(set (match_dup 3) (match_dup 2))
18849    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18850               (clobber (reg:CC FLAGS_REG))])]
18852   if (!rtx_equal_p (operands[0], operands[1]))
18853     emit_move_insn (operands[0], operands[1]);
18856 (define_peephole2
18857   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18858                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18859                             (match_operand:SI 2 "const_int_operand" "")))
18860               (clobber (reg:CC FLAGS_REG))])
18861    (match_scratch:SI 3 "r")]
18862   "TARGET_K8 && !optimize_size
18863    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18864   [(set (match_dup 3) (match_dup 2))
18865    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18866               (clobber (reg:CC FLAGS_REG))])]
18868   if (!rtx_equal_p (operands[0], operands[1]))
18869     emit_move_insn (operands[0], operands[1]);
18872 (define_peephole2
18873   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18874                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18875                             (match_operand:HI 2 "immediate_operand" "")))
18876               (clobber (reg:CC FLAGS_REG))])
18877    (match_scratch:HI 3 "r")]
18878   "TARGET_K8 && !optimize_size"
18879   [(set (match_dup 3) (match_dup 2))
18880    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18881               (clobber (reg:CC FLAGS_REG))])]
18883   if (!rtx_equal_p (operands[0], operands[1]))
18884     emit_move_insn (operands[0], operands[1]);
18887 ;; Call-value patterns last so that the wildcard operand does not
18888 ;; disrupt insn-recog's switch tables.
18890 (define_insn "*call_value_pop_0"
18891   [(set (match_operand 0 "" "")
18892         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18893               (match_operand:SI 2 "" "")))
18894    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
18895                             (match_operand:SI 3 "immediate_operand" "")))]
18896   "!TARGET_64BIT"
18898   if (SIBLING_CALL_P (insn))
18899     return "jmp\t%P1";
18900   else
18901     return "call\t%P1";
18903   [(set_attr "type" "callv")])
18905 (define_insn "*call_value_pop_1"
18906   [(set (match_operand 0 "" "")
18907         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18908               (match_operand:SI 2 "" "")))
18909    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
18910                             (match_operand:SI 3 "immediate_operand" "i")))]
18911   "!TARGET_64BIT"
18913   if (constant_call_address_operand (operands[1], Pmode))
18914     {
18915       if (SIBLING_CALL_P (insn))
18916         return "jmp\t%P1";
18917       else
18918         return "call\t%P1";
18919     }
18920   if (SIBLING_CALL_P (insn))
18921     return "jmp\t%A1";
18922   else
18923     return "call\t%A1";
18925   [(set_attr "type" "callv")])
18927 (define_insn "*call_value_0"
18928   [(set (match_operand 0 "" "")
18929         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18930               (match_operand:SI 2 "" "")))]
18931   "!TARGET_64BIT"
18933   if (SIBLING_CALL_P (insn))
18934     return "jmp\t%P1";
18935   else
18936     return "call\t%P1";
18938   [(set_attr "type" "callv")])
18940 (define_insn "*call_value_0_rex64"
18941   [(set (match_operand 0 "" "")
18942         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18943               (match_operand:DI 2 "const_int_operand" "")))]
18944   "TARGET_64BIT"
18946   if (SIBLING_CALL_P (insn))
18947     return "jmp\t%P1";
18948   else
18949     return "call\t%P1";
18951   [(set_attr "type" "callv")])
18953 (define_insn "*call_value_1"
18954   [(set (match_operand 0 "" "")
18955         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18956               (match_operand:SI 2 "" "")))]
18957   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18959   if (constant_call_address_operand (operands[1], Pmode))
18960     return "call\t%P1";
18961   return "call\t%A1";
18963   [(set_attr "type" "callv")])
18965 (define_insn "*sibcall_value_1"
18966   [(set (match_operand 0 "" "")
18967         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18968               (match_operand:SI 2 "" "")))]
18969   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18971   if (constant_call_address_operand (operands[1], Pmode))
18972     return "jmp\t%P1";
18973   return "jmp\t%A1";
18975   [(set_attr "type" "callv")])
18977 (define_insn "*call_value_1_rex64"
18978   [(set (match_operand 0 "" "")
18979         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18980               (match_operand:DI 2 "" "")))]
18981   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18983   if (constant_call_address_operand (operands[1], Pmode))
18984     return "call\t%P1";
18985   return "call\t%A1";
18987   [(set_attr "type" "callv")])
18989 (define_insn "*sibcall_value_1_rex64"
18990   [(set (match_operand 0 "" "")
18991         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18992               (match_operand:DI 2 "" "")))]
18993   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18994   "jmp\t%P1"
18995   [(set_attr "type" "callv")])
18997 (define_insn "*sibcall_value_1_rex64_v"
18998   [(set (match_operand 0 "" "")
18999         (call (mem:QI (reg:DI 40))
19000               (match_operand:DI 1 "" "")))]
19001   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19002   "jmp\t*%%r11"
19003   [(set_attr "type" "callv")])
19005 (define_insn "trap"
19006   [(trap_if (const_int 1) (const_int 5))]
19007   ""
19008   "int\t$5")
19010 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19011 ;;; for the sake of bounds checking.  By emitting bounds checks as
19012 ;;; conditional traps rather than as conditional jumps around
19013 ;;; unconditional traps we avoid introducing spurious basic-block
19014 ;;; boundaries and facilitate elimination of redundant checks.  In
19015 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19016 ;;; interrupt 5.
19017 ;;; 
19018 ;;; FIXME: Static branch prediction rules for ix86 are such that
19019 ;;; forward conditional branches predict as untaken.  As implemented
19020 ;;; below, pseudo conditional traps violate that rule.  We should use
19021 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19022 ;;; section loaded at the end of the text segment and branch forward
19023 ;;; there on bounds-failure, and then jump back immediately (in case
19024 ;;; the system chooses to ignore bounds violations, or to report
19025 ;;; violations and continue execution).
19027 (define_expand "conditional_trap"
19028   [(trap_if (match_operator 0 "comparison_operator"
19029              [(match_dup 2) (const_int 0)])
19030             (match_operand 1 "const_int_operand" ""))]
19031   ""
19033   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19034                               ix86_expand_compare (GET_CODE (operands[0]),
19035                                                    NULL, NULL),
19036                               operands[1]));
19037   DONE;
19040 (define_insn "*conditional_trap_1"
19041   [(trap_if (match_operator 0 "comparison_operator"
19042              [(reg FLAGS_REG) (const_int 0)])
19043             (match_operand 1 "const_int_operand" ""))]
19044   ""
19046   operands[2] = gen_label_rtx ();
19047   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19048   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19049                              CODE_LABEL_NUMBER (operands[2]));
19050   RET;
19053 (define_expand "sse_prologue_save"
19054   [(parallel [(set (match_operand:BLK 0 "" "")
19055                    (unspec:BLK [(reg:DI 21)
19056                                 (reg:DI 22)
19057                                 (reg:DI 23)
19058                                 (reg:DI 24)
19059                                 (reg:DI 25)
19060                                 (reg:DI 26)
19061                                 (reg:DI 27)
19062                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19063               (use (match_operand:DI 1 "register_operand" ""))
19064               (use (match_operand:DI 2 "immediate_operand" ""))
19065               (use (label_ref:DI (match_operand 3 "" "")))])]
19066   "TARGET_64BIT"
19067   "")
19069 (define_insn "*sse_prologue_save_insn"
19070   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19071                           (match_operand:DI 4 "const_int_operand" "n")))
19072         (unspec:BLK [(reg:DI 21)
19073                      (reg:DI 22)
19074                      (reg:DI 23)
19075                      (reg:DI 24)
19076                      (reg:DI 25)
19077                      (reg:DI 26)
19078                      (reg:DI 27)
19079                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19080    (use (match_operand:DI 1 "register_operand" "r"))
19081    (use (match_operand:DI 2 "const_int_operand" "i"))
19082    (use (label_ref:DI (match_operand 3 "" "X")))]
19083   "TARGET_64BIT
19084    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19085    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19086   "*
19088   int i;
19089   operands[0] = gen_rtx_MEM (Pmode,
19090                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19091   output_asm_insn (\"jmp\\t%A1\", operands);
19092   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19093     {
19094       operands[4] = adjust_address (operands[0], DImode, i*16);
19095       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19096       PUT_MODE (operands[4], TImode);
19097       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19098         output_asm_insn (\"rex\", operands);
19099       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19100     }
19101   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19102                              CODE_LABEL_NUMBER (operands[3]));
19103   RET;
19105   "
19106   [(set_attr "type" "other")
19107    (set_attr "length_immediate" "0")
19108    (set_attr "length_address" "0")
19109    (set_attr "length" "135")
19110    (set_attr "memory" "store")
19111    (set_attr "modrm" "0")
19112    (set_attr "mode" "DI")])
19114 (define_expand "prefetch"
19115   [(prefetch (match_operand 0 "address_operand" "")
19116              (match_operand:SI 1 "const_int_operand" "")
19117              (match_operand:SI 2 "const_int_operand" ""))]
19118   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19120   int rw = INTVAL (operands[1]);
19121   int locality = INTVAL (operands[2]);
19123   if (rw != 0 && rw != 1)
19124     abort ();
19125   if (locality < 0 || locality > 3)
19126     abort ();
19127   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19128     abort ();
19130   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19131      suported by SSE counterpart or the SSE prefetch is not available
19132      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19133      of locality.  */
19134   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19135     operands[2] = GEN_INT (3);
19136   else
19137     operands[1] = const0_rtx;
19140 (define_insn "*prefetch_sse"
19141   [(prefetch (match_operand:SI 0 "address_operand" "p")
19142              (const_int 0)
19143              (match_operand:SI 1 "const_int_operand" ""))]
19144   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19146   static const char * const patterns[4] = {
19147    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19148   };
19150   int locality = INTVAL (operands[1]);
19151   if (locality < 0 || locality > 3)
19152     abort ();
19154   return patterns[locality];  
19156   [(set_attr "type" "sse")
19157    (set_attr "memory" "none")])
19159 (define_insn "*prefetch_sse_rex"
19160   [(prefetch (match_operand:DI 0 "address_operand" "p")
19161              (const_int 0)
19162              (match_operand:SI 1 "const_int_operand" ""))]
19163   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19165   static const char * const patterns[4] = {
19166    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19167   };
19169   int locality = INTVAL (operands[1]);
19170   if (locality < 0 || locality > 3)
19171     abort ();
19173   return patterns[locality];  
19175   [(set_attr "type" "sse")
19176    (set_attr "memory" "none")])
19178 (define_insn "*prefetch_3dnow"
19179   [(prefetch (match_operand:SI 0 "address_operand" "p")
19180              (match_operand:SI 1 "const_int_operand" "n")
19181              (const_int 3))]
19182   "TARGET_3DNOW && !TARGET_64BIT"
19184   if (INTVAL (operands[1]) == 0)
19185     return "prefetch\t%a0";
19186   else
19187     return "prefetchw\t%a0";
19189   [(set_attr "type" "mmx")
19190    (set_attr "memory" "none")])
19192 (define_insn "*prefetch_3dnow_rex"
19193   [(prefetch (match_operand:DI 0 "address_operand" "p")
19194              (match_operand:SI 1 "const_int_operand" "n")
19195              (const_int 3))]
19196   "TARGET_3DNOW && TARGET_64BIT"
19198   if (INTVAL (operands[1]) == 0)
19199     return "prefetch\t%a0";
19200   else
19201     return "prefetchw\t%a0";
19203   [(set_attr "type" "mmx")
19204    (set_attr "memory" "none")])
19206 (include "sse.md")
19207 (include "mmx.md")