* reg-stack.c (subst_stack_regs_pat): Handle <UNSPEC_FIST_FLOOR> and
[official-gcc.git] / gcc / config / i386 / i386.md
blobe65d9c790afc9c2bb0a90d7341d0e5298e173bb4
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_FNSTSW               21)
78    (UNSPEC_SAHF                 22)
79    (UNSPEC_FSTCW                23)
80    (UNSPEC_ADD_CARRY            24)
81    (UNSPEC_FLDCW                25)
82    (UNSPEC_REP                  26)
83    (UNSPEC_EH_RETURN            27)
85    ; For SSE/MMX support:
86    (UNSPEC_FIX_NOTRUNC          30)
87    (UNSPEC_MASKMOV              31)
88    (UNSPEC_MOVMSK               32)
89    (UNSPEC_MOVNT                33)
90    (UNSPEC_MOVU                 34)
91    (UNSPEC_RCP                  35)
92    (UNSPEC_RSQRT                36)
93    (UNSPEC_SFENCE               37)
94    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
95    (UNSPEC_PFRCP                39)
96    (UNSPEC_PFRCPIT1             40)
97    (UNSPEC_PFRCPIT2             41)
98    (UNSPEC_PFRSQRT              42)
99    (UNSPEC_PFRSQIT1             43)
100    (UNSPEC_MFENCE               44)
101    (UNSPEC_LFENCE               45)
102    (UNSPEC_PSADBW               46)
103    (UNSPEC_LDQQU                47)
105    ; Generic math support
106    (UNSPEC_COPYSIGN             50)
107    (UNSPEC_IEEE_MIN             51)     ; not commutative
108    (UNSPEC_IEEE_MAX             52)     ; not commutative
110    ; x87 Floating point
111    (UNSPEC_SIN                  60)
112    (UNSPEC_COS                  61)
113    (UNSPEC_FPATAN               62)
114    (UNSPEC_FYL2X                63)
115    (UNSPEC_FYL2XP1              64)
116    (UNSPEC_FRNDINT              65)
117    (UNSPEC_FIST                 66)
118    (UNSPEC_F2XM1                67)
120    ; x87 Rounding
121    (UNSPEC_FRNDINT_FLOOR        70)
122    (UNSPEC_FRNDINT_CEIL         71)
123    (UNSPEC_FRNDINT_TRUNC        72)
124    (UNSPEC_FRNDINT_MASK_PM      73)
125    (UNSPEC_FIST_FLOOR           74)
126    (UNSPEC_FIST_CEIL            75)
128    ; x87 Double output FP
129    (UNSPEC_SINCOS_COS           80)
130    (UNSPEC_SINCOS_SIN           81)
131    (UNSPEC_TAN_ONE              82)
132    (UNSPEC_TAN_TAN              83)
133    (UNSPEC_XTRACT_FRACT         84)
134    (UNSPEC_XTRACT_EXP           85)
135    (UNSPEC_FSCALE_FRACT         86)
136    (UNSPEC_FSCALE_EXP           87)
137    (UNSPEC_FPREM_F              88)
138    (UNSPEC_FPREM_U              89)
139    (UNSPEC_FPREM1_F             90)
140    (UNSPEC_FPREM1_U             91)
141   ])
143 (define_constants
144   [(UNSPECV_BLOCKAGE            0)
145    (UNSPECV_STACK_PROBE         1)
146    (UNSPECV_EMMS                2)
147    (UNSPECV_LDMXCSR             3)
148    (UNSPECV_STMXCSR             4)
149    (UNSPECV_FEMMS               5)
150    (UNSPECV_CLFLUSH             6)
151    (UNSPECV_ALIGN               7)
152    (UNSPECV_MONITOR             8)
153    (UNSPECV_MWAIT               9)
154   ])
156 ;; Registers by name.
157 (define_constants
158   [(BP_REG                       6)
159    (SP_REG                       7)
160    (FLAGS_REG                   17)
161    (FPSR_REG                    18)
162    (DIRFLAG_REG                 19)
163   ])
165 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
166 ;; from i386.c.
168 ;; In C guard expressions, put expressions which may be compile-time
169 ;; constants first.  This allows for better optimization.  For
170 ;; example, write "TARGET_64BIT && reload_completed", not
171 ;; "reload_completed && TARGET_64BIT".
174 ;; Processor type.  This attribute must exactly match the processor_type
175 ;; enumeration in i386.h.
176 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
177   (const (symbol_ref "ix86_tune")))
179 ;; A basic instruction type.  Refinements due to arguments to be
180 ;; provided in other attributes.
181 (define_attr "type"
182   "other,multi,
183    alu,alu1,negnot,imov,imovx,lea,
184    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
185    icmp,test,ibr,setcc,icmov,
186    push,pop,call,callv,leave,
187    str,cld,
188    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
189    sselog,sselog1,sseiadd,sseishft,sseimul,
190    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
191    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
192   (const_string "other"))
194 ;; Main data type used by the insn
195 (define_attr "mode"
196   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
197   (const_string "unknown"))
199 ;; The CPU unit operations uses.
200 (define_attr "unit" "integer,i387,sse,mmx,unknown"
201   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
202            (const_string "i387")
203          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
204                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
205            (const_string "sse")
206          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
207            (const_string "mmx")
208          (eq_attr "type" "other")
209            (const_string "unknown")]
210          (const_string "integer")))
212 ;; The (bounding maximum) length of an instruction immediate.
213 (define_attr "length_immediate" ""
214   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
215            (const_int 0)
216          (eq_attr "unit" "i387,sse,mmx")
217            (const_int 0)
218          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
219                           imul,icmp,push,pop")
220            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
221          (eq_attr "type" "imov,test")
222            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
223          (eq_attr "type" "call")
224            (if_then_else (match_operand 0 "constant_call_address_operand" "")
225              (const_int 4)
226              (const_int 0))
227          (eq_attr "type" "callv")
228            (if_then_else (match_operand 1 "constant_call_address_operand" "")
229              (const_int 4)
230              (const_int 0))
231          ;; We don't know the size before shorten_branches.  Expect
232          ;; the instruction to fit for better scheduling.
233          (eq_attr "type" "ibr")
234            (const_int 1)
235          ]
236          (symbol_ref "/* Update immediate_length and other attributes! */
237                       abort(),1")))
239 ;; The (bounding maximum) length of an instruction address.
240 (define_attr "length_address" ""
241   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
242            (const_int 0)
243          (and (eq_attr "type" "call")
244               (match_operand 0 "constant_call_address_operand" ""))
245              (const_int 0)
246          (and (eq_attr "type" "callv")
247               (match_operand 1 "constant_call_address_operand" ""))
248              (const_int 0)
249          ]
250          (symbol_ref "ix86_attr_length_address_default (insn)")))
252 ;; Set when length prefix is used.
253 (define_attr "prefix_data16" ""
254   (if_then_else (ior (eq_attr "mode" "HI")
255                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
256     (const_int 1)
257     (const_int 0)))
259 ;; Set when string REP prefix is used.
260 (define_attr "prefix_rep" "" 
261   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
262     (const_int 1)
263     (const_int 0)))
265 ;; Set when 0f opcode prefix is used.
266 (define_attr "prefix_0f" ""
267   (if_then_else 
268     (ior (eq_attr "type" "imovx,setcc,icmov")
269          (eq_attr "unit" "sse,mmx"))
270     (const_int 1)
271     (const_int 0)))
273 ;; Set when REX opcode prefix is used.
274 (define_attr "prefix_rex" ""
275   (cond [(and (eq_attr "mode" "DI")
276               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
277            (const_int 1)
278          (and (eq_attr "mode" "QI")
279               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
280                   (const_int 0)))
281            (const_int 1)
282          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
283              (const_int 0))
284            (const_int 1)
285         ]
286         (const_int 0)))
288 ;; Set when modrm byte is used.
289 (define_attr "modrm" ""
290   (cond [(eq_attr "type" "str,cld,leave")
291            (const_int 0)
292          (eq_attr "unit" "i387")
293            (const_int 0)
294          (and (eq_attr "type" "incdec")
295               (ior (match_operand:SI 1 "register_operand" "")
296                    (match_operand:HI 1 "register_operand" "")))
297            (const_int 0)
298          (and (eq_attr "type" "push")
299               (not (match_operand 1 "memory_operand" "")))
300            (const_int 0)
301          (and (eq_attr "type" "pop")
302               (not (match_operand 0 "memory_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "imov")
305               (and (match_operand 0 "register_operand" "")
306                    (match_operand 1 "immediate_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "call")
309               (match_operand 0 "constant_call_address_operand" ""))
310              (const_int 0)
311          (and (eq_attr "type" "callv")
312               (match_operand 1 "constant_call_address_operand" ""))
313              (const_int 0)
314          ]
315          (const_int 1)))
317 ;; The (bounding maximum) length of an instruction in bytes.
318 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
319 ;; Later we may want to split them and compute proper length as for
320 ;; other insns.
321 (define_attr "length" ""
322   (cond [(eq_attr "type" "other,multi,fistp,frndint")
323            (const_int 16)
324          (eq_attr "type" "fcmp")
325            (const_int 4)
326          (eq_attr "unit" "i387")
327            (plus (const_int 2)
328                  (plus (attr "prefix_data16")
329                        (attr "length_address")))]
330          (plus (plus (attr "modrm")
331                      (plus (attr "prefix_0f")
332                            (plus (attr "prefix_rex")
333                                  (const_int 1))))
334                (plus (attr "prefix_rep")
335                      (plus (attr "prefix_data16")
336                            (plus (attr "length_immediate")
337                                  (attr "length_address")))))))
339 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
340 ;; `store' if there is a simple memory reference therein, or `unknown'
341 ;; if the instruction is complex.
343 (define_attr "memory" "none,load,store,both,unknown"
344   (cond [(eq_attr "type" "other,multi,str")
345            (const_string "unknown")
346          (eq_attr "type" "lea,fcmov,fpspc,cld")
347            (const_string "none")
348          (eq_attr "type" "fistp,leave")
349            (const_string "both")
350          (eq_attr "type" "frndint")
351            (const_string "load")
352          (eq_attr "type" "push")
353            (if_then_else (match_operand 1 "memory_operand" "")
354              (const_string "both")
355              (const_string "store"))
356          (eq_attr "type" "pop")
357            (if_then_else (match_operand 0 "memory_operand" "")
358              (const_string "both")
359              (const_string "load"))
360          (eq_attr "type" "setcc")
361            (if_then_else (match_operand 0 "memory_operand" "")
362              (const_string "store")
363              (const_string "none"))
364          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
365            (if_then_else (ior (match_operand 0 "memory_operand" "")
366                               (match_operand 1 "memory_operand" ""))
367              (const_string "load")
368              (const_string "none"))
369          (eq_attr "type" "ibr")
370            (if_then_else (match_operand 0 "memory_operand" "")
371              (const_string "load")
372              (const_string "none"))
373          (eq_attr "type" "call")
374            (if_then_else (match_operand 0 "constant_call_address_operand" "")
375              (const_string "none")
376              (const_string "load"))
377          (eq_attr "type" "callv")
378            (if_then_else (match_operand 1 "constant_call_address_operand" "")
379              (const_string "none")
380              (const_string "load"))
381          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
382               (match_operand 1 "memory_operand" ""))
383            (const_string "both")
384          (and (match_operand 0 "memory_operand" "")
385               (match_operand 1 "memory_operand" ""))
386            (const_string "both")
387          (match_operand 0 "memory_operand" "")
388            (const_string "store")
389          (match_operand 1 "memory_operand" "")
390            (const_string "load")
391          (and (eq_attr "type"
392                  "!alu1,negnot,ishift1,
393                    imov,imovx,icmp,test,
394                    fmov,fcmp,fsgn,
395                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
396                    mmx,mmxmov,mmxcmp,mmxcvt")
397               (match_operand 2 "memory_operand" ""))
398            (const_string "load")
399          (and (eq_attr "type" "icmov")
400               (match_operand 3 "memory_operand" ""))
401            (const_string "load")
402         ]
403         (const_string "none")))
405 ;; Indicates if an instruction has both an immediate and a displacement.
407 (define_attr "imm_disp" "false,true,unknown"
408   (cond [(eq_attr "type" "other,multi")
409            (const_string "unknown")
410          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
411               (and (match_operand 0 "memory_displacement_operand" "")
412                    (match_operand 1 "immediate_operand" "")))
413            (const_string "true")
414          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
415               (and (match_operand 0 "memory_displacement_operand" "")
416                    (match_operand 2 "immediate_operand" "")))
417            (const_string "true")
418         ]
419         (const_string "false")))
421 ;; Indicates if an FP operation has an integer source.
423 (define_attr "fp_int_src" "false,true"
424   (const_string "false"))
426 ;; Defines rounding mode of an FP operation.
428 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
429   (const_string "any"))
431 ;; Describe a user's asm statement.
432 (define_asm_attributes
433   [(set_attr "length" "128")
434    (set_attr "type" "multi")])
436 ;; All x87 floating point modes
437 (define_mode_macro X87MODEF [SF DF XF])
439 ;; All integer modes handled by x87 fisttp operator.
440 (define_mode_macro X87MODEI [HI SI DI])
442 ;; All integer modes handled by integer x87 operators.
443 (define_mode_macro X87MODEI12 [HI SI])
445 ;; All SSE floating point modes
446 (define_mode_macro SSEMODEF [SF DF])
448 ;; All integer modes handled by SSE cvtts?2si* operators.
449 (define_mode_macro SSEMODEI24 [SI DI])
452 ;; Scheduling descriptions
454 (include "pentium.md")
455 (include "ppro.md")
456 (include "k6.md")
457 (include "athlon.md")
460 ;; Operand and operator predicates
462 (include "predicates.md")
465 ;; Compare instructions.
467 ;; All compare insns have expanders that save the operands away without
468 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
469 ;; after the cmp) will actually emit the cmpM.
471 (define_expand "cmpdi"
472   [(set (reg:CC FLAGS_REG)
473         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
474                     (match_operand:DI 1 "x86_64_general_operand" "")))]
475   ""
477   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
478     operands[0] = force_reg (DImode, operands[0]);
479   ix86_compare_op0 = operands[0];
480   ix86_compare_op1 = operands[1];
481   DONE;
484 (define_expand "cmpsi"
485   [(set (reg:CC FLAGS_REG)
486         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
487                     (match_operand:SI 1 "general_operand" "")))]
488   ""
490   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
491     operands[0] = force_reg (SImode, operands[0]);
492   ix86_compare_op0 = operands[0];
493   ix86_compare_op1 = operands[1];
494   DONE;
497 (define_expand "cmphi"
498   [(set (reg:CC FLAGS_REG)
499         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
500                     (match_operand:HI 1 "general_operand" "")))]
501   ""
503   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
504     operands[0] = force_reg (HImode, operands[0]);
505   ix86_compare_op0 = operands[0];
506   ix86_compare_op1 = operands[1];
507   DONE;
510 (define_expand "cmpqi"
511   [(set (reg:CC FLAGS_REG)
512         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
513                     (match_operand:QI 1 "general_operand" "")))]
514   "TARGET_QIMODE_MATH"
516   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
517     operands[0] = force_reg (QImode, operands[0]);
518   ix86_compare_op0 = operands[0];
519   ix86_compare_op1 = operands[1];
520   DONE;
523 (define_insn "cmpdi_ccno_1_rex64"
524   [(set (reg FLAGS_REG)
525         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
526                  (match_operand:DI 1 "const0_operand" "n,n")))]
527   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
528   "@
529    test{q}\t{%0, %0|%0, %0}
530    cmp{q}\t{%1, %0|%0, %1}"
531   [(set_attr "type" "test,icmp")
532    (set_attr "length_immediate" "0,1")
533    (set_attr "mode" "DI")])
535 (define_insn "*cmpdi_minus_1_rex64"
536   [(set (reg FLAGS_REG)
537         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
538                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
539                  (const_int 0)))]
540   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
541   "cmp{q}\t{%1, %0|%0, %1}"
542   [(set_attr "type" "icmp")
543    (set_attr "mode" "DI")])
545 (define_expand "cmpdi_1_rex64"
546   [(set (reg:CC FLAGS_REG)
547         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
548                     (match_operand:DI 1 "general_operand" "")))]
549   "TARGET_64BIT"
550   "")
552 (define_insn "cmpdi_1_insn_rex64"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
555                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
556   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
557   "cmp{q}\t{%1, %0|%0, %1}"
558   [(set_attr "type" "icmp")
559    (set_attr "mode" "DI")])
562 (define_insn "*cmpsi_ccno_1"
563   [(set (reg FLAGS_REG)
564         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
565                  (match_operand:SI 1 "const0_operand" "n,n")))]
566   "ix86_match_ccmode (insn, CCNOmode)"
567   "@
568    test{l}\t{%0, %0|%0, %0}
569    cmp{l}\t{%1, %0|%0, %1}"
570   [(set_attr "type" "test,icmp")
571    (set_attr "length_immediate" "0,1")
572    (set_attr "mode" "SI")])
574 (define_insn "*cmpsi_minus_1"
575   [(set (reg FLAGS_REG)
576         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                            (match_operand:SI 1 "general_operand" "ri,mr"))
578                  (const_int 0)))]
579   "ix86_match_ccmode (insn, CCGOCmode)"
580   "cmp{l}\t{%1, %0|%0, %1}"
581   [(set_attr "type" "icmp")
582    (set_attr "mode" "SI")])
584 (define_expand "cmpsi_1"
585   [(set (reg:CC FLAGS_REG)
586         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
587                     (match_operand:SI 1 "general_operand" "ri,mr")))]
588   ""
589   "")
591 (define_insn "*cmpsi_1_insn"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
594                  (match_operand:SI 1 "general_operand" "ri,mr")))]
595   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
596     && ix86_match_ccmode (insn, CCmode)"
597   "cmp{l}\t{%1, %0|%0, %1}"
598   [(set_attr "type" "icmp")
599    (set_attr "mode" "SI")])
601 (define_insn "*cmphi_ccno_1"
602   [(set (reg FLAGS_REG)
603         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
604                  (match_operand:HI 1 "const0_operand" "n,n")))]
605   "ix86_match_ccmode (insn, CCNOmode)"
606   "@
607    test{w}\t{%0, %0|%0, %0}
608    cmp{w}\t{%1, %0|%0, %1}"
609   [(set_attr "type" "test,icmp")
610    (set_attr "length_immediate" "0,1")
611    (set_attr "mode" "HI")])
613 (define_insn "*cmphi_minus_1"
614   [(set (reg FLAGS_REG)
615         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                            (match_operand:HI 1 "general_operand" "ri,mr"))
617                  (const_int 0)))]
618   "ix86_match_ccmode (insn, CCGOCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
623 (define_insn "*cmphi_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
626                  (match_operand:HI 1 "general_operand" "ri,mr")))]
627   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628    && ix86_match_ccmode (insn, CCmode)"
629   "cmp{w}\t{%1, %0|%0, %1}"
630   [(set_attr "type" "icmp")
631    (set_attr "mode" "HI")])
633 (define_insn "*cmpqi_ccno_1"
634   [(set (reg FLAGS_REG)
635         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
636                  (match_operand:QI 1 "const0_operand" "n,n")))]
637   "ix86_match_ccmode (insn, CCNOmode)"
638   "@
639    test{b}\t{%0, %0|%0, %0}
640    cmp{b}\t{$0, %0|%0, 0}"
641   [(set_attr "type" "test,icmp")
642    (set_attr "length_immediate" "0,1")
643    (set_attr "mode" "QI")])
645 (define_insn "*cmpqi_1"
646   [(set (reg FLAGS_REG)
647         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                  (match_operand:QI 1 "general_operand" "qi,mq")))]
649   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
650     && ix86_match_ccmode (insn, CCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
655 (define_insn "*cmpqi_minus_1"
656   [(set (reg FLAGS_REG)
657         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
658                            (match_operand:QI 1 "general_operand" "qi,mq"))
659                  (const_int 0)))]
660   "ix86_match_ccmode (insn, CCGOCmode)"
661   "cmp{b}\t{%1, %0|%0, %1}"
662   [(set_attr "type" "icmp")
663    (set_attr "mode" "QI")])
665 (define_insn "*cmpqi_ext_1"
666   [(set (reg FLAGS_REG)
667         (compare
668           (match_operand:QI 0 "general_operand" "Qm")
669           (subreg:QI
670             (zero_extract:SI
671               (match_operand 1 "ext_register_operand" "Q")
672               (const_int 8)
673               (const_int 8)) 0)))]
674   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
675   "cmp{b}\t{%h1, %0|%0, %h1}"
676   [(set_attr "type" "icmp")
677    (set_attr "mode" "QI")])
679 (define_insn "*cmpqi_ext_1_rex64"
680   [(set (reg FLAGS_REG)
681         (compare
682           (match_operand:QI 0 "register_operand" "Q")
683           (subreg:QI
684             (zero_extract:SI
685               (match_operand 1 "ext_register_operand" "Q")
686               (const_int 8)
687               (const_int 8)) 0)))]
688   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
689   "cmp{b}\t{%h1, %0|%0, %h1}"
690   [(set_attr "type" "icmp")
691    (set_attr "mode" "QI")])
693 (define_insn "*cmpqi_ext_2"
694   [(set (reg FLAGS_REG)
695         (compare
696           (subreg:QI
697             (zero_extract:SI
698               (match_operand 0 "ext_register_operand" "Q")
699               (const_int 8)
700               (const_int 8)) 0)
701           (match_operand:QI 1 "const0_operand" "n")))]
702   "ix86_match_ccmode (insn, CCNOmode)"
703   "test{b}\t%h0, %h0"
704   [(set_attr "type" "test")
705    (set_attr "length_immediate" "0")
706    (set_attr "mode" "QI")])
708 (define_expand "cmpqi_ext_3"
709   [(set (reg:CC FLAGS_REG)
710         (compare:CC
711           (subreg:QI
712             (zero_extract:SI
713               (match_operand 0 "ext_register_operand" "")
714               (const_int 8)
715               (const_int 8)) 0)
716           (match_operand:QI 1 "general_operand" "")))]
717   ""
718   "")
720 (define_insn "cmpqi_ext_3_insn"
721   [(set (reg FLAGS_REG)
722         (compare
723           (subreg:QI
724             (zero_extract:SI
725               (match_operand 0 "ext_register_operand" "Q")
726               (const_int 8)
727               (const_int 8)) 0)
728           (match_operand:QI 1 "general_operand" "Qmn")))]
729   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730   "cmp{b}\t{%1, %h0|%h0, %1}"
731   [(set_attr "type" "icmp")
732    (set_attr "mode" "QI")])
734 (define_insn "cmpqi_ext_3_insn_rex64"
735   [(set (reg FLAGS_REG)
736         (compare
737           (subreg:QI
738             (zero_extract:SI
739               (match_operand 0 "ext_register_operand" "Q")
740               (const_int 8)
741               (const_int 8)) 0)
742           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
743   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744   "cmp{b}\t{%1, %h0|%h0, %1}"
745   [(set_attr "type" "icmp")
746    (set_attr "mode" "QI")])
748 (define_insn "*cmpqi_ext_4"
749   [(set (reg FLAGS_REG)
750         (compare
751           (subreg:QI
752             (zero_extract:SI
753               (match_operand 0 "ext_register_operand" "Q")
754               (const_int 8)
755               (const_int 8)) 0)
756           (subreg:QI
757             (zero_extract:SI
758               (match_operand 1 "ext_register_operand" "Q")
759               (const_int 8)
760               (const_int 8)) 0)))]
761   "ix86_match_ccmode (insn, CCmode)"
762   "cmp{b}\t{%h1, %h0|%h0, %h1}"
763   [(set_attr "type" "icmp")
764    (set_attr "mode" "QI")])
766 ;; These implement float point compares.
767 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
768 ;; which would allow mix and match FP modes on the compares.  Which is what
769 ;; the old patterns did, but with many more of them.
771 (define_expand "cmpxf"
772   [(set (reg:CC FLAGS_REG)
773         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
774                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
775   "TARGET_80387"
777   ix86_compare_op0 = operands[0];
778   ix86_compare_op1 = operands[1];
779   DONE;
782 (define_expand "cmpdf"
783   [(set (reg:CC FLAGS_REG)
784         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
785                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
786   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
788   ix86_compare_op0 = operands[0];
789   ix86_compare_op1 = operands[1];
790   DONE;
793 (define_expand "cmpsf"
794   [(set (reg:CC FLAGS_REG)
795         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
796                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
797   "TARGET_80387 || TARGET_SSE_MATH"
799   ix86_compare_op0 = operands[0];
800   ix86_compare_op1 = operands[1];
801   DONE;
804 ;; FP compares, step 1:
805 ;; Set the FP condition codes.
807 ;; CCFPmode     compare with exceptions
808 ;; CCFPUmode    compare with no exceptions
810 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
811 ;; used to manage the reg stack popping would not be preserved.
813 (define_insn "*cmpfp_0_sf"
814   [(set (match_operand:HI 0 "register_operand" "=a")
815         (unspec:HI
816           [(compare:CCFP
817              (match_operand:SF 1 "register_operand" "f")
818              (match_operand:SF 2 "const0_operand" "X"))]
819         UNSPEC_FNSTSW))]
820   "TARGET_80387"
821   "* return output_fp_compare (insn, operands, 0, 0);"
822   [(set_attr "type" "multi")
823    (set_attr "mode" "SF")])
825 (define_insn "*cmpfp_0_df"
826   [(set (match_operand:HI 0 "register_operand" "=a")
827         (unspec:HI
828           [(compare:CCFP
829              (match_operand:DF 1 "register_operand" "f")
830              (match_operand:DF 2 "const0_operand" "X"))]
831         UNSPEC_FNSTSW))]
832   "TARGET_80387"
833   "* return output_fp_compare (insn, operands, 0, 0);"
834   [(set_attr "type" "multi")
835    (set_attr "mode" "DF")])
837 (define_insn "*cmpfp_0_xf"
838   [(set (match_operand:HI 0 "register_operand" "=a")
839         (unspec:HI
840           [(compare:CCFP
841              (match_operand:XF 1 "register_operand" "f")
842              (match_operand:XF 2 "const0_operand" "X"))]
843         UNSPEC_FNSTSW))]
844   "TARGET_80387"
845   "* return output_fp_compare (insn, operands, 0, 0);"
846   [(set_attr "type" "multi")
847    (set_attr "mode" "XF")])
849 (define_insn "*cmpfp_sf"
850   [(set (match_operand:HI 0 "register_operand" "=a")
851         (unspec:HI
852           [(compare:CCFP
853              (match_operand:SF 1 "register_operand" "f")
854              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
855           UNSPEC_FNSTSW))]
856   "TARGET_80387"
857   "* return output_fp_compare (insn, operands, 0, 0);"
858   [(set_attr "type" "multi")
859    (set_attr "mode" "SF")])
861 (define_insn "*cmpfp_df"
862   [(set (match_operand:HI 0 "register_operand" "=a")
863         (unspec:HI
864           [(compare:CCFP
865              (match_operand:DF 1 "register_operand" "f")
866              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
867           UNSPEC_FNSTSW))]
868   "TARGET_80387"
869   "* return output_fp_compare (insn, operands, 0, 0);"
870   [(set_attr "type" "multi")
871    (set_attr "mode" "DF")])
873 (define_insn "*cmpfp_xf"
874   [(set (match_operand:HI 0 "register_operand" "=a")
875         (unspec:HI
876           [(compare:CCFP
877              (match_operand:XF 1 "register_operand" "f")
878              (match_operand:XF 2 "register_operand" "f"))]
879           UNSPEC_FNSTSW))]
880   "TARGET_80387"
881   "* return output_fp_compare (insn, operands, 0, 0);"
882   [(set_attr "type" "multi")
883    (set_attr "mode" "XF")])
885 (define_insn "*cmpfp_u"
886   [(set (match_operand:HI 0 "register_operand" "=a")
887         (unspec:HI
888           [(compare:CCFPU
889              (match_operand 1 "register_operand" "f")
890              (match_operand 2 "register_operand" "f"))]
891           UNSPEC_FNSTSW))]
892   "TARGET_80387
893    && FLOAT_MODE_P (GET_MODE (operands[1]))
894    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
895   "* return output_fp_compare (insn, operands, 0, 1);"
896   [(set_attr "type" "multi")
897    (set (attr "mode")
898      (cond [(match_operand:SF 1 "" "")
899               (const_string "SF")
900             (match_operand:DF 1 "" "")
901               (const_string "DF")
902            ]
903            (const_string "XF")))])
905 (define_insn "*cmpfp_<mode>"
906   [(set (match_operand:HI 0 "register_operand" "=a")
907         (unspec:HI
908           [(compare:CCFP
909              (match_operand 1 "register_operand" "f")
910              (match_operator 3 "float_operator"
911                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
912           UNSPEC_FNSTSW))]
913   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
914    && FLOAT_MODE_P (GET_MODE (operands[1]))
915    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
916   "* return output_fp_compare (insn, operands, 0, 0);"
917   [(set_attr "type" "multi")
918    (set_attr "fp_int_src" "true")
919    (set_attr "mode" "<MODE>")])
921 ;; FP compares, step 2
922 ;; Move the fpsw to ax.
924 (define_insn "x86_fnstsw_1"
925   [(set (match_operand:HI 0 "register_operand" "=a")
926         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
927   "TARGET_80387"
928   "fnstsw\t%0"
929   [(set_attr "length" "2")
930    (set_attr "mode" "SI")
931    (set_attr "unit" "i387")])
933 ;; FP compares, step 3
934 ;; Get ax into flags, general case.
936 (define_insn "x86_sahf_1"
937   [(set (reg:CC FLAGS_REG)
938         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
939   "!TARGET_64BIT"
940   "sahf"
941   [(set_attr "length" "1")
942    (set_attr "athlon_decode" "vector")
943    (set_attr "mode" "SI")])
945 ;; Pentium Pro can do steps 1 through 3 in one go.
947 (define_insn "*cmpfp_i_mixed"
948   [(set (reg:CCFP FLAGS_REG)
949         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
950                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
951   "TARGET_MIX_SSE_I387
952    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
953    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
954   "* return output_fp_compare (insn, operands, 1, 0);"
955   [(set_attr "type" "fcmp,ssecomi")
956    (set (attr "mode")
957      (if_then_else (match_operand:SF 1 "" "")
958         (const_string "SF")
959         (const_string "DF")))
960    (set_attr "athlon_decode" "vector")])
962 (define_insn "*cmpfp_i_sse"
963   [(set (reg:CCFP FLAGS_REG)
964         (compare:CCFP (match_operand 0 "register_operand" "x")
965                       (match_operand 1 "nonimmediate_operand" "xm")))]
966   "TARGET_SSE_MATH
967    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
968    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
969   "* return output_fp_compare (insn, operands, 1, 0);"
970   [(set_attr "type" "ssecomi")
971    (set (attr "mode")
972      (if_then_else (match_operand:SF 1 "" "")
973         (const_string "SF")
974         (const_string "DF")))
975    (set_attr "athlon_decode" "vector")])
977 (define_insn "*cmpfp_i_i387"
978   [(set (reg:CCFP FLAGS_REG)
979         (compare:CCFP (match_operand 0 "register_operand" "f")
980                       (match_operand 1 "register_operand" "f")))]
981   "TARGET_80387 && TARGET_CMOVE
982    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
983    && FLOAT_MODE_P (GET_MODE (operands[0]))
984    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
985   "* return output_fp_compare (insn, operands, 1, 0);"
986   [(set_attr "type" "fcmp")
987    (set (attr "mode")
988      (cond [(match_operand:SF 1 "" "")
989               (const_string "SF")
990             (match_operand:DF 1 "" "")
991               (const_string "DF")
992            ]
993            (const_string "XF")))
994    (set_attr "athlon_decode" "vector")])
996 (define_insn "*cmpfp_iu_mixed"
997   [(set (reg:CCFPU FLAGS_REG)
998         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
999                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1000   "TARGET_MIX_SSE_I387
1001    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1003   "* return output_fp_compare (insn, operands, 1, 1);"
1004   [(set_attr "type" "fcmp,ssecomi")
1005    (set (attr "mode")
1006      (if_then_else (match_operand:SF 1 "" "")
1007         (const_string "SF")
1008         (const_string "DF")))
1009    (set_attr "athlon_decode" "vector")])
1011 (define_insn "*cmpfp_iu_sse"
1012   [(set (reg:CCFPU FLAGS_REG)
1013         (compare:CCFPU (match_operand 0 "register_operand" "x")
1014                        (match_operand 1 "nonimmediate_operand" "xm")))]
1015   "TARGET_SSE_MATH
1016    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1017    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1018   "* return output_fp_compare (insn, operands, 1, 1);"
1019   [(set_attr "type" "ssecomi")
1020    (set (attr "mode")
1021      (if_then_else (match_operand:SF 1 "" "")
1022         (const_string "SF")
1023         (const_string "DF")))
1024    (set_attr "athlon_decode" "vector")])
1026 (define_insn "*cmpfp_iu_387"
1027   [(set (reg:CCFPU FLAGS_REG)
1028         (compare:CCFPU (match_operand 0 "register_operand" "f")
1029                        (match_operand 1 "register_operand" "f")))]
1030   "TARGET_80387 && TARGET_CMOVE
1031    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1032    && FLOAT_MODE_P (GET_MODE (operands[0]))
1033    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034   "* return output_fp_compare (insn, operands, 1, 1);"
1035   [(set_attr "type" "fcmp")
1036    (set (attr "mode")
1037      (cond [(match_operand:SF 1 "" "")
1038               (const_string "SF")
1039             (match_operand:DF 1 "" "")
1040               (const_string "DF")
1041            ]
1042            (const_string "XF")))
1043    (set_attr "athlon_decode" "vector")])
1045 ;; Move instructions.
1047 ;; General case of fullword move.
1049 (define_expand "movsi"
1050   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1051         (match_operand:SI 1 "general_operand" ""))]
1052   ""
1053   "ix86_expand_move (SImode, operands); DONE;")
1055 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1056 ;; general_operand.
1058 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1059 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1060 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1061 ;; targets without our curiosities, and it is just as easy to represent
1062 ;; this differently.
1064 (define_insn "*pushsi2"
1065   [(set (match_operand:SI 0 "push_operand" "=<")
1066         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1067   "!TARGET_64BIT"
1068   "push{l}\t%1"
1069   [(set_attr "type" "push")
1070    (set_attr "mode" "SI")])
1072 ;; For 64BIT abi we always round up to 8 bytes.
1073 (define_insn "*pushsi2_rex64"
1074   [(set (match_operand:SI 0 "push_operand" "=X")
1075         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1076   "TARGET_64BIT"
1077   "push{q}\t%q1"
1078   [(set_attr "type" "push")
1079    (set_attr "mode" "SI")])
1081 (define_insn "*pushsi2_prologue"
1082   [(set (match_operand:SI 0 "push_operand" "=<")
1083         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1084    (clobber (mem:BLK (scratch)))]
1085   "!TARGET_64BIT"
1086   "push{l}\t%1"
1087   [(set_attr "type" "push")
1088    (set_attr "mode" "SI")])
1090 (define_insn "*popsi1_epilogue"
1091   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1092         (mem:SI (reg:SI SP_REG)))
1093    (set (reg:SI SP_REG)
1094         (plus:SI (reg:SI SP_REG) (const_int 4)))
1095    (clobber (mem:BLK (scratch)))]
1096   "!TARGET_64BIT"
1097   "pop{l}\t%0"
1098   [(set_attr "type" "pop")
1099    (set_attr "mode" "SI")])
1101 (define_insn "popsi1"
1102   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1103         (mem:SI (reg:SI SP_REG)))
1104    (set (reg:SI SP_REG)
1105         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1106   "!TARGET_64BIT"
1107   "pop{l}\t%0"
1108   [(set_attr "type" "pop")
1109    (set_attr "mode" "SI")])
1111 (define_insn "*movsi_xor"
1112   [(set (match_operand:SI 0 "register_operand" "=r")
1113         (match_operand:SI 1 "const0_operand" "i"))
1114    (clobber (reg:CC FLAGS_REG))]
1115   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1116   "xor{l}\t{%0, %0|%0, %0}"
1117   [(set_attr "type" "alu1")
1118    (set_attr "mode" "SI")
1119    (set_attr "length_immediate" "0")])
1121 (define_insn "*movsi_or"
1122   [(set (match_operand:SI 0 "register_operand" "=r")
1123         (match_operand:SI 1 "immediate_operand" "i"))
1124    (clobber (reg:CC FLAGS_REG))]
1125   "reload_completed
1126    && operands[1] == constm1_rtx
1127    && (TARGET_PENTIUM || optimize_size)"
1129   operands[1] = constm1_rtx;
1130   return "or{l}\t{%1, %0|%0, %1}";
1132   [(set_attr "type" "alu1")
1133    (set_attr "mode" "SI")
1134    (set_attr "length_immediate" "1")])
1136 (define_insn "*movsi_1"
1137   [(set (match_operand:SI 0 "nonimmediate_operand"
1138                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1139         (match_operand:SI 1 "general_operand"
1140                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1141   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1143   switch (get_attr_type (insn))
1144     {
1145     case TYPE_SSELOG1:
1146       if (get_attr_mode (insn) == MODE_TI)
1147         return "pxor\t%0, %0";
1148       return "xorps\t%0, %0";
1150     case TYPE_SSEMOV:
1151       switch (get_attr_mode (insn))
1152         {
1153         case MODE_TI:
1154           return "movdqa\t{%1, %0|%0, %1}";
1155         case MODE_V4SF:
1156           return "movaps\t{%1, %0|%0, %1}";
1157         case MODE_SI:
1158           return "movd\t{%1, %0|%0, %1}";
1159         case MODE_SF:
1160           return "movss\t{%1, %0|%0, %1}";
1161         default:
1162           gcc_unreachable ();
1163         }
1165     case TYPE_MMXADD:
1166       return "pxor\t%0, %0";
1168     case TYPE_MMXMOV:
1169       if (get_attr_mode (insn) == MODE_DI)
1170         return "movq\t{%1, %0|%0, %1}";
1171       return "movd\t{%1, %0|%0, %1}";
1173     case TYPE_LEA:
1174       return "lea{l}\t{%1, %0|%0, %1}";
1176     default:
1177       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1178         abort();
1179       return "mov{l}\t{%1, %0|%0, %1}";
1180     }
1182   [(set (attr "type")
1183      (cond [(eq_attr "alternative" "2")
1184               (const_string "mmx")
1185             (eq_attr "alternative" "3,4,5")
1186               (const_string "mmxmov")
1187             (eq_attr "alternative" "6")
1188               (const_string "sselog1")
1189             (eq_attr "alternative" "7,8,9,10,11")
1190               (const_string "ssemov")
1191             (and (ne (symbol_ref "flag_pic") (const_int 0))
1192                  (match_operand:SI 1 "symbolic_operand" ""))
1193               (const_string "lea")
1194            ]
1195            (const_string "imov")))
1196    (set (attr "mode")
1197      (cond [(eq_attr "alternative" "2,3")
1198               (const_string "DI")
1199             (eq_attr "alternative" "6,7")
1200               (if_then_else
1201                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1202                 (const_string "V4SF")
1203                 (const_string "TI"))
1204             (and (eq_attr "alternative" "8,9,10,11")
1205                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1206               (const_string "SF")
1207            ]
1208            (const_string "SI")))])
1210 ;; Stores and loads of ax to arbitrary constant address.
1211 ;; We fake an second form of instruction to force reload to load address
1212 ;; into register when rax is not available
1213 (define_insn "*movabssi_1_rex64"
1214   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1215         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1216   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1217   "@
1218    movabs{l}\t{%1, %P0|%P0, %1}
1219    mov{l}\t{%1, %a0|%a0, %1}"
1220   [(set_attr "type" "imov")
1221    (set_attr "modrm" "0,*")
1222    (set_attr "length_address" "8,0")
1223    (set_attr "length_immediate" "0,*")
1224    (set_attr "memory" "store")
1225    (set_attr "mode" "SI")])
1227 (define_insn "*movabssi_2_rex64"
1228   [(set (match_operand:SI 0 "register_operand" "=a,r")
1229         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1230   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1231   "@
1232    movabs{l}\t{%P1, %0|%0, %P1}
1233    mov{l}\t{%a1, %0|%0, %a1}"
1234   [(set_attr "type" "imov")
1235    (set_attr "modrm" "0,*")
1236    (set_attr "length_address" "8,0")
1237    (set_attr "length_immediate" "0")
1238    (set_attr "memory" "load")
1239    (set_attr "mode" "SI")])
1241 (define_insn "*swapsi"
1242   [(set (match_operand:SI 0 "register_operand" "+r")
1243         (match_operand:SI 1 "register_operand" "+r"))
1244    (set (match_dup 1)
1245         (match_dup 0))]
1246   ""
1247   "xchg{l}\t%1, %0"
1248   [(set_attr "type" "imov")
1249    (set_attr "mode" "SI")
1250    (set_attr "pent_pair" "np")
1251    (set_attr "athlon_decode" "vector")])
1253 (define_expand "movhi"
1254   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1255         (match_operand:HI 1 "general_operand" ""))]
1256   ""
1257   "ix86_expand_move (HImode, operands); DONE;")
1259 (define_insn "*pushhi2"
1260   [(set (match_operand:HI 0 "push_operand" "=<,<")
1261         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1262   "!TARGET_64BIT"
1263   "@
1264    push{w}\t{|WORD PTR }%1
1265    push{w}\t%1"
1266   [(set_attr "type" "push")
1267    (set_attr "mode" "HI")])
1269 ;; For 64BIT abi we always round up to 8 bytes.
1270 (define_insn "*pushhi2_rex64"
1271   [(set (match_operand:HI 0 "push_operand" "=X")
1272         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1273   "TARGET_64BIT"
1274   "push{q}\t%q1"
1275   [(set_attr "type" "push")
1276    (set_attr "mode" "QI")])
1278 (define_insn "*movhi_1"
1279   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1280         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1281   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1283   switch (get_attr_type (insn))
1284     {
1285     case TYPE_IMOVX:
1286       /* movzwl is faster than movw on p2 due to partial word stalls,
1287          though not as fast as an aligned movl.  */
1288       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1289     default:
1290       if (get_attr_mode (insn) == MODE_SI)
1291         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1292       else
1293         return "mov{w}\t{%1, %0|%0, %1}";
1294     }
1296   [(set (attr "type")
1297      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1298               (const_string "imov")
1299             (and (eq_attr "alternative" "0")
1300                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1301                           (const_int 0))
1302                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1303                           (const_int 0))))
1304               (const_string "imov")
1305             (and (eq_attr "alternative" "1,2")
1306                  (match_operand:HI 1 "aligned_operand" ""))
1307               (const_string "imov")
1308             (and (ne (symbol_ref "TARGET_MOVX")
1309                      (const_int 0))
1310                  (eq_attr "alternative" "0,2"))
1311               (const_string "imovx")
1312            ]
1313            (const_string "imov")))
1314     (set (attr "mode")
1315       (cond [(eq_attr "type" "imovx")
1316                (const_string "SI")
1317              (and (eq_attr "alternative" "1,2")
1318                   (match_operand:HI 1 "aligned_operand" ""))
1319                (const_string "SI")
1320              (and (eq_attr "alternative" "0")
1321                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1322                            (const_int 0))
1323                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1324                            (const_int 0))))
1325                (const_string "SI")
1326             ]
1327             (const_string "HI")))])
1329 ;; Stores and loads of ax to arbitrary constant address.
1330 ;; We fake an second form of instruction to force reload to load address
1331 ;; into register when rax is not available
1332 (define_insn "*movabshi_1_rex64"
1333   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1334         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1335   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1336   "@
1337    movabs{w}\t{%1, %P0|%P0, %1}
1338    mov{w}\t{%1, %a0|%a0, %1}"
1339   [(set_attr "type" "imov")
1340    (set_attr "modrm" "0,*")
1341    (set_attr "length_address" "8,0")
1342    (set_attr "length_immediate" "0,*")
1343    (set_attr "memory" "store")
1344    (set_attr "mode" "HI")])
1346 (define_insn "*movabshi_2_rex64"
1347   [(set (match_operand:HI 0 "register_operand" "=a,r")
1348         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1349   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1350   "@
1351    movabs{w}\t{%P1, %0|%0, %P1}
1352    mov{w}\t{%a1, %0|%0, %a1}"
1353   [(set_attr "type" "imov")
1354    (set_attr "modrm" "0,*")
1355    (set_attr "length_address" "8,0")
1356    (set_attr "length_immediate" "0")
1357    (set_attr "memory" "load")
1358    (set_attr "mode" "HI")])
1360 (define_insn "*swaphi_1"
1361   [(set (match_operand:HI 0 "register_operand" "+r")
1362         (match_operand:HI 1 "register_operand" "+r"))
1363    (set (match_dup 1)
1364         (match_dup 0))]
1365   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1366   "xchg{l}\t%k1, %k0"
1367   [(set_attr "type" "imov")
1368    (set_attr "mode" "SI")
1369    (set_attr "pent_pair" "np")
1370    (set_attr "athlon_decode" "vector")])
1372 (define_insn "*swaphi_2"
1373   [(set (match_operand:HI 0 "register_operand" "+r")
1374         (match_operand:HI 1 "register_operand" "+r"))
1375    (set (match_dup 1)
1376         (match_dup 0))]
1377   "TARGET_PARTIAL_REG_STALL"
1378   "xchg{w}\t%1, %0"
1379   [(set_attr "type" "imov")
1380    (set_attr "mode" "HI")
1381    (set_attr "pent_pair" "np")
1382    (set_attr "athlon_decode" "vector")])
1384 (define_expand "movstricthi"
1385   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1386         (match_operand:HI 1 "general_operand" ""))]
1387   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1389   /* Don't generate memory->memory moves, go through a register */
1390   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1391     operands[1] = force_reg (HImode, operands[1]);
1394 (define_insn "*movstricthi_1"
1395   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1396         (match_operand:HI 1 "general_operand" "rn,m"))]
1397   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1398    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1399   "mov{w}\t{%1, %0|%0, %1}"
1400   [(set_attr "type" "imov")
1401    (set_attr "mode" "HI")])
1403 (define_insn "*movstricthi_xor"
1404   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1405         (match_operand:HI 1 "const0_operand" "i"))
1406    (clobber (reg:CC FLAGS_REG))]
1407   "reload_completed
1408    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1409   "xor{w}\t{%0, %0|%0, %0}"
1410   [(set_attr "type" "alu1")
1411    (set_attr "mode" "HI")
1412    (set_attr "length_immediate" "0")])
1414 (define_expand "movqi"
1415   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1416         (match_operand:QI 1 "general_operand" ""))]
1417   ""
1418   "ix86_expand_move (QImode, operands); DONE;")
1420 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1421 ;; "push a byte".  But actually we use pushw, which has the effect
1422 ;; of rounding the amount pushed up to a halfword.
1424 (define_insn "*pushqi2"
1425   [(set (match_operand:QI 0 "push_operand" "=X,X")
1426         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1427   "!TARGET_64BIT"
1428   "@
1429    push{w}\t{|word ptr }%1
1430    push{w}\t%w1"
1431   [(set_attr "type" "push")
1432    (set_attr "mode" "HI")])
1434 ;; For 64BIT abi we always round up to 8 bytes.
1435 (define_insn "*pushqi2_rex64"
1436   [(set (match_operand:QI 0 "push_operand" "=X")
1437         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1438   "TARGET_64BIT"
1439   "push{q}\t%q1"
1440   [(set_attr "type" "push")
1441    (set_attr "mode" "QI")])
1443 ;; Situation is quite tricky about when to choose full sized (SImode) move
1444 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1445 ;; partial register dependency machines (such as AMD Athlon), where QImode
1446 ;; moves issue extra dependency and for partial register stalls machines
1447 ;; that don't use QImode patterns (and QImode move cause stall on the next
1448 ;; instruction).
1450 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1451 ;; register stall machines with, where we use QImode instructions, since
1452 ;; partial register stall can be caused there.  Then we use movzx.
1453 (define_insn "*movqi_1"
1454   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1455         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1456   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1458   switch (get_attr_type (insn))
1459     {
1460     case TYPE_IMOVX:
1461       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1462         abort ();
1463       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1464     default:
1465       if (get_attr_mode (insn) == MODE_SI)
1466         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1467       else
1468         return "mov{b}\t{%1, %0|%0, %1}";
1469     }
1471   [(set (attr "type")
1472      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1473               (const_string "imov")
1474             (and (eq_attr "alternative" "3")
1475                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1476                           (const_int 0))
1477                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1478                           (const_int 0))))
1479               (const_string "imov")
1480             (eq_attr "alternative" "3,5")
1481               (const_string "imovx")
1482             (and (ne (symbol_ref "TARGET_MOVX")
1483                      (const_int 0))
1484                  (eq_attr "alternative" "2"))
1485               (const_string "imovx")
1486            ]
1487            (const_string "imov")))
1488    (set (attr "mode")
1489       (cond [(eq_attr "alternative" "3,4,5")
1490                (const_string "SI")
1491              (eq_attr "alternative" "6")
1492                (const_string "QI")
1493              (eq_attr "type" "imovx")
1494                (const_string "SI")
1495              (and (eq_attr "type" "imov")
1496                   (and (eq_attr "alternative" "0,1")
1497                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1498                            (const_int 0))))
1499                (const_string "SI")
1500              ;; Avoid partial register stalls when not using QImode arithmetic
1501              (and (eq_attr "type" "imov")
1502                   (and (eq_attr "alternative" "0,1")
1503                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1504                                 (const_int 0))
1505                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1506                                 (const_int 0)))))
1507                (const_string "SI")
1508            ]
1509            (const_string "QI")))])
1511 (define_expand "reload_outqi"
1512   [(parallel [(match_operand:QI 0 "" "=m")
1513               (match_operand:QI 1 "register_operand" "r")
1514               (match_operand:QI 2 "register_operand" "=&q")])]
1515   ""
1517   rtx op0, op1, op2;
1518   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1520   if (reg_overlap_mentioned_p (op2, op0))
1521     abort ();
1522   if (! q_regs_operand (op1, QImode))
1523     {
1524       emit_insn (gen_movqi (op2, op1));
1525       op1 = op2;
1526     }
1527   emit_insn (gen_movqi (op0, op1));
1528   DONE;
1531 (define_insn "*swapqi_1"
1532   [(set (match_operand:QI 0 "register_operand" "+r")
1533         (match_operand:QI 1 "register_operand" "+r"))
1534    (set (match_dup 1)
1535         (match_dup 0))]
1536   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1537   "xchg{l}\t%k1, %k0"
1538   [(set_attr "type" "imov")
1539    (set_attr "mode" "SI")
1540    (set_attr "pent_pair" "np")
1541    (set_attr "athlon_decode" "vector")])
1543 (define_insn "*swapqi_2"
1544   [(set (match_operand:QI 0 "register_operand" "+q")
1545         (match_operand:QI 1 "register_operand" "+q"))
1546    (set (match_dup 1)
1547         (match_dup 0))]
1548   "TARGET_PARTIAL_REG_STALL"
1549   "xchg{b}\t%1, %0"
1550   [(set_attr "type" "imov")
1551    (set_attr "mode" "QI")
1552    (set_attr "pent_pair" "np")
1553    (set_attr "athlon_decode" "vector")])
1555 (define_expand "movstrictqi"
1556   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1557         (match_operand:QI 1 "general_operand" ""))]
1558   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1560   /* Don't generate memory->memory moves, go through a register.  */
1561   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1562     operands[1] = force_reg (QImode, operands[1]);
1565 (define_insn "*movstrictqi_1"
1566   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1567         (match_operand:QI 1 "general_operand" "*qn,m"))]
1568   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1569    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1570   "mov{b}\t{%1, %0|%0, %1}"
1571   [(set_attr "type" "imov")
1572    (set_attr "mode" "QI")])
1574 (define_insn "*movstrictqi_xor"
1575   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1576         (match_operand:QI 1 "const0_operand" "i"))
1577    (clobber (reg:CC FLAGS_REG))]
1578   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1579   "xor{b}\t{%0, %0|%0, %0}"
1580   [(set_attr "type" "alu1")
1581    (set_attr "mode" "QI")
1582    (set_attr "length_immediate" "0")])
1584 (define_insn "*movsi_extv_1"
1585   [(set (match_operand:SI 0 "register_operand" "=R")
1586         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1587                          (const_int 8)
1588                          (const_int 8)))]
1589   ""
1590   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1591   [(set_attr "type" "imovx")
1592    (set_attr "mode" "SI")])
1594 (define_insn "*movhi_extv_1"
1595   [(set (match_operand:HI 0 "register_operand" "=R")
1596         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1597                          (const_int 8)
1598                          (const_int 8)))]
1599   ""
1600   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1601   [(set_attr "type" "imovx")
1602    (set_attr "mode" "SI")])
1604 (define_insn "*movqi_extv_1"
1605   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1606         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1607                          (const_int 8)
1608                          (const_int 8)))]
1609   "!TARGET_64BIT"
1611   switch (get_attr_type (insn))
1612     {
1613     case TYPE_IMOVX:
1614       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1615     default:
1616       return "mov{b}\t{%h1, %0|%0, %h1}";
1617     }
1619   [(set (attr "type")
1620      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1621                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1622                              (ne (symbol_ref "TARGET_MOVX")
1623                                  (const_int 0))))
1624         (const_string "imovx")
1625         (const_string "imov")))
1626    (set (attr "mode")
1627      (if_then_else (eq_attr "type" "imovx")
1628         (const_string "SI")
1629         (const_string "QI")))])
1631 (define_insn "*movqi_extv_1_rex64"
1632   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1633         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1634                          (const_int 8)
1635                          (const_int 8)))]
1636   "TARGET_64BIT"
1638   switch (get_attr_type (insn))
1639     {
1640     case TYPE_IMOVX:
1641       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1642     default:
1643       return "mov{b}\t{%h1, %0|%0, %h1}";
1644     }
1646   [(set (attr "type")
1647      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1648                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1649                              (ne (symbol_ref "TARGET_MOVX")
1650                                  (const_int 0))))
1651         (const_string "imovx")
1652         (const_string "imov")))
1653    (set (attr "mode")
1654      (if_then_else (eq_attr "type" "imovx")
1655         (const_string "SI")
1656         (const_string "QI")))])
1658 ;; Stores and loads of ax to arbitrary constant address.
1659 ;; We fake an second form of instruction to force reload to load address
1660 ;; into register when rax is not available
1661 (define_insn "*movabsqi_1_rex64"
1662   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1663         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1664   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1665   "@
1666    movabs{b}\t{%1, %P0|%P0, %1}
1667    mov{b}\t{%1, %a0|%a0, %1}"
1668   [(set_attr "type" "imov")
1669    (set_attr "modrm" "0,*")
1670    (set_attr "length_address" "8,0")
1671    (set_attr "length_immediate" "0,*")
1672    (set_attr "memory" "store")
1673    (set_attr "mode" "QI")])
1675 (define_insn "*movabsqi_2_rex64"
1676   [(set (match_operand:QI 0 "register_operand" "=a,r")
1677         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1678   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1679   "@
1680    movabs{b}\t{%P1, %0|%0, %P1}
1681    mov{b}\t{%a1, %0|%0, %a1}"
1682   [(set_attr "type" "imov")
1683    (set_attr "modrm" "0,*")
1684    (set_attr "length_address" "8,0")
1685    (set_attr "length_immediate" "0")
1686    (set_attr "memory" "load")
1687    (set_attr "mode" "QI")])
1689 (define_insn "*movsi_extzv_1"
1690   [(set (match_operand:SI 0 "register_operand" "=R")
1691         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1692                          (const_int 8)
1693                          (const_int 8)))]
1694   ""
1695   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1696   [(set_attr "type" "imovx")
1697    (set_attr "mode" "SI")])
1699 (define_insn "*movqi_extzv_2"
1700   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1701         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1702                                     (const_int 8)
1703                                     (const_int 8)) 0))]
1704   "!TARGET_64BIT"
1706   switch (get_attr_type (insn))
1707     {
1708     case TYPE_IMOVX:
1709       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1710     default:
1711       return "mov{b}\t{%h1, %0|%0, %h1}";
1712     }
1714   [(set (attr "type")
1715      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1716                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1717                              (ne (symbol_ref "TARGET_MOVX")
1718                                  (const_int 0))))
1719         (const_string "imovx")
1720         (const_string "imov")))
1721    (set (attr "mode")
1722      (if_then_else (eq_attr "type" "imovx")
1723         (const_string "SI")
1724         (const_string "QI")))])
1726 (define_insn "*movqi_extzv_2_rex64"
1727   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1728         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1729                                     (const_int 8)
1730                                     (const_int 8)) 0))]
1731   "TARGET_64BIT"
1733   switch (get_attr_type (insn))
1734     {
1735     case TYPE_IMOVX:
1736       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1737     default:
1738       return "mov{b}\t{%h1, %0|%0, %h1}";
1739     }
1741   [(set (attr "type")
1742      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1743                         (ne (symbol_ref "TARGET_MOVX")
1744                             (const_int 0)))
1745         (const_string "imovx")
1746         (const_string "imov")))
1747    (set (attr "mode")
1748      (if_then_else (eq_attr "type" "imovx")
1749         (const_string "SI")
1750         (const_string "QI")))])
1752 (define_insn "movsi_insv_1"
1753   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1754                          (const_int 8)
1755                          (const_int 8))
1756         (match_operand:SI 1 "general_operand" "Qmn"))]
1757   "!TARGET_64BIT"
1758   "mov{b}\t{%b1, %h0|%h0, %b1}"
1759   [(set_attr "type" "imov")
1760    (set_attr "mode" "QI")])
1762 (define_insn "movdi_insv_1_rex64"
1763   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1764                          (const_int 8)
1765                          (const_int 8))
1766         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1767   "TARGET_64BIT"
1768   "mov{b}\t{%b1, %h0|%h0, %b1}"
1769   [(set_attr "type" "imov")
1770    (set_attr "mode" "QI")])
1772 (define_insn "*movqi_insv_2"
1773   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1774                          (const_int 8)
1775                          (const_int 8))
1776         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1777                      (const_int 8)))]
1778   ""
1779   "mov{b}\t{%h1, %h0|%h0, %h1}"
1780   [(set_attr "type" "imov")
1781    (set_attr "mode" "QI")])
1783 (define_expand "movdi"
1784   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1785         (match_operand:DI 1 "general_operand" ""))]
1786   ""
1787   "ix86_expand_move (DImode, operands); DONE;")
1789 (define_insn "*pushdi"
1790   [(set (match_operand:DI 0 "push_operand" "=<")
1791         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1792   "!TARGET_64BIT"
1793   "#")
1795 (define_insn "*pushdi2_rex64"
1796   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1797         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1798   "TARGET_64BIT"
1799   "@
1800    push{q}\t%1
1801    #"
1802   [(set_attr "type" "push,multi")
1803    (set_attr "mode" "DI")])
1805 ;; Convert impossible pushes of immediate to existing instructions.
1806 ;; First try to get scratch register and go through it.  In case this
1807 ;; fails, push sign extended lower part first and then overwrite
1808 ;; upper part by 32bit move.
1809 (define_peephole2
1810   [(match_scratch:DI 2 "r")
1811    (set (match_operand:DI 0 "push_operand" "")
1812         (match_operand:DI 1 "immediate_operand" ""))]
1813   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1814    && !x86_64_immediate_operand (operands[1], DImode)"
1815   [(set (match_dup 2) (match_dup 1))
1816    (set (match_dup 0) (match_dup 2))]
1817   "")
1819 ;; We need to define this as both peepholer and splitter for case
1820 ;; peephole2 pass is not run.
1821 ;; "&& 1" is needed to keep it from matching the previous pattern.
1822 (define_peephole2
1823   [(set (match_operand:DI 0 "push_operand" "")
1824         (match_operand:DI 1 "immediate_operand" ""))]
1825   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1826    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1827   [(set (match_dup 0) (match_dup 1))
1828    (set (match_dup 2) (match_dup 3))]
1829   "split_di (operands + 1, 1, operands + 2, operands + 3);
1830    operands[1] = gen_lowpart (DImode, operands[2]);
1831    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1832                                                     GEN_INT (4)));
1833   ")
1835 (define_split
1836   [(set (match_operand:DI 0 "push_operand" "")
1837         (match_operand:DI 1 "immediate_operand" ""))]
1838   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1839    && !symbolic_operand (operands[1], DImode)
1840    && !x86_64_immediate_operand (operands[1], DImode)"
1841   [(set (match_dup 0) (match_dup 1))
1842    (set (match_dup 2) (match_dup 3))]
1843   "split_di (operands + 1, 1, operands + 2, operands + 3);
1844    operands[1] = gen_lowpart (DImode, operands[2]);
1845    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1846                                                     GEN_INT (4)));
1847   ")
1849 (define_insn "*pushdi2_prologue_rex64"
1850   [(set (match_operand:DI 0 "push_operand" "=<")
1851         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1852    (clobber (mem:BLK (scratch)))]
1853   "TARGET_64BIT"
1854   "push{q}\t%1"
1855   [(set_attr "type" "push")
1856    (set_attr "mode" "DI")])
1858 (define_insn "*popdi1_epilogue_rex64"
1859   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1860         (mem:DI (reg:DI SP_REG)))
1861    (set (reg:DI SP_REG)
1862         (plus:DI (reg:DI SP_REG) (const_int 8)))
1863    (clobber (mem:BLK (scratch)))]
1864   "TARGET_64BIT"
1865   "pop{q}\t%0"
1866   [(set_attr "type" "pop")
1867    (set_attr "mode" "DI")])
1869 (define_insn "popdi1"
1870   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1871         (mem:DI (reg:DI SP_REG)))
1872    (set (reg:DI SP_REG)
1873         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1874   "TARGET_64BIT"
1875   "pop{q}\t%0"
1876   [(set_attr "type" "pop")
1877    (set_attr "mode" "DI")])
1879 (define_insn "*movdi_xor_rex64"
1880   [(set (match_operand:DI 0 "register_operand" "=r")
1881         (match_operand:DI 1 "const0_operand" "i"))
1882    (clobber (reg:CC FLAGS_REG))]
1883   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1884    && reload_completed"
1885   "xor{l}\t{%k0, %k0|%k0, %k0}"
1886   [(set_attr "type" "alu1")
1887    (set_attr "mode" "SI")
1888    (set_attr "length_immediate" "0")])
1890 (define_insn "*movdi_or_rex64"
1891   [(set (match_operand:DI 0 "register_operand" "=r")
1892         (match_operand:DI 1 "const_int_operand" "i"))
1893    (clobber (reg:CC FLAGS_REG))]
1894   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1895    && reload_completed
1896    && operands[1] == constm1_rtx"
1898   operands[1] = constm1_rtx;
1899   return "or{q}\t{%1, %0|%0, %1}";
1901   [(set_attr "type" "alu1")
1902    (set_attr "mode" "DI")
1903    (set_attr "length_immediate" "1")])
1905 (define_insn "*movdi_2"
1906   [(set (match_operand:DI 0 "nonimmediate_operand"
1907                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1908         (match_operand:DI 1 "general_operand"
1909                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1910   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1911   "@
1912    #
1913    #
1914    pxor\t%0, %0
1915    movq\t{%1, %0|%0, %1}
1916    movq\t{%1, %0|%0, %1}
1917    pxor\t%0, %0
1918    movq\t{%1, %0|%0, %1}
1919    movdqa\t{%1, %0|%0, %1}
1920    movq\t{%1, %0|%0, %1}
1921    xorps\t%0, %0
1922    movlps\t{%1, %0|%0, %1}
1923    movaps\t{%1, %0|%0, %1}
1924    movlps\t{%1, %0|%0, %1}"
1925   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1926    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1928 (define_split
1929   [(set (match_operand:DI 0 "push_operand" "")
1930         (match_operand:DI 1 "general_operand" ""))]
1931   "!TARGET_64BIT && reload_completed
1932    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1933   [(const_int 0)]
1934   "ix86_split_long_move (operands); DONE;")
1936 ;; %%% This multiword shite has got to go.
1937 (define_split
1938   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1939         (match_operand:DI 1 "general_operand" ""))]
1940   "!TARGET_64BIT && reload_completed
1941    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1942    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1943   [(const_int 0)]
1944   "ix86_split_long_move (operands); DONE;")
1946 (define_insn "*movdi_1_rex64"
1947   [(set (match_operand:DI 0 "nonimmediate_operand"
1948                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1949         (match_operand:DI 1 "general_operand"
1950                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1951   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1953   switch (get_attr_type (insn))
1954     {
1955     case TYPE_SSECVT:
1956       if (which_alternative == 13)
1957         return "movq2dq\t{%1, %0|%0, %1}";
1958       else
1959         return "movdq2q\t{%1, %0|%0, %1}";
1960     case TYPE_SSEMOV:
1961       if (get_attr_mode (insn) == MODE_TI)
1962           return "movdqa\t{%1, %0|%0, %1}";
1963       /* FALLTHRU */
1964     case TYPE_MMXMOV:
1965       /* Moves from and into integer register is done using movd opcode with
1966          REX prefix.  */
1967       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1968           return "movd\t{%1, %0|%0, %1}";
1969       return "movq\t{%1, %0|%0, %1}";
1970     case TYPE_SSELOG1:
1971     case TYPE_MMXADD:
1972       return "pxor\t%0, %0";
1973     case TYPE_MULTI:
1974       return "#";
1975     case TYPE_LEA:
1976       return "lea{q}\t{%a1, %0|%0, %a1}";
1977     default:
1978       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1979         abort ();
1980       if (get_attr_mode (insn) == MODE_SI)
1981         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1982       else if (which_alternative == 2)
1983         return "movabs{q}\t{%1, %0|%0, %1}";
1984       else
1985         return "mov{q}\t{%1, %0|%0, %1}";
1986     }
1988   [(set (attr "type")
1989      (cond [(eq_attr "alternative" "5")
1990               (const_string "mmx")
1991             (eq_attr "alternative" "6,7,8")
1992               (const_string "mmxmov")
1993             (eq_attr "alternative" "9")
1994               (const_string "sselog1")
1995             (eq_attr "alternative" "10,11,12")
1996               (const_string "ssemov")
1997             (eq_attr "alternative" "13,14")
1998               (const_string "ssecvt")
1999             (eq_attr "alternative" "4")
2000               (const_string "multi")
2001             (and (ne (symbol_ref "flag_pic") (const_int 0))
2002                  (match_operand:DI 1 "symbolic_operand" ""))
2003               (const_string "lea")
2004            ]
2005            (const_string "imov")))
2006    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2007    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2008    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2010 ;; Stores and loads of ax to arbitrary constant address.
2011 ;; We fake an second form of instruction to force reload to load address
2012 ;; into register when rax is not available
2013 (define_insn "*movabsdi_1_rex64"
2014   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2015         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2016   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2017   "@
2018    movabs{q}\t{%1, %P0|%P0, %1}
2019    mov{q}\t{%1, %a0|%a0, %1}"
2020   [(set_attr "type" "imov")
2021    (set_attr "modrm" "0,*")
2022    (set_attr "length_address" "8,0")
2023    (set_attr "length_immediate" "0,*")
2024    (set_attr "memory" "store")
2025    (set_attr "mode" "DI")])
2027 (define_insn "*movabsdi_2_rex64"
2028   [(set (match_operand:DI 0 "register_operand" "=a,r")
2029         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2030   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2031   "@
2032    movabs{q}\t{%P1, %0|%0, %P1}
2033    mov{q}\t{%a1, %0|%0, %a1}"
2034   [(set_attr "type" "imov")
2035    (set_attr "modrm" "0,*")
2036    (set_attr "length_address" "8,0")
2037    (set_attr "length_immediate" "0")
2038    (set_attr "memory" "load")
2039    (set_attr "mode" "DI")])
2041 ;; Convert impossible stores of immediate to existing instructions.
2042 ;; First try to get scratch register and go through it.  In case this
2043 ;; fails, move by 32bit parts.
2044 (define_peephole2
2045   [(match_scratch:DI 2 "r")
2046    (set (match_operand:DI 0 "memory_operand" "")
2047         (match_operand:DI 1 "immediate_operand" ""))]
2048   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2049    && !x86_64_immediate_operand (operands[1], DImode)"
2050   [(set (match_dup 2) (match_dup 1))
2051    (set (match_dup 0) (match_dup 2))]
2052   "")
2054 ;; We need to define this as both peepholer and splitter for case
2055 ;; peephole2 pass is not run.
2056 ;; "&& 1" is needed to keep it from matching the previous pattern.
2057 (define_peephole2
2058   [(set (match_operand:DI 0 "memory_operand" "")
2059         (match_operand:DI 1 "immediate_operand" ""))]
2060   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2061    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2062   [(set (match_dup 2) (match_dup 3))
2063    (set (match_dup 4) (match_dup 5))]
2064   "split_di (operands, 2, operands + 2, operands + 4);")
2066 (define_split
2067   [(set (match_operand:DI 0 "memory_operand" "")
2068         (match_operand:DI 1 "immediate_operand" ""))]
2069   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2070    && !symbolic_operand (operands[1], DImode)
2071    && !x86_64_immediate_operand (operands[1], DImode)"
2072   [(set (match_dup 2) (match_dup 3))
2073    (set (match_dup 4) (match_dup 5))]
2074   "split_di (operands, 2, operands + 2, operands + 4);")
2076 (define_insn "*swapdi_rex64"
2077   [(set (match_operand:DI 0 "register_operand" "+r")
2078         (match_operand:DI 1 "register_operand" "+r"))
2079    (set (match_dup 1)
2080         (match_dup 0))]
2081   "TARGET_64BIT"
2082   "xchg{q}\t%1, %0"
2083   [(set_attr "type" "imov")
2084    (set_attr "mode" "DI")
2085    (set_attr "pent_pair" "np")
2086    (set_attr "athlon_decode" "vector")])
2088 (define_expand "movti"
2089   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2090         (match_operand:TI 1 "nonimmediate_operand" ""))]
2091   "TARGET_SSE || TARGET_64BIT"
2093   if (TARGET_64BIT)
2094     ix86_expand_move (TImode, operands);
2095   else
2096     ix86_expand_vector_move (TImode, operands);
2097   DONE;
2100 (define_insn "*movti_internal"
2101   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2102         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2103   "TARGET_SSE && !TARGET_64BIT
2104    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2106   switch (which_alternative)
2107     {
2108     case 0:
2109       if (get_attr_mode (insn) == MODE_V4SF)
2110         return "xorps\t%0, %0";
2111       else
2112         return "pxor\t%0, %0";
2113     case 1:
2114     case 2:
2115       if (get_attr_mode (insn) == MODE_V4SF)
2116         return "movaps\t{%1, %0|%0, %1}";
2117       else
2118         return "movdqa\t{%1, %0|%0, %1}";
2119     default:
2120       abort ();
2121     }
2123   [(set_attr "type" "ssemov,ssemov,ssemov")
2124    (set (attr "mode")
2125         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2126                  (const_string "V4SF")
2128                (eq_attr "alternative" "0,1")
2129                  (if_then_else
2130                    (ne (symbol_ref "optimize_size")
2131                        (const_int 0))
2132                    (const_string "V4SF")
2133                    (const_string "TI"))
2134                (eq_attr "alternative" "2")
2135                  (if_then_else
2136                    (ne (symbol_ref "optimize_size")
2137                        (const_int 0))
2138                    (const_string "V4SF")
2139                    (const_string "TI"))]
2140                (const_string "TI")))])
2142 (define_insn "*movti_rex64"
2143   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2144         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2145   "TARGET_64BIT
2146    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2148   switch (which_alternative)
2149     {
2150     case 0:
2151     case 1:
2152       return "#";
2153     case 2:
2154       if (get_attr_mode (insn) == MODE_V4SF)
2155         return "xorps\t%0, %0";
2156       else
2157         return "pxor\t%0, %0";
2158     case 3:
2159     case 4:
2160       if (get_attr_mode (insn) == MODE_V4SF)
2161         return "movaps\t{%1, %0|%0, %1}";
2162       else
2163         return "movdqa\t{%1, %0|%0, %1}";
2164     default:
2165       abort ();
2166     }
2168   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2169    (set (attr "mode")
2170         (cond [(eq_attr "alternative" "2,3")
2171                  (if_then_else
2172                    (ne (symbol_ref "optimize_size")
2173                        (const_int 0))
2174                    (const_string "V4SF")
2175                    (const_string "TI"))
2176                (eq_attr "alternative" "4")
2177                  (if_then_else
2178                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2179                             (const_int 0))
2180                         (ne (symbol_ref "optimize_size")
2181                             (const_int 0)))
2182                    (const_string "V4SF")
2183                    (const_string "TI"))]
2184                (const_string "DI")))])
2186 (define_split
2187   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2188         (match_operand:TI 1 "general_operand" ""))]
2189   "reload_completed && !SSE_REG_P (operands[0])
2190    && !SSE_REG_P (operands[1])"
2191   [(const_int 0)]
2192   "ix86_split_long_move (operands); DONE;")
2194 (define_expand "movsf"
2195   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2196         (match_operand:SF 1 "general_operand" ""))]
2197   ""
2198   "ix86_expand_move (SFmode, operands); DONE;")
2200 (define_insn "*pushsf"
2201   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2202         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2203   "!TARGET_64BIT"
2205   switch (which_alternative)
2206     {
2207     case 1:
2208       return "push{l}\t%1";
2210     default:
2211       /* This insn should be already split before reg-stack.  */
2212       abort ();
2213     }
2215   [(set_attr "type" "multi,push,multi")
2216    (set_attr "mode" "SF,SI,SF")])
2218 (define_insn "*pushsf_rex64"
2219   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2220         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2221   "TARGET_64BIT"
2223   switch (which_alternative)
2224     {
2225     case 1:
2226       return "push{q}\t%q1";
2228     default:
2229       /* This insn should be already split before reg-stack.  */
2230       abort ();
2231     }
2233   [(set_attr "type" "multi,push,multi")
2234    (set_attr "mode" "SF,DI,SF")])
2236 (define_split
2237   [(set (match_operand:SF 0 "push_operand" "")
2238         (match_operand:SF 1 "memory_operand" ""))]
2239   "reload_completed
2240    && GET_CODE (operands[1]) == MEM
2241    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2242    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2243   [(set (match_dup 0)
2244         (match_dup 1))]
2245   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2248 ;; %%% Kill this when call knows how to work this out.
2249 (define_split
2250   [(set (match_operand:SF 0 "push_operand" "")
2251         (match_operand:SF 1 "any_fp_register_operand" ""))]
2252   "!TARGET_64BIT"
2253   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2254    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2256 (define_split
2257   [(set (match_operand:SF 0 "push_operand" "")
2258         (match_operand:SF 1 "any_fp_register_operand" ""))]
2259   "TARGET_64BIT"
2260   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2261    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2263 (define_insn "*movsf_1"
2264   [(set (match_operand:SF 0 "nonimmediate_operand"
2265           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2266         (match_operand:SF 1 "general_operand"
2267           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2268   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2269    && (reload_in_progress || reload_completed
2270        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2271        || GET_CODE (operands[1]) != CONST_DOUBLE
2272        || memory_operand (operands[0], SFmode))" 
2274   switch (which_alternative)
2275     {
2276     case 0:
2277       return output_387_reg_move (insn, operands);
2279     case 1:
2280       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2281         return "fstp%z0\t%y0";
2282       else
2283         return "fst%z0\t%y0";
2285     case 2:
2286       return standard_80387_constant_opcode (operands[1]);
2288     case 3:
2289     case 4:
2290       return "mov{l}\t{%1, %0|%0, %1}";
2291     case 5:
2292       if (get_attr_mode (insn) == MODE_TI)
2293         return "pxor\t%0, %0";
2294       else
2295         return "xorps\t%0, %0";
2296     case 6:
2297       if (get_attr_mode (insn) == MODE_V4SF)
2298         return "movaps\t{%1, %0|%0, %1}";
2299       else
2300         return "movss\t{%1, %0|%0, %1}";
2301     case 7:
2302     case 8:
2303       return "movss\t{%1, %0|%0, %1}";
2305     case 9:
2306     case 10:
2307       return "movd\t{%1, %0|%0, %1}";
2309     case 11:
2310       return "movq\t{%1, %0|%0, %1}";
2312     default:
2313       abort();
2314     }
2316   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2317    (set (attr "mode")
2318         (cond [(eq_attr "alternative" "3,4,9,10")
2319                  (const_string "SI")
2320                (eq_attr "alternative" "5")
2321                  (if_then_else
2322                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2323                                  (const_int 0))
2324                              (ne (symbol_ref "TARGET_SSE2")
2325                                  (const_int 0)))
2326                         (eq (symbol_ref "optimize_size")
2327                             (const_int 0)))
2328                    (const_string "TI")
2329                    (const_string "V4SF"))
2330                /* For architectures resolving dependencies on
2331                   whole SSE registers use APS move to break dependency
2332                   chains, otherwise use short move to avoid extra work. 
2334                   Do the same for architectures resolving dependencies on
2335                   the parts.  While in DF mode it is better to always handle
2336                   just register parts, the SF mode is different due to lack
2337                   of instructions to load just part of the register.  It is
2338                   better to maintain the whole registers in single format
2339                   to avoid problems on using packed logical operations.  */
2340                (eq_attr "alternative" "6")
2341                  (if_then_else
2342                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2343                             (const_int 0))
2344                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2345                             (const_int 0)))
2346                    (const_string "V4SF")
2347                    (const_string "SF"))
2348                (eq_attr "alternative" "11")
2349                  (const_string "DI")]
2350                (const_string "SF")))])
2352 (define_insn "*swapsf"
2353   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2354         (match_operand:SF 1 "fp_register_operand" "+f"))
2355    (set (match_dup 1)
2356         (match_dup 0))]
2357   "reload_completed || TARGET_80387"
2359   if (STACK_TOP_P (operands[0]))
2360     return "fxch\t%1";
2361   else
2362     return "fxch\t%0";
2364   [(set_attr "type" "fxch")
2365    (set_attr "mode" "SF")])
2367 (define_expand "movdf"
2368   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2369         (match_operand:DF 1 "general_operand" ""))]
2370   ""
2371   "ix86_expand_move (DFmode, operands); DONE;")
2373 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2374 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2375 ;; On the average, pushdf using integers can be still shorter.  Allow this
2376 ;; pattern for optimize_size too.
2378 (define_insn "*pushdf_nointeger"
2379   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2380         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2381   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2383   /* This insn should be already split before reg-stack.  */
2384   abort ();
2386   [(set_attr "type" "multi")
2387    (set_attr "mode" "DF,SI,SI,DF")])
2389 (define_insn "*pushdf_integer"
2390   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2391         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2392   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2394   /* This insn should be already split before reg-stack.  */
2395   abort ();
2397   [(set_attr "type" "multi")
2398    (set_attr "mode" "DF,SI,DF")])
2400 ;; %%% Kill this when call knows how to work this out.
2401 (define_split
2402   [(set (match_operand:DF 0 "push_operand" "")
2403         (match_operand:DF 1 "any_fp_register_operand" ""))]
2404   "!TARGET_64BIT && reload_completed"
2405   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2406    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2407   "")
2409 (define_split
2410   [(set (match_operand:DF 0 "push_operand" "")
2411         (match_operand:DF 1 "any_fp_register_operand" ""))]
2412   "TARGET_64BIT && reload_completed"
2413   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2414    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2415   "")
2417 (define_split
2418   [(set (match_operand:DF 0 "push_operand" "")
2419         (match_operand:DF 1 "general_operand" ""))]
2420   "reload_completed"
2421   [(const_int 0)]
2422   "ix86_split_long_move (operands); DONE;")
2424 ;; Moving is usually shorter when only FP registers are used. This separate
2425 ;; movdf pattern avoids the use of integer registers for FP operations
2426 ;; when optimizing for size.
2428 (define_insn "*movdf_nointeger"
2429   [(set (match_operand:DF 0 "nonimmediate_operand"
2430                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2431         (match_operand:DF 1 "general_operand"
2432                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2433   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2434    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2435    && (reload_in_progress || reload_completed
2436        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2437        || GET_CODE (operands[1]) != CONST_DOUBLE
2438        || memory_operand (operands[0], DFmode))" 
2440   switch (which_alternative)
2441     {
2442     case 0:
2443       return output_387_reg_move (insn, operands);
2445     case 1:
2446       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2447         return "fstp%z0\t%y0";
2448       else
2449         return "fst%z0\t%y0";
2451     case 2:
2452       return standard_80387_constant_opcode (operands[1]);
2454     case 3:
2455     case 4:
2456       return "#";
2457     case 5:
2458       switch (get_attr_mode (insn))
2459         {
2460         case MODE_V4SF:
2461           return "xorps\t%0, %0";
2462         case MODE_V2DF:
2463           return "xorpd\t%0, %0";
2464         case MODE_TI:
2465           return "pxor\t%0, %0";
2466         default:
2467           abort ();
2468         }
2469     case 6:
2470     case 7:
2471     case 8:
2472       switch (get_attr_mode (insn))
2473         {
2474         case MODE_V4SF:
2475           return "movaps\t{%1, %0|%0, %1}";
2476         case MODE_V2DF:
2477           return "movapd\t{%1, %0|%0, %1}";
2478         case MODE_TI:
2479           return "movdqa\t{%1, %0|%0, %1}";
2480         case MODE_DI:
2481           return "movq\t{%1, %0|%0, %1}";
2482         case MODE_DF:
2483           return "movsd\t{%1, %0|%0, %1}";
2484         case MODE_V1DF:
2485           return "movlpd\t{%1, %0|%0, %1}";
2486         case MODE_V2SF:
2487           return "movlps\t{%1, %0|%0, %1}";
2488         default:
2489           abort ();
2490         }
2492     default:
2493       abort();
2494     }
2496   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2497    (set (attr "mode")
2498         (cond [(eq_attr "alternative" "0,1,2")
2499                  (const_string "DF")
2500                (eq_attr "alternative" "3,4")
2501                  (const_string "SI")
2503                /* For SSE1, we have many fewer alternatives.  */
2504                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2505                  (cond [(eq_attr "alternative" "5,6")
2506                           (const_string "V4SF")
2507                        ]
2508                    (const_string "V2SF"))
2510                /* xorps is one byte shorter.  */
2511                (eq_attr "alternative" "5")
2512                  (cond [(ne (symbol_ref "optimize_size")
2513                             (const_int 0))
2514                           (const_string "V4SF")
2515                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2516                             (const_int 0))
2517                           (const_string "TI")
2518                        ]
2519                        (const_string "V2DF"))
2521                /* For architectures resolving dependencies on
2522                   whole SSE registers use APD move to break dependency
2523                   chains, otherwise use short move to avoid extra work.
2525                   movaps encodes one byte shorter.  */
2526                (eq_attr "alternative" "6")
2527                  (cond
2528                    [(ne (symbol_ref "optimize_size")
2529                         (const_int 0))
2530                       (const_string "V4SF")
2531                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2532                         (const_int 0))
2533                       (const_string "V2DF")
2534                    ]
2535                    (const_string "DF"))
2536                /* For architectures resolving dependencies on register
2537                   parts we may avoid extra work to zero out upper part
2538                   of register.  */
2539                (eq_attr "alternative" "7")
2540                  (if_then_else
2541                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2542                        (const_int 0))
2543                    (const_string "V1DF")
2544                    (const_string "DF"))
2545               ]
2546               (const_string "DF")))])
2548 (define_insn "*movdf_integer"
2549   [(set (match_operand:DF 0 "nonimmediate_operand"
2550                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2551         (match_operand:DF 1 "general_operand"
2552                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2553   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2554    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2555    && (reload_in_progress || reload_completed
2556        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2557        || GET_CODE (operands[1]) != CONST_DOUBLE
2558        || memory_operand (operands[0], DFmode))" 
2560   switch (which_alternative)
2561     {
2562     case 0:
2563       return output_387_reg_move (insn, operands);
2565     case 1:
2566       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2567         return "fstp%z0\t%y0";
2568       else
2569         return "fst%z0\t%y0";
2571     case 2:
2572       return standard_80387_constant_opcode (operands[1]);
2574     case 3:
2575     case 4:
2576       return "#";
2578     case 5:
2579       switch (get_attr_mode (insn))
2580         {
2581         case MODE_V4SF:
2582           return "xorps\t%0, %0";
2583         case MODE_V2DF:
2584           return "xorpd\t%0, %0";
2585         case MODE_TI:
2586           return "pxor\t%0, %0";
2587         default:
2588           abort ();
2589         }
2590     case 6:
2591     case 7:
2592     case 8:
2593       switch (get_attr_mode (insn))
2594         {
2595         case MODE_V4SF:
2596           return "movaps\t{%1, %0|%0, %1}";
2597         case MODE_V2DF:
2598           return "movapd\t{%1, %0|%0, %1}";
2599         case MODE_TI:
2600           return "movdqa\t{%1, %0|%0, %1}";
2601         case MODE_DI:
2602           return "movq\t{%1, %0|%0, %1}";
2603         case MODE_DF:
2604           return "movsd\t{%1, %0|%0, %1}";
2605         case MODE_V1DF:
2606           return "movlpd\t{%1, %0|%0, %1}";
2607         case MODE_V2SF:
2608           return "movlps\t{%1, %0|%0, %1}";
2609         default:
2610           abort ();
2611         }
2613     default:
2614       abort();
2615     }
2617   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2618    (set (attr "mode")
2619         (cond [(eq_attr "alternative" "0,1,2")
2620                  (const_string "DF")
2621                (eq_attr "alternative" "3,4")
2622                  (const_string "SI")
2624                /* For SSE1, we have many fewer alternatives.  */
2625                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2626                  (cond [(eq_attr "alternative" "5,6")
2627                           (const_string "V4SF")
2628                        ]
2629                    (const_string "V2SF"))
2631                /* xorps is one byte shorter.  */
2632                (eq_attr "alternative" "5")
2633                  (cond [(ne (symbol_ref "optimize_size")
2634                             (const_int 0))
2635                           (const_string "V4SF")
2636                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2637                             (const_int 0))
2638                           (const_string "TI")
2639                        ]
2640                        (const_string "V2DF"))
2642                /* For architectures resolving dependencies on
2643                   whole SSE registers use APD move to break dependency
2644                   chains, otherwise use short move to avoid extra work.
2646                   movaps encodes one byte shorter.  */
2647                (eq_attr "alternative" "6")
2648                  (cond
2649                    [(ne (symbol_ref "optimize_size")
2650                         (const_int 0))
2651                       (const_string "V4SF")
2652                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2653                         (const_int 0))
2654                       (const_string "V2DF")
2655                    ]
2656                    (const_string "DF"))
2657                /* For architectures resolving dependencies on register
2658                   parts we may avoid extra work to zero out upper part
2659                   of register.  */
2660                (eq_attr "alternative" "7")
2661                  (if_then_else
2662                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2663                        (const_int 0))
2664                    (const_string "V1DF")
2665                    (const_string "DF"))
2666               ]
2667               (const_string "DF")))])
2669 (define_split
2670   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2671         (match_operand:DF 1 "general_operand" ""))]
2672   "reload_completed
2673    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2674    && ! (ANY_FP_REG_P (operands[0]) || 
2675          (GET_CODE (operands[0]) == SUBREG
2676           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2677    && ! (ANY_FP_REG_P (operands[1]) || 
2678          (GET_CODE (operands[1]) == SUBREG
2679           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2680   [(const_int 0)]
2681   "ix86_split_long_move (operands); DONE;")
2683 (define_insn "*swapdf"
2684   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2685         (match_operand:DF 1 "fp_register_operand" "+f"))
2686    (set (match_dup 1)
2687         (match_dup 0))]
2688   "reload_completed || TARGET_80387"
2690   if (STACK_TOP_P (operands[0]))
2691     return "fxch\t%1";
2692   else
2693     return "fxch\t%0";
2695   [(set_attr "type" "fxch")
2696    (set_attr "mode" "DF")])
2698 (define_expand "movxf"
2699   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2700         (match_operand:XF 1 "general_operand" ""))]
2701   ""
2702   "ix86_expand_move (XFmode, operands); DONE;")
2704 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2705 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2706 ;; Pushing using integer instructions is longer except for constants
2707 ;; and direct memory references.
2708 ;; (assuming that any given constant is pushed only once, but this ought to be
2709 ;;  handled elsewhere).
2711 (define_insn "*pushxf_nointeger"
2712   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2713         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2714   "optimize_size"
2716   /* This insn should be already split before reg-stack.  */
2717   abort ();
2719   [(set_attr "type" "multi")
2720    (set_attr "mode" "XF,SI,SI")])
2722 (define_insn "*pushxf_integer"
2723   [(set (match_operand:XF 0 "push_operand" "=<,<")
2724         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2725   "!optimize_size"
2727   /* This insn should be already split before reg-stack.  */
2728   abort ();
2730   [(set_attr "type" "multi")
2731    (set_attr "mode" "XF,SI")])
2733 (define_split
2734   [(set (match_operand 0 "push_operand" "")
2735         (match_operand 1 "general_operand" ""))]
2736   "reload_completed
2737    && (GET_MODE (operands[0]) == XFmode
2738        || GET_MODE (operands[0]) == DFmode)
2739    && !ANY_FP_REG_P (operands[1])"
2740   [(const_int 0)]
2741   "ix86_split_long_move (operands); DONE;")
2743 (define_split
2744   [(set (match_operand:XF 0 "push_operand" "")
2745         (match_operand:XF 1 "any_fp_register_operand" ""))]
2746   "!TARGET_64BIT"
2747   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2748    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2749   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2751 (define_split
2752   [(set (match_operand:XF 0 "push_operand" "")
2753         (match_operand:XF 1 "any_fp_register_operand" ""))]
2754   "TARGET_64BIT"
2755   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2756    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2757   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2759 ;; Do not use integer registers when optimizing for size
2760 (define_insn "*movxf_nointeger"
2761   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2762         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2763   "optimize_size
2764    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2765    && (reload_in_progress || reload_completed
2766        || GET_CODE (operands[1]) != CONST_DOUBLE
2767        || memory_operand (operands[0], XFmode))" 
2769   switch (which_alternative)
2770     {
2771     case 0:
2772       return output_387_reg_move (insn, operands);
2774     case 1:
2775       /* There is no non-popping store to memory for XFmode.  So if
2776          we need one, follow the store with a load.  */
2777       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2778         return "fstp%z0\t%y0\;fld%z0\t%y0";
2779       else
2780         return "fstp%z0\t%y0";
2782     case 2:
2783       return standard_80387_constant_opcode (operands[1]);
2785     case 3: case 4:
2786       return "#";
2787     }
2788   abort();
2790   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2791    (set_attr "mode" "XF,XF,XF,SI,SI")])
2793 (define_insn "*movxf_integer"
2794   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2795         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2796   "!optimize_size
2797    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2798    && (reload_in_progress || reload_completed
2799        || GET_CODE (operands[1]) != CONST_DOUBLE
2800        || memory_operand (operands[0], XFmode))" 
2802   switch (which_alternative)
2803     {
2804     case 0:
2805       return output_387_reg_move (insn, operands);
2807     case 1:
2808       /* There is no non-popping store to memory for XFmode.  So if
2809          we need one, follow the store with a load.  */
2810       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2811         return "fstp%z0\t%y0\;fld%z0\t%y0";
2812       else
2813         return "fstp%z0\t%y0";
2815     case 2:
2816       return standard_80387_constant_opcode (operands[1]);
2818     case 3: case 4:
2819       return "#";
2820     }
2821   abort();
2823   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2824    (set_attr "mode" "XF,XF,XF,SI,SI")])
2826 (define_split
2827   [(set (match_operand 0 "nonimmediate_operand" "")
2828         (match_operand 1 "general_operand" ""))]
2829   "reload_completed
2830    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2831    && GET_MODE (operands[0]) == XFmode
2832    && ! (ANY_FP_REG_P (operands[0]) || 
2833          (GET_CODE (operands[0]) == SUBREG
2834           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2835    && ! (ANY_FP_REG_P (operands[1]) || 
2836          (GET_CODE (operands[1]) == SUBREG
2837           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2838   [(const_int 0)]
2839   "ix86_split_long_move (operands); DONE;")
2841 (define_split
2842   [(set (match_operand 0 "register_operand" "")
2843         (match_operand 1 "memory_operand" ""))]
2844   "reload_completed
2845    && GET_CODE (operands[1]) == MEM
2846    && (GET_MODE (operands[0]) == XFmode
2847        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2848    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2849    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2850   [(set (match_dup 0) (match_dup 1))]
2852   rtx c = get_pool_constant (XEXP (operands[1], 0));
2853   rtx r = operands[0];
2855   if (GET_CODE (r) == SUBREG)
2856     r = SUBREG_REG (r);
2858   if (SSE_REG_P (r))
2859     {
2860       if (!standard_sse_constant_p (c))
2861         FAIL;
2862     }
2863   else if (FP_REG_P (r))
2864     {
2865       if (!standard_80387_constant_p (c))
2866         FAIL;
2867     }
2868   else if (MMX_REG_P (r))
2869     FAIL;
2871   operands[1] = c;
2874 (define_insn "swapxf"
2875   [(set (match_operand:XF 0 "register_operand" "+f")
2876         (match_operand:XF 1 "register_operand" "+f"))
2877    (set (match_dup 1)
2878         (match_dup 0))]
2879   "TARGET_80387"
2881   if (STACK_TOP_P (operands[0]))
2882     return "fxch\t%1";
2883   else
2884     return "fxch\t%0";
2886   [(set_attr "type" "fxch")
2887    (set_attr "mode" "XF")])
2889 (define_expand "movtf"
2890   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2891         (match_operand:TF 1 "nonimmediate_operand" ""))]
2892   "TARGET_64BIT"
2894   ix86_expand_move (TFmode, operands);
2895   DONE;
2898 (define_insn "*movtf_internal"
2899   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2900         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2901   "TARGET_64BIT
2902    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2904   switch (which_alternative)
2905     {
2906     case 0:
2907     case 1:
2908       return "#";
2909     case 2:
2910       if (get_attr_mode (insn) == MODE_V4SF)
2911         return "xorps\t%0, %0";
2912       else
2913         return "pxor\t%0, %0";
2914     case 3:
2915     case 4:
2916       if (get_attr_mode (insn) == MODE_V4SF)
2917         return "movaps\t{%1, %0|%0, %1}";
2918       else
2919         return "movdqa\t{%1, %0|%0, %1}";
2920     default:
2921       abort ();
2922     }
2924   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2925    (set (attr "mode")
2926         (cond [(eq_attr "alternative" "2,3")
2927                  (if_then_else
2928                    (ne (symbol_ref "optimize_size")
2929                        (const_int 0))
2930                    (const_string "V4SF")
2931                    (const_string "TI"))
2932                (eq_attr "alternative" "4")
2933                  (if_then_else
2934                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2935                             (const_int 0))
2936                         (ne (symbol_ref "optimize_size")
2937                             (const_int 0)))
2938                    (const_string "V4SF")
2939                    (const_string "TI"))]
2940                (const_string "DI")))])
2942 (define_split
2943   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2944         (match_operand:TF 1 "general_operand" ""))]
2945   "reload_completed && !SSE_REG_P (operands[0])
2946    && !SSE_REG_P (operands[1])"
2947   [(const_int 0)]
2948   "ix86_split_long_move (operands); DONE;")
2950 ;; Zero extension instructions
2952 (define_expand "zero_extendhisi2"
2953   [(set (match_operand:SI 0 "register_operand" "")
2954      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2955   ""
2957   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2958     {
2959       operands[1] = force_reg (HImode, operands[1]);
2960       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2961       DONE;
2962     }
2965 (define_insn "zero_extendhisi2_and"
2966   [(set (match_operand:SI 0 "register_operand" "=r")
2967      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2968    (clobber (reg:CC FLAGS_REG))]
2969   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2970   "#"
2971   [(set_attr "type" "alu1")
2972    (set_attr "mode" "SI")])
2974 (define_split
2975   [(set (match_operand:SI 0 "register_operand" "")
2976         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2977    (clobber (reg:CC FLAGS_REG))]
2978   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2979   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2980               (clobber (reg:CC FLAGS_REG))])]
2981   "")
2983 (define_insn "*zero_extendhisi2_movzwl"
2984   [(set (match_operand:SI 0 "register_operand" "=r")
2985      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2986   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2987   "movz{wl|x}\t{%1, %0|%0, %1}"
2988   [(set_attr "type" "imovx")
2989    (set_attr "mode" "SI")])
2991 (define_expand "zero_extendqihi2"
2992   [(parallel
2993     [(set (match_operand:HI 0 "register_operand" "")
2994        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2995      (clobber (reg:CC FLAGS_REG))])]
2996   ""
2997   "")
2999 (define_insn "*zero_extendqihi2_and"
3000   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3001      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3002    (clobber (reg:CC FLAGS_REG))]
3003   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3004   "#"
3005   [(set_attr "type" "alu1")
3006    (set_attr "mode" "HI")])
3008 (define_insn "*zero_extendqihi2_movzbw_and"
3009   [(set (match_operand:HI 0 "register_operand" "=r,r")
3010      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3011    (clobber (reg:CC FLAGS_REG))]
3012   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3013   "#"
3014   [(set_attr "type" "imovx,alu1")
3015    (set_attr "mode" "HI")])
3017 (define_insn "*zero_extendqihi2_movzbw"
3018   [(set (match_operand:HI 0 "register_operand" "=r")
3019      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3020   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3021   "movz{bw|x}\t{%1, %0|%0, %1}"
3022   [(set_attr "type" "imovx")
3023    (set_attr "mode" "HI")])
3025 ;; For the movzbw case strip only the clobber
3026 (define_split
3027   [(set (match_operand:HI 0 "register_operand" "")
3028         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3029    (clobber (reg:CC FLAGS_REG))]
3030   "reload_completed 
3031    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3032    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3033   [(set (match_operand:HI 0 "register_operand" "")
3034         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3036 ;; When source and destination does not overlap, clear destination
3037 ;; first and then do the movb
3038 (define_split
3039   [(set (match_operand:HI 0 "register_operand" "")
3040         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3041    (clobber (reg:CC FLAGS_REG))]
3042   "reload_completed
3043    && ANY_QI_REG_P (operands[0])
3044    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3045    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3046   [(set (match_dup 0) (const_int 0))
3047    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3048   "operands[2] = gen_lowpart (QImode, operands[0]);")
3050 ;; Rest is handled by single and.
3051 (define_split
3052   [(set (match_operand:HI 0 "register_operand" "")
3053         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3054    (clobber (reg:CC FLAGS_REG))]
3055   "reload_completed
3056    && true_regnum (operands[0]) == true_regnum (operands[1])"
3057   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3058               (clobber (reg:CC FLAGS_REG))])]
3059   "")
3061 (define_expand "zero_extendqisi2"
3062   [(parallel
3063     [(set (match_operand:SI 0 "register_operand" "")
3064        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3065      (clobber (reg:CC FLAGS_REG))])]
3066   ""
3067   "")
3069 (define_insn "*zero_extendqisi2_and"
3070   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3071      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3074   "#"
3075   [(set_attr "type" "alu1")
3076    (set_attr "mode" "SI")])
3078 (define_insn "*zero_extendqisi2_movzbw_and"
3079   [(set (match_operand:SI 0 "register_operand" "=r,r")
3080      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3081    (clobber (reg:CC FLAGS_REG))]
3082   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3083   "#"
3084   [(set_attr "type" "imovx,alu1")
3085    (set_attr "mode" "SI")])
3087 (define_insn "*zero_extendqisi2_movzbw"
3088   [(set (match_operand:SI 0 "register_operand" "=r")
3089      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3090   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3091   "movz{bl|x}\t{%1, %0|%0, %1}"
3092   [(set_attr "type" "imovx")
3093    (set_attr "mode" "SI")])
3095 ;; For the movzbl case strip only the clobber
3096 (define_split
3097   [(set (match_operand:SI 0 "register_operand" "")
3098         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3099    (clobber (reg:CC FLAGS_REG))]
3100   "reload_completed 
3101    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3102    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3103   [(set (match_dup 0)
3104         (zero_extend:SI (match_dup 1)))])
3106 ;; When source and destination does not overlap, clear destination
3107 ;; first and then do the movb
3108 (define_split
3109   [(set (match_operand:SI 0 "register_operand" "")
3110         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3111    (clobber (reg:CC FLAGS_REG))]
3112   "reload_completed
3113    && ANY_QI_REG_P (operands[0])
3114    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3115    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3116    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3117   [(set (match_dup 0) (const_int 0))
3118    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3119   "operands[2] = gen_lowpart (QImode, operands[0]);")
3121 ;; Rest is handled by single and.
3122 (define_split
3123   [(set (match_operand:SI 0 "register_operand" "")
3124         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3125    (clobber (reg:CC FLAGS_REG))]
3126   "reload_completed
3127    && true_regnum (operands[0]) == true_regnum (operands[1])"
3128   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3129               (clobber (reg:CC FLAGS_REG))])]
3130   "")
3132 ;; %%% Kill me once multi-word ops are sane.
3133 (define_expand "zero_extendsidi2"
3134   [(set (match_operand:DI 0 "register_operand" "=r")
3135      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3136   ""
3137   "if (!TARGET_64BIT)
3138      {
3139        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3140        DONE;
3141      }
3142   ")
3144 (define_insn "zero_extendsidi2_32"
3145   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3146         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3147    (clobber (reg:CC FLAGS_REG))]
3148   "!TARGET_64BIT"
3149   "@
3150    #
3151    #
3152    #
3153    movd\t{%1, %0|%0, %1}
3154    movd\t{%1, %0|%0, %1}"
3155   [(set_attr "mode" "SI,SI,SI,DI,TI")
3156    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3158 (define_insn "zero_extendsidi2_rex64"
3159   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3160      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3161   "TARGET_64BIT"
3162   "@
3163    mov\t{%k1, %k0|%k0, %k1}
3164    #
3165    movd\t{%1, %0|%0, %1}
3166    movd\t{%1, %0|%0, %1}"
3167   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3168    (set_attr "mode" "SI,DI,SI,SI")])
3170 (define_split
3171   [(set (match_operand:DI 0 "memory_operand" "")
3172      (zero_extend:DI (match_dup 0)))]
3173   "TARGET_64BIT"
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 "register_operand" "")
3179         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3180    (clobber (reg:CC FLAGS_REG))]
3181   "!TARGET_64BIT && reload_completed
3182    && true_regnum (operands[0]) == true_regnum (operands[1])"
3183   [(set (match_dup 4) (const_int 0))]
3184   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3186 (define_split 
3187   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3188         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3189    (clobber (reg:CC FLAGS_REG))]
3190   "!TARGET_64BIT && reload_completed
3191    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3192   [(set (match_dup 3) (match_dup 1))
3193    (set (match_dup 4) (const_int 0))]
3194   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3196 (define_insn "zero_extendhidi2"
3197   [(set (match_operand:DI 0 "register_operand" "=r,r")
3198      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3199   "TARGET_64BIT"
3200   "@
3201    movz{wl|x}\t{%1, %k0|%k0, %1}
3202    movz{wq|x}\t{%1, %0|%0, %1}"
3203   [(set_attr "type" "imovx")
3204    (set_attr "mode" "SI,DI")])
3206 (define_insn "zero_extendqidi2"
3207   [(set (match_operand:DI 0 "register_operand" "=r,r")
3208      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3209   "TARGET_64BIT"
3210   "@
3211    movz{bl|x}\t{%1, %k0|%k0, %1}
3212    movz{bq|x}\t{%1, %0|%0, %1}"
3213   [(set_attr "type" "imovx")
3214    (set_attr "mode" "SI,DI")])
3216 ;; Sign extension instructions
3218 (define_expand "extendsidi2"
3219   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3220                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3221               (clobber (reg:CC FLAGS_REG))
3222               (clobber (match_scratch:SI 2 ""))])]
3223   ""
3225   if (TARGET_64BIT)
3226     {
3227       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3228       DONE;
3229     }
3232 (define_insn "*extendsidi2_1"
3233   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3234         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3235    (clobber (reg:CC FLAGS_REG))
3236    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3237   "!TARGET_64BIT"
3238   "#")
3240 (define_insn "extendsidi2_rex64"
3241   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3242         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3243   "TARGET_64BIT"
3244   "@
3245    {cltq|cdqe}
3246    movs{lq|x}\t{%1,%0|%0, %1}"
3247   [(set_attr "type" "imovx")
3248    (set_attr "mode" "DI")
3249    (set_attr "prefix_0f" "0")
3250    (set_attr "modrm" "0,1")])
3252 (define_insn "extendhidi2"
3253   [(set (match_operand:DI 0 "register_operand" "=r")
3254         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3255   "TARGET_64BIT"
3256   "movs{wq|x}\t{%1,%0|%0, %1}"
3257   [(set_attr "type" "imovx")
3258    (set_attr "mode" "DI")])
3260 (define_insn "extendqidi2"
3261   [(set (match_operand:DI 0 "register_operand" "=r")
3262         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3263   "TARGET_64BIT"
3264   "movs{bq|x}\t{%1,%0|%0, %1}"
3265    [(set_attr "type" "imovx")
3266     (set_attr "mode" "DI")])
3268 ;; Extend to memory case when source register does die.
3269 (define_split 
3270   [(set (match_operand:DI 0 "memory_operand" "")
3271         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3272    (clobber (reg:CC FLAGS_REG))
3273    (clobber (match_operand:SI 2 "register_operand" ""))]
3274   "(reload_completed
3275     && dead_or_set_p (insn, operands[1])
3276     && !reg_mentioned_p (operands[1], operands[0]))"
3277   [(set (match_dup 3) (match_dup 1))
3278    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3279               (clobber (reg:CC FLAGS_REG))])
3280    (set (match_dup 4) (match_dup 1))]
3281   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3283 ;; Extend to memory case when source register does not die.
3284 (define_split 
3285   [(set (match_operand:DI 0 "memory_operand" "")
3286         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287    (clobber (reg:CC FLAGS_REG))
3288    (clobber (match_operand:SI 2 "register_operand" ""))]
3289   "reload_completed"
3290   [(const_int 0)]
3292   split_di (&operands[0], 1, &operands[3], &operands[4]);
3294   emit_move_insn (operands[3], operands[1]);
3296   /* Generate a cltd if possible and doing so it profitable.  */
3297   if (true_regnum (operands[1]) == 0
3298       && true_regnum (operands[2]) == 1
3299       && (optimize_size || TARGET_USE_CLTD))
3300     {
3301       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3302     }
3303   else
3304     {
3305       emit_move_insn (operands[2], operands[1]);
3306       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3307     }
3308   emit_move_insn (operands[4], operands[2]);
3309   DONE;
3312 ;; Extend to register case.  Optimize case where source and destination
3313 ;; registers match and cases where we can use cltd.
3314 (define_split 
3315   [(set (match_operand:DI 0 "register_operand" "")
3316         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3317    (clobber (reg:CC FLAGS_REG))
3318    (clobber (match_scratch:SI 2 ""))]
3319   "reload_completed"
3320   [(const_int 0)]
3322   split_di (&operands[0], 1, &operands[3], &operands[4]);
3324   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3325     emit_move_insn (operands[3], operands[1]);
3327   /* Generate a cltd if possible and doing so it profitable.  */
3328   if (true_regnum (operands[3]) == 0
3329       && (optimize_size || TARGET_USE_CLTD))
3330     {
3331       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3332       DONE;
3333     }
3335   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3336     emit_move_insn (operands[4], operands[1]);
3338   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3339   DONE;
3342 (define_insn "extendhisi2"
3343   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3344         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3345   ""
3347   switch (get_attr_prefix_0f (insn))
3348     {
3349     case 0:
3350       return "{cwtl|cwde}";
3351     default:
3352       return "movs{wl|x}\t{%1,%0|%0, %1}";
3353     }
3355   [(set_attr "type" "imovx")
3356    (set_attr "mode" "SI")
3357    (set (attr "prefix_0f")
3358      ;; movsx is short decodable while cwtl is vector decoded.
3359      (if_then_else (and (eq_attr "cpu" "!k6")
3360                         (eq_attr "alternative" "0"))
3361         (const_string "0")
3362         (const_string "1")))
3363    (set (attr "modrm")
3364      (if_then_else (eq_attr "prefix_0f" "0")
3365         (const_string "0")
3366         (const_string "1")))])
3368 (define_insn "*extendhisi2_zext"
3369   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3370         (zero_extend:DI
3371           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3372   "TARGET_64BIT"
3374   switch (get_attr_prefix_0f (insn))
3375     {
3376     case 0:
3377       return "{cwtl|cwde}";
3378     default:
3379       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3380     }
3382   [(set_attr "type" "imovx")
3383    (set_attr "mode" "SI")
3384    (set (attr "prefix_0f")
3385      ;; movsx is short decodable while cwtl is vector decoded.
3386      (if_then_else (and (eq_attr "cpu" "!k6")
3387                         (eq_attr "alternative" "0"))
3388         (const_string "0")
3389         (const_string "1")))
3390    (set (attr "modrm")
3391      (if_then_else (eq_attr "prefix_0f" "0")
3392         (const_string "0")
3393         (const_string "1")))])
3395 (define_insn "extendqihi2"
3396   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3397         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3398   ""
3400   switch (get_attr_prefix_0f (insn))
3401     {
3402     case 0:
3403       return "{cbtw|cbw}";
3404     default:
3405       return "movs{bw|x}\t{%1,%0|%0, %1}";
3406     }
3408   [(set_attr "type" "imovx")
3409    (set_attr "mode" "HI")
3410    (set (attr "prefix_0f")
3411      ;; movsx is short decodable while cwtl is vector decoded.
3412      (if_then_else (and (eq_attr "cpu" "!k6")
3413                         (eq_attr "alternative" "0"))
3414         (const_string "0")
3415         (const_string "1")))
3416    (set (attr "modrm")
3417      (if_then_else (eq_attr "prefix_0f" "0")
3418         (const_string "0")
3419         (const_string "1")))])
3421 (define_insn "extendqisi2"
3422   [(set (match_operand:SI 0 "register_operand" "=r")
3423         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3424   ""
3425   "movs{bl|x}\t{%1,%0|%0, %1}"
3426    [(set_attr "type" "imovx")
3427     (set_attr "mode" "SI")])
3429 (define_insn "*extendqisi2_zext"
3430   [(set (match_operand:DI 0 "register_operand" "=r")
3431         (zero_extend:DI
3432           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3433   "TARGET_64BIT"
3434   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3435    [(set_attr "type" "imovx")
3436     (set_attr "mode" "SI")])
3438 ;; Conversions between float and double.
3440 ;; These are all no-ops in the model used for the 80387.  So just
3441 ;; emit moves.
3443 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3444 (define_insn "*dummy_extendsfdf2"
3445   [(set (match_operand:DF 0 "push_operand" "=<")
3446         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3447   "0"
3448   "#")
3450 (define_split
3451   [(set (match_operand:DF 0 "push_operand" "")
3452         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3453   "!TARGET_64BIT"
3454   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3455    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3457 (define_split
3458   [(set (match_operand:DF 0 "push_operand" "")
3459         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3460   "TARGET_64BIT"
3461   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3462    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3464 (define_insn "*dummy_extendsfxf2"
3465   [(set (match_operand:XF 0 "push_operand" "=<")
3466         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3467   "0"
3468   "#")
3470 (define_split
3471   [(set (match_operand:XF 0 "push_operand" "")
3472         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3473   ""
3474   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3475    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3476   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3478 (define_split
3479   [(set (match_operand:XF 0 "push_operand" "")
3480         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3481   "TARGET_64BIT"
3482   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3483    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3484   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3486 (define_split
3487   [(set (match_operand:XF 0 "push_operand" "")
3488         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3489   ""
3490   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3491    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3492   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3494 (define_split
3495   [(set (match_operand:XF 0 "push_operand" "")
3496         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3497   "TARGET_64BIT"
3498   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3499    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3500   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3502 (define_expand "extendsfdf2"
3503   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3504         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3505   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3507   /* ??? Needed for compress_float_constant since all fp constants
3508      are LEGITIMATE_CONSTANT_P.  */
3509   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3510     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3511   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3512     operands[1] = force_reg (SFmode, operands[1]);
3515 (define_insn "*extendsfdf2_mixed"
3516   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3517         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3518   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3519    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3521   switch (which_alternative)
3522     {
3523     case 0:
3524       return output_387_reg_move (insn, operands);
3526     case 1:
3527       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3528         return "fstp%z0\t%y0";
3529       else
3530         return "fst%z0\t%y0";
3532     case 2:
3533       return "cvtss2sd\t{%1, %0|%0, %1}";
3535     default:
3536       abort ();
3537     }
3539   [(set_attr "type" "fmov,fmov,ssecvt")
3540    (set_attr "mode" "SF,XF,DF")])
3542 (define_insn "*extendsfdf2_sse"
3543   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3544         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3545   "TARGET_SSE2 && TARGET_SSE_MATH
3546    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3547   "cvtss2sd\t{%1, %0|%0, %1}"
3548   [(set_attr "type" "ssecvt")
3549    (set_attr "mode" "DF")])
3551 (define_insn "*extendsfdf2_i387"
3552   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3553         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3554   "TARGET_80387
3555    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557   switch (which_alternative)
3558     {
3559     case 0:
3560       return output_387_reg_move (insn, operands);
3562     case 1:
3563       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3564         return "fstp%z0\t%y0";
3565       else
3566         return "fst%z0\t%y0";
3568     default:
3569       abort ();
3570     }
3572   [(set_attr "type" "fmov")
3573    (set_attr "mode" "SF,XF")])
3575 (define_expand "extendsfxf2"
3576   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3577         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3578   "TARGET_80387"
3580   /* ??? Needed for compress_float_constant since all fp constants
3581      are LEGITIMATE_CONSTANT_P.  */
3582   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3583     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3584   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3585     operands[1] = force_reg (SFmode, operands[1]);
3588 (define_insn "*extendsfxf2_i387"
3589   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3590         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3591   "TARGET_80387
3592    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3594   switch (which_alternative)
3595     {
3596     case 0:
3597       return output_387_reg_move (insn, operands);
3599     case 1:
3600       /* There is no non-popping store to memory for XFmode.  So if
3601          we need one, follow the store with a load.  */
3602       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3603         return "fstp%z0\t%y0";
3604       else
3605         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3607     default:
3608       abort ();
3609     }
3611   [(set_attr "type" "fmov")
3612    (set_attr "mode" "SF,XF")])
3614 (define_expand "extenddfxf2"
3615   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3616         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3617   "TARGET_80387"
3619   /* ??? Needed for compress_float_constant since all fp constants
3620      are LEGITIMATE_CONSTANT_P.  */
3621   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3622     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3623   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3624     operands[1] = force_reg (DFmode, operands[1]);
3627 (define_insn "*extenddfxf2_i387"
3628   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3629         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3630   "TARGET_80387
3631    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3633   switch (which_alternative)
3634     {
3635     case 0:
3636       return output_387_reg_move (insn, operands);
3638     case 1:
3639       /* There is no non-popping store to memory for XFmode.  So if
3640          we need one, follow the store with a load.  */
3641       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3642         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3643       else
3644         return "fstp%z0\t%y0";
3646     default:
3647       abort ();
3648     }
3650   [(set_attr "type" "fmov")
3651    (set_attr "mode" "DF,XF")])
3653 ;; %%% This seems bad bad news.
3654 ;; This cannot output into an f-reg because there is no way to be sure
3655 ;; of truncating in that case.  Otherwise this is just like a simple move
3656 ;; insn.  So we pretend we can output to a reg in order to get better
3657 ;; register preferencing, but we really use a stack slot.
3659 ;; Conversion from DFmode to SFmode.
3661 (define_expand "truncdfsf2"
3662   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3663         (float_truncate:SF
3664           (match_operand:DF 1 "nonimmediate_operand" "")))]
3665   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3667   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3668     operands[1] = force_reg (DFmode, operands[1]);
3670   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3671     ;
3672   else if (flag_unsafe_math_optimizations)
3673     ;
3674   else
3675     {
3676       rtx temp = assign_386_stack_local (SFmode, 0);
3677       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3678       DONE;
3679     }
3682 (define_expand "truncdfsf2_with_temp"
3683   [(parallel [(set (match_operand:SF 0 "" "")
3684                    (float_truncate:SF (match_operand:DF 1 "" "")))
3685               (clobber (match_operand:SF 2 "" ""))])]
3686   "")
3688 (define_insn "*truncdfsf_fast_mixed"
3689   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3690         (float_truncate:SF
3691           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3692   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3694   switch (which_alternative)
3695     {
3696     case 0:
3697       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3698         return "fstp%z0\t%y0";
3699       else
3700         return "fst%z0\t%y0";
3701     case 1:
3702       return output_387_reg_move (insn, operands);
3703     case 2:
3704       return "cvtsd2ss\t{%1, %0|%0, %1}";
3705     default:
3706       abort ();
3707     }
3709   [(set_attr "type" "fmov,fmov,ssecvt")
3710    (set_attr "mode" "SF")])
3712 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3713 ;; because nothing we do here is unsafe.
3714 (define_insn "*truncdfsf_fast_sse"
3715   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3716         (float_truncate:SF
3717           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3718   "TARGET_SSE2 && TARGET_SSE_MATH"
3719   "cvtsd2ss\t{%1, %0|%0, %1}"
3720   [(set_attr "type" "ssecvt")
3721    (set_attr "mode" "SF")])
3723 (define_insn "*truncdfsf_fast_i387"
3724   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3725         (float_truncate:SF
3726           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3727   "TARGET_80387 && flag_unsafe_math_optimizations"
3728   "* return output_387_reg_move (insn, operands);"
3729   [(set_attr "type" "fmov")
3730    (set_attr "mode" "SF")])
3732 (define_insn "*truncdfsf_mixed"
3733   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3734         (float_truncate:SF
3735           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3736    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3737   "TARGET_MIX_SSE_I387"
3739   switch (which_alternative)
3740     {
3741     case 0:
3742       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3743         return "fstp%z0\t%y0";
3744       else
3745         return "fst%z0\t%y0";
3746     case 1:
3747       return "#";
3748     case 2:
3749       return "cvtsd2ss\t{%1, %0|%0, %1}";
3750     default:
3751       abort ();
3752     }
3754   [(set_attr "type" "fmov,multi,ssecvt")
3755    (set_attr "mode" "SF")])
3757 (define_insn "*truncdfsf_i387"
3758   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3759         (float_truncate:SF
3760           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3761    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3762   "TARGET_80387"
3764   switch (which_alternative)
3765     {
3766     case 0:
3767       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3768         return "fstp%z0\t%y0";
3769       else
3770         return "fst%z0\t%y0";
3771     case 1:
3772       return "#";
3773     default:
3774       abort ();
3775     }
3777   [(set_attr "type" "fmov,multi")
3778    (set_attr "mode" "SF")])
3780 (define_insn "*truncdfsf2_i387_1"
3781   [(set (match_operand:SF 0 "memory_operand" "=m")
3782         (float_truncate:SF
3783           (match_operand:DF 1 "register_operand" "f")))]
3784   "TARGET_80387
3785    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3786    && !TARGET_MIX_SSE_I387"
3788   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3789     return "fstp%z0\t%y0";
3790   else
3791     return "fst%z0\t%y0";
3793   [(set_attr "type" "fmov")
3794    (set_attr "mode" "SF")])
3796 (define_split
3797   [(set (match_operand:SF 0 "register_operand" "")
3798         (float_truncate:SF
3799          (match_operand:DF 1 "fp_register_operand" "")))
3800    (clobber (match_operand 2 "" ""))]
3801   "reload_completed"
3802   [(set (match_dup 2) (match_dup 1))
3803    (set (match_dup 0) (match_dup 2))]
3805   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3808 ;; Conversion from XFmode to SFmode.
3810 (define_expand "truncxfsf2"
3811   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3812                    (float_truncate:SF
3813                     (match_operand:XF 1 "register_operand" "")))
3814               (clobber (match_dup 2))])]
3815   "TARGET_80387"
3817   if (flag_unsafe_math_optimizations)
3818     {
3819       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3820       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3821       if (reg != operands[0])
3822         emit_move_insn (operands[0], reg);
3823       DONE;
3824     }
3825   else
3826     operands[2] = assign_386_stack_local (SFmode, 0);
3829 (define_insn "*truncxfsf2_mixed"
3830   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3831         (float_truncate:SF
3832          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3833    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3834   "TARGET_MIX_SSE_I387"
3836   switch (which_alternative)
3837     {
3838     case 0:
3839       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3840         return "fstp%z0\t%y0";
3841       else
3842         return "fst%z0\t%y0";
3843     default:
3844       abort();
3845     }
3847   [(set_attr "type" "fmov,multi,multi,multi")
3848    (set_attr "mode" "SF")])
3850 (define_insn "truncxfsf2_i387_noop"
3851   [(set (match_operand:SF 0 "register_operand" "=f")
3852         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3853   "TARGET_80387 && flag_unsafe_math_optimizations"
3855   return output_387_reg_move (insn, operands);
3857   [(set_attr "type" "fmov")
3858    (set_attr "mode" "SF")])
3860 (define_insn "*truncxfsf2_i387"
3861   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3862         (float_truncate:SF
3863          (match_operand:XF 1 "register_operand" "f,f,f")))
3864    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3865   "TARGET_80387"
3867   switch (which_alternative)
3868     {
3869     case 0:
3870       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3871         return "fstp%z0\t%y0";
3872       else
3873         return "fst%z0\t%y0";
3874     default:
3875       abort ();
3876     }
3878   [(set_attr "type" "fmov,multi,multi")
3879    (set_attr "mode" "SF")])
3881 (define_insn "*truncxfsf2_i387_1"
3882   [(set (match_operand:SF 0 "memory_operand" "=m")
3883         (float_truncate:SF
3884          (match_operand:XF 1 "register_operand" "f")))]
3885   "TARGET_80387"
3887   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3888     return "fstp%z0\t%y0";
3889   else
3890     return "fst%z0\t%y0";
3892   [(set_attr "type" "fmov")
3893    (set_attr "mode" "SF")])
3895 (define_split
3896   [(set (match_operand:SF 0 "register_operand" "")
3897         (float_truncate:SF
3898          (match_operand:XF 1 "register_operand" "")))
3899    (clobber (match_operand:SF 2 "memory_operand" ""))]
3900   "TARGET_80387 && reload_completed"
3901   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3902    (set (match_dup 0) (match_dup 2))]
3903   "")
3905 (define_split
3906   [(set (match_operand:SF 0 "memory_operand" "")
3907         (float_truncate:SF
3908          (match_operand:XF 1 "register_operand" "")))
3909    (clobber (match_operand:SF 2 "memory_operand" ""))]
3910   "TARGET_80387"
3911   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3912   "")
3914 ;; Conversion from XFmode to DFmode.
3916 (define_expand "truncxfdf2"
3917   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3918                    (float_truncate:DF
3919                     (match_operand:XF 1 "register_operand" "")))
3920               (clobber (match_dup 2))])]
3921   "TARGET_80387"
3923   if (flag_unsafe_math_optimizations)
3924     {
3925       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3926       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3927       if (reg != operands[0])
3928         emit_move_insn (operands[0], reg);
3929       DONE;
3930     }
3931   else
3932     operands[2] = assign_386_stack_local (DFmode, 0);
3935 (define_insn "*truncxfdf2_mixed"
3936   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3937         (float_truncate:DF
3938          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3939    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3940   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3942   switch (which_alternative)
3943     {
3944     case 0:
3945       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3946         return "fstp%z0\t%y0";
3947       else
3948         return "fst%z0\t%y0";
3949     default:
3950       abort();
3951     }
3952   abort ();
3954   [(set_attr "type" "fmov,multi,multi,multi")
3955    (set_attr "mode" "DF")])
3957 (define_insn "truncxfdf2_i387_noop"
3958   [(set (match_operand:DF 0 "register_operand" "=f")
3959         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3960   "TARGET_80387 && flag_unsafe_math_optimizations"
3962   return output_387_reg_move (insn, operands);
3964   [(set_attr "type" "fmov")
3965    (set_attr "mode" "DF")])
3967 (define_insn "*truncxfdf2_i387"
3968   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3969         (float_truncate:DF
3970          (match_operand:XF 1 "register_operand" "f,f,f")))
3971    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3972   "TARGET_80387"
3974   switch (which_alternative)
3975     {
3976     case 0:
3977       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3978         return "fstp%z0\t%y0";
3979       else
3980         return "fst%z0\t%y0";
3981     default:
3982       abort ();
3983     }
3985   [(set_attr "type" "fmov,multi,multi")
3986    (set_attr "mode" "DF")])
3988 (define_insn "*truncxfdf2_i387_1"
3989   [(set (match_operand:DF 0 "memory_operand" "=m")
3990         (float_truncate:DF
3991           (match_operand:XF 1 "register_operand" "f")))]
3992   "TARGET_80387"
3994   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3995     return "fstp%z0\t%y0";
3996   else
3997     return "fst%z0\t%y0";
3999   [(set_attr "type" "fmov")
4000    (set_attr "mode" "DF")])
4002 (define_split
4003   [(set (match_operand:DF 0 "register_operand" "")
4004         (float_truncate:DF
4005          (match_operand:XF 1 "register_operand" "")))
4006    (clobber (match_operand:DF 2 "memory_operand" ""))]
4007   "TARGET_80387 && reload_completed"
4008   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4009    (set (match_dup 0) (match_dup 2))]
4010   "")
4012 (define_split
4013   [(set (match_operand:DF 0 "memory_operand" "")
4014         (float_truncate:DF
4015          (match_operand:XF 1 "register_operand" "")))
4016    (clobber (match_operand:DF 2 "memory_operand" ""))]
4017   "TARGET_80387"
4018   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4019   "")
4021 ;; Signed conversion to DImode.
4023 (define_expand "fix_truncxfdi2"
4024   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4025                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4026               (clobber (reg:CC FLAGS_REG))])]
4027   "TARGET_80387"
4029   if (TARGET_FISTTP)
4030    {
4031      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4032      DONE;
4033    }
4036 (define_expand "fix_trunc<mode>di2"
4037   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4038                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4039               (clobber (reg:CC FLAGS_REG))])]
4040   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4042   if (TARGET_FISTTP
4043       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4044    {
4045      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4046      DONE;
4047    }
4048   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4049    {
4050      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4051      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4052      if (out != operands[0])
4053         emit_move_insn (operands[0], out);
4054      DONE;
4055    }
4058 ;; Signed conversion to SImode.
4060 (define_expand "fix_truncxfsi2"
4061   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4062                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4063               (clobber (reg:CC FLAGS_REG))])]
4064   "TARGET_80387"
4066   if (TARGET_FISTTP)
4067    {
4068      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4069      DONE;
4070    }
4073 (define_expand "fix_trunc<mode>si2"
4074   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4075                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4076               (clobber (reg:CC FLAGS_REG))])]
4077   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4079   if (TARGET_FISTTP
4080       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4081    {
4082      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4083      DONE;
4084    }
4085   if (SSE_FLOAT_MODE_P (<MODE>mode))
4086    {
4087      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4088      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4089      if (out != operands[0])
4090         emit_move_insn (operands[0], out);
4091      DONE;
4092    }
4095 ;; Signed conversion to HImode.
4097 (define_expand "fix_trunc<mode>hi2"
4098   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4099                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4100               (clobber (reg:CC FLAGS_REG))])]
4101   "TARGET_80387
4102    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4104   if (TARGET_FISTTP)
4105    {
4106      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4107      DONE;
4108    }
4111 ;; When SSE is available, it is always faster to use it!
4112 (define_insn "fix_truncsfdi_sse"
4113   [(set (match_operand:DI 0 "register_operand" "=r,r")
4114         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4115   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4116   "cvttss2si{q}\t{%1, %0|%0, %1}"
4117   [(set_attr "type" "sseicvt")
4118    (set_attr "mode" "SF")
4119    (set_attr "athlon_decode" "double,vector")])
4121 (define_insn "fix_truncdfdi_sse"
4122   [(set (match_operand:DI 0 "register_operand" "=r,r")
4123         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4124   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4125   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4126   [(set_attr "type" "sseicvt")
4127    (set_attr "mode" "DF")
4128    (set_attr "athlon_decode" "double,vector")])
4130 (define_insn "fix_truncsfsi_sse"
4131   [(set (match_operand:SI 0 "register_operand" "=r,r")
4132         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4133   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4134   "cvttss2si\t{%1, %0|%0, %1}"
4135   [(set_attr "type" "sseicvt")
4136    (set_attr "mode" "DF")
4137    (set_attr "athlon_decode" "double,vector")])
4139 (define_insn "fix_truncdfsi_sse"
4140   [(set (match_operand:SI 0 "register_operand" "=r,r")
4141         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4142   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4143   "cvttsd2si\t{%1, %0|%0, %1}"
4144   [(set_attr "type" "sseicvt")
4145    (set_attr "mode" "DF")
4146    (set_attr "athlon_decode" "double,vector")])
4148 ;; Avoid vector decoded forms of the instruction.
4149 (define_peephole2
4150   [(match_scratch:DF 2 "Y")
4151    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4152         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4153   "TARGET_K8 && !optimize_size"
4154   [(set (match_dup 2) (match_dup 1))
4155    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4156   "")
4158 (define_peephole2
4159   [(match_scratch:SF 2 "x")
4160    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4161         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4162   "TARGET_K8 && !optimize_size"
4163   [(set (match_dup 2) (match_dup 1))
4164    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4165   "")
4167 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4168   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4169         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4170   "TARGET_80387 && TARGET_FISTTP
4171    && FLOAT_MODE_P (GET_MODE (operands[1]))
4172    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4173          && (TARGET_64BIT || <MODE>mode != DImode))
4174         && TARGET_SSE_MATH)
4175    && !(reload_completed || reload_in_progress)"
4176   "#"
4177   "&& 1"
4178   [(const_int 0)]
4180   if (memory_operand (operands[0], VOIDmode))
4181     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4182   else
4183     {
4184       operands[2] = assign_386_stack_local (<MODE>mode, 0);
4185       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4186                                                             operands[1],
4187                                                             operands[2]));
4188     }
4189   DONE;
4191   [(set_attr "type" "fisttp")
4192    (set_attr "mode" "<MODE>")])
4194 (define_insn "fix_trunc<mode>_i387_fisttp"
4195   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4196         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4197    (clobber (match_scratch:XF 2 "=&1f"))]
4198   "TARGET_80387 && TARGET_FISTTP
4199    && FLOAT_MODE_P (GET_MODE (operands[1]))
4200    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201          && (TARGET_64BIT || <MODE>mode != DImode))
4202         && TARGET_SSE_MATH)"
4203   "* return output_fix_trunc (insn, operands, 1);"
4204   [(set_attr "type" "fisttp")
4205    (set_attr "mode" "<MODE>")])
4207 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4208   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4209         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4210    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4211    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4212   "TARGET_80387 && TARGET_FISTTP
4213    && FLOAT_MODE_P (GET_MODE (operands[1]))
4214    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4215         && (TARGET_64BIT || <MODE>mode != DImode))
4216         && TARGET_SSE_MATH)"
4217   "#"
4218   [(set_attr "type" "fisttp")
4219    (set_attr "mode" "<MODE>")])
4221 (define_split
4222   [(set (match_operand:X87MODEI 0 "register_operand" "")
4223         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4224    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4225    (clobber (match_scratch 3 ""))]
4226   "reload_completed"
4227   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4228               (clobber (match_dup 3))])
4229    (set (match_dup 0) (match_dup 2))]
4230   "")
4232 (define_split
4233   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4234         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4235    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4236    (clobber (match_scratch 3 ""))]
4237   "reload_completed"
4238   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4239               (clobber (match_dup 3))])]
4240   "")
4242 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4243 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4244 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4245 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4246 ;; function in i386.c.
4247 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4248   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4249         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4250    (clobber (reg:CC FLAGS_REG))]
4251   "TARGET_80387 && !TARGET_FISTTP
4252    && FLOAT_MODE_P (GET_MODE (operands[1]))
4253    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4254          && (TARGET_64BIT || <MODE>mode != DImode))
4255    && !(reload_completed || reload_in_progress)"
4256   "#"
4257   "&& 1"
4258   [(const_int 0)]
4260   ix86_optimize_mode_switching = 1;
4261   operands[2] = assign_386_stack_local (HImode, 1);
4262   operands[3] = assign_386_stack_local (HImode, 2);
4263   if (memory_operand (operands[0], VOIDmode))
4264     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4265                                          operands[2], operands[3]));
4266   else
4267     {
4268       operands[4] = assign_386_stack_local (<MODE>mode, 0);
4269       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4270                                                      operands[2], operands[3],
4271                                                      operands[4]));
4272     }
4273   DONE;
4275   [(set_attr "type" "fistp")
4276    (set_attr "i387_cw" "trunc")
4277    (set_attr "mode" "<MODE>")])
4279 (define_insn "fix_truncdi_i387"
4280   [(set (match_operand:DI 0 "memory_operand" "=m")
4281         (fix:DI (match_operand 1 "register_operand" "f")))
4282    (use (match_operand:HI 2 "memory_operand" "m"))
4283    (use (match_operand:HI 3 "memory_operand" "m"))
4284    (clobber (match_scratch:XF 4 "=&1f"))]
4285   "TARGET_80387 && !TARGET_FISTTP
4286    && FLOAT_MODE_P (GET_MODE (operands[1]))
4287    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4288   "* return output_fix_trunc (insn, operands, 0);"
4289   [(set_attr "type" "fistp")
4290    (set_attr "i387_cw" "trunc")
4291    (set_attr "mode" "DI")])
4293 (define_insn "fix_truncdi_i387_with_temp"
4294   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4295         (fix:DI (match_operand 1 "register_operand" "f,f")))
4296    (use (match_operand:HI 2 "memory_operand" "m,m"))
4297    (use (match_operand:HI 3 "memory_operand" "m,m"))
4298    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4299    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4300   "TARGET_80387 && !TARGET_FISTTP
4301    && FLOAT_MODE_P (GET_MODE (operands[1]))
4302    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4303   "#"
4304   [(set_attr "type" "fistp")
4305    (set_attr "i387_cw" "trunc")
4306    (set_attr "mode" "DI")])
4308 (define_split 
4309   [(set (match_operand:DI 0 "register_operand" "")
4310         (fix:DI (match_operand 1 "register_operand" "")))
4311    (use (match_operand:HI 2 "memory_operand" ""))
4312    (use (match_operand:HI 3 "memory_operand" ""))
4313    (clobber (match_operand:DI 4 "memory_operand" ""))
4314    (clobber (match_scratch 5 ""))]
4315   "reload_completed"
4316   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4317               (use (match_dup 2))
4318               (use (match_dup 3))
4319               (clobber (match_dup 5))])
4320    (set (match_dup 0) (match_dup 4))]
4321   "")
4323 (define_split 
4324   [(set (match_operand:DI 0 "memory_operand" "")
4325         (fix:DI (match_operand 1 "register_operand" "")))
4326    (use (match_operand:HI 2 "memory_operand" ""))
4327    (use (match_operand:HI 3 "memory_operand" ""))
4328    (clobber (match_operand:DI 4 "memory_operand" ""))
4329    (clobber (match_scratch 5 ""))]
4330   "reload_completed"
4331   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4332               (use (match_dup 2))
4333               (use (match_dup 3))
4334               (clobber (match_dup 5))])]
4335   "")
4337 (define_insn "fix_trunc<mode>_i387"
4338   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4339         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4340    (use (match_operand:HI 2 "memory_operand" "m"))
4341    (use (match_operand:HI 3 "memory_operand" "m"))]
4342   "TARGET_80387 && !TARGET_FISTTP
4343    && FLOAT_MODE_P (GET_MODE (operands[1]))
4344    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4345   "* return output_fix_trunc (insn, operands, 0);"
4346   [(set_attr "type" "fistp")
4347    (set_attr "i387_cw" "trunc")
4348    (set_attr "mode" "<MODE>")])
4350 (define_insn "fix_trunc<mode>_i387_with_temp"
4351   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4352         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4353    (use (match_operand:HI 2 "memory_operand" "m,m"))
4354    (use (match_operand:HI 3 "memory_operand" "m,m"))
4355    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4356   "TARGET_80387 && !TARGET_FISTTP
4357    && FLOAT_MODE_P (GET_MODE (operands[1]))
4358    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4359   "#"
4360   [(set_attr "type" "fistp")
4361    (set_attr "i387_cw" "trunc")
4362    (set_attr "mode" "<MODE>")])
4364 (define_split 
4365   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4366         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4367    (use (match_operand:HI 2 "memory_operand" ""))
4368    (use (match_operand:HI 3 "memory_operand" ""))
4369    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4370   "reload_completed"
4371   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4372               (use (match_dup 2))
4373               (use (match_dup 3))])
4374    (set (match_dup 0) (match_dup 4))]
4375   "")
4377 (define_split 
4378   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4379         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4380    (use (match_operand:HI 2 "memory_operand" ""))
4381    (use (match_operand:HI 3 "memory_operand" ""))
4382    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4383   "reload_completed"
4384   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4385               (use (match_dup 2))
4386               (use (match_dup 3))])]
4387   "")
4389 (define_insn "x86_fnstcw_1"
4390   [(set (match_operand:HI 0 "memory_operand" "=m")
4391         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4392   "TARGET_80387"
4393   "fnstcw\t%0"
4394   [(set_attr "length" "2")
4395    (set_attr "mode" "HI")
4396    (set_attr "unit" "i387")])
4398 (define_insn "x86_fldcw_1"
4399   [(set (reg:HI FPSR_REG)
4400         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4401   "TARGET_80387"
4402   "fldcw\t%0"
4403   [(set_attr "length" "2")
4404    (set_attr "mode" "HI")
4405    (set_attr "unit" "i387")
4406    (set_attr "athlon_decode" "vector")])
4408 ;; Conversion between fixed point and floating point.
4410 ;; Even though we only accept memory inputs, the backend _really_
4411 ;; wants to be able to do this between registers.
4413 (define_expand "floathisf2"
4414   [(set (match_operand:SF 0 "register_operand" "")
4415         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4416   "TARGET_80387 || TARGET_SSE_MATH"
4418   if (TARGET_SSE_MATH)
4419     {
4420       emit_insn (gen_floatsisf2 (operands[0],
4421                                  convert_to_mode (SImode, operands[1], 0)));
4422       DONE;
4423     }
4426 (define_insn "*floathisf2_i387"
4427   [(set (match_operand:SF 0 "register_operand" "=f,f")
4428         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4429   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4430   "@
4431    fild%z1\t%1
4432    #"
4433   [(set_attr "type" "fmov,multi")
4434    (set_attr "mode" "SF")
4435    (set_attr "fp_int_src" "true")])
4437 (define_expand "floatsisf2"
4438   [(set (match_operand:SF 0 "register_operand" "")
4439         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4440   "TARGET_80387 || TARGET_SSE_MATH"
4441   "")
4443 (define_insn "*floatsisf2_mixed"
4444   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4445         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4446   "TARGET_MIX_SSE_I387"
4447   "@
4448    fild%z1\t%1
4449    #
4450    cvtsi2ss\t{%1, %0|%0, %1}
4451    cvtsi2ss\t{%1, %0|%0, %1}"
4452   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4453    (set_attr "mode" "SF")
4454    (set_attr "athlon_decode" "*,*,vector,double")
4455    (set_attr "fp_int_src" "true")])
4457 (define_insn "*floatsisf2_sse"
4458   [(set (match_operand:SF 0 "register_operand" "=x,x")
4459         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4460   "TARGET_SSE_MATH"
4461   "cvtsi2ss\t{%1, %0|%0, %1}"
4462   [(set_attr "type" "sseicvt")
4463    (set_attr "mode" "SF")
4464    (set_attr "athlon_decode" "vector,double")
4465    (set_attr "fp_int_src" "true")])
4467 (define_insn "*floatsisf2_i387"
4468   [(set (match_operand:SF 0 "register_operand" "=f,f")
4469         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4470   "TARGET_80387"
4471   "@
4472    fild%z1\t%1
4473    #"
4474   [(set_attr "type" "fmov,multi")
4475    (set_attr "mode" "SF")
4476    (set_attr "fp_int_src" "true")])
4478 (define_expand "floatdisf2"
4479   [(set (match_operand:SF 0 "register_operand" "")
4480         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4481   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4482   "")
4484 (define_insn "*floatdisf2_mixed"
4485   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4486         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4487   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4488   "@
4489    fild%z1\t%1
4490    #
4491    cvtsi2ss{q}\t{%1, %0|%0, %1}
4492    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4493   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4494    (set_attr "mode" "SF")
4495    (set_attr "athlon_decode" "*,*,vector,double")
4496    (set_attr "fp_int_src" "true")])
4498 (define_insn "*floatdisf2_sse"
4499   [(set (match_operand:SF 0 "register_operand" "=x,x")
4500         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4501   "TARGET_64BIT && TARGET_SSE_MATH"
4502   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4503   [(set_attr "type" "sseicvt")
4504    (set_attr "mode" "SF")
4505    (set_attr "athlon_decode" "vector,double")
4506    (set_attr "fp_int_src" "true")])
4508 (define_insn "*floatdisf2_i387"
4509   [(set (match_operand:SF 0 "register_operand" "=f,f")
4510         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4511   "TARGET_80387"
4512   "@
4513    fild%z1\t%1
4514    #"
4515   [(set_attr "type" "fmov,multi")
4516    (set_attr "mode" "SF")
4517    (set_attr "fp_int_src" "true")])
4519 (define_expand "floathidf2"
4520   [(set (match_operand:DF 0 "register_operand" "")
4521         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4522   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4524   if (TARGET_SSE2 && TARGET_SSE_MATH)
4525     {
4526       emit_insn (gen_floatsidf2 (operands[0],
4527                                  convert_to_mode (SImode, operands[1], 0)));
4528       DONE;
4529     }
4532 (define_insn "*floathidf2_i387"
4533   [(set (match_operand:DF 0 "register_operand" "=f,f")
4534         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4535   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4536   "@
4537    fild%z1\t%1
4538    #"
4539   [(set_attr "type" "fmov,multi")
4540    (set_attr "mode" "DF")
4541    (set_attr "fp_int_src" "true")])
4543 (define_expand "floatsidf2"
4544   [(set (match_operand:DF 0 "register_operand" "")
4545         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4546   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4547   "")
4549 (define_insn "*floatsidf2_mixed"
4550   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4551         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4552   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4553   "@
4554    fild%z1\t%1
4555    #
4556    cvtsi2sd\t{%1, %0|%0, %1}
4557    cvtsi2sd\t{%1, %0|%0, %1}"
4558   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4559    (set_attr "mode" "DF")
4560    (set_attr "athlon_decode" "*,*,double,direct")
4561    (set_attr "fp_int_src" "true")])
4563 (define_insn "*floatsidf2_sse"
4564   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4565         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4566   "TARGET_SSE2 && TARGET_SSE_MATH"
4567   "cvtsi2sd\t{%1, %0|%0, %1}"
4568   [(set_attr "type" "sseicvt")
4569    (set_attr "mode" "DF")
4570    (set_attr "athlon_decode" "double,direct")
4571    (set_attr "fp_int_src" "true")])
4573 (define_insn "*floatsidf2_i387"
4574   [(set (match_operand:DF 0 "register_operand" "=f,f")
4575         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4576   "TARGET_80387"
4577   "@
4578    fild%z1\t%1
4579    #"
4580   [(set_attr "type" "fmov,multi")
4581    (set_attr "mode" "DF")
4582    (set_attr "fp_int_src" "true")])
4584 (define_expand "floatdidf2"
4585   [(set (match_operand:DF 0 "register_operand" "")
4586         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4587   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4588   "")
4590 (define_insn "*floatdidf2_mixed"
4591   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4592         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4593   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4594   "@
4595    fild%z1\t%1
4596    #
4597    cvtsi2sd{q}\t{%1, %0|%0, %1}
4598    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4599   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4600    (set_attr "mode" "DF")
4601    (set_attr "athlon_decode" "*,*,double,direct")
4602    (set_attr "fp_int_src" "true")])
4604 (define_insn "*floatdidf2_sse"
4605   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4606         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4607   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4608   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4609   [(set_attr "type" "sseicvt")
4610    (set_attr "mode" "DF")
4611    (set_attr "athlon_decode" "double,direct")
4612    (set_attr "fp_int_src" "true")])
4614 (define_insn "*floatdidf2_i387"
4615   [(set (match_operand:DF 0 "register_operand" "=f,f")
4616         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4617   "TARGET_80387"
4618   "@
4619    fild%z1\t%1
4620    #"
4621   [(set_attr "type" "fmov,multi")
4622    (set_attr "mode" "DF")
4623    (set_attr "fp_int_src" "true")])
4625 (define_insn "floathixf2"
4626   [(set (match_operand:XF 0 "register_operand" "=f,f")
4627         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4628   "TARGET_80387"
4629   "@
4630    fild%z1\t%1
4631    #"
4632   [(set_attr "type" "fmov,multi")
4633    (set_attr "mode" "XF")
4634    (set_attr "fp_int_src" "true")])
4636 (define_insn "floatsixf2"
4637   [(set (match_operand:XF 0 "register_operand" "=f,f")
4638         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4639   "TARGET_80387"
4640   "@
4641    fild%z1\t%1
4642    #"
4643   [(set_attr "type" "fmov,multi")
4644    (set_attr "mode" "XF")
4645    (set_attr "fp_int_src" "true")])
4647 (define_insn "floatdixf2"
4648   [(set (match_operand:XF 0 "register_operand" "=f,f")
4649         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4650   "TARGET_80387"
4651   "@
4652    fild%z1\t%1
4653    #"
4654   [(set_attr "type" "fmov,multi")
4655    (set_attr "mode" "XF")
4656    (set_attr "fp_int_src" "true")])
4658 ;; %%% Kill these when reload knows how to do it.
4659 (define_split
4660   [(set (match_operand 0 "fp_register_operand" "")
4661         (float (match_operand 1 "register_operand" "")))]
4662   "reload_completed
4663    && TARGET_80387
4664    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4665   [(const_int 0)]
4667   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4668   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4669   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4670   ix86_free_from_memory (GET_MODE (operands[1]));
4671   DONE;
4674 (define_expand "floatunssisf2"
4675   [(use (match_operand:SF 0 "register_operand" ""))
4676    (use (match_operand:SI 1 "register_operand" ""))]
4677   "!TARGET_64BIT && TARGET_SSE_MATH"
4678   "x86_emit_floatuns (operands); DONE;")
4680 (define_expand "floatunsdisf2"
4681   [(use (match_operand:SF 0 "register_operand" ""))
4682    (use (match_operand:DI 1 "register_operand" ""))]
4683   "TARGET_64BIT && TARGET_SSE_MATH"
4684   "x86_emit_floatuns (operands); DONE;")
4686 (define_expand "floatunsdidf2"
4687   [(use (match_operand:DF 0 "register_operand" ""))
4688    (use (match_operand:DI 1 "register_operand" ""))]
4689   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4690   "x86_emit_floatuns (operands); DONE;")
4692 ;; SSE extract/set expanders
4695 ;; Add instructions
4697 ;; %%% splits for addsidi3
4698 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4699 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4700 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4702 (define_expand "adddi3"
4703   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4704         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4705                  (match_operand:DI 2 "x86_64_general_operand" "")))
4706    (clobber (reg:CC FLAGS_REG))]
4707   ""
4708   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4710 (define_insn "*adddi3_1"
4711   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4712         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4713                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4714    (clobber (reg:CC FLAGS_REG))]
4715   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4716   "#")
4718 (define_split
4719   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4720         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4721                  (match_operand:DI 2 "general_operand" "")))
4722    (clobber (reg:CC FLAGS_REG))]
4723   "!TARGET_64BIT && reload_completed"
4724   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4725                                           UNSPEC_ADD_CARRY))
4726               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4727    (parallel [(set (match_dup 3)
4728                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4729                                      (match_dup 4))
4730                             (match_dup 5)))
4731               (clobber (reg:CC FLAGS_REG))])]
4732   "split_di (operands+0, 1, operands+0, operands+3);
4733    split_di (operands+1, 1, operands+1, operands+4);
4734    split_di (operands+2, 1, operands+2, operands+5);")
4736 (define_insn "adddi3_carry_rex64"
4737   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4738           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4739                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4740                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4741    (clobber (reg:CC FLAGS_REG))]
4742   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4743   "adc{q}\t{%2, %0|%0, %2}"
4744   [(set_attr "type" "alu")
4745    (set_attr "pent_pair" "pu")
4746    (set_attr "mode" "DI")])
4748 (define_insn "*adddi3_cc_rex64"
4749   [(set (reg:CC FLAGS_REG)
4750         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4751                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4752                    UNSPEC_ADD_CARRY))
4753    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4754         (plus:DI (match_dup 1) (match_dup 2)))]
4755   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4756   "add{q}\t{%2, %0|%0, %2}"
4757   [(set_attr "type" "alu")
4758    (set_attr "mode" "DI")])
4760 (define_insn "addqi3_carry"
4761   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4762           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4763                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4764                    (match_operand:QI 2 "general_operand" "qi,qm")))
4765    (clobber (reg:CC FLAGS_REG))]
4766   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4767   "adc{b}\t{%2, %0|%0, %2}"
4768   [(set_attr "type" "alu")
4769    (set_attr "pent_pair" "pu")
4770    (set_attr "mode" "QI")])
4772 (define_insn "addhi3_carry"
4773   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4774           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4775                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4776                    (match_operand:HI 2 "general_operand" "ri,rm")))
4777    (clobber (reg:CC FLAGS_REG))]
4778   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4779   "adc{w}\t{%2, %0|%0, %2}"
4780   [(set_attr "type" "alu")
4781    (set_attr "pent_pair" "pu")
4782    (set_attr "mode" "HI")])
4784 (define_insn "addsi3_carry"
4785   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4786           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4787                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4788                    (match_operand:SI 2 "general_operand" "ri,rm")))
4789    (clobber (reg:CC FLAGS_REG))]
4790   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4791   "adc{l}\t{%2, %0|%0, %2}"
4792   [(set_attr "type" "alu")
4793    (set_attr "pent_pair" "pu")
4794    (set_attr "mode" "SI")])
4796 (define_insn "*addsi3_carry_zext"
4797   [(set (match_operand:DI 0 "register_operand" "=r")
4798           (zero_extend:DI 
4799             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4800                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4801                      (match_operand:SI 2 "general_operand" "rim"))))
4802    (clobber (reg:CC FLAGS_REG))]
4803   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4804   "adc{l}\t{%2, %k0|%k0, %2}"
4805   [(set_attr "type" "alu")
4806    (set_attr "pent_pair" "pu")
4807    (set_attr "mode" "SI")])
4809 (define_insn "*addsi3_cc"
4810   [(set (reg:CC FLAGS_REG)
4811         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4812                     (match_operand:SI 2 "general_operand" "ri,rm")]
4813                    UNSPEC_ADD_CARRY))
4814    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4815         (plus:SI (match_dup 1) (match_dup 2)))]
4816   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4817   "add{l}\t{%2, %0|%0, %2}"
4818   [(set_attr "type" "alu")
4819    (set_attr "mode" "SI")])
4821 (define_insn "addqi3_cc"
4822   [(set (reg:CC FLAGS_REG)
4823         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4824                     (match_operand:QI 2 "general_operand" "qi,qm")]
4825                    UNSPEC_ADD_CARRY))
4826    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4827         (plus:QI (match_dup 1) (match_dup 2)))]
4828   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4829   "add{b}\t{%2, %0|%0, %2}"
4830   [(set_attr "type" "alu")
4831    (set_attr "mode" "QI")])
4833 (define_expand "addsi3"
4834   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4835                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4836                             (match_operand:SI 2 "general_operand" "")))
4837               (clobber (reg:CC FLAGS_REG))])]
4838   ""
4839   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4841 (define_insn "*lea_1"
4842   [(set (match_operand:SI 0 "register_operand" "=r")
4843         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4844   "!TARGET_64BIT"
4845   "lea{l}\t{%a1, %0|%0, %a1}"
4846   [(set_attr "type" "lea")
4847    (set_attr "mode" "SI")])
4849 (define_insn "*lea_1_rex64"
4850   [(set (match_operand:SI 0 "register_operand" "=r")
4851         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4852   "TARGET_64BIT"
4853   "lea{l}\t{%a1, %0|%0, %a1}"
4854   [(set_attr "type" "lea")
4855    (set_attr "mode" "SI")])
4857 (define_insn "*lea_1_zext"
4858   [(set (match_operand:DI 0 "register_operand" "=r")
4859         (zero_extend:DI
4860          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4861   "TARGET_64BIT"
4862   "lea{l}\t{%a1, %k0|%k0, %a1}"
4863   [(set_attr "type" "lea")
4864    (set_attr "mode" "SI")])
4866 (define_insn "*lea_2_rex64"
4867   [(set (match_operand:DI 0 "register_operand" "=r")
4868         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4869   "TARGET_64BIT"
4870   "lea{q}\t{%a1, %0|%0, %a1}"
4871   [(set_attr "type" "lea")
4872    (set_attr "mode" "DI")])
4874 ;; The lea patterns for non-Pmodes needs to be matched by several
4875 ;; insns converted to real lea by splitters.
4877 (define_insn_and_split "*lea_general_1"
4878   [(set (match_operand 0 "register_operand" "=r")
4879         (plus (plus (match_operand 1 "index_register_operand" "l")
4880                     (match_operand 2 "register_operand" "r"))
4881               (match_operand 3 "immediate_operand" "i")))]
4882   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4883     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4884    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4885    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4886    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4887    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4888        || GET_MODE (operands[3]) == VOIDmode)"
4889   "#"
4890   "&& reload_completed"
4891   [(const_int 0)]
4893   rtx pat;
4894   operands[0] = gen_lowpart (SImode, operands[0]);
4895   operands[1] = gen_lowpart (Pmode, operands[1]);
4896   operands[2] = gen_lowpart (Pmode, operands[2]);
4897   operands[3] = gen_lowpart (Pmode, operands[3]);
4898   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4899                       operands[3]);
4900   if (Pmode != SImode)
4901     pat = gen_rtx_SUBREG (SImode, pat, 0);
4902   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4903   DONE;
4905   [(set_attr "type" "lea")
4906    (set_attr "mode" "SI")])
4908 (define_insn_and_split "*lea_general_1_zext"
4909   [(set (match_operand:DI 0 "register_operand" "=r")
4910         (zero_extend:DI
4911           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4912                             (match_operand:SI 2 "register_operand" "r"))
4913                    (match_operand:SI 3 "immediate_operand" "i"))))]
4914   "TARGET_64BIT"
4915   "#"
4916   "&& reload_completed"
4917   [(set (match_dup 0)
4918         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4919                                                      (match_dup 2))
4920                                             (match_dup 3)) 0)))]
4922   operands[1] = gen_lowpart (Pmode, operands[1]);
4923   operands[2] = gen_lowpart (Pmode, operands[2]);
4924   operands[3] = gen_lowpart (Pmode, operands[3]);
4926   [(set_attr "type" "lea")
4927    (set_attr "mode" "SI")])
4929 (define_insn_and_split "*lea_general_2"
4930   [(set (match_operand 0 "register_operand" "=r")
4931         (plus (mult (match_operand 1 "index_register_operand" "l")
4932                     (match_operand 2 "const248_operand" "i"))
4933               (match_operand 3 "nonmemory_operand" "ri")))]
4934   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4935     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4936    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4937    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4938    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4939        || GET_MODE (operands[3]) == VOIDmode)"
4940   "#"
4941   "&& reload_completed"
4942   [(const_int 0)]
4944   rtx pat;
4945   operands[0] = gen_lowpart (SImode, operands[0]);
4946   operands[1] = gen_lowpart (Pmode, operands[1]);
4947   operands[3] = gen_lowpart (Pmode, operands[3]);
4948   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4949                       operands[3]);
4950   if (Pmode != SImode)
4951     pat = gen_rtx_SUBREG (SImode, pat, 0);
4952   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4953   DONE;
4955   [(set_attr "type" "lea")
4956    (set_attr "mode" "SI")])
4958 (define_insn_and_split "*lea_general_2_zext"
4959   [(set (match_operand:DI 0 "register_operand" "=r")
4960         (zero_extend:DI
4961           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4962                             (match_operand:SI 2 "const248_operand" "n"))
4963                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4964   "TARGET_64BIT"
4965   "#"
4966   "&& reload_completed"
4967   [(set (match_dup 0)
4968         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4969                                                      (match_dup 2))
4970                                             (match_dup 3)) 0)))]
4972   operands[1] = gen_lowpart (Pmode, operands[1]);
4973   operands[3] = gen_lowpart (Pmode, operands[3]);
4975   [(set_attr "type" "lea")
4976    (set_attr "mode" "SI")])
4978 (define_insn_and_split "*lea_general_3"
4979   [(set (match_operand 0 "register_operand" "=r")
4980         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4981                           (match_operand 2 "const248_operand" "i"))
4982                     (match_operand 3 "register_operand" "r"))
4983               (match_operand 4 "immediate_operand" "i")))]
4984   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4985     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4986    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4987    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4988    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4989   "#"
4990   "&& reload_completed"
4991   [(const_int 0)]
4993   rtx pat;
4994   operands[0] = gen_lowpart (SImode, operands[0]);
4995   operands[1] = gen_lowpart (Pmode, operands[1]);
4996   operands[3] = gen_lowpart (Pmode, operands[3]);
4997   operands[4] = gen_lowpart (Pmode, operands[4]);
4998   pat = gen_rtx_PLUS (Pmode,
4999                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5000                                                          operands[2]),
5001                                     operands[3]),
5002                       operands[4]);
5003   if (Pmode != SImode)
5004     pat = gen_rtx_SUBREG (SImode, pat, 0);
5005   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5006   DONE;
5008   [(set_attr "type" "lea")
5009    (set_attr "mode" "SI")])
5011 (define_insn_and_split "*lea_general_3_zext"
5012   [(set (match_operand:DI 0 "register_operand" "=r")
5013         (zero_extend:DI
5014           (plus:SI (plus:SI (mult:SI
5015                               (match_operand:SI 1 "index_register_operand" "l")
5016                               (match_operand:SI 2 "const248_operand" "n"))
5017                             (match_operand:SI 3 "register_operand" "r"))
5018                    (match_operand:SI 4 "immediate_operand" "i"))))]
5019   "TARGET_64BIT"
5020   "#"
5021   "&& reload_completed"
5022   [(set (match_dup 0)
5023         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5024                                                               (match_dup 2))
5025                                                      (match_dup 3))
5026                                             (match_dup 4)) 0)))]
5028   operands[1] = gen_lowpart (Pmode, operands[1]);
5029   operands[3] = gen_lowpart (Pmode, operands[3]);
5030   operands[4] = gen_lowpart (Pmode, operands[4]);
5032   [(set_attr "type" "lea")
5033    (set_attr "mode" "SI")])
5035 (define_insn "*adddi_1_rex64"
5036   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5037         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5038                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5039    (clobber (reg:CC FLAGS_REG))]
5040   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5042   switch (get_attr_type (insn))
5043     {
5044     case TYPE_LEA:
5045       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5046       return "lea{q}\t{%a2, %0|%0, %a2}";
5048     case TYPE_INCDEC:
5049       if (! rtx_equal_p (operands[0], operands[1]))
5050         abort ();
5051       if (operands[2] == const1_rtx)
5052         return "inc{q}\t%0";
5053       else if (operands[2] == constm1_rtx)
5054         return "dec{q}\t%0";
5055       else
5056         abort ();
5058     default:
5059       if (! rtx_equal_p (operands[0], operands[1]))
5060         abort ();
5062       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5063          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5064       if (GET_CODE (operands[2]) == CONST_INT
5065           /* Avoid overflows.  */
5066           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5067           && (INTVAL (operands[2]) == 128
5068               || (INTVAL (operands[2]) < 0
5069                   && INTVAL (operands[2]) != -128)))
5070         {
5071           operands[2] = GEN_INT (-INTVAL (operands[2]));
5072           return "sub{q}\t{%2, %0|%0, %2}";
5073         }
5074       return "add{q}\t{%2, %0|%0, %2}";
5075     }
5077   [(set (attr "type")
5078      (cond [(eq_attr "alternative" "2")
5079               (const_string "lea")
5080             ; Current assemblers are broken and do not allow @GOTOFF in
5081             ; ought but a memory context.
5082             (match_operand:DI 2 "pic_symbolic_operand" "")
5083               (const_string "lea")
5084             (match_operand:DI 2 "incdec_operand" "")
5085               (const_string "incdec")
5086            ]
5087            (const_string "alu")))
5088    (set_attr "mode" "DI")])
5090 ;; Convert lea to the lea pattern to avoid flags dependency.
5091 (define_split
5092   [(set (match_operand:DI 0 "register_operand" "")
5093         (plus:DI (match_operand:DI 1 "register_operand" "")
5094                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5095    (clobber (reg:CC FLAGS_REG))]
5096   "TARGET_64BIT && reload_completed
5097    && true_regnum (operands[0]) != true_regnum (operands[1])"
5098   [(set (match_dup 0)
5099         (plus:DI (match_dup 1)
5100                  (match_dup 2)))]
5101   "")
5103 (define_insn "*adddi_2_rex64"
5104   [(set (reg FLAGS_REG)
5105         (compare
5106           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5107                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5108           (const_int 0)))                       
5109    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5110         (plus:DI (match_dup 1) (match_dup 2)))]
5111   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5112    && ix86_binary_operator_ok (PLUS, DImode, operands)
5113    /* Current assemblers are broken and do not allow @GOTOFF in
5114       ought but a memory context.  */
5115    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5117   switch (get_attr_type (insn))
5118     {
5119     case TYPE_INCDEC:
5120       if (! rtx_equal_p (operands[0], operands[1]))
5121         abort ();
5122       if (operands[2] == const1_rtx)
5123         return "inc{q}\t%0";
5124       else if (operands[2] == constm1_rtx)
5125         return "dec{q}\t%0";
5126       else
5127         abort ();
5129     default:
5130       if (! rtx_equal_p (operands[0], operands[1]))
5131         abort ();
5132       /* ???? We ought to handle there the 32bit case too
5133          - do we need new constraint?  */
5134       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5135          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5136       if (GET_CODE (operands[2]) == CONST_INT
5137           /* Avoid overflows.  */
5138           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5139           && (INTVAL (operands[2]) == 128
5140               || (INTVAL (operands[2]) < 0
5141                   && INTVAL (operands[2]) != -128)))
5142         {
5143           operands[2] = GEN_INT (-INTVAL (operands[2]));
5144           return "sub{q}\t{%2, %0|%0, %2}";
5145         }
5146       return "add{q}\t{%2, %0|%0, %2}";
5147     }
5149   [(set (attr "type")
5150      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5151         (const_string "incdec")
5152         (const_string "alu")))
5153    (set_attr "mode" "DI")])
5155 (define_insn "*adddi_3_rex64"
5156   [(set (reg FLAGS_REG)
5157         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5158                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5159    (clobber (match_scratch:DI 0 "=r"))]
5160   "TARGET_64BIT
5161    && ix86_match_ccmode (insn, CCZmode)
5162    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5163    /* Current assemblers are broken and do not allow @GOTOFF in
5164       ought but a memory context.  */
5165    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5167   switch (get_attr_type (insn))
5168     {
5169     case TYPE_INCDEC:
5170       if (! rtx_equal_p (operands[0], operands[1]))
5171         abort ();
5172       if (operands[2] == const1_rtx)
5173         return "inc{q}\t%0";
5174       else if (operands[2] == constm1_rtx)
5175         return "dec{q}\t%0";
5176       else
5177         abort ();
5179     default:
5180       if (! rtx_equal_p (operands[0], operands[1]))
5181         abort ();
5182       /* ???? We ought to handle there the 32bit case too
5183          - do we need new constraint?  */
5184       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5185          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5186       if (GET_CODE (operands[2]) == CONST_INT
5187           /* Avoid overflows.  */
5188           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5189           && (INTVAL (operands[2]) == 128
5190               || (INTVAL (operands[2]) < 0
5191                   && INTVAL (operands[2]) != -128)))
5192         {
5193           operands[2] = GEN_INT (-INTVAL (operands[2]));
5194           return "sub{q}\t{%2, %0|%0, %2}";
5195         }
5196       return "add{q}\t{%2, %0|%0, %2}";
5197     }
5199   [(set (attr "type")
5200      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5201         (const_string "incdec")
5202         (const_string "alu")))
5203    (set_attr "mode" "DI")])
5205 ; For comparisons against 1, -1 and 128, we may generate better code
5206 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5207 ; is matched then.  We can't accept general immediate, because for
5208 ; case of overflows,  the result is messed up.
5209 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5210 ; when negated.
5211 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5212 ; only for comparisons not depending on it.
5213 (define_insn "*adddi_4_rex64"
5214   [(set (reg FLAGS_REG)
5215         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5216                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5217    (clobber (match_scratch:DI 0 "=rm"))]
5218   "TARGET_64BIT
5219    &&  ix86_match_ccmode (insn, CCGCmode)"
5221   switch (get_attr_type (insn))
5222     {
5223     case TYPE_INCDEC:
5224       if (operands[2] == constm1_rtx)
5225         return "inc{q}\t%0";
5226       else if (operands[2] == const1_rtx)
5227         return "dec{q}\t%0";
5228       else
5229         abort();
5231     default:
5232       if (! rtx_equal_p (operands[0], operands[1]))
5233         abort ();
5234       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5235          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5236       if ((INTVAL (operands[2]) == -128
5237            || (INTVAL (operands[2]) > 0
5238                && INTVAL (operands[2]) != 128))
5239           /* Avoid overflows.  */
5240           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5241         return "sub{q}\t{%2, %0|%0, %2}";
5242       operands[2] = GEN_INT (-INTVAL (operands[2]));
5243       return "add{q}\t{%2, %0|%0, %2}";
5244     }
5246   [(set (attr "type")
5247      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5248         (const_string "incdec")
5249         (const_string "alu")))
5250    (set_attr "mode" "DI")])
5252 (define_insn "*adddi_5_rex64"
5253   [(set (reg FLAGS_REG)
5254         (compare
5255           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5256                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5257           (const_int 0)))                       
5258    (clobber (match_scratch:DI 0 "=r"))]
5259   "TARGET_64BIT
5260    && ix86_match_ccmode (insn, CCGOCmode)
5261    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5262    /* Current assemblers are broken and do not allow @GOTOFF in
5263       ought but a memory context.  */
5264    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5266   switch (get_attr_type (insn))
5267     {
5268     case TYPE_INCDEC:
5269       if (! rtx_equal_p (operands[0], operands[1]))
5270         abort ();
5271       if (operands[2] == const1_rtx)
5272         return "inc{q}\t%0";
5273       else if (operands[2] == constm1_rtx)
5274         return "dec{q}\t%0";
5275       else
5276         abort();
5278     default:
5279       if (! rtx_equal_p (operands[0], operands[1]))
5280         abort ();
5281       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5282          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5283       if (GET_CODE (operands[2]) == CONST_INT
5284           /* Avoid overflows.  */
5285           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5286           && (INTVAL (operands[2]) == 128
5287               || (INTVAL (operands[2]) < 0
5288                   && INTVAL (operands[2]) != -128)))
5289         {
5290           operands[2] = GEN_INT (-INTVAL (operands[2]));
5291           return "sub{q}\t{%2, %0|%0, %2}";
5292         }
5293       return "add{q}\t{%2, %0|%0, %2}";
5294     }
5296   [(set (attr "type")
5297      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5298         (const_string "incdec")
5299         (const_string "alu")))
5300    (set_attr "mode" "DI")])
5303 (define_insn "*addsi_1"
5304   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5305         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5306                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5307    (clobber (reg:CC FLAGS_REG))]
5308   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5310   switch (get_attr_type (insn))
5311     {
5312     case TYPE_LEA:
5313       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5314       return "lea{l}\t{%a2, %0|%0, %a2}";
5316     case TYPE_INCDEC:
5317       if (! rtx_equal_p (operands[0], operands[1]))
5318         abort ();
5319       if (operands[2] == const1_rtx)
5320         return "inc{l}\t%0";
5321       else if (operands[2] == constm1_rtx)
5322         return "dec{l}\t%0";
5323       else
5324         abort();
5326     default:
5327       if (! rtx_equal_p (operands[0], operands[1]))
5328         abort ();
5330       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5331          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5332       if (GET_CODE (operands[2]) == CONST_INT
5333           && (INTVAL (operands[2]) == 128
5334               || (INTVAL (operands[2]) < 0
5335                   && INTVAL (operands[2]) != -128)))
5336         {
5337           operands[2] = GEN_INT (-INTVAL (operands[2]));
5338           return "sub{l}\t{%2, %0|%0, %2}";
5339         }
5340       return "add{l}\t{%2, %0|%0, %2}";
5341     }
5343   [(set (attr "type")
5344      (cond [(eq_attr "alternative" "2")
5345               (const_string "lea")
5346             ; Current assemblers are broken and do not allow @GOTOFF in
5347             ; ought but a memory context.
5348             (match_operand:SI 2 "pic_symbolic_operand" "")
5349               (const_string "lea")
5350             (match_operand:SI 2 "incdec_operand" "")
5351               (const_string "incdec")
5352            ]
5353            (const_string "alu")))
5354    (set_attr "mode" "SI")])
5356 ;; Convert lea to the lea pattern to avoid flags dependency.
5357 (define_split
5358   [(set (match_operand 0 "register_operand" "")
5359         (plus (match_operand 1 "register_operand" "")
5360               (match_operand 2 "nonmemory_operand" "")))
5361    (clobber (reg:CC FLAGS_REG))]
5362   "reload_completed
5363    && true_regnum (operands[0]) != true_regnum (operands[1])"
5364   [(const_int 0)]
5366   rtx pat;
5367   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5368      may confuse gen_lowpart.  */
5369   if (GET_MODE (operands[0]) != Pmode)
5370     {
5371       operands[1] = gen_lowpart (Pmode, operands[1]);
5372       operands[2] = gen_lowpart (Pmode, operands[2]);
5373     }
5374   operands[0] = gen_lowpart (SImode, operands[0]);
5375   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5376   if (Pmode != SImode)
5377     pat = gen_rtx_SUBREG (SImode, pat, 0);
5378   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5379   DONE;
5382 ;; It may seem that nonimmediate operand is proper one for operand 1.
5383 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5384 ;; we take care in ix86_binary_operator_ok to not allow two memory
5385 ;; operands so proper swapping will be done in reload.  This allow
5386 ;; patterns constructed from addsi_1 to match.
5387 (define_insn "addsi_1_zext"
5388   [(set (match_operand:DI 0 "register_operand" "=r,r")
5389         (zero_extend:DI
5390           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5391                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5392    (clobber (reg:CC FLAGS_REG))]
5393   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5395   switch (get_attr_type (insn))
5396     {
5397     case TYPE_LEA:
5398       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5399       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5401     case TYPE_INCDEC:
5402       if (operands[2] == const1_rtx)
5403         return "inc{l}\t%k0";
5404       else if (operands[2] == constm1_rtx)
5405         return "dec{l}\t%k0";
5406       else
5407         abort();
5409     default:
5410       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5411          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5412       if (GET_CODE (operands[2]) == CONST_INT
5413           && (INTVAL (operands[2]) == 128
5414               || (INTVAL (operands[2]) < 0
5415                   && INTVAL (operands[2]) != -128)))
5416         {
5417           operands[2] = GEN_INT (-INTVAL (operands[2]));
5418           return "sub{l}\t{%2, %k0|%k0, %2}";
5419         }
5420       return "add{l}\t{%2, %k0|%k0, %2}";
5421     }
5423   [(set (attr "type")
5424      (cond [(eq_attr "alternative" "1")
5425               (const_string "lea")
5426             ; Current assemblers are broken and do not allow @GOTOFF in
5427             ; ought but a memory context.
5428             (match_operand:SI 2 "pic_symbolic_operand" "")
5429               (const_string "lea")
5430             (match_operand:SI 2 "incdec_operand" "")
5431               (const_string "incdec")
5432            ]
5433            (const_string "alu")))
5434    (set_attr "mode" "SI")])
5436 ;; Convert lea to the lea pattern to avoid flags dependency.
5437 (define_split
5438   [(set (match_operand:DI 0 "register_operand" "")
5439         (zero_extend:DI
5440           (plus:SI (match_operand:SI 1 "register_operand" "")
5441                    (match_operand:SI 2 "nonmemory_operand" ""))))
5442    (clobber (reg:CC FLAGS_REG))]
5443   "TARGET_64BIT && reload_completed
5444    && true_regnum (operands[0]) != true_regnum (operands[1])"
5445   [(set (match_dup 0)
5446         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5448   operands[1] = gen_lowpart (Pmode, operands[1]);
5449   operands[2] = gen_lowpart (Pmode, operands[2]);
5452 (define_insn "*addsi_2"
5453   [(set (reg FLAGS_REG)
5454         (compare
5455           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5456                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5457           (const_int 0)))                       
5458    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5459         (plus:SI (match_dup 1) (match_dup 2)))]
5460   "ix86_match_ccmode (insn, CCGOCmode)
5461    && ix86_binary_operator_ok (PLUS, SImode, operands)
5462    /* Current assemblers are broken and do not allow @GOTOFF in
5463       ought but a memory context.  */
5464    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5466   switch (get_attr_type (insn))
5467     {
5468     case TYPE_INCDEC:
5469       if (! rtx_equal_p (operands[0], operands[1]))
5470         abort ();
5471       if (operands[2] == const1_rtx)
5472         return "inc{l}\t%0";
5473       else if (operands[2] == constm1_rtx)
5474         return "dec{l}\t%0";
5475       else
5476         abort();
5478     default:
5479       if (! rtx_equal_p (operands[0], operands[1]))
5480         abort ();
5481       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5482          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5483       if (GET_CODE (operands[2]) == CONST_INT
5484           && (INTVAL (operands[2]) == 128
5485               || (INTVAL (operands[2]) < 0
5486                   && INTVAL (operands[2]) != -128)))
5487         {
5488           operands[2] = GEN_INT (-INTVAL (operands[2]));
5489           return "sub{l}\t{%2, %0|%0, %2}";
5490         }
5491       return "add{l}\t{%2, %0|%0, %2}";
5492     }
5494   [(set (attr "type")
5495      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5496         (const_string "incdec")
5497         (const_string "alu")))
5498    (set_attr "mode" "SI")])
5500 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5501 (define_insn "*addsi_2_zext"
5502   [(set (reg FLAGS_REG)
5503         (compare
5504           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5505                    (match_operand:SI 2 "general_operand" "rmni"))
5506           (const_int 0)))                       
5507    (set (match_operand:DI 0 "register_operand" "=r")
5508         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5509   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5510    && ix86_binary_operator_ok (PLUS, SImode, operands)
5511    /* Current assemblers are broken and do not allow @GOTOFF in
5512       ought but a memory context.  */
5513    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5515   switch (get_attr_type (insn))
5516     {
5517     case TYPE_INCDEC:
5518       if (operands[2] == const1_rtx)
5519         return "inc{l}\t%k0";
5520       else if (operands[2] == constm1_rtx)
5521         return "dec{l}\t%k0";
5522       else
5523         abort();
5525     default:
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, %k0|%k0, %2}";
5535         }
5536       return "add{l}\t{%2, %k0|%k0, %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 (define_insn "*addsi_3"
5546   [(set (reg FLAGS_REG)
5547         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5548                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5549    (clobber (match_scratch:SI 0 "=r"))]
5550   "ix86_match_ccmode (insn, CCZmode)
5551    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5552    /* Current assemblers are broken and do not allow @GOTOFF in
5553       ought but a memory context.  */
5554    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5556   switch (get_attr_type (insn))
5557     {
5558     case TYPE_INCDEC:
5559       if (! rtx_equal_p (operands[0], operands[1]))
5560         abort ();
5561       if (operands[2] == const1_rtx)
5562         return "inc{l}\t%0";
5563       else if (operands[2] == constm1_rtx)
5564         return "dec{l}\t%0";
5565       else
5566         abort();
5568     default:
5569       if (! rtx_equal_p (operands[0], operands[1]))
5570         abort ();
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, %0|%0, %2}";
5580         }
5581       return "add{l}\t{%2, %0|%0, %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 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5591 (define_insn "*addsi_3_zext"
5592   [(set (reg FLAGS_REG)
5593         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5594                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5595    (set (match_operand:DI 0 "register_operand" "=r")
5596         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5597   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5598    && ix86_binary_operator_ok (PLUS, SImode, operands)
5599    /* Current assemblers are broken and do not allow @GOTOFF in
5600       ought but a memory context.  */
5601    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5603   switch (get_attr_type (insn))
5604     {
5605     case TYPE_INCDEC:
5606       if (operands[2] == const1_rtx)
5607         return "inc{l}\t%k0";
5608       else if (operands[2] == constm1_rtx)
5609         return "dec{l}\t%k0";
5610       else
5611         abort();
5613     default:
5614       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5615          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5616       if (GET_CODE (operands[2]) == CONST_INT
5617           && (INTVAL (operands[2]) == 128
5618               || (INTVAL (operands[2]) < 0
5619                   && INTVAL (operands[2]) != -128)))
5620         {
5621           operands[2] = GEN_INT (-INTVAL (operands[2]));
5622           return "sub{l}\t{%2, %k0|%k0, %2}";
5623         }
5624       return "add{l}\t{%2, %k0|%k0, %2}";
5625     }
5627   [(set (attr "type")
5628      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5629         (const_string "incdec")
5630         (const_string "alu")))
5631    (set_attr "mode" "SI")])
5633 ; For comparisons against 1, -1 and 128, we may generate better code
5634 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5635 ; is matched then.  We can't accept general immediate, because for
5636 ; case of overflows,  the result is messed up.
5637 ; This pattern also don't hold of 0x80000000, since the value overflows
5638 ; when negated.
5639 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5640 ; only for comparisons not depending on it.
5641 (define_insn "*addsi_4"
5642   [(set (reg FLAGS_REG)
5643         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5644                  (match_operand:SI 2 "const_int_operand" "n")))
5645    (clobber (match_scratch:SI 0 "=rm"))]
5646   "ix86_match_ccmode (insn, CCGCmode)
5647    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5649   switch (get_attr_type (insn))
5650     {
5651     case TYPE_INCDEC:
5652       if (operands[2] == constm1_rtx)
5653         return "inc{l}\t%0";
5654       else if (operands[2] == const1_rtx)
5655         return "dec{l}\t%0";
5656       else
5657         abort();
5659     default:
5660       if (! rtx_equal_p (operands[0], operands[1]))
5661         abort ();
5662       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5663          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5664       if ((INTVAL (operands[2]) == -128
5665            || (INTVAL (operands[2]) > 0
5666                && INTVAL (operands[2]) != 128)))
5667         return "sub{l}\t{%2, %0|%0, %2}";
5668       operands[2] = GEN_INT (-INTVAL (operands[2]));
5669       return "add{l}\t{%2, %0|%0, %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 (define_insn "*addsi_5"
5679   [(set (reg FLAGS_REG)
5680         (compare
5681           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5682                    (match_operand:SI 2 "general_operand" "rmni"))
5683           (const_int 0)))                       
5684    (clobber (match_scratch:SI 0 "=r"))]
5685   "ix86_match_ccmode (insn, CCGOCmode)
5686    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5687    /* Current assemblers are broken and do not allow @GOTOFF in
5688       ought but a memory context.  */
5689    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5691   switch (get_attr_type (insn))
5692     {
5693     case TYPE_INCDEC:
5694       if (! rtx_equal_p (operands[0], operands[1]))
5695         abort ();
5696       if (operands[2] == const1_rtx)
5697         return "inc{l}\t%0";
5698       else if (operands[2] == constm1_rtx)
5699         return "dec{l}\t%0";
5700       else
5701         abort();
5703     default:
5704       if (! rtx_equal_p (operands[0], operands[1]))
5705         abort ();
5706       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5707          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5708       if (GET_CODE (operands[2]) == CONST_INT
5709           && (INTVAL (operands[2]) == 128
5710               || (INTVAL (operands[2]) < 0
5711                   && INTVAL (operands[2]) != -128)))
5712         {
5713           operands[2] = GEN_INT (-INTVAL (operands[2]));
5714           return "sub{l}\t{%2, %0|%0, %2}";
5715         }
5716       return "add{l}\t{%2, %0|%0, %2}";
5717     }
5719   [(set (attr "type")
5720      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5721         (const_string "incdec")
5722         (const_string "alu")))
5723    (set_attr "mode" "SI")])
5725 (define_expand "addhi3"
5726   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5727                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5728                             (match_operand:HI 2 "general_operand" "")))
5729               (clobber (reg:CC FLAGS_REG))])]
5730   "TARGET_HIMODE_MATH"
5731   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5733 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5734 ;; type optimizations enabled by define-splits.  This is not important
5735 ;; for PII, and in fact harmful because of partial register stalls.
5737 (define_insn "*addhi_1_lea"
5738   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5739         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5740                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5741    (clobber (reg:CC FLAGS_REG))]
5742   "!TARGET_PARTIAL_REG_STALL
5743    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5745   switch (get_attr_type (insn))
5746     {
5747     case TYPE_LEA:
5748       return "#";
5749     case TYPE_INCDEC:
5750       if (operands[2] == const1_rtx)
5751         return "inc{w}\t%0";
5752       else if (operands[2] == constm1_rtx)
5753         return "dec{w}\t%0";
5754       abort();
5756     default:
5757       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5758          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5759       if (GET_CODE (operands[2]) == CONST_INT
5760           && (INTVAL (operands[2]) == 128
5761               || (INTVAL (operands[2]) < 0
5762                   && INTVAL (operands[2]) != -128)))
5763         {
5764           operands[2] = GEN_INT (-INTVAL (operands[2]));
5765           return "sub{w}\t{%2, %0|%0, %2}";
5766         }
5767       return "add{w}\t{%2, %0|%0, %2}";
5768     }
5770   [(set (attr "type")
5771      (if_then_else (eq_attr "alternative" "2")
5772         (const_string "lea")
5773         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5774            (const_string "incdec")
5775            (const_string "alu"))))
5776    (set_attr "mode" "HI,HI,SI")])
5778 (define_insn "*addhi_1"
5779   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5780         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5781                  (match_operand:HI 2 "general_operand" "ri,rm")))
5782    (clobber (reg:CC FLAGS_REG))]
5783   "TARGET_PARTIAL_REG_STALL
5784    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5786   switch (get_attr_type (insn))
5787     {
5788     case TYPE_INCDEC:
5789       if (operands[2] == const1_rtx)
5790         return "inc{w}\t%0";
5791       else if (operands[2] == constm1_rtx)
5792         return "dec{w}\t%0";
5793       abort();
5795     default:
5796       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5797          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5798       if (GET_CODE (operands[2]) == CONST_INT
5799           && (INTVAL (operands[2]) == 128
5800               || (INTVAL (operands[2]) < 0
5801                   && INTVAL (operands[2]) != -128)))
5802         {
5803           operands[2] = GEN_INT (-INTVAL (operands[2]));
5804           return "sub{w}\t{%2, %0|%0, %2}";
5805         }
5806       return "add{w}\t{%2, %0|%0, %2}";
5807     }
5809   [(set (attr "type")
5810      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5811         (const_string "incdec")
5812         (const_string "alu")))
5813    (set_attr "mode" "HI")])
5815 (define_insn "*addhi_2"
5816   [(set (reg FLAGS_REG)
5817         (compare
5818           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5819                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5820           (const_int 0)))                       
5821    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5822         (plus:HI (match_dup 1) (match_dup 2)))]
5823   "ix86_match_ccmode (insn, CCGOCmode)
5824    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5826   switch (get_attr_type (insn))
5827     {
5828     case TYPE_INCDEC:
5829       if (operands[2] == const1_rtx)
5830         return "inc{w}\t%0";
5831       else if (operands[2] == constm1_rtx)
5832         return "dec{w}\t%0";
5833       abort();
5835     default:
5836       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5837          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5838       if (GET_CODE (operands[2]) == CONST_INT
5839           && (INTVAL (operands[2]) == 128
5840               || (INTVAL (operands[2]) < 0
5841                   && INTVAL (operands[2]) != -128)))
5842         {
5843           operands[2] = GEN_INT (-INTVAL (operands[2]));
5844           return "sub{w}\t{%2, %0|%0, %2}";
5845         }
5846       return "add{w}\t{%2, %0|%0, %2}";
5847     }
5849   [(set (attr "type")
5850      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5851         (const_string "incdec")
5852         (const_string "alu")))
5853    (set_attr "mode" "HI")])
5855 (define_insn "*addhi_3"
5856   [(set (reg FLAGS_REG)
5857         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5858                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5859    (clobber (match_scratch:HI 0 "=r"))]
5860   "ix86_match_ccmode (insn, CCZmode)
5861    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5863   switch (get_attr_type (insn))
5864     {
5865     case TYPE_INCDEC:
5866       if (operands[2] == const1_rtx)
5867         return "inc{w}\t%0";
5868       else if (operands[2] == constm1_rtx)
5869         return "dec{w}\t%0";
5870       abort();
5872     default:
5873       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5875       if (GET_CODE (operands[2]) == CONST_INT
5876           && (INTVAL (operands[2]) == 128
5877               || (INTVAL (operands[2]) < 0
5878                   && INTVAL (operands[2]) != -128)))
5879         {
5880           operands[2] = GEN_INT (-INTVAL (operands[2]));
5881           return "sub{w}\t{%2, %0|%0, %2}";
5882         }
5883       return "add{w}\t{%2, %0|%0, %2}";
5884     }
5886   [(set (attr "type")
5887      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5888         (const_string "incdec")
5889         (const_string "alu")))
5890    (set_attr "mode" "HI")])
5892 ; See comments above addsi_4 for details.
5893 (define_insn "*addhi_4"
5894   [(set (reg FLAGS_REG)
5895         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5896                  (match_operand:HI 2 "const_int_operand" "n")))
5897    (clobber (match_scratch:HI 0 "=rm"))]
5898   "ix86_match_ccmode (insn, CCGCmode)
5899    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5901   switch (get_attr_type (insn))
5902     {
5903     case TYPE_INCDEC:
5904       if (operands[2] == constm1_rtx)
5905         return "inc{w}\t%0";
5906       else if (operands[2] == const1_rtx)
5907         return "dec{w}\t%0";
5908       else
5909         abort();
5911     default:
5912       if (! rtx_equal_p (operands[0], operands[1]))
5913         abort ();
5914       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5915          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5916       if ((INTVAL (operands[2]) == -128
5917            || (INTVAL (operands[2]) > 0
5918                && INTVAL (operands[2]) != 128)))
5919         return "sub{w}\t{%2, %0|%0, %2}";
5920       operands[2] = GEN_INT (-INTVAL (operands[2]));
5921       return "add{w}\t{%2, %0|%0, %2}";
5922     }
5924   [(set (attr "type")
5925      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5926         (const_string "incdec")
5927         (const_string "alu")))
5928    (set_attr "mode" "SI")])
5931 (define_insn "*addhi_5"
5932   [(set (reg FLAGS_REG)
5933         (compare
5934           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5935                    (match_operand:HI 2 "general_operand" "rmni"))
5936           (const_int 0)))                       
5937    (clobber (match_scratch:HI 0 "=r"))]
5938   "ix86_match_ccmode (insn, CCGOCmode)
5939    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5941   switch (get_attr_type (insn))
5942     {
5943     case TYPE_INCDEC:
5944       if (operands[2] == const1_rtx)
5945         return "inc{w}\t%0";
5946       else if (operands[2] == constm1_rtx)
5947         return "dec{w}\t%0";
5948       abort();
5950     default:
5951       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5952          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5953       if (GET_CODE (operands[2]) == CONST_INT
5954           && (INTVAL (operands[2]) == 128
5955               || (INTVAL (operands[2]) < 0
5956                   && INTVAL (operands[2]) != -128)))
5957         {
5958           operands[2] = GEN_INT (-INTVAL (operands[2]));
5959           return "sub{w}\t{%2, %0|%0, %2}";
5960         }
5961       return "add{w}\t{%2, %0|%0, %2}";
5962     }
5964   [(set (attr "type")
5965      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5966         (const_string "incdec")
5967         (const_string "alu")))
5968    (set_attr "mode" "HI")])
5970 (define_expand "addqi3"
5971   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5972                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5973                             (match_operand:QI 2 "general_operand" "")))
5974               (clobber (reg:CC FLAGS_REG))])]
5975   "TARGET_QIMODE_MATH"
5976   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5978 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5979 (define_insn "*addqi_1_lea"
5980   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5981         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5982                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5983    (clobber (reg:CC FLAGS_REG))]
5984   "!TARGET_PARTIAL_REG_STALL
5985    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5987   int widen = (which_alternative == 2);
5988   switch (get_attr_type (insn))
5989     {
5990     case TYPE_LEA:
5991       return "#";
5992     case TYPE_INCDEC:
5993       if (operands[2] == const1_rtx)
5994         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5995       else if (operands[2] == constm1_rtx)
5996         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5997       abort();
5999     default:
6000       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6001          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6002       if (GET_CODE (operands[2]) == CONST_INT
6003           && (INTVAL (operands[2]) == 128
6004               || (INTVAL (operands[2]) < 0
6005                   && INTVAL (operands[2]) != -128)))
6006         {
6007           operands[2] = GEN_INT (-INTVAL (operands[2]));
6008           if (widen)
6009             return "sub{l}\t{%2, %k0|%k0, %2}";
6010           else
6011             return "sub{b}\t{%2, %0|%0, %2}";
6012         }
6013       if (widen)
6014         return "add{l}\t{%k2, %k0|%k0, %k2}";
6015       else
6016         return "add{b}\t{%2, %0|%0, %2}";
6017     }
6019   [(set (attr "type")
6020      (if_then_else (eq_attr "alternative" "3")
6021         (const_string "lea")
6022         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6023            (const_string "incdec")
6024            (const_string "alu"))))
6025    (set_attr "mode" "QI,QI,SI,SI")])
6027 (define_insn "*addqi_1"
6028   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6029         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6030                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6031    (clobber (reg:CC FLAGS_REG))]
6032   "TARGET_PARTIAL_REG_STALL
6033    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6035   int widen = (which_alternative == 2);
6036   switch (get_attr_type (insn))
6037     {
6038     case TYPE_INCDEC:
6039       if (operands[2] == const1_rtx)
6040         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6041       else if (operands[2] == constm1_rtx)
6042         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6043       abort();
6045     default:
6046       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6047          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6048       if (GET_CODE (operands[2]) == CONST_INT
6049           && (INTVAL (operands[2]) == 128
6050               || (INTVAL (operands[2]) < 0
6051                   && INTVAL (operands[2]) != -128)))
6052         {
6053           operands[2] = GEN_INT (-INTVAL (operands[2]));
6054           if (widen)
6055             return "sub{l}\t{%2, %k0|%k0, %2}";
6056           else
6057             return "sub{b}\t{%2, %0|%0, %2}";
6058         }
6059       if (widen)
6060         return "add{l}\t{%k2, %k0|%k0, %k2}";
6061       else
6062         return "add{b}\t{%2, %0|%0, %2}";
6063     }
6065   [(set (attr "type")
6066      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6067         (const_string "incdec")
6068         (const_string "alu")))
6069    (set_attr "mode" "QI,QI,SI")])
6071 (define_insn "*addqi_1_slp"
6072   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6073         (plus:QI (match_dup 0)
6074                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6075    (clobber (reg:CC FLAGS_REG))]
6076   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6077    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6079   switch (get_attr_type (insn))
6080     {
6081     case TYPE_INCDEC:
6082       if (operands[1] == const1_rtx)
6083         return "inc{b}\t%0";
6084       else if (operands[1] == constm1_rtx)
6085         return "dec{b}\t%0";
6086       abort();
6088     default:
6089       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6090       if (GET_CODE (operands[1]) == CONST_INT
6091           && INTVAL (operands[1]) < 0)
6092         {
6093           operands[1] = GEN_INT (-INTVAL (operands[1]));
6094           return "sub{b}\t{%1, %0|%0, %1}";
6095         }
6096       return "add{b}\t{%1, %0|%0, %1}";
6097     }
6099   [(set (attr "type")
6100      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6101         (const_string "incdec")
6102         (const_string "alu1")))
6103    (set (attr "memory")
6104      (if_then_else (match_operand 1 "memory_operand" "")
6105         (const_string "load")
6106         (const_string "none")))
6107    (set_attr "mode" "QI")])
6109 (define_insn "*addqi_2"
6110   [(set (reg FLAGS_REG)
6111         (compare
6112           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6113                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6114           (const_int 0)))
6115    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6116         (plus:QI (match_dup 1) (match_dup 2)))]
6117   "ix86_match_ccmode (insn, CCGOCmode)
6118    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6120   switch (get_attr_type (insn))
6121     {
6122     case TYPE_INCDEC:
6123       if (operands[2] == const1_rtx)
6124         return "inc{b}\t%0";
6125       else if (operands[2] == constm1_rtx
6126                || (GET_CODE (operands[2]) == CONST_INT
6127                    && INTVAL (operands[2]) == 255))
6128         return "dec{b}\t%0";
6129       abort();
6131     default:
6132       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6133       if (GET_CODE (operands[2]) == CONST_INT
6134           && INTVAL (operands[2]) < 0)
6135         {
6136           operands[2] = GEN_INT (-INTVAL (operands[2]));
6137           return "sub{b}\t{%2, %0|%0, %2}";
6138         }
6139       return "add{b}\t{%2, %0|%0, %2}";
6140     }
6142   [(set (attr "type")
6143      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6144         (const_string "incdec")
6145         (const_string "alu")))
6146    (set_attr "mode" "QI")])
6148 (define_insn "*addqi_3"
6149   [(set (reg FLAGS_REG)
6150         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6151                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6152    (clobber (match_scratch:QI 0 "=q"))]
6153   "ix86_match_ccmode (insn, CCZmode)
6154    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6156   switch (get_attr_type (insn))
6157     {
6158     case TYPE_INCDEC:
6159       if (operands[2] == const1_rtx)
6160         return "inc{b}\t%0";
6161       else if (operands[2] == constm1_rtx
6162                || (GET_CODE (operands[2]) == CONST_INT
6163                    && INTVAL (operands[2]) == 255))
6164         return "dec{b}\t%0";
6165       abort();
6167     default:
6168       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6169       if (GET_CODE (operands[2]) == CONST_INT
6170           && INTVAL (operands[2]) < 0)
6171         {
6172           operands[2] = GEN_INT (-INTVAL (operands[2]));
6173           return "sub{b}\t{%2, %0|%0, %2}";
6174         }
6175       return "add{b}\t{%2, %0|%0, %2}";
6176     }
6178   [(set (attr "type")
6179      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6180         (const_string "incdec")
6181         (const_string "alu")))
6182    (set_attr "mode" "QI")])
6184 ; See comments above addsi_4 for details.
6185 (define_insn "*addqi_4"
6186   [(set (reg FLAGS_REG)
6187         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6188                  (match_operand:QI 2 "const_int_operand" "n")))
6189    (clobber (match_scratch:QI 0 "=qm"))]
6190   "ix86_match_ccmode (insn, CCGCmode)
6191    && (INTVAL (operands[2]) & 0xff) != 0x80"
6193   switch (get_attr_type (insn))
6194     {
6195     case TYPE_INCDEC:
6196       if (operands[2] == constm1_rtx
6197           || (GET_CODE (operands[2]) == CONST_INT
6198               && INTVAL (operands[2]) == 255))
6199         return "inc{b}\t%0";
6200       else if (operands[2] == const1_rtx)
6201         return "dec{b}\t%0";
6202       else
6203         abort();
6205     default:
6206       if (! rtx_equal_p (operands[0], operands[1]))
6207         abort ();
6208       if (INTVAL (operands[2]) < 0)
6209         {
6210           operands[2] = GEN_INT (-INTVAL (operands[2]));
6211           return "add{b}\t{%2, %0|%0, %2}";
6212         }
6213       return "sub{b}\t{%2, %0|%0, %2}";
6214     }
6216   [(set (attr "type")
6217      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6218         (const_string "incdec")
6219         (const_string "alu")))
6220    (set_attr "mode" "QI")])
6223 (define_insn "*addqi_5"
6224   [(set (reg FLAGS_REG)
6225         (compare
6226           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6227                    (match_operand:QI 2 "general_operand" "qmni"))
6228           (const_int 0)))
6229    (clobber (match_scratch:QI 0 "=q"))]
6230   "ix86_match_ccmode (insn, CCGOCmode)
6231    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6233   switch (get_attr_type (insn))
6234     {
6235     case TYPE_INCDEC:
6236       if (operands[2] == const1_rtx)
6237         return "inc{b}\t%0";
6238       else if (operands[2] == constm1_rtx
6239                || (GET_CODE (operands[2]) == CONST_INT
6240                    && INTVAL (operands[2]) == 255))
6241         return "dec{b}\t%0";
6242       abort();
6244     default:
6245       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6246       if (GET_CODE (operands[2]) == CONST_INT
6247           && INTVAL (operands[2]) < 0)
6248         {
6249           operands[2] = GEN_INT (-INTVAL (operands[2]));
6250           return "sub{b}\t{%2, %0|%0, %2}";
6251         }
6252       return "add{b}\t{%2, %0|%0, %2}";
6253     }
6255   [(set (attr "type")
6256      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6257         (const_string "incdec")
6258         (const_string "alu")))
6259    (set_attr "mode" "QI")])
6262 (define_insn "addqi_ext_1"
6263   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6264                          (const_int 8)
6265                          (const_int 8))
6266         (plus:SI
6267           (zero_extract:SI
6268             (match_operand 1 "ext_register_operand" "0")
6269             (const_int 8)
6270             (const_int 8))
6271           (match_operand:QI 2 "general_operand" "Qmn")))
6272    (clobber (reg:CC FLAGS_REG))]
6273   "!TARGET_64BIT"
6275   switch (get_attr_type (insn))
6276     {
6277     case TYPE_INCDEC:
6278       if (operands[2] == const1_rtx)
6279         return "inc{b}\t%h0";
6280       else if (operands[2] == constm1_rtx
6281                || (GET_CODE (operands[2]) == CONST_INT
6282                    && INTVAL (operands[2]) == 255))
6283         return "dec{b}\t%h0";
6284       abort();
6286     default:
6287       return "add{b}\t{%2, %h0|%h0, %2}";
6288     }
6290   [(set (attr "type")
6291      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6292         (const_string "incdec")
6293         (const_string "alu")))
6294    (set_attr "mode" "QI")])
6296 (define_insn "*addqi_ext_1_rex64"
6297   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6298                          (const_int 8)
6299                          (const_int 8))
6300         (plus:SI
6301           (zero_extract:SI
6302             (match_operand 1 "ext_register_operand" "0")
6303             (const_int 8)
6304             (const_int 8))
6305           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6306    (clobber (reg:CC FLAGS_REG))]
6307   "TARGET_64BIT"
6309   switch (get_attr_type (insn))
6310     {
6311     case TYPE_INCDEC:
6312       if (operands[2] == const1_rtx)
6313         return "inc{b}\t%h0";
6314       else if (operands[2] == constm1_rtx
6315                || (GET_CODE (operands[2]) == CONST_INT
6316                    && INTVAL (operands[2]) == 255))
6317         return "dec{b}\t%h0";
6318       abort();
6320     default:
6321       return "add{b}\t{%2, %h0|%h0, %2}";
6322     }
6324   [(set (attr "type")
6325      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6326         (const_string "incdec")
6327         (const_string "alu")))
6328    (set_attr "mode" "QI")])
6330 (define_insn "*addqi_ext_2"
6331   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6332                          (const_int 8)
6333                          (const_int 8))
6334         (plus:SI
6335           (zero_extract:SI
6336             (match_operand 1 "ext_register_operand" "%0")
6337             (const_int 8)
6338             (const_int 8))
6339           (zero_extract:SI
6340             (match_operand 2 "ext_register_operand" "Q")
6341             (const_int 8)
6342             (const_int 8))))
6343    (clobber (reg:CC FLAGS_REG))]
6344   ""
6345   "add{b}\t{%h2, %h0|%h0, %h2}"
6346   [(set_attr "type" "alu")
6347    (set_attr "mode" "QI")])
6349 ;; The patterns that match these are at the end of this file.
6351 (define_expand "addxf3"
6352   [(set (match_operand:XF 0 "register_operand" "")
6353         (plus:XF (match_operand:XF 1 "register_operand" "")
6354                  (match_operand:XF 2 "register_operand" "")))]
6355   "TARGET_80387"
6356   "")
6358 (define_expand "adddf3"
6359   [(set (match_operand:DF 0 "register_operand" "")
6360         (plus:DF (match_operand:DF 1 "register_operand" "")
6361                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6362   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6363   "")
6365 (define_expand "addsf3"
6366   [(set (match_operand:SF 0 "register_operand" "")
6367         (plus:SF (match_operand:SF 1 "register_operand" "")
6368                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6369   "TARGET_80387 || TARGET_SSE_MATH"
6370   "")
6372 ;; Subtract instructions
6374 ;; %%% splits for subsidi3
6376 (define_expand "subdi3"
6377   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6378                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6379                              (match_operand:DI 2 "x86_64_general_operand" "")))
6380               (clobber (reg:CC FLAGS_REG))])]
6381   ""
6382   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6384 (define_insn "*subdi3_1"
6385   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6386         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6387                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6388    (clobber (reg:CC FLAGS_REG))]
6389   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6390   "#")
6392 (define_split
6393   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6394         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6395                   (match_operand:DI 2 "general_operand" "")))
6396    (clobber (reg:CC FLAGS_REG))]
6397   "!TARGET_64BIT && reload_completed"
6398   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6399               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6400    (parallel [(set (match_dup 3)
6401                    (minus:SI (match_dup 4)
6402                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6403                                       (match_dup 5))))
6404               (clobber (reg:CC FLAGS_REG))])]
6405   "split_di (operands+0, 1, operands+0, operands+3);
6406    split_di (operands+1, 1, operands+1, operands+4);
6407    split_di (operands+2, 1, operands+2, operands+5);")
6409 (define_insn "subdi3_carry_rex64"
6410   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6411           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6412             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6413                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6414    (clobber (reg:CC FLAGS_REG))]
6415   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6416   "sbb{q}\t{%2, %0|%0, %2}"
6417   [(set_attr "type" "alu")
6418    (set_attr "pent_pair" "pu")
6419    (set_attr "mode" "DI")])
6421 (define_insn "*subdi_1_rex64"
6422   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6423         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6424                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6425    (clobber (reg:CC FLAGS_REG))]
6426   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6427   "sub{q}\t{%2, %0|%0, %2}"
6428   [(set_attr "type" "alu")
6429    (set_attr "mode" "DI")])
6431 (define_insn "*subdi_2_rex64"
6432   [(set (reg FLAGS_REG)
6433         (compare
6434           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6435                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6436           (const_int 0)))
6437    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6438         (minus:DI (match_dup 1) (match_dup 2)))]
6439   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6440    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6441   "sub{q}\t{%2, %0|%0, %2}"
6442   [(set_attr "type" "alu")
6443    (set_attr "mode" "DI")])
6445 (define_insn "*subdi_3_rex63"
6446   [(set (reg FLAGS_REG)
6447         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6448                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6449    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6450         (minus:DI (match_dup 1) (match_dup 2)))]
6451   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6452    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6453   "sub{q}\t{%2, %0|%0, %2}"
6454   [(set_attr "type" "alu")
6455    (set_attr "mode" "DI")])
6457 (define_insn "subqi3_carry"
6458   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6459           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6460             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6461                (match_operand:QI 2 "general_operand" "qi,qm"))))
6462    (clobber (reg:CC FLAGS_REG))]
6463   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6464   "sbb{b}\t{%2, %0|%0, %2}"
6465   [(set_attr "type" "alu")
6466    (set_attr "pent_pair" "pu")
6467    (set_attr "mode" "QI")])
6469 (define_insn "subhi3_carry"
6470   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6471           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6472             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6473                (match_operand:HI 2 "general_operand" "ri,rm"))))
6474    (clobber (reg:CC FLAGS_REG))]
6475   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6476   "sbb{w}\t{%2, %0|%0, %2}"
6477   [(set_attr "type" "alu")
6478    (set_attr "pent_pair" "pu")
6479    (set_attr "mode" "HI")])
6481 (define_insn "subsi3_carry"
6482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6483           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6484             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6485                (match_operand:SI 2 "general_operand" "ri,rm"))))
6486    (clobber (reg:CC FLAGS_REG))]
6487   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6488   "sbb{l}\t{%2, %0|%0, %2}"
6489   [(set_attr "type" "alu")
6490    (set_attr "pent_pair" "pu")
6491    (set_attr "mode" "SI")])
6493 (define_insn "subsi3_carry_zext"
6494   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6495           (zero_extend:DI
6496             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6497               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6498                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6499    (clobber (reg:CC FLAGS_REG))]
6500   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6501   "sbb{l}\t{%2, %k0|%k0, %2}"
6502   [(set_attr "type" "alu")
6503    (set_attr "pent_pair" "pu")
6504    (set_attr "mode" "SI")])
6506 (define_expand "subsi3"
6507   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6508                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6509                              (match_operand:SI 2 "general_operand" "")))
6510               (clobber (reg:CC FLAGS_REG))])]
6511   ""
6512   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6514 (define_insn "*subsi_1"
6515   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6516         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6517                   (match_operand:SI 2 "general_operand" "ri,rm")))
6518    (clobber (reg:CC FLAGS_REG))]
6519   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6520   "sub{l}\t{%2, %0|%0, %2}"
6521   [(set_attr "type" "alu")
6522    (set_attr "mode" "SI")])
6524 (define_insn "*subsi_1_zext"
6525   [(set (match_operand:DI 0 "register_operand" "=r")
6526         (zero_extend:DI
6527           (minus:SI (match_operand:SI 1 "register_operand" "0")
6528                     (match_operand:SI 2 "general_operand" "rim"))))
6529    (clobber (reg:CC FLAGS_REG))]
6530   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6531   "sub{l}\t{%2, %k0|%k0, %2}"
6532   [(set_attr "type" "alu")
6533    (set_attr "mode" "SI")])
6535 (define_insn "*subsi_2"
6536   [(set (reg FLAGS_REG)
6537         (compare
6538           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6539                     (match_operand:SI 2 "general_operand" "ri,rm"))
6540           (const_int 0)))
6541    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6542         (minus:SI (match_dup 1) (match_dup 2)))]
6543   "ix86_match_ccmode (insn, CCGOCmode)
6544    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6545   "sub{l}\t{%2, %0|%0, %2}"
6546   [(set_attr "type" "alu")
6547    (set_attr "mode" "SI")])
6549 (define_insn "*subsi_2_zext"
6550   [(set (reg FLAGS_REG)
6551         (compare
6552           (minus:SI (match_operand:SI 1 "register_operand" "0")
6553                     (match_operand:SI 2 "general_operand" "rim"))
6554           (const_int 0)))
6555    (set (match_operand:DI 0 "register_operand" "=r")
6556         (zero_extend:DI
6557           (minus:SI (match_dup 1)
6558                     (match_dup 2))))]
6559   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6560    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6561   "sub{l}\t{%2, %k0|%k0, %2}"
6562   [(set_attr "type" "alu")
6563    (set_attr "mode" "SI")])
6565 (define_insn "*subsi_3"
6566   [(set (reg FLAGS_REG)
6567         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6568                  (match_operand:SI 2 "general_operand" "ri,rm")))
6569    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6570         (minus:SI (match_dup 1) (match_dup 2)))]
6571   "ix86_match_ccmode (insn, CCmode)
6572    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6573   "sub{l}\t{%2, %0|%0, %2}"
6574   [(set_attr "type" "alu")
6575    (set_attr "mode" "SI")])
6577 (define_insn "*subsi_3_zext"
6578   [(set (reg FLAGS_REG)
6579         (compare (match_operand:SI 1 "register_operand" "0")
6580                  (match_operand:SI 2 "general_operand" "rim")))
6581    (set (match_operand:DI 0 "register_operand" "=r")
6582         (zero_extend:DI
6583           (minus:SI (match_dup 1)
6584                     (match_dup 2))))]
6585   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6586    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587   "sub{q}\t{%2, %0|%0, %2}"
6588   [(set_attr "type" "alu")
6589    (set_attr "mode" "DI")])
6591 (define_expand "subhi3"
6592   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6593                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6594                              (match_operand:HI 2 "general_operand" "")))
6595               (clobber (reg:CC FLAGS_REG))])]
6596   "TARGET_HIMODE_MATH"
6597   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6599 (define_insn "*subhi_1"
6600   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6601         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6602                   (match_operand:HI 2 "general_operand" "ri,rm")))
6603    (clobber (reg:CC FLAGS_REG))]
6604   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6605   "sub{w}\t{%2, %0|%0, %2}"
6606   [(set_attr "type" "alu")
6607    (set_attr "mode" "HI")])
6609 (define_insn "*subhi_2"
6610   [(set (reg FLAGS_REG)
6611         (compare
6612           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6613                     (match_operand:HI 2 "general_operand" "ri,rm"))
6614           (const_int 0)))
6615    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6616         (minus:HI (match_dup 1) (match_dup 2)))]
6617   "ix86_match_ccmode (insn, CCGOCmode)
6618    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6619   "sub{w}\t{%2, %0|%0, %2}"
6620   [(set_attr "type" "alu")
6621    (set_attr "mode" "HI")])
6623 (define_insn "*subhi_3"
6624   [(set (reg FLAGS_REG)
6625         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6626                  (match_operand:HI 2 "general_operand" "ri,rm")))
6627    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6628         (minus:HI (match_dup 1) (match_dup 2)))]
6629   "ix86_match_ccmode (insn, CCmode)
6630    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6631   "sub{w}\t{%2, %0|%0, %2}"
6632   [(set_attr "type" "alu")
6633    (set_attr "mode" "HI")])
6635 (define_expand "subqi3"
6636   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6637                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6638                              (match_operand:QI 2 "general_operand" "")))
6639               (clobber (reg:CC FLAGS_REG))])]
6640   "TARGET_QIMODE_MATH"
6641   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6643 (define_insn "*subqi_1"
6644   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6645         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6646                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6647    (clobber (reg:CC FLAGS_REG))]
6648   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6649   "sub{b}\t{%2, %0|%0, %2}"
6650   [(set_attr "type" "alu")
6651    (set_attr "mode" "QI")])
6653 (define_insn "*subqi_1_slp"
6654   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6655         (minus:QI (match_dup 0)
6656                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6657    (clobber (reg:CC FLAGS_REG))]
6658   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6659    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6660   "sub{b}\t{%1, %0|%0, %1}"
6661   [(set_attr "type" "alu1")
6662    (set_attr "mode" "QI")])
6664 (define_insn "*subqi_2"
6665   [(set (reg FLAGS_REG)
6666         (compare
6667           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6668                     (match_operand:QI 2 "general_operand" "qi,qm"))
6669           (const_int 0)))
6670    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6671         (minus:HI (match_dup 1) (match_dup 2)))]
6672   "ix86_match_ccmode (insn, CCGOCmode)
6673    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6674   "sub{b}\t{%2, %0|%0, %2}"
6675   [(set_attr "type" "alu")
6676    (set_attr "mode" "QI")])
6678 (define_insn "*subqi_3"
6679   [(set (reg FLAGS_REG)
6680         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6681                  (match_operand:QI 2 "general_operand" "qi,qm")))
6682    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6683         (minus:HI (match_dup 1) (match_dup 2)))]
6684   "ix86_match_ccmode (insn, CCmode)
6685    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6686   "sub{b}\t{%2, %0|%0, %2}"
6687   [(set_attr "type" "alu")
6688    (set_attr "mode" "QI")])
6690 ;; The patterns that match these are at the end of this file.
6692 (define_expand "subxf3"
6693   [(set (match_operand:XF 0 "register_operand" "")
6694         (minus:XF (match_operand:XF 1 "register_operand" "")
6695                   (match_operand:XF 2 "register_operand" "")))]
6696   "TARGET_80387"
6697   "")
6699 (define_expand "subdf3"
6700   [(set (match_operand:DF 0 "register_operand" "")
6701         (minus:DF (match_operand:DF 1 "register_operand" "")
6702                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6703   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6704   "")
6706 (define_expand "subsf3"
6707   [(set (match_operand:SF 0 "register_operand" "")
6708         (minus:SF (match_operand:SF 1 "register_operand" "")
6709                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6710   "TARGET_80387 || TARGET_SSE_MATH"
6711   "")
6713 ;; Multiply instructions
6715 (define_expand "muldi3"
6716   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6717                    (mult:DI (match_operand:DI 1 "register_operand" "")
6718                             (match_operand:DI 2 "x86_64_general_operand" "")))
6719               (clobber (reg:CC FLAGS_REG))])]
6720   "TARGET_64BIT"
6721   "")
6723 (define_insn "*muldi3_1_rex64"
6724   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6725         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6726                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6727    (clobber (reg:CC FLAGS_REG))]
6728   "TARGET_64BIT
6729    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6730   "@
6731    imul{q}\t{%2, %1, %0|%0, %1, %2}
6732    imul{q}\t{%2, %1, %0|%0, %1, %2}
6733    imul{q}\t{%2, %0|%0, %2}"
6734   [(set_attr "type" "imul")
6735    (set_attr "prefix_0f" "0,0,1")
6736    (set (attr "athlon_decode")
6737         (cond [(eq_attr "cpu" "athlon")
6738                   (const_string "vector")
6739                (eq_attr "alternative" "1")
6740                   (const_string "vector")
6741                (and (eq_attr "alternative" "2")
6742                     (match_operand 1 "memory_operand" ""))
6743                   (const_string "vector")]
6744               (const_string "direct")))
6745    (set_attr "mode" "DI")])
6747 (define_expand "mulsi3"
6748   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6749                    (mult:SI (match_operand:SI 1 "register_operand" "")
6750                             (match_operand:SI 2 "general_operand" "")))
6751               (clobber (reg:CC FLAGS_REG))])]
6752   ""
6753   "")
6755 (define_insn "*mulsi3_1"
6756   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6757         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6758                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6759    (clobber (reg:CC FLAGS_REG))]
6760   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6761   "@
6762    imul{l}\t{%2, %1, %0|%0, %1, %2}
6763    imul{l}\t{%2, %1, %0|%0, %1, %2}
6764    imul{l}\t{%2, %0|%0, %2}"
6765   [(set_attr "type" "imul")
6766    (set_attr "prefix_0f" "0,0,1")
6767    (set (attr "athlon_decode")
6768         (cond [(eq_attr "cpu" "athlon")
6769                   (const_string "vector")
6770                (eq_attr "alternative" "1")
6771                   (const_string "vector")
6772                (and (eq_attr "alternative" "2")
6773                     (match_operand 1 "memory_operand" ""))
6774                   (const_string "vector")]
6775               (const_string "direct")))
6776    (set_attr "mode" "SI")])
6778 (define_insn "*mulsi3_1_zext"
6779   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6780         (zero_extend:DI
6781           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6782                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6783    (clobber (reg:CC FLAGS_REG))]
6784   "TARGET_64BIT
6785    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6786   "@
6787    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6788    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6789    imul{l}\t{%2, %k0|%k0, %2}"
6790   [(set_attr "type" "imul")
6791    (set_attr "prefix_0f" "0,0,1")
6792    (set (attr "athlon_decode")
6793         (cond [(eq_attr "cpu" "athlon")
6794                   (const_string "vector")
6795                (eq_attr "alternative" "1")
6796                   (const_string "vector")
6797                (and (eq_attr "alternative" "2")
6798                     (match_operand 1 "memory_operand" ""))
6799                   (const_string "vector")]
6800               (const_string "direct")))
6801    (set_attr "mode" "SI")])
6803 (define_expand "mulhi3"
6804   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6805                    (mult:HI (match_operand:HI 1 "register_operand" "")
6806                             (match_operand:HI 2 "general_operand" "")))
6807               (clobber (reg:CC FLAGS_REG))])]
6808   "TARGET_HIMODE_MATH"
6809   "")
6811 (define_insn "*mulhi3_1"
6812   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6813         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6814                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6815    (clobber (reg:CC FLAGS_REG))]
6816   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6817   "@
6818    imul{w}\t{%2, %1, %0|%0, %1, %2}
6819    imul{w}\t{%2, %1, %0|%0, %1, %2}
6820    imul{w}\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "imul")
6822    (set_attr "prefix_0f" "0,0,1")
6823    (set (attr "athlon_decode")
6824         (cond [(eq_attr "cpu" "athlon")
6825                   (const_string "vector")
6826                (eq_attr "alternative" "1,2")
6827                   (const_string "vector")]
6828               (const_string "direct")))
6829    (set_attr "mode" "HI")])
6831 (define_expand "mulqi3"
6832   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6833                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6834                             (match_operand:QI 2 "register_operand" "")))
6835               (clobber (reg:CC FLAGS_REG))])]
6836   "TARGET_QIMODE_MATH"
6837   "")
6839 (define_insn "*mulqi3_1"
6840   [(set (match_operand:QI 0 "register_operand" "=a")
6841         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6842                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6843    (clobber (reg:CC FLAGS_REG))]
6844   "TARGET_QIMODE_MATH
6845    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6846   "mul{b}\t%2"
6847   [(set_attr "type" "imul")
6848    (set_attr "length_immediate" "0")
6849    (set (attr "athlon_decode")
6850      (if_then_else (eq_attr "cpu" "athlon")
6851         (const_string "vector")
6852         (const_string "direct")))
6853    (set_attr "mode" "QI")])
6855 (define_expand "umulqihi3"
6856   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6857                    (mult:HI (zero_extend:HI
6858                               (match_operand:QI 1 "nonimmediate_operand" ""))
6859                             (zero_extend:HI
6860                               (match_operand:QI 2 "register_operand" ""))))
6861               (clobber (reg:CC FLAGS_REG))])]
6862   "TARGET_QIMODE_MATH"
6863   "")
6865 (define_insn "*umulqihi3_1"
6866   [(set (match_operand:HI 0 "register_operand" "=a")
6867         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6868                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6869    (clobber (reg:CC FLAGS_REG))]
6870   "TARGET_QIMODE_MATH
6871    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6872   "mul{b}\t%2"
6873   [(set_attr "type" "imul")
6874    (set_attr "length_immediate" "0")
6875    (set (attr "athlon_decode")
6876      (if_then_else (eq_attr "cpu" "athlon")
6877         (const_string "vector")
6878         (const_string "direct")))
6879    (set_attr "mode" "QI")])
6881 (define_expand "mulqihi3"
6882   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6883                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6884                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6885               (clobber (reg:CC FLAGS_REG))])]
6886   "TARGET_QIMODE_MATH"
6887   "")
6889 (define_insn "*mulqihi3_insn"
6890   [(set (match_operand:HI 0 "register_operand" "=a")
6891         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6892                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6893    (clobber (reg:CC FLAGS_REG))]
6894   "TARGET_QIMODE_MATH
6895    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6896   "imul{b}\t%2"
6897   [(set_attr "type" "imul")
6898    (set_attr "length_immediate" "0")
6899    (set (attr "athlon_decode")
6900      (if_then_else (eq_attr "cpu" "athlon")
6901         (const_string "vector")
6902         (const_string "direct")))
6903    (set_attr "mode" "QI")])
6905 (define_expand "umulditi3"
6906   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6907                    (mult:TI (zero_extend:TI
6908                               (match_operand:DI 1 "nonimmediate_operand" ""))
6909                             (zero_extend:TI
6910                               (match_operand:DI 2 "register_operand" ""))))
6911               (clobber (reg:CC FLAGS_REG))])]
6912   "TARGET_64BIT"
6913   "")
6915 (define_insn "*umulditi3_insn"
6916   [(set (match_operand:TI 0 "register_operand" "=A")
6917         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6918                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6919    (clobber (reg:CC FLAGS_REG))]
6920   "TARGET_64BIT
6921    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6922   "mul{q}\t%2"
6923   [(set_attr "type" "imul")
6924    (set_attr "length_immediate" "0")
6925    (set (attr "athlon_decode")
6926      (if_then_else (eq_attr "cpu" "athlon")
6927         (const_string "vector")
6928         (const_string "double")))
6929    (set_attr "mode" "DI")])
6931 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6932 (define_expand "umulsidi3"
6933   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6934                    (mult:DI (zero_extend:DI
6935                               (match_operand:SI 1 "nonimmediate_operand" ""))
6936                             (zero_extend:DI
6937                               (match_operand:SI 2 "register_operand" ""))))
6938               (clobber (reg:CC FLAGS_REG))])]
6939   "!TARGET_64BIT"
6940   "")
6942 (define_insn "*umulsidi3_insn"
6943   [(set (match_operand:DI 0 "register_operand" "=A")
6944         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6945                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6946    (clobber (reg:CC FLAGS_REG))]
6947   "!TARGET_64BIT
6948    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6949   "mul{l}\t%2"
6950   [(set_attr "type" "imul")
6951    (set_attr "length_immediate" "0")
6952    (set (attr "athlon_decode")
6953      (if_then_else (eq_attr "cpu" "athlon")
6954         (const_string "vector")
6955         (const_string "double")))
6956    (set_attr "mode" "SI")])
6958 (define_expand "mulditi3"
6959   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6960                    (mult:TI (sign_extend:TI
6961                               (match_operand:DI 1 "nonimmediate_operand" ""))
6962                             (sign_extend:TI
6963                               (match_operand:DI 2 "register_operand" ""))))
6964               (clobber (reg:CC FLAGS_REG))])]
6965   "TARGET_64BIT"
6966   "")
6968 (define_insn "*mulditi3_insn"
6969   [(set (match_operand:TI 0 "register_operand" "=A")
6970         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6971                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6972    (clobber (reg:CC FLAGS_REG))]
6973   "TARGET_64BIT
6974    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6975   "imul{q}\t%2"
6976   [(set_attr "type" "imul")
6977    (set_attr "length_immediate" "0")
6978    (set (attr "athlon_decode")
6979      (if_then_else (eq_attr "cpu" "athlon")
6980         (const_string "vector")
6981         (const_string "double")))
6982    (set_attr "mode" "DI")])
6984 (define_expand "mulsidi3"
6985   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6986                    (mult:DI (sign_extend:DI
6987                               (match_operand:SI 1 "nonimmediate_operand" ""))
6988                             (sign_extend:DI
6989                               (match_operand:SI 2 "register_operand" ""))))
6990               (clobber (reg:CC FLAGS_REG))])]
6991   "!TARGET_64BIT"
6992   "")
6994 (define_insn "*mulsidi3_insn"
6995   [(set (match_operand:DI 0 "register_operand" "=A")
6996         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6997                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6998    (clobber (reg:CC FLAGS_REG))]
6999   "!TARGET_64BIT
7000    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7001   "imul{l}\t%2"
7002   [(set_attr "type" "imul")
7003    (set_attr "length_immediate" "0")
7004    (set (attr "athlon_decode")
7005      (if_then_else (eq_attr "cpu" "athlon")
7006         (const_string "vector")
7007         (const_string "double")))
7008    (set_attr "mode" "SI")])
7010 (define_expand "umuldi3_highpart"
7011   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7012                    (truncate:DI
7013                      (lshiftrt:TI
7014                        (mult:TI (zero_extend:TI
7015                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7016                                 (zero_extend:TI
7017                                   (match_operand:DI 2 "register_operand" "")))
7018                        (const_int 64))))
7019               (clobber (match_scratch:DI 3 ""))
7020               (clobber (reg:CC FLAGS_REG))])]
7021   "TARGET_64BIT"
7022   "")
7024 (define_insn "*umuldi3_highpart_rex64"
7025   [(set (match_operand:DI 0 "register_operand" "=d")
7026         (truncate:DI
7027           (lshiftrt:TI
7028             (mult:TI (zero_extend:TI
7029                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7030                      (zero_extend:TI
7031                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7032             (const_int 64))))
7033    (clobber (match_scratch:DI 3 "=1"))
7034    (clobber (reg:CC FLAGS_REG))]
7035   "TARGET_64BIT
7036    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7037   "mul{q}\t%2"
7038   [(set_attr "type" "imul")
7039    (set_attr "length_immediate" "0")
7040    (set (attr "athlon_decode")
7041      (if_then_else (eq_attr "cpu" "athlon")
7042         (const_string "vector")
7043         (const_string "double")))
7044    (set_attr "mode" "DI")])
7046 (define_expand "umulsi3_highpart"
7047   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7048                    (truncate:SI
7049                      (lshiftrt:DI
7050                        (mult:DI (zero_extend:DI
7051                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7052                                 (zero_extend:DI
7053                                   (match_operand:SI 2 "register_operand" "")))
7054                        (const_int 32))))
7055               (clobber (match_scratch:SI 3 ""))
7056               (clobber (reg:CC FLAGS_REG))])]
7057   ""
7058   "")
7060 (define_insn "*umulsi3_highpart_insn"
7061   [(set (match_operand:SI 0 "register_operand" "=d")
7062         (truncate:SI
7063           (lshiftrt:DI
7064             (mult:DI (zero_extend:DI
7065                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7066                      (zero_extend:DI
7067                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7068             (const_int 32))))
7069    (clobber (match_scratch:SI 3 "=1"))
7070    (clobber (reg:CC FLAGS_REG))]
7071   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7072   "mul{l}\t%2"
7073   [(set_attr "type" "imul")
7074    (set_attr "length_immediate" "0")
7075    (set (attr "athlon_decode")
7076      (if_then_else (eq_attr "cpu" "athlon")
7077         (const_string "vector")
7078         (const_string "double")))
7079    (set_attr "mode" "SI")])
7081 (define_insn "*umulsi3_highpart_zext"
7082   [(set (match_operand:DI 0 "register_operand" "=d")
7083         (zero_extend:DI (truncate:SI
7084           (lshiftrt:DI
7085             (mult:DI (zero_extend:DI
7086                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7087                      (zero_extend:DI
7088                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7089             (const_int 32)))))
7090    (clobber (match_scratch:SI 3 "=1"))
7091    (clobber (reg:CC FLAGS_REG))]
7092   "TARGET_64BIT
7093    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7094   "mul{l}\t%2"
7095   [(set_attr "type" "imul")
7096    (set_attr "length_immediate" "0")
7097    (set (attr "athlon_decode")
7098      (if_then_else (eq_attr "cpu" "athlon")
7099         (const_string "vector")
7100         (const_string "double")))
7101    (set_attr "mode" "SI")])
7103 (define_expand "smuldi3_highpart"
7104   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7105                    (truncate:DI
7106                      (lshiftrt:TI
7107                        (mult:TI (sign_extend:TI
7108                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7109                                 (sign_extend:TI
7110                                   (match_operand:DI 2 "register_operand" "")))
7111                        (const_int 64))))
7112               (clobber (match_scratch:DI 3 ""))
7113               (clobber (reg:CC FLAGS_REG))])]
7114   "TARGET_64BIT"
7115   "")
7117 (define_insn "*smuldi3_highpart_rex64"
7118   [(set (match_operand:DI 0 "register_operand" "=d")
7119         (truncate:DI
7120           (lshiftrt:TI
7121             (mult:TI (sign_extend:TI
7122                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7123                      (sign_extend:TI
7124                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7125             (const_int 64))))
7126    (clobber (match_scratch:DI 3 "=1"))
7127    (clobber (reg:CC FLAGS_REG))]
7128   "TARGET_64BIT
7129    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7130   "imul{q}\t%2"
7131   [(set_attr "type" "imul")
7132    (set (attr "athlon_decode")
7133      (if_then_else (eq_attr "cpu" "athlon")
7134         (const_string "vector")
7135         (const_string "double")))
7136    (set_attr "mode" "DI")])
7138 (define_expand "smulsi3_highpart"
7139   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7140                    (truncate:SI
7141                      (lshiftrt:DI
7142                        (mult:DI (sign_extend:DI
7143                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7144                                 (sign_extend:DI
7145                                   (match_operand:SI 2 "register_operand" "")))
7146                        (const_int 32))))
7147               (clobber (match_scratch:SI 3 ""))
7148               (clobber (reg:CC FLAGS_REG))])]
7149   ""
7150   "")
7152 (define_insn "*smulsi3_highpart_insn"
7153   [(set (match_operand:SI 0 "register_operand" "=d")
7154         (truncate:SI
7155           (lshiftrt:DI
7156             (mult:DI (sign_extend:DI
7157                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7158                      (sign_extend:DI
7159                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7160             (const_int 32))))
7161    (clobber (match_scratch:SI 3 "=1"))
7162    (clobber (reg:CC FLAGS_REG))]
7163   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7164   "imul{l}\t%2"
7165   [(set_attr "type" "imul")
7166    (set (attr "athlon_decode")
7167      (if_then_else (eq_attr "cpu" "athlon")
7168         (const_string "vector")
7169         (const_string "double")))
7170    (set_attr "mode" "SI")])
7172 (define_insn "*smulsi3_highpart_zext"
7173   [(set (match_operand:DI 0 "register_operand" "=d")
7174         (zero_extend:DI (truncate:SI
7175           (lshiftrt:DI
7176             (mult:DI (sign_extend:DI
7177                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7178                      (sign_extend:DI
7179                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7180             (const_int 32)))))
7181    (clobber (match_scratch:SI 3 "=1"))
7182    (clobber (reg:CC FLAGS_REG))]
7183   "TARGET_64BIT
7184    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7185   "imul{l}\t%2"
7186   [(set_attr "type" "imul")
7187    (set (attr "athlon_decode")
7188      (if_then_else (eq_attr "cpu" "athlon")
7189         (const_string "vector")
7190         (const_string "double")))
7191    (set_attr "mode" "SI")])
7193 ;; The patterns that match these are at the end of this file.
7195 (define_expand "mulxf3"
7196   [(set (match_operand:XF 0 "register_operand" "")
7197         (mult:XF (match_operand:XF 1 "register_operand" "")
7198                  (match_operand:XF 2 "register_operand" "")))]
7199   "TARGET_80387"
7200   "")
7202 (define_expand "muldf3"
7203   [(set (match_operand:DF 0 "register_operand" "")
7204         (mult:DF (match_operand:DF 1 "register_operand" "")
7205                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7206   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7207   "")
7209 (define_expand "mulsf3"
7210   [(set (match_operand:SF 0 "register_operand" "")
7211         (mult:SF (match_operand:SF 1 "register_operand" "")
7212                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7213   "TARGET_80387 || TARGET_SSE_MATH"
7214   "")
7216 ;; Divide instructions
7218 (define_insn "divqi3"
7219   [(set (match_operand:QI 0 "register_operand" "=a")
7220         (div:QI (match_operand:HI 1 "register_operand" "0")
7221                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7222    (clobber (reg:CC FLAGS_REG))]
7223   "TARGET_QIMODE_MATH"
7224   "idiv{b}\t%2"
7225   [(set_attr "type" "idiv")
7226    (set_attr "mode" "QI")])
7228 (define_insn "udivqi3"
7229   [(set (match_operand:QI 0 "register_operand" "=a")
7230         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7231                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7232    (clobber (reg:CC FLAGS_REG))]
7233   "TARGET_QIMODE_MATH"
7234   "div{b}\t%2"
7235   [(set_attr "type" "idiv")
7236    (set_attr "mode" "QI")])
7238 ;; The patterns that match these are at the end of this file.
7240 (define_expand "divxf3"
7241   [(set (match_operand:XF 0 "register_operand" "")
7242         (div:XF (match_operand:XF 1 "register_operand" "")
7243                 (match_operand:XF 2 "register_operand" "")))]
7244   "TARGET_80387"
7245   "")
7247 (define_expand "divdf3"
7248   [(set (match_operand:DF 0 "register_operand" "")
7249         (div: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 "divsf3"
7255   [(set (match_operand:SF 0 "register_operand" "")
7256         (div:SF (match_operand:SF 1 "register_operand" "")
7257                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7258   "TARGET_80387 || TARGET_SSE_MATH"
7259   "")
7261 ;; Remainder instructions.
7263 (define_expand "divmoddi4"
7264   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7265                    (div:DI (match_operand:DI 1 "register_operand" "")
7266                            (match_operand:DI 2 "nonimmediate_operand" "")))
7267               (set (match_operand:DI 3 "register_operand" "")
7268                    (mod:DI (match_dup 1) (match_dup 2)))
7269               (clobber (reg:CC FLAGS_REG))])]
7270   "TARGET_64BIT"
7271   "")
7273 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7274 ;; Penalize eax case slightly because it results in worse scheduling
7275 ;; of code.
7276 (define_insn "*divmoddi4_nocltd_rex64"
7277   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7278         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7279                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7280    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7281         (mod:DI (match_dup 2) (match_dup 3)))
7282    (clobber (reg:CC FLAGS_REG))]
7283   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7284   "#"
7285   [(set_attr "type" "multi")])
7287 (define_insn "*divmoddi4_cltd_rex64"
7288   [(set (match_operand:DI 0 "register_operand" "=a")
7289         (div:DI (match_operand:DI 2 "register_operand" "a")
7290                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7291    (set (match_operand:DI 1 "register_operand" "=&d")
7292         (mod:DI (match_dup 2) (match_dup 3)))
7293    (clobber (reg:CC FLAGS_REG))]
7294   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7295   "#"
7296   [(set_attr "type" "multi")])
7298 (define_insn "*divmoddi_noext_rex64"
7299   [(set (match_operand:DI 0 "register_operand" "=a")
7300         (div:DI (match_operand:DI 1 "register_operand" "0")
7301                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7302    (set (match_operand:DI 3 "register_operand" "=d")
7303         (mod:DI (match_dup 1) (match_dup 2)))
7304    (use (match_operand:DI 4 "register_operand" "3"))
7305    (clobber (reg:CC FLAGS_REG))]
7306   "TARGET_64BIT"
7307   "idiv{q}\t%2"
7308   [(set_attr "type" "idiv")
7309    (set_attr "mode" "DI")])
7311 (define_split
7312   [(set (match_operand:DI 0 "register_operand" "")
7313         (div:DI (match_operand:DI 1 "register_operand" "")
7314                 (match_operand:DI 2 "nonimmediate_operand" "")))
7315    (set (match_operand:DI 3 "register_operand" "")
7316         (mod:DI (match_dup 1) (match_dup 2)))
7317    (clobber (reg:CC FLAGS_REG))]
7318   "TARGET_64BIT && reload_completed"
7319   [(parallel [(set (match_dup 3)
7320                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7321               (clobber (reg:CC FLAGS_REG))])
7322    (parallel [(set (match_dup 0)
7323                    (div:DI (reg:DI 0) (match_dup 2)))
7324               (set (match_dup 3)
7325                    (mod:DI (reg:DI 0) (match_dup 2)))
7326               (use (match_dup 3))
7327               (clobber (reg:CC FLAGS_REG))])]
7329   /* Avoid use of cltd in favor of a mov+shift.  */
7330   if (!TARGET_USE_CLTD && !optimize_size)
7331     {
7332       if (true_regnum (operands[1]))
7333         emit_move_insn (operands[0], operands[1]);
7334       else
7335         emit_move_insn (operands[3], operands[1]);
7336       operands[4] = operands[3];
7337     }
7338   else
7339     {
7340       if (true_regnum (operands[1]))
7341         abort();
7342       operands[4] = operands[1];
7343     }
7347 (define_expand "divmodsi4"
7348   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7349                    (div:SI (match_operand:SI 1 "register_operand" "")
7350                            (match_operand:SI 2 "nonimmediate_operand" "")))
7351               (set (match_operand:SI 3 "register_operand" "")
7352                    (mod:SI (match_dup 1) (match_dup 2)))
7353               (clobber (reg:CC FLAGS_REG))])]
7354   ""
7355   "")
7357 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7358 ;; Penalize eax case slightly because it results in worse scheduling
7359 ;; of code.
7360 (define_insn "*divmodsi4_nocltd"
7361   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7362         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7363                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7364    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7365         (mod:SI (match_dup 2) (match_dup 3)))
7366    (clobber (reg:CC FLAGS_REG))]
7367   "!optimize_size && !TARGET_USE_CLTD"
7368   "#"
7369   [(set_attr "type" "multi")])
7371 (define_insn "*divmodsi4_cltd"
7372   [(set (match_operand:SI 0 "register_operand" "=a")
7373         (div:SI (match_operand:SI 2 "register_operand" "a")
7374                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7375    (set (match_operand:SI 1 "register_operand" "=&d")
7376         (mod:SI (match_dup 2) (match_dup 3)))
7377    (clobber (reg:CC FLAGS_REG))]
7378   "optimize_size || TARGET_USE_CLTD"
7379   "#"
7380   [(set_attr "type" "multi")])
7382 (define_insn "*divmodsi_noext"
7383   [(set (match_operand:SI 0 "register_operand" "=a")
7384         (div:SI (match_operand:SI 1 "register_operand" "0")
7385                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7386    (set (match_operand:SI 3 "register_operand" "=d")
7387         (mod:SI (match_dup 1) (match_dup 2)))
7388    (use (match_operand:SI 4 "register_operand" "3"))
7389    (clobber (reg:CC FLAGS_REG))]
7390   ""
7391   "idiv{l}\t%2"
7392   [(set_attr "type" "idiv")
7393    (set_attr "mode" "SI")])
7395 (define_split
7396   [(set (match_operand:SI 0 "register_operand" "")
7397         (div:SI (match_operand:SI 1 "register_operand" "")
7398                 (match_operand:SI 2 "nonimmediate_operand" "")))
7399    (set (match_operand:SI 3 "register_operand" "")
7400         (mod:SI (match_dup 1) (match_dup 2)))
7401    (clobber (reg:CC FLAGS_REG))]
7402   "reload_completed"
7403   [(parallel [(set (match_dup 3)
7404                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7405               (clobber (reg:CC FLAGS_REG))])
7406    (parallel [(set (match_dup 0)
7407                    (div:SI (reg:SI 0) (match_dup 2)))
7408               (set (match_dup 3)
7409                    (mod:SI (reg:SI 0) (match_dup 2)))
7410               (use (match_dup 3))
7411               (clobber (reg:CC FLAGS_REG))])]
7413   /* Avoid use of cltd in favor of a mov+shift.  */
7414   if (!TARGET_USE_CLTD && !optimize_size)
7415     {
7416       if (true_regnum (operands[1]))
7417         emit_move_insn (operands[0], operands[1]);
7418       else
7419         emit_move_insn (operands[3], operands[1]);
7420       operands[4] = operands[3];
7421     }
7422   else
7423     {
7424       if (true_regnum (operands[1]))
7425         abort();
7426       operands[4] = operands[1];
7427     }
7429 ;; %%% Split me.
7430 (define_insn "divmodhi4"
7431   [(set (match_operand:HI 0 "register_operand" "=a")
7432         (div:HI (match_operand:HI 1 "register_operand" "0")
7433                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7434    (set (match_operand:HI 3 "register_operand" "=&d")
7435         (mod:HI (match_dup 1) (match_dup 2)))
7436    (clobber (reg:CC FLAGS_REG))]
7437   "TARGET_HIMODE_MATH"
7438   "cwtd\;idiv{w}\t%2"
7439   [(set_attr "type" "multi")
7440    (set_attr "length_immediate" "0")
7441    (set_attr "mode" "SI")])
7443 (define_insn "udivmoddi4"
7444   [(set (match_operand:DI 0 "register_operand" "=a")
7445         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7446                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7447    (set (match_operand:DI 3 "register_operand" "=&d")
7448         (umod:DI (match_dup 1) (match_dup 2)))
7449    (clobber (reg:CC FLAGS_REG))]
7450   "TARGET_64BIT"
7451   "xor{q}\t%3, %3\;div{q}\t%2"
7452   [(set_attr "type" "multi")
7453    (set_attr "length_immediate" "0")
7454    (set_attr "mode" "DI")])
7456 (define_insn "*udivmoddi4_noext"
7457   [(set (match_operand:DI 0 "register_operand" "=a")
7458         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7459                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7460    (set (match_operand:DI 3 "register_operand" "=d")
7461         (umod:DI (match_dup 1) (match_dup 2)))
7462    (use (match_dup 3))
7463    (clobber (reg:CC FLAGS_REG))]
7464   "TARGET_64BIT"
7465   "div{q}\t%2"
7466   [(set_attr "type" "idiv")
7467    (set_attr "mode" "DI")])
7469 (define_split
7470   [(set (match_operand:DI 0 "register_operand" "")
7471         (udiv:DI (match_operand:DI 1 "register_operand" "")
7472                  (match_operand:DI 2 "nonimmediate_operand" "")))
7473    (set (match_operand:DI 3 "register_operand" "")
7474         (umod:DI (match_dup 1) (match_dup 2)))
7475    (clobber (reg:CC FLAGS_REG))]
7476   "TARGET_64BIT && reload_completed"
7477   [(set (match_dup 3) (const_int 0))
7478    (parallel [(set (match_dup 0)
7479                    (udiv:DI (match_dup 1) (match_dup 2)))
7480               (set (match_dup 3)
7481                    (umod:DI (match_dup 1) (match_dup 2)))
7482               (use (match_dup 3))
7483               (clobber (reg:CC FLAGS_REG))])]
7484   "")
7486 (define_insn "udivmodsi4"
7487   [(set (match_operand:SI 0 "register_operand" "=a")
7488         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7489                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7490    (set (match_operand:SI 3 "register_operand" "=&d")
7491         (umod:SI (match_dup 1) (match_dup 2)))
7492    (clobber (reg:CC FLAGS_REG))]
7493   ""
7494   "xor{l}\t%3, %3\;div{l}\t%2"
7495   [(set_attr "type" "multi")
7496    (set_attr "length_immediate" "0")
7497    (set_attr "mode" "SI")])
7499 (define_insn "*udivmodsi4_noext"
7500   [(set (match_operand:SI 0 "register_operand" "=a")
7501         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7502                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7503    (set (match_operand:SI 3 "register_operand" "=d")
7504         (umod:SI (match_dup 1) (match_dup 2)))
7505    (use (match_dup 3))
7506    (clobber (reg:CC FLAGS_REG))]
7507   ""
7508   "div{l}\t%2"
7509   [(set_attr "type" "idiv")
7510    (set_attr "mode" "SI")])
7512 (define_split
7513   [(set (match_operand:SI 0 "register_operand" "")
7514         (udiv:SI (match_operand:SI 1 "register_operand" "")
7515                  (match_operand:SI 2 "nonimmediate_operand" "")))
7516    (set (match_operand:SI 3 "register_operand" "")
7517         (umod:SI (match_dup 1) (match_dup 2)))
7518    (clobber (reg:CC FLAGS_REG))]
7519   "reload_completed"
7520   [(set (match_dup 3) (const_int 0))
7521    (parallel [(set (match_dup 0)
7522                    (udiv:SI (match_dup 1) (match_dup 2)))
7523               (set (match_dup 3)
7524                    (umod:SI (match_dup 1) (match_dup 2)))
7525               (use (match_dup 3))
7526               (clobber (reg:CC FLAGS_REG))])]
7527   "")
7529 (define_expand "udivmodhi4"
7530   [(set (match_dup 4) (const_int 0))
7531    (parallel [(set (match_operand:HI 0 "register_operand" "")
7532                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7533                             (match_operand:HI 2 "nonimmediate_operand" "")))
7534               (set (match_operand:HI 3 "register_operand" "")
7535                    (umod:HI (match_dup 1) (match_dup 2)))
7536               (use (match_dup 4))
7537               (clobber (reg:CC FLAGS_REG))])]
7538   "TARGET_HIMODE_MATH"
7539   "operands[4] = gen_reg_rtx (HImode);")
7541 (define_insn "*udivmodhi_noext"
7542   [(set (match_operand:HI 0 "register_operand" "=a")
7543         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7544                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7545    (set (match_operand:HI 3 "register_operand" "=d")
7546         (umod:HI (match_dup 1) (match_dup 2)))
7547    (use (match_operand:HI 4 "register_operand" "3"))
7548    (clobber (reg:CC FLAGS_REG))]
7549   ""
7550   "div{w}\t%2"
7551   [(set_attr "type" "idiv")
7552    (set_attr "mode" "HI")])
7554 ;; We cannot use div/idiv for double division, because it causes
7555 ;; "division by zero" on the overflow and that's not what we expect
7556 ;; from truncate.  Because true (non truncating) double division is
7557 ;; never generated, we can't create this insn anyway.
7559 ;(define_insn ""
7560 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7561 ;       (truncate:SI
7562 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7563 ;                  (zero_extend:DI
7564 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7565 ;   (set (match_operand:SI 3 "register_operand" "=d")
7566 ;       (truncate:SI
7567 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7568 ;   (clobber (reg:CC FLAGS_REG))]
7569 ;  ""
7570 ;  "div{l}\t{%2, %0|%0, %2}"
7571 ;  [(set_attr "type" "idiv")])
7573 ;;- Logical AND instructions
7575 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7576 ;; Note that this excludes ah.
7578 (define_insn "*testdi_1_rex64"
7579   [(set (reg FLAGS_REG)
7580         (compare
7581           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7582                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7583           (const_int 0)))]
7584   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7585    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7586   "@
7587    test{l}\t{%k1, %k0|%k0, %k1}
7588    test{l}\t{%k1, %k0|%k0, %k1}
7589    test{q}\t{%1, %0|%0, %1}
7590    test{q}\t{%1, %0|%0, %1}
7591    test{q}\t{%1, %0|%0, %1}"
7592   [(set_attr "type" "test")
7593    (set_attr "modrm" "0,1,0,1,1")
7594    (set_attr "mode" "SI,SI,DI,DI,DI")
7595    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7597 (define_insn "testsi_1"
7598   [(set (reg FLAGS_REG)
7599         (compare
7600           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7601                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7602           (const_int 0)))]
7603   "ix86_match_ccmode (insn, CCNOmode)
7604    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7605   "test{l}\t{%1, %0|%0, %1}"
7606   [(set_attr "type" "test")
7607    (set_attr "modrm" "0,1,1")
7608    (set_attr "mode" "SI")
7609    (set_attr "pent_pair" "uv,np,uv")])
7611 (define_expand "testsi_ccno_1"
7612   [(set (reg:CCNO FLAGS_REG)
7613         (compare:CCNO
7614           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7615                   (match_operand:SI 1 "nonmemory_operand" ""))
7616           (const_int 0)))]
7617   ""
7618   "")
7620 (define_insn "*testhi_1"
7621   [(set (reg FLAGS_REG)
7622         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7623                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7624                  (const_int 0)))]
7625   "ix86_match_ccmode (insn, CCNOmode)
7626    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7627   "test{w}\t{%1, %0|%0, %1}"
7628   [(set_attr "type" "test")
7629    (set_attr "modrm" "0,1,1")
7630    (set_attr "mode" "HI")
7631    (set_attr "pent_pair" "uv,np,uv")])
7633 (define_expand "testqi_ccz_1"
7634   [(set (reg:CCZ FLAGS_REG)
7635         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7636                              (match_operand:QI 1 "nonmemory_operand" ""))
7637                  (const_int 0)))]
7638   ""
7639   "")
7641 (define_insn "*testqi_1_maybe_si"
7642   [(set (reg FLAGS_REG)
7643         (compare
7644           (and:QI
7645             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7646             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7647           (const_int 0)))]
7648    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7649     && ix86_match_ccmode (insn,
7650                          GET_CODE (operands[1]) == CONST_INT
7651                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7653   if (which_alternative == 3)
7654     {
7655       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7656         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7657       return "test{l}\t{%1, %k0|%k0, %1}";
7658     }
7659   return "test{b}\t{%1, %0|%0, %1}";
7661   [(set_attr "type" "test")
7662    (set_attr "modrm" "0,1,1,1")
7663    (set_attr "mode" "QI,QI,QI,SI")
7664    (set_attr "pent_pair" "uv,np,uv,np")])
7666 (define_insn "*testqi_1"
7667   [(set (reg FLAGS_REG)
7668         (compare
7669           (and:QI
7670             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7671             (match_operand:QI 1 "general_operand" "n,n,qn"))
7672           (const_int 0)))]
7673   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7674    && ix86_match_ccmode (insn, CCNOmode)"
7675   "test{b}\t{%1, %0|%0, %1}"
7676   [(set_attr "type" "test")
7677    (set_attr "modrm" "0,1,1")
7678    (set_attr "mode" "QI")
7679    (set_attr "pent_pair" "uv,np,uv")])
7681 (define_expand "testqi_ext_ccno_0"
7682   [(set (reg:CCNO FLAGS_REG)
7683         (compare:CCNO
7684           (and:SI
7685             (zero_extract:SI
7686               (match_operand 0 "ext_register_operand" "")
7687               (const_int 8)
7688               (const_int 8))
7689             (match_operand 1 "const_int_operand" ""))
7690           (const_int 0)))]
7691   ""
7692   "")
7694 (define_insn "*testqi_ext_0"
7695   [(set (reg FLAGS_REG)
7696         (compare
7697           (and:SI
7698             (zero_extract:SI
7699               (match_operand 0 "ext_register_operand" "Q")
7700               (const_int 8)
7701               (const_int 8))
7702             (match_operand 1 "const_int_operand" "n"))
7703           (const_int 0)))]
7704   "ix86_match_ccmode (insn, CCNOmode)"
7705   "test{b}\t{%1, %h0|%h0, %1}"
7706   [(set_attr "type" "test")
7707    (set_attr "mode" "QI")
7708    (set_attr "length_immediate" "1")
7709    (set_attr "pent_pair" "np")])
7711 (define_insn "*testqi_ext_1"
7712   [(set (reg FLAGS_REG)
7713         (compare
7714           (and:SI
7715             (zero_extract:SI
7716               (match_operand 0 "ext_register_operand" "Q")
7717               (const_int 8)
7718               (const_int 8))
7719             (zero_extend:SI
7720               (match_operand:QI 1 "general_operand" "Qm")))
7721           (const_int 0)))]
7722   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7723    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7724   "test{b}\t{%1, %h0|%h0, %1}"
7725   [(set_attr "type" "test")
7726    (set_attr "mode" "QI")])
7728 (define_insn "*testqi_ext_1_rex64"
7729   [(set (reg FLAGS_REG)
7730         (compare
7731           (and:SI
7732             (zero_extract:SI
7733               (match_operand 0 "ext_register_operand" "Q")
7734               (const_int 8)
7735               (const_int 8))
7736             (zero_extend:SI
7737               (match_operand:QI 1 "register_operand" "Q")))
7738           (const_int 0)))]
7739   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7740   "test{b}\t{%1, %h0|%h0, %1}"
7741   [(set_attr "type" "test")
7742    (set_attr "mode" "QI")])
7744 (define_insn "*testqi_ext_2"
7745   [(set (reg FLAGS_REG)
7746         (compare
7747           (and:SI
7748             (zero_extract:SI
7749               (match_operand 0 "ext_register_operand" "Q")
7750               (const_int 8)
7751               (const_int 8))
7752             (zero_extract:SI
7753               (match_operand 1 "ext_register_operand" "Q")
7754               (const_int 8)
7755               (const_int 8)))
7756           (const_int 0)))]
7757   "ix86_match_ccmode (insn, CCNOmode)"
7758   "test{b}\t{%h1, %h0|%h0, %h1}"
7759   [(set_attr "type" "test")
7760    (set_attr "mode" "QI")])
7762 ;; Combine likes to form bit extractions for some tests.  Humor it.
7763 (define_insn "*testqi_ext_3"
7764   [(set (reg FLAGS_REG)
7765         (compare (zero_extract:SI
7766                    (match_operand 0 "nonimmediate_operand" "rm")
7767                    (match_operand:SI 1 "const_int_operand" "")
7768                    (match_operand:SI 2 "const_int_operand" ""))
7769                  (const_int 0)))]
7770   "ix86_match_ccmode (insn, CCNOmode)
7771    && (GET_MODE (operands[0]) == SImode
7772        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7773        || GET_MODE (operands[0]) == HImode
7774        || GET_MODE (operands[0]) == QImode)"
7775   "#")
7777 (define_insn "*testqi_ext_3_rex64"
7778   [(set (reg FLAGS_REG)
7779         (compare (zero_extract:DI
7780                    (match_operand 0 "nonimmediate_operand" "rm")
7781                    (match_operand:DI 1 "const_int_operand" "")
7782                    (match_operand:DI 2 "const_int_operand" ""))
7783                  (const_int 0)))]
7784   "TARGET_64BIT
7785    && ix86_match_ccmode (insn, CCNOmode)
7786    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7787    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7788    /* Ensure that resulting mask is zero or sign extended operand.  */
7789    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7790        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7791            && INTVAL (operands[1]) > 32))
7792    && (GET_MODE (operands[0]) == SImode
7793        || GET_MODE (operands[0]) == DImode
7794        || GET_MODE (operands[0]) == HImode
7795        || GET_MODE (operands[0]) == QImode)"
7796   "#")
7798 (define_split
7799   [(set (match_operand 0 "flags_reg_operand" "")
7800         (match_operator 1 "compare_operator"
7801           [(zero_extract
7802              (match_operand 2 "nonimmediate_operand" "")
7803              (match_operand 3 "const_int_operand" "")
7804              (match_operand 4 "const_int_operand" ""))
7805            (const_int 0)]))]
7806   "ix86_match_ccmode (insn, CCNOmode)"
7807   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7809   rtx val = operands[2];
7810   HOST_WIDE_INT len = INTVAL (operands[3]);
7811   HOST_WIDE_INT pos = INTVAL (operands[4]);
7812   HOST_WIDE_INT mask;
7813   enum machine_mode mode, submode;
7815   mode = GET_MODE (val);
7816   if (GET_CODE (val) == MEM)
7817     {
7818       /* ??? Combine likes to put non-volatile mem extractions in QImode
7819          no matter the size of the test.  So find a mode that works.  */
7820       if (! MEM_VOLATILE_P (val))
7821         {
7822           mode = smallest_mode_for_size (pos + len, MODE_INT);
7823           val = adjust_address (val, mode, 0);
7824         }
7825     }
7826   else if (GET_CODE (val) == SUBREG
7827            && (submode = GET_MODE (SUBREG_REG (val)),
7828                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7829            && pos + len <= GET_MODE_BITSIZE (submode))
7830     {
7831       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7832       mode = submode;
7833       val = SUBREG_REG (val);
7834     }
7835   else if (mode == HImode && pos + len <= 8)
7836     {
7837       /* Small HImode tests can be converted to QImode.  */
7838       mode = QImode;
7839       val = gen_lowpart (QImode, val);
7840     }
7842   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7843   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7845   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7848 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7849 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7850 ;; this is relatively important trick.
7851 ;; Do the conversion only post-reload to avoid limiting of the register class
7852 ;; to QI regs.
7853 (define_split
7854   [(set (match_operand 0 "flags_reg_operand" "")
7855         (match_operator 1 "compare_operator"
7856           [(and (match_operand 2 "register_operand" "")
7857                 (match_operand 3 "const_int_operand" ""))
7858            (const_int 0)]))]
7859    "reload_completed
7860     && QI_REG_P (operands[2])
7861     && GET_MODE (operands[2]) != QImode
7862     && ((ix86_match_ccmode (insn, CCZmode)
7863          && !(INTVAL (operands[3]) & ~(255 << 8)))
7864         || (ix86_match_ccmode (insn, CCNOmode)
7865             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7866   [(set (match_dup 0)
7867         (match_op_dup 1
7868           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7869                    (match_dup 3))
7870            (const_int 0)]))]
7871   "operands[2] = gen_lowpart (SImode, operands[2]);
7872    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7874 (define_split
7875   [(set (match_operand 0 "flags_reg_operand" "")
7876         (match_operator 1 "compare_operator"
7877           [(and (match_operand 2 "nonimmediate_operand" "")
7878                 (match_operand 3 "const_int_operand" ""))
7879            (const_int 0)]))]
7880    "reload_completed
7881     && GET_MODE (operands[2]) != QImode
7882     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7883     && ((ix86_match_ccmode (insn, CCZmode)
7884          && !(INTVAL (operands[3]) & ~255))
7885         || (ix86_match_ccmode (insn, CCNOmode)
7886             && !(INTVAL (operands[3]) & ~127)))"
7887   [(set (match_dup 0)
7888         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7889                          (const_int 0)]))]
7890   "operands[2] = gen_lowpart (QImode, operands[2]);
7891    operands[3] = gen_lowpart (QImode, operands[3]);")
7894 ;; %%% This used to optimize known byte-wide and operations to memory,
7895 ;; and sometimes to QImode registers.  If this is considered useful,
7896 ;; it should be done with splitters.
7898 (define_expand "anddi3"
7899   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7900         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7901                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7902    (clobber (reg:CC FLAGS_REG))]
7903   "TARGET_64BIT"
7904   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7906 (define_insn "*anddi_1_rex64"
7907   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7908         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7909                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7910    (clobber (reg:CC FLAGS_REG))]
7911   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7913   switch (get_attr_type (insn))
7914     {
7915     case TYPE_IMOVX:
7916       {
7917         enum machine_mode mode;
7919         if (GET_CODE (operands[2]) != CONST_INT)
7920           abort ();
7921         if (INTVAL (operands[2]) == 0xff)
7922           mode = QImode;
7923         else if (INTVAL (operands[2]) == 0xffff)
7924           mode = HImode;
7925         else
7926           abort ();
7927         
7928         operands[1] = gen_lowpart (mode, operands[1]);
7929         if (mode == QImode)
7930           return "movz{bq|x}\t{%1,%0|%0, %1}";
7931         else
7932           return "movz{wq|x}\t{%1,%0|%0, %1}";
7933       }
7935     default:
7936       if (! rtx_equal_p (operands[0], operands[1]))
7937         abort ();
7938       if (get_attr_mode (insn) == MODE_SI)
7939         return "and{l}\t{%k2, %k0|%k0, %k2}";
7940       else
7941         return "and{q}\t{%2, %0|%0, %2}";
7942     }
7944   [(set_attr "type" "alu,alu,alu,imovx")
7945    (set_attr "length_immediate" "*,*,*,0")
7946    (set_attr "mode" "SI,DI,DI,DI")])
7948 (define_insn "*anddi_2"
7949   [(set (reg FLAGS_REG)
7950         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7951                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7952                  (const_int 0)))
7953    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7954         (and:DI (match_dup 1) (match_dup 2)))]
7955   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7956    && ix86_binary_operator_ok (AND, DImode, operands)"
7957   "@
7958    and{l}\t{%k2, %k0|%k0, %k2}
7959    and{q}\t{%2, %0|%0, %2}
7960    and{q}\t{%2, %0|%0, %2}"
7961   [(set_attr "type" "alu")
7962    (set_attr "mode" "SI,DI,DI")])
7964 (define_expand "andsi3"
7965   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7966         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7967                 (match_operand:SI 2 "general_operand" "")))
7968    (clobber (reg:CC FLAGS_REG))]
7969   ""
7970   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7972 (define_insn "*andsi_1"
7973   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7974         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7975                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7976    (clobber (reg:CC FLAGS_REG))]
7977   "ix86_binary_operator_ok (AND, SImode, operands)"
7979   switch (get_attr_type (insn))
7980     {
7981     case TYPE_IMOVX:
7982       {
7983         enum machine_mode mode;
7985         if (GET_CODE (operands[2]) != CONST_INT)
7986           abort ();
7987         if (INTVAL (operands[2]) == 0xff)
7988           mode = QImode;
7989         else if (INTVAL (operands[2]) == 0xffff)
7990           mode = HImode;
7991         else
7992           abort ();
7993         
7994         operands[1] = gen_lowpart (mode, operands[1]);
7995         if (mode == QImode)
7996           return "movz{bl|x}\t{%1,%0|%0, %1}";
7997         else
7998           return "movz{wl|x}\t{%1,%0|%0, %1}";
7999       }
8001     default:
8002       if (! rtx_equal_p (operands[0], operands[1]))
8003         abort ();
8004       return "and{l}\t{%2, %0|%0, %2}";
8005     }
8007   [(set_attr "type" "alu,alu,imovx")
8008    (set_attr "length_immediate" "*,*,0")
8009    (set_attr "mode" "SI")])
8011 (define_split
8012   [(set (match_operand 0 "register_operand" "")
8013         (and (match_dup 0)
8014              (const_int -65536)))
8015    (clobber (reg:CC FLAGS_REG))]
8016   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8017   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8018   "operands[1] = gen_lowpart (HImode, operands[0]);")
8020 (define_split
8021   [(set (match_operand 0 "ext_register_operand" "")
8022         (and (match_dup 0)
8023              (const_int -256)))
8024    (clobber (reg:CC FLAGS_REG))]
8025   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8026   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8027   "operands[1] = gen_lowpart (QImode, operands[0]);")
8029 (define_split
8030   [(set (match_operand 0 "ext_register_operand" "")
8031         (and (match_dup 0)
8032              (const_int -65281)))
8033    (clobber (reg:CC FLAGS_REG))]
8034   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8035   [(parallel [(set (zero_extract:SI (match_dup 0)
8036                                     (const_int 8)
8037                                     (const_int 8))
8038                    (xor:SI 
8039                      (zero_extract:SI (match_dup 0)
8040                                       (const_int 8)
8041                                       (const_int 8))
8042                      (zero_extract:SI (match_dup 0)
8043                                       (const_int 8)
8044                                       (const_int 8))))
8045               (clobber (reg:CC FLAGS_REG))])]
8046   "operands[0] = gen_lowpart (SImode, operands[0]);")
8048 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8049 (define_insn "*andsi_1_zext"
8050   [(set (match_operand:DI 0 "register_operand" "=r")
8051         (zero_extend:DI
8052           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8053                   (match_operand:SI 2 "general_operand" "rim"))))
8054    (clobber (reg:CC FLAGS_REG))]
8055   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8056   "and{l}\t{%2, %k0|%k0, %2}"
8057   [(set_attr "type" "alu")
8058    (set_attr "mode" "SI")])
8060 (define_insn "*andsi_2"
8061   [(set (reg FLAGS_REG)
8062         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8063                          (match_operand:SI 2 "general_operand" "rim,ri"))
8064                  (const_int 0)))
8065    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8066         (and:SI (match_dup 1) (match_dup 2)))]
8067   "ix86_match_ccmode (insn, CCNOmode)
8068    && ix86_binary_operator_ok (AND, SImode, operands)"
8069   "and{l}\t{%2, %0|%0, %2}"
8070   [(set_attr "type" "alu")
8071    (set_attr "mode" "SI")])
8073 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8074 (define_insn "*andsi_2_zext"
8075   [(set (reg FLAGS_REG)
8076         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8077                          (match_operand:SI 2 "general_operand" "rim"))
8078                  (const_int 0)))
8079    (set (match_operand:DI 0 "register_operand" "=r")
8080         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8081   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8082    && ix86_binary_operator_ok (AND, SImode, operands)"
8083   "and{l}\t{%2, %k0|%k0, %2}"
8084   [(set_attr "type" "alu")
8085    (set_attr "mode" "SI")])
8087 (define_expand "andhi3"
8088   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8089         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8090                 (match_operand:HI 2 "general_operand" "")))
8091    (clobber (reg:CC FLAGS_REG))]
8092   "TARGET_HIMODE_MATH"
8093   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8095 (define_insn "*andhi_1"
8096   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8097         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8098                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8099    (clobber (reg:CC FLAGS_REG))]
8100   "ix86_binary_operator_ok (AND, HImode, operands)"
8102   switch (get_attr_type (insn))
8103     {
8104     case TYPE_IMOVX:
8105       if (GET_CODE (operands[2]) != CONST_INT)
8106         abort ();
8107       if (INTVAL (operands[2]) == 0xff)
8108         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8109       abort ();
8111     default:
8112       if (! rtx_equal_p (operands[0], operands[1]))
8113         abort ();
8115       return "and{w}\t{%2, %0|%0, %2}";
8116     }
8118   [(set_attr "type" "alu,alu,imovx")
8119    (set_attr "length_immediate" "*,*,0")
8120    (set_attr "mode" "HI,HI,SI")])
8122 (define_insn "*andhi_2"
8123   [(set (reg FLAGS_REG)
8124         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8125                          (match_operand:HI 2 "general_operand" "rim,ri"))
8126                  (const_int 0)))
8127    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8128         (and:HI (match_dup 1) (match_dup 2)))]
8129   "ix86_match_ccmode (insn, CCNOmode)
8130    && ix86_binary_operator_ok (AND, HImode, operands)"
8131   "and{w}\t{%2, %0|%0, %2}"
8132   [(set_attr "type" "alu")
8133    (set_attr "mode" "HI")])
8135 (define_expand "andqi3"
8136   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8137         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8138                 (match_operand:QI 2 "general_operand" "")))
8139    (clobber (reg:CC FLAGS_REG))]
8140   "TARGET_QIMODE_MATH"
8141   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8143 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8144 (define_insn "*andqi_1"
8145   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8146         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8147                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8148    (clobber (reg:CC FLAGS_REG))]
8149   "ix86_binary_operator_ok (AND, QImode, operands)"
8150   "@
8151    and{b}\t{%2, %0|%0, %2}
8152    and{b}\t{%2, %0|%0, %2}
8153    and{l}\t{%k2, %k0|%k0, %k2}"
8154   [(set_attr "type" "alu")
8155    (set_attr "mode" "QI,QI,SI")])
8157 (define_insn "*andqi_1_slp"
8158   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8159         (and:QI (match_dup 0)
8160                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8161    (clobber (reg:CC FLAGS_REG))]
8162   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8164   "and{b}\t{%1, %0|%0, %1}"
8165   [(set_attr "type" "alu1")
8166    (set_attr "mode" "QI")])
8168 (define_insn "*andqi_2_maybe_si"
8169   [(set (reg FLAGS_REG)
8170         (compare (and:QI
8171                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8172                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8173                  (const_int 0)))
8174    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8175         (and:QI (match_dup 1) (match_dup 2)))]
8176   "ix86_binary_operator_ok (AND, QImode, operands)
8177    && ix86_match_ccmode (insn,
8178                          GET_CODE (operands[2]) == CONST_INT
8179                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8181   if (which_alternative == 2)
8182     {
8183       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8184         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8185       return "and{l}\t{%2, %k0|%k0, %2}";
8186     }
8187   return "and{b}\t{%2, %0|%0, %2}";
8189   [(set_attr "type" "alu")
8190    (set_attr "mode" "QI,QI,SI")])
8192 (define_insn "*andqi_2"
8193   [(set (reg FLAGS_REG)
8194         (compare (and:QI
8195                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8196                    (match_operand:QI 2 "general_operand" "qim,qi"))
8197                  (const_int 0)))
8198    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8199         (and:QI (match_dup 1) (match_dup 2)))]
8200   "ix86_match_ccmode (insn, CCNOmode)
8201    && ix86_binary_operator_ok (AND, QImode, operands)"
8202   "and{b}\t{%2, %0|%0, %2}"
8203   [(set_attr "type" "alu")
8204    (set_attr "mode" "QI")])
8206 (define_insn "*andqi_2_slp"
8207   [(set (reg FLAGS_REG)
8208         (compare (and:QI
8209                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8210                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8211                  (const_int 0)))
8212    (set (strict_low_part (match_dup 0))
8213         (and:QI (match_dup 0) (match_dup 1)))]
8214   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8215    && ix86_match_ccmode (insn, CCNOmode)
8216    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8217   "and{b}\t{%1, %0|%0, %1}"
8218   [(set_attr "type" "alu1")
8219    (set_attr "mode" "QI")])
8221 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8222 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8223 ;; for a QImode operand, which of course failed.
8225 (define_insn "andqi_ext_0"
8226   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8227                          (const_int 8)
8228                          (const_int 8))
8229         (and:SI 
8230           (zero_extract:SI
8231             (match_operand 1 "ext_register_operand" "0")
8232             (const_int 8)
8233             (const_int 8))
8234           (match_operand 2 "const_int_operand" "n")))
8235    (clobber (reg:CC FLAGS_REG))]
8236   ""
8237   "and{b}\t{%2, %h0|%h0, %2}"
8238   [(set_attr "type" "alu")
8239    (set_attr "length_immediate" "1")
8240    (set_attr "mode" "QI")])
8242 ;; Generated by peephole translating test to and.  This shows up
8243 ;; often in fp comparisons.
8245 (define_insn "*andqi_ext_0_cc"
8246   [(set (reg FLAGS_REG)
8247         (compare
8248           (and:SI
8249             (zero_extract:SI
8250               (match_operand 1 "ext_register_operand" "0")
8251               (const_int 8)
8252               (const_int 8))
8253             (match_operand 2 "const_int_operand" "n"))
8254           (const_int 0)))
8255    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8256                          (const_int 8)
8257                          (const_int 8))
8258         (and:SI 
8259           (zero_extract:SI
8260             (match_dup 1)
8261             (const_int 8)
8262             (const_int 8))
8263           (match_dup 2)))]
8264   "ix86_match_ccmode (insn, CCNOmode)"
8265   "and{b}\t{%2, %h0|%h0, %2}"
8266   [(set_attr "type" "alu")
8267    (set_attr "length_immediate" "1")
8268    (set_attr "mode" "QI")])
8270 (define_insn "*andqi_ext_1"
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           (zero_extend:SI
8280             (match_operand:QI 2 "general_operand" "Qm"))))
8281    (clobber (reg:CC FLAGS_REG))]
8282   "!TARGET_64BIT"
8283   "and{b}\t{%2, %h0|%h0, %2}"
8284   [(set_attr "type" "alu")
8285    (set_attr "length_immediate" "0")
8286    (set_attr "mode" "QI")])
8288 (define_insn "*andqi_ext_1_rex64"
8289   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8290                          (const_int 8)
8291                          (const_int 8))
8292         (and:SI 
8293           (zero_extract:SI
8294             (match_operand 1 "ext_register_operand" "0")
8295             (const_int 8)
8296             (const_int 8))
8297           (zero_extend:SI
8298             (match_operand 2 "ext_register_operand" "Q"))))
8299    (clobber (reg:CC FLAGS_REG))]
8300   "TARGET_64BIT"
8301   "and{b}\t{%2, %h0|%h0, %2}"
8302   [(set_attr "type" "alu")
8303    (set_attr "length_immediate" "0")
8304    (set_attr "mode" "QI")])
8306 (define_insn "*andqi_ext_2"
8307   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8308                          (const_int 8)
8309                          (const_int 8))
8310         (and:SI
8311           (zero_extract:SI
8312             (match_operand 1 "ext_register_operand" "%0")
8313             (const_int 8)
8314             (const_int 8))
8315           (zero_extract:SI
8316             (match_operand 2 "ext_register_operand" "Q")
8317             (const_int 8)
8318             (const_int 8))))
8319    (clobber (reg:CC FLAGS_REG))]
8320   ""
8321   "and{b}\t{%h2, %h0|%h0, %h2}"
8322   [(set_attr "type" "alu")
8323    (set_attr "length_immediate" "0")
8324    (set_attr "mode" "QI")])
8326 ;; Convert wide AND instructions with immediate operand to shorter QImode
8327 ;; equivalents when possible.
8328 ;; Don't do the splitting with memory operands, since it introduces risk
8329 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8330 ;; for size, but that can (should?) be handled by generic code instead.
8331 (define_split
8332   [(set (match_operand 0 "register_operand" "")
8333         (and (match_operand 1 "register_operand" "")
8334              (match_operand 2 "const_int_operand" "")))
8335    (clobber (reg:CC FLAGS_REG))]
8336    "reload_completed
8337     && QI_REG_P (operands[0])
8338     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8339     && !(~INTVAL (operands[2]) & ~(255 << 8))
8340     && GET_MODE (operands[0]) != QImode"
8341   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8342                    (and:SI (zero_extract:SI (match_dup 1)
8343                                             (const_int 8) (const_int 8))
8344                            (match_dup 2)))
8345               (clobber (reg:CC FLAGS_REG))])]
8346   "operands[0] = gen_lowpart (SImode, operands[0]);
8347    operands[1] = gen_lowpart (SImode, operands[1]);
8348    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8350 ;; Since AND can be encoded with sign extended immediate, this is only
8351 ;; profitable when 7th bit is not set.
8352 (define_split
8353   [(set (match_operand 0 "register_operand" "")
8354         (and (match_operand 1 "general_operand" "")
8355              (match_operand 2 "const_int_operand" "")))
8356    (clobber (reg:CC FLAGS_REG))]
8357    "reload_completed
8358     && ANY_QI_REG_P (operands[0])
8359     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8360     && !(~INTVAL (operands[2]) & ~255)
8361     && !(INTVAL (operands[2]) & 128)
8362     && GET_MODE (operands[0]) != QImode"
8363   [(parallel [(set (strict_low_part (match_dup 0))
8364                    (and:QI (match_dup 1)
8365                            (match_dup 2)))
8366               (clobber (reg:CC FLAGS_REG))])]
8367   "operands[0] = gen_lowpart (QImode, operands[0]);
8368    operands[1] = gen_lowpart (QImode, operands[1]);
8369    operands[2] = gen_lowpart (QImode, operands[2]);")
8371 ;; Logical inclusive OR instructions
8373 ;; %%% This used to optimize known byte-wide and operations to memory.
8374 ;; If this is considered useful, it should be done with splitters.
8376 (define_expand "iordi3"
8377   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8378         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8379                 (match_operand:DI 2 "x86_64_general_operand" "")))
8380    (clobber (reg:CC FLAGS_REG))]
8381   "TARGET_64BIT"
8382   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8384 (define_insn "*iordi_1_rex64"
8385   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8386         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8387                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8388    (clobber (reg:CC FLAGS_REG))]
8389   "TARGET_64BIT
8390    && ix86_binary_operator_ok (IOR, DImode, operands)"
8391   "or{q}\t{%2, %0|%0, %2}"
8392   [(set_attr "type" "alu")
8393    (set_attr "mode" "DI")])
8395 (define_insn "*iordi_2_rex64"
8396   [(set (reg FLAGS_REG)
8397         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8398                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8399                  (const_int 0)))
8400    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8401         (ior:DI (match_dup 1) (match_dup 2)))]
8402   "TARGET_64BIT
8403    && ix86_match_ccmode (insn, CCNOmode)
8404    && ix86_binary_operator_ok (IOR, DImode, operands)"
8405   "or{q}\t{%2, %0|%0, %2}"
8406   [(set_attr "type" "alu")
8407    (set_attr "mode" "DI")])
8409 (define_insn "*iordi_3_rex64"
8410   [(set (reg FLAGS_REG)
8411         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8412                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8413                  (const_int 0)))
8414    (clobber (match_scratch:DI 0 "=r"))]
8415   "TARGET_64BIT
8416    && ix86_match_ccmode (insn, CCNOmode)
8417    && ix86_binary_operator_ok (IOR, DImode, operands)"
8418   "or{q}\t{%2, %0|%0, %2}"
8419   [(set_attr "type" "alu")
8420    (set_attr "mode" "DI")])
8423 (define_expand "iorsi3"
8424   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8425         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8426                 (match_operand:SI 2 "general_operand" "")))
8427    (clobber (reg:CC FLAGS_REG))]
8428   ""
8429   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8431 (define_insn "*iorsi_1"
8432   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8433         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8434                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8435    (clobber (reg:CC FLAGS_REG))]
8436   "ix86_binary_operator_ok (IOR, SImode, operands)"
8437   "or{l}\t{%2, %0|%0, %2}"
8438   [(set_attr "type" "alu")
8439    (set_attr "mode" "SI")])
8441 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8442 (define_insn "*iorsi_1_zext"
8443   [(set (match_operand:DI 0 "register_operand" "=rm")
8444         (zero_extend:DI
8445           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8446                   (match_operand:SI 2 "general_operand" "rim"))))
8447    (clobber (reg:CC FLAGS_REG))]
8448   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8449   "or{l}\t{%2, %k0|%k0, %2}"
8450   [(set_attr "type" "alu")
8451    (set_attr "mode" "SI")])
8453 (define_insn "*iorsi_1_zext_imm"
8454   [(set (match_operand:DI 0 "register_operand" "=rm")
8455         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8456                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8457    (clobber (reg:CC FLAGS_REG))]
8458   "TARGET_64BIT"
8459   "or{l}\t{%2, %k0|%k0, %2}"
8460   [(set_attr "type" "alu")
8461    (set_attr "mode" "SI")])
8463 (define_insn "*iorsi_2"
8464   [(set (reg FLAGS_REG)
8465         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8466                          (match_operand:SI 2 "general_operand" "rim,ri"))
8467                  (const_int 0)))
8468    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8469         (ior:SI (match_dup 1) (match_dup 2)))]
8470   "ix86_match_ccmode (insn, CCNOmode)
8471    && ix86_binary_operator_ok (IOR, SImode, operands)"
8472   "or{l}\t{%2, %0|%0, %2}"
8473   [(set_attr "type" "alu")
8474    (set_attr "mode" "SI")])
8476 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8477 ;; ??? Special case for immediate operand is missing - it is tricky.
8478 (define_insn "*iorsi_2_zext"
8479   [(set (reg FLAGS_REG)
8480         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8481                          (match_operand:SI 2 "general_operand" "rim"))
8482                  (const_int 0)))
8483    (set (match_operand:DI 0 "register_operand" "=r")
8484         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8485   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8486    && ix86_binary_operator_ok (IOR, SImode, operands)"
8487   "or{l}\t{%2, %k0|%k0, %2}"
8488   [(set_attr "type" "alu")
8489    (set_attr "mode" "SI")])
8491 (define_insn "*iorsi_2_zext_imm"
8492   [(set (reg FLAGS_REG)
8493         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8494                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8495                  (const_int 0)))
8496    (set (match_operand:DI 0 "register_operand" "=r")
8497         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8498   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8499    && ix86_binary_operator_ok (IOR, SImode, operands)"
8500   "or{l}\t{%2, %k0|%k0, %2}"
8501   [(set_attr "type" "alu")
8502    (set_attr "mode" "SI")])
8504 (define_insn "*iorsi_3"
8505   [(set (reg FLAGS_REG)
8506         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8507                          (match_operand:SI 2 "general_operand" "rim"))
8508                  (const_int 0)))
8509    (clobber (match_scratch:SI 0 "=r"))]
8510   "ix86_match_ccmode (insn, CCNOmode)
8511    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8512   "or{l}\t{%2, %0|%0, %2}"
8513   [(set_attr "type" "alu")
8514    (set_attr "mode" "SI")])
8516 (define_expand "iorhi3"
8517   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8518         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8519                 (match_operand:HI 2 "general_operand" "")))
8520    (clobber (reg:CC FLAGS_REG))]
8521   "TARGET_HIMODE_MATH"
8522   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8524 (define_insn "*iorhi_1"
8525   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8526         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8527                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8528    (clobber (reg:CC FLAGS_REG))]
8529   "ix86_binary_operator_ok (IOR, HImode, operands)"
8530   "or{w}\t{%2, %0|%0, %2}"
8531   [(set_attr "type" "alu")
8532    (set_attr "mode" "HI")])
8534 (define_insn "*iorhi_2"
8535   [(set (reg FLAGS_REG)
8536         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8537                          (match_operand:HI 2 "general_operand" "rim,ri"))
8538                  (const_int 0)))
8539    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8540         (ior:HI (match_dup 1) (match_dup 2)))]
8541   "ix86_match_ccmode (insn, CCNOmode)
8542    && ix86_binary_operator_ok (IOR, HImode, operands)"
8543   "or{w}\t{%2, %0|%0, %2}"
8544   [(set_attr "type" "alu")
8545    (set_attr "mode" "HI")])
8547 (define_insn "*iorhi_3"
8548   [(set (reg FLAGS_REG)
8549         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8550                          (match_operand:HI 2 "general_operand" "rim"))
8551                  (const_int 0)))
8552    (clobber (match_scratch:HI 0 "=r"))]
8553   "ix86_match_ccmode (insn, CCNOmode)
8554    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8555   "or{w}\t{%2, %0|%0, %2}"
8556   [(set_attr "type" "alu")
8557    (set_attr "mode" "HI")])
8559 (define_expand "iorqi3"
8560   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8561         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8562                 (match_operand:QI 2 "general_operand" "")))
8563    (clobber (reg:CC FLAGS_REG))]
8564   "TARGET_QIMODE_MATH"
8565   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8567 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8568 (define_insn "*iorqi_1"
8569   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8570         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8571                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8572    (clobber (reg:CC FLAGS_REG))]
8573   "ix86_binary_operator_ok (IOR, QImode, operands)"
8574   "@
8575    or{b}\t{%2, %0|%0, %2}
8576    or{b}\t{%2, %0|%0, %2}
8577    or{l}\t{%k2, %k0|%k0, %k2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "QI,QI,SI")])
8581 (define_insn "*iorqi_1_slp"
8582   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8583         (ior:QI (match_dup 0)
8584                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8585    (clobber (reg:CC FLAGS_REG))]
8586   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8587    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8588   "or{b}\t{%1, %0|%0, %1}"
8589   [(set_attr "type" "alu1")
8590    (set_attr "mode" "QI")])
8592 (define_insn "*iorqi_2"
8593   [(set (reg FLAGS_REG)
8594         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8595                          (match_operand:QI 2 "general_operand" "qim,qi"))
8596                  (const_int 0)))
8597    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8598         (ior:QI (match_dup 1) (match_dup 2)))]
8599   "ix86_match_ccmode (insn, CCNOmode)
8600    && ix86_binary_operator_ok (IOR, QImode, operands)"
8601   "or{b}\t{%2, %0|%0, %2}"
8602   [(set_attr "type" "alu")
8603    (set_attr "mode" "QI")])
8605 (define_insn "*iorqi_2_slp"
8606   [(set (reg FLAGS_REG)
8607         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8608                          (match_operand:QI 1 "general_operand" "qim,qi"))
8609                  (const_int 0)))
8610    (set (strict_low_part (match_dup 0))
8611         (ior:QI (match_dup 0) (match_dup 1)))]
8612   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8613    && ix86_match_ccmode (insn, CCNOmode)
8614    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8615   "or{b}\t{%1, %0|%0, %1}"
8616   [(set_attr "type" "alu1")
8617    (set_attr "mode" "QI")])
8619 (define_insn "*iorqi_3"
8620   [(set (reg FLAGS_REG)
8621         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8622                          (match_operand:QI 2 "general_operand" "qim"))
8623                  (const_int 0)))
8624    (clobber (match_scratch:QI 0 "=q"))]
8625   "ix86_match_ccmode (insn, CCNOmode)
8626    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8627   "or{b}\t{%2, %0|%0, %2}"
8628   [(set_attr "type" "alu")
8629    (set_attr "mode" "QI")])
8631 (define_insn "iorqi_ext_0"
8632   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8633                          (const_int 8)
8634                          (const_int 8))
8635         (ior:SI 
8636           (zero_extract:SI
8637             (match_operand 1 "ext_register_operand" "0")
8638             (const_int 8)
8639             (const_int 8))
8640           (match_operand 2 "const_int_operand" "n")))
8641    (clobber (reg:CC FLAGS_REG))]
8642   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8643   "or{b}\t{%2, %h0|%h0, %2}"
8644   [(set_attr "type" "alu")
8645    (set_attr "length_immediate" "1")
8646    (set_attr "mode" "QI")])
8648 (define_insn "*iorqi_ext_1"
8649   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8650                          (const_int 8)
8651                          (const_int 8))
8652         (ior:SI 
8653           (zero_extract:SI
8654             (match_operand 1 "ext_register_operand" "0")
8655             (const_int 8)
8656             (const_int 8))
8657           (zero_extend:SI
8658             (match_operand:QI 2 "general_operand" "Qm"))))
8659    (clobber (reg:CC FLAGS_REG))]
8660   "!TARGET_64BIT
8661    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8662   "or{b}\t{%2, %h0|%h0, %2}"
8663   [(set_attr "type" "alu")
8664    (set_attr "length_immediate" "0")
8665    (set_attr "mode" "QI")])
8667 (define_insn "*iorqi_ext_1_rex64"
8668   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8669                          (const_int 8)
8670                          (const_int 8))
8671         (ior:SI 
8672           (zero_extract:SI
8673             (match_operand 1 "ext_register_operand" "0")
8674             (const_int 8)
8675             (const_int 8))
8676           (zero_extend:SI
8677             (match_operand 2 "ext_register_operand" "Q"))))
8678    (clobber (reg:CC FLAGS_REG))]
8679   "TARGET_64BIT
8680    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8681   "or{b}\t{%2, %h0|%h0, %2}"
8682   [(set_attr "type" "alu")
8683    (set_attr "length_immediate" "0")
8684    (set_attr "mode" "QI")])
8686 (define_insn "*iorqi_ext_2"
8687   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8688                          (const_int 8)
8689                          (const_int 8))
8690         (ior:SI 
8691           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8692                            (const_int 8)
8693                            (const_int 8))
8694           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8695                            (const_int 8)
8696                            (const_int 8))))
8697    (clobber (reg:CC FLAGS_REG))]
8698   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8699   "ior{b}\t{%h2, %h0|%h0, %h2}"
8700   [(set_attr "type" "alu")
8701    (set_attr "length_immediate" "0")
8702    (set_attr "mode" "QI")])
8704 (define_split
8705   [(set (match_operand 0 "register_operand" "")
8706         (ior (match_operand 1 "register_operand" "")
8707              (match_operand 2 "const_int_operand" "")))
8708    (clobber (reg:CC FLAGS_REG))]
8709    "reload_completed
8710     && QI_REG_P (operands[0])
8711     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8712     && !(INTVAL (operands[2]) & ~(255 << 8))
8713     && GET_MODE (operands[0]) != QImode"
8714   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8715                    (ior:SI (zero_extract:SI (match_dup 1)
8716                                             (const_int 8) (const_int 8))
8717                            (match_dup 2)))
8718               (clobber (reg:CC FLAGS_REG))])]
8719   "operands[0] = gen_lowpart (SImode, operands[0]);
8720    operands[1] = gen_lowpart (SImode, operands[1]);
8721    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8723 ;; Since OR can be encoded with sign extended immediate, this is only
8724 ;; profitable when 7th bit is set.
8725 (define_split
8726   [(set (match_operand 0 "register_operand" "")
8727         (ior (match_operand 1 "general_operand" "")
8728              (match_operand 2 "const_int_operand" "")))
8729    (clobber (reg:CC FLAGS_REG))]
8730    "reload_completed
8731     && ANY_QI_REG_P (operands[0])
8732     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8733     && !(INTVAL (operands[2]) & ~255)
8734     && (INTVAL (operands[2]) & 128)
8735     && GET_MODE (operands[0]) != QImode"
8736   [(parallel [(set (strict_low_part (match_dup 0))
8737                    (ior:QI (match_dup 1)
8738                            (match_dup 2)))
8739               (clobber (reg:CC FLAGS_REG))])]
8740   "operands[0] = gen_lowpart (QImode, operands[0]);
8741    operands[1] = gen_lowpart (QImode, operands[1]);
8742    operands[2] = gen_lowpart (QImode, operands[2]);")
8744 ;; Logical XOR instructions
8746 ;; %%% This used to optimize known byte-wide and operations to memory.
8747 ;; If this is considered useful, it should be done with splitters.
8749 (define_expand "xordi3"
8750   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8751         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8752                 (match_operand:DI 2 "x86_64_general_operand" "")))
8753    (clobber (reg:CC FLAGS_REG))]
8754   "TARGET_64BIT"
8755   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8757 (define_insn "*xordi_1_rex64"
8758   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8759         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8760                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8761    (clobber (reg:CC FLAGS_REG))]
8762   "TARGET_64BIT
8763    && ix86_binary_operator_ok (XOR, DImode, operands)"
8764   "@
8765    xor{q}\t{%2, %0|%0, %2}
8766    xor{q}\t{%2, %0|%0, %2}"
8767   [(set_attr "type" "alu")
8768    (set_attr "mode" "DI,DI")])
8770 (define_insn "*xordi_2_rex64"
8771   [(set (reg FLAGS_REG)
8772         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8773                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8774                  (const_int 0)))
8775    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8776         (xor:DI (match_dup 1) (match_dup 2)))]
8777   "TARGET_64BIT
8778    && ix86_match_ccmode (insn, CCNOmode)
8779    && ix86_binary_operator_ok (XOR, DImode, operands)"
8780   "@
8781    xor{q}\t{%2, %0|%0, %2}
8782    xor{q}\t{%2, %0|%0, %2}"
8783   [(set_attr "type" "alu")
8784    (set_attr "mode" "DI,DI")])
8786 (define_insn "*xordi_3_rex64"
8787   [(set (reg FLAGS_REG)
8788         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8789                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8790                  (const_int 0)))
8791    (clobber (match_scratch:DI 0 "=r"))]
8792   "TARGET_64BIT
8793    && ix86_match_ccmode (insn, CCNOmode)
8794    && ix86_binary_operator_ok (XOR, DImode, operands)"
8795   "xor{q}\t{%2, %0|%0, %2}"
8796   [(set_attr "type" "alu")
8797    (set_attr "mode" "DI")])
8799 (define_expand "xorsi3"
8800   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8801         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8802                 (match_operand:SI 2 "general_operand" "")))
8803    (clobber (reg:CC FLAGS_REG))]
8804   ""
8805   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8807 (define_insn "*xorsi_1"
8808   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8809         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8810                 (match_operand:SI 2 "general_operand" "ri,rm")))
8811    (clobber (reg:CC FLAGS_REG))]
8812   "ix86_binary_operator_ok (XOR, SImode, operands)"
8813   "xor{l}\t{%2, %0|%0, %2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "mode" "SI")])
8817 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8818 ;; Add speccase for immediates
8819 (define_insn "*xorsi_1_zext"
8820   [(set (match_operand:DI 0 "register_operand" "=r")
8821         (zero_extend:DI
8822           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8823                   (match_operand:SI 2 "general_operand" "rim"))))
8824    (clobber (reg:CC FLAGS_REG))]
8825   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8826   "xor{l}\t{%2, %k0|%k0, %2}"
8827   [(set_attr "type" "alu")
8828    (set_attr "mode" "SI")])
8830 (define_insn "*xorsi_1_zext_imm"
8831   [(set (match_operand:DI 0 "register_operand" "=r")
8832         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8833                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8834    (clobber (reg:CC FLAGS_REG))]
8835   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8836   "xor{l}\t{%2, %k0|%k0, %2}"
8837   [(set_attr "type" "alu")
8838    (set_attr "mode" "SI")])
8840 (define_insn "*xorsi_2"
8841   [(set (reg FLAGS_REG)
8842         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8843                          (match_operand:SI 2 "general_operand" "rim,ri"))
8844                  (const_int 0)))
8845    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8846         (xor:SI (match_dup 1) (match_dup 2)))]
8847   "ix86_match_ccmode (insn, CCNOmode)
8848    && ix86_binary_operator_ok (XOR, SImode, operands)"
8849   "xor{l}\t{%2, %0|%0, %2}"
8850   [(set_attr "type" "alu")
8851    (set_attr "mode" "SI")])
8853 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8854 ;; ??? Special case for immediate operand is missing - it is tricky.
8855 (define_insn "*xorsi_2_zext"
8856   [(set (reg FLAGS_REG)
8857         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8858                          (match_operand:SI 2 "general_operand" "rim"))
8859                  (const_int 0)))
8860    (set (match_operand:DI 0 "register_operand" "=r")
8861         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8862   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8863    && ix86_binary_operator_ok (XOR, SImode, operands)"
8864   "xor{l}\t{%2, %k0|%k0, %2}"
8865   [(set_attr "type" "alu")
8866    (set_attr "mode" "SI")])
8868 (define_insn "*xorsi_2_zext_imm"
8869   [(set (reg FLAGS_REG)
8870         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8871                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8872                  (const_int 0)))
8873    (set (match_operand:DI 0 "register_operand" "=r")
8874         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8875   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8876    && ix86_binary_operator_ok (XOR, SImode, operands)"
8877   "xor{l}\t{%2, %k0|%k0, %2}"
8878   [(set_attr "type" "alu")
8879    (set_attr "mode" "SI")])
8881 (define_insn "*xorsi_3"
8882   [(set (reg FLAGS_REG)
8883         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8884                          (match_operand:SI 2 "general_operand" "rim"))
8885                  (const_int 0)))
8886    (clobber (match_scratch:SI 0 "=r"))]
8887   "ix86_match_ccmode (insn, CCNOmode)
8888    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8889   "xor{l}\t{%2, %0|%0, %2}"
8890   [(set_attr "type" "alu")
8891    (set_attr "mode" "SI")])
8893 (define_expand "xorhi3"
8894   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8895         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8896                 (match_operand:HI 2 "general_operand" "")))
8897    (clobber (reg:CC FLAGS_REG))]
8898   "TARGET_HIMODE_MATH"
8899   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8901 (define_insn "*xorhi_1"
8902   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8903         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8904                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8905    (clobber (reg:CC FLAGS_REG))]
8906   "ix86_binary_operator_ok (XOR, HImode, operands)"
8907   "xor{w}\t{%2, %0|%0, %2}"
8908   [(set_attr "type" "alu")
8909    (set_attr "mode" "HI")])
8911 (define_insn "*xorhi_2"
8912   [(set (reg FLAGS_REG)
8913         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8914                          (match_operand:HI 2 "general_operand" "rim,ri"))
8915                  (const_int 0)))
8916    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8917         (xor:HI (match_dup 1) (match_dup 2)))]
8918   "ix86_match_ccmode (insn, CCNOmode)
8919    && ix86_binary_operator_ok (XOR, HImode, operands)"
8920   "xor{w}\t{%2, %0|%0, %2}"
8921   [(set_attr "type" "alu")
8922    (set_attr "mode" "HI")])
8924 (define_insn "*xorhi_3"
8925   [(set (reg FLAGS_REG)
8926         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8927                          (match_operand:HI 2 "general_operand" "rim"))
8928                  (const_int 0)))
8929    (clobber (match_scratch:HI 0 "=r"))]
8930   "ix86_match_ccmode (insn, CCNOmode)
8931    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8932   "xor{w}\t{%2, %0|%0, %2}"
8933   [(set_attr "type" "alu")
8934    (set_attr "mode" "HI")])
8936 (define_expand "xorqi3"
8937   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8938         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8939                 (match_operand:QI 2 "general_operand" "")))
8940    (clobber (reg:CC FLAGS_REG))]
8941   "TARGET_QIMODE_MATH"
8942   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8944 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8945 (define_insn "*xorqi_1"
8946   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8947         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8948                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8949    (clobber (reg:CC FLAGS_REG))]
8950   "ix86_binary_operator_ok (XOR, QImode, operands)"
8951   "@
8952    xor{b}\t{%2, %0|%0, %2}
8953    xor{b}\t{%2, %0|%0, %2}
8954    xor{l}\t{%k2, %k0|%k0, %k2}"
8955   [(set_attr "type" "alu")
8956    (set_attr "mode" "QI,QI,SI")])
8958 (define_insn "*xorqi_1_slp"
8959   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8960         (xor:QI (match_dup 0)
8961                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8962    (clobber (reg:CC FLAGS_REG))]
8963   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8964    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8965   "xor{b}\t{%1, %0|%0, %1}"
8966   [(set_attr "type" "alu1")
8967    (set_attr "mode" "QI")])
8969 (define_insn "xorqi_ext_0"
8970   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8971                          (const_int 8)
8972                          (const_int 8))
8973         (xor:SI 
8974           (zero_extract:SI
8975             (match_operand 1 "ext_register_operand" "0")
8976             (const_int 8)
8977             (const_int 8))
8978           (match_operand 2 "const_int_operand" "n")))
8979    (clobber (reg:CC FLAGS_REG))]
8980   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8981   "xor{b}\t{%2, %h0|%h0, %2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "length_immediate" "1")
8984    (set_attr "mode" "QI")])
8986 (define_insn "*xorqi_ext_1"
8987   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8988                          (const_int 8)
8989                          (const_int 8))
8990         (xor:SI 
8991           (zero_extract:SI
8992             (match_operand 1 "ext_register_operand" "0")
8993             (const_int 8)
8994             (const_int 8))
8995           (zero_extend:SI
8996             (match_operand:QI 2 "general_operand" "Qm"))))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "!TARGET_64BIT
8999    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9000   "xor{b}\t{%2, %h0|%h0, %2}"
9001   [(set_attr "type" "alu")
9002    (set_attr "length_immediate" "0")
9003    (set_attr "mode" "QI")])
9005 (define_insn "*xorqi_ext_1_rex64"
9006   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9007                          (const_int 8)
9008                          (const_int 8))
9009         (xor:SI 
9010           (zero_extract:SI
9011             (match_operand 1 "ext_register_operand" "0")
9012             (const_int 8)
9013             (const_int 8))
9014           (zero_extend:SI
9015             (match_operand 2 "ext_register_operand" "Q"))))
9016    (clobber (reg:CC FLAGS_REG))]
9017   "TARGET_64BIT
9018    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9019   "xor{b}\t{%2, %h0|%h0, %2}"
9020   [(set_attr "type" "alu")
9021    (set_attr "length_immediate" "0")
9022    (set_attr "mode" "QI")])
9024 (define_insn "*xorqi_ext_2"
9025   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9026                          (const_int 8)
9027                          (const_int 8))
9028         (xor:SI 
9029           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9030                            (const_int 8)
9031                            (const_int 8))
9032           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9033                            (const_int 8)
9034                            (const_int 8))))
9035    (clobber (reg:CC FLAGS_REG))]
9036   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9037   "xor{b}\t{%h2, %h0|%h0, %h2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "length_immediate" "0")
9040    (set_attr "mode" "QI")])
9042 (define_insn "*xorqi_cc_1"
9043   [(set (reg FLAGS_REG)
9044         (compare
9045           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9046                   (match_operand:QI 2 "general_operand" "qim,qi"))
9047           (const_int 0)))
9048    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9049         (xor:QI (match_dup 1) (match_dup 2)))]
9050   "ix86_match_ccmode (insn, CCNOmode)
9051    && ix86_binary_operator_ok (XOR, QImode, operands)"
9052   "xor{b}\t{%2, %0|%0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "QI")])
9056 (define_insn "*xorqi_2_slp"
9057   [(set (reg FLAGS_REG)
9058         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9059                          (match_operand:QI 1 "general_operand" "qim,qi"))
9060                  (const_int 0)))
9061    (set (strict_low_part (match_dup 0))
9062         (xor:QI (match_dup 0) (match_dup 1)))]
9063   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9064    && ix86_match_ccmode (insn, CCNOmode)
9065    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9066   "xor{b}\t{%1, %0|%0, %1}"
9067   [(set_attr "type" "alu1")
9068    (set_attr "mode" "QI")])
9070 (define_insn "*xorqi_cc_2"
9071   [(set (reg FLAGS_REG)
9072         (compare
9073           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9074                   (match_operand:QI 2 "general_operand" "qim"))
9075           (const_int 0)))
9076    (clobber (match_scratch:QI 0 "=q"))]
9077   "ix86_match_ccmode (insn, CCNOmode)
9078    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9079   "xor{b}\t{%2, %0|%0, %2}"
9080   [(set_attr "type" "alu")
9081    (set_attr "mode" "QI")])
9083 (define_insn "*xorqi_cc_ext_1"
9084   [(set (reg FLAGS_REG)
9085         (compare
9086           (xor:SI
9087             (zero_extract:SI
9088               (match_operand 1 "ext_register_operand" "0")
9089               (const_int 8)
9090               (const_int 8))
9091             (match_operand:QI 2 "general_operand" "qmn"))
9092           (const_int 0)))
9093    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9094                          (const_int 8)
9095                          (const_int 8))
9096         (xor:SI 
9097           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9098           (match_dup 2)))]
9099   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9100   "xor{b}\t{%2, %h0|%h0, %2}"
9101   [(set_attr "type" "alu")
9102    (set_attr "mode" "QI")])
9104 (define_insn "*xorqi_cc_ext_1_rex64"
9105   [(set (reg FLAGS_REG)
9106         (compare
9107           (xor:SI
9108             (zero_extract:SI
9109               (match_operand 1 "ext_register_operand" "0")
9110               (const_int 8)
9111               (const_int 8))
9112             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9113           (const_int 0)))
9114    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9115                          (const_int 8)
9116                          (const_int 8))
9117         (xor:SI 
9118           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9119           (match_dup 2)))]
9120   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9121   "xor{b}\t{%2, %h0|%h0, %2}"
9122   [(set_attr "type" "alu")
9123    (set_attr "mode" "QI")])
9125 (define_expand "xorqi_cc_ext_1"
9126   [(parallel [
9127      (set (reg:CCNO FLAGS_REG)
9128           (compare:CCNO
9129             (xor:SI
9130               (zero_extract:SI
9131                 (match_operand 1 "ext_register_operand" "")
9132                 (const_int 8)
9133                 (const_int 8))
9134               (match_operand:QI 2 "general_operand" ""))
9135             (const_int 0)))
9136      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9137                            (const_int 8)
9138                            (const_int 8))
9139           (xor:SI 
9140             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9141             (match_dup 2)))])]
9142   ""
9143   "")
9145 (define_split
9146   [(set (match_operand 0 "register_operand" "")
9147         (xor (match_operand 1 "register_operand" "")
9148              (match_operand 2 "const_int_operand" "")))
9149    (clobber (reg:CC FLAGS_REG))]
9150    "reload_completed
9151     && QI_REG_P (operands[0])
9152     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9153     && !(INTVAL (operands[2]) & ~(255 << 8))
9154     && GET_MODE (operands[0]) != QImode"
9155   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9156                    (xor:SI (zero_extract:SI (match_dup 1)
9157                                             (const_int 8) (const_int 8))
9158                            (match_dup 2)))
9159               (clobber (reg:CC FLAGS_REG))])]
9160   "operands[0] = gen_lowpart (SImode, operands[0]);
9161    operands[1] = gen_lowpart (SImode, operands[1]);
9162    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9164 ;; Since XOR can be encoded with sign extended immediate, this is only
9165 ;; profitable when 7th bit is set.
9166 (define_split
9167   [(set (match_operand 0 "register_operand" "")
9168         (xor (match_operand 1 "general_operand" "")
9169              (match_operand 2 "const_int_operand" "")))
9170    (clobber (reg:CC FLAGS_REG))]
9171    "reload_completed
9172     && ANY_QI_REG_P (operands[0])
9173     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9174     && !(INTVAL (operands[2]) & ~255)
9175     && (INTVAL (operands[2]) & 128)
9176     && GET_MODE (operands[0]) != QImode"
9177   [(parallel [(set (strict_low_part (match_dup 0))
9178                    (xor:QI (match_dup 1)
9179                            (match_dup 2)))
9180               (clobber (reg:CC FLAGS_REG))])]
9181   "operands[0] = gen_lowpart (QImode, operands[0]);
9182    operands[1] = gen_lowpart (QImode, operands[1]);
9183    operands[2] = gen_lowpart (QImode, operands[2]);")
9185 ;; Negation instructions
9187 (define_expand "negdi2"
9188   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9189                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9190               (clobber (reg:CC FLAGS_REG))])]
9191   ""
9192   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9194 (define_insn "*negdi2_1"
9195   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9196         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9197    (clobber (reg:CC FLAGS_REG))]
9198   "!TARGET_64BIT
9199    && ix86_unary_operator_ok (NEG, DImode, operands)"
9200   "#")
9202 (define_split
9203   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9204         (neg:DI (match_operand:DI 1 "general_operand" "")))
9205    (clobber (reg:CC FLAGS_REG))]
9206   "!TARGET_64BIT && reload_completed"
9207   [(parallel
9208     [(set (reg:CCZ FLAGS_REG)
9209           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9210      (set (match_dup 0) (neg:SI (match_dup 2)))])
9211    (parallel
9212     [(set (match_dup 1)
9213           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9214                             (match_dup 3))
9215                    (const_int 0)))
9216      (clobber (reg:CC FLAGS_REG))])
9217    (parallel
9218     [(set (match_dup 1)
9219           (neg:SI (match_dup 1)))
9220      (clobber (reg:CC FLAGS_REG))])]
9221   "split_di (operands+1, 1, operands+2, operands+3);
9222    split_di (operands+0, 1, operands+0, operands+1);")
9224 (define_insn "*negdi2_1_rex64"
9225   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9226         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9227    (clobber (reg:CC FLAGS_REG))]
9228   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9229   "neg{q}\t%0"
9230   [(set_attr "type" "negnot")
9231    (set_attr "mode" "DI")])
9233 ;; The problem with neg is that it does not perform (compare x 0),
9234 ;; it really performs (compare 0 x), which leaves us with the zero
9235 ;; flag being the only useful item.
9237 (define_insn "*negdi2_cmpz_rex64"
9238   [(set (reg:CCZ FLAGS_REG)
9239         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9240                      (const_int 0)))
9241    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9242         (neg:DI (match_dup 1)))]
9243   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9244   "neg{q}\t%0"
9245   [(set_attr "type" "negnot")
9246    (set_attr "mode" "DI")])
9249 (define_expand "negsi2"
9250   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9251                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9252               (clobber (reg:CC FLAGS_REG))])]
9253   ""
9254   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9256 (define_insn "*negsi2_1"
9257   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9258         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9259    (clobber (reg:CC FLAGS_REG))]
9260   "ix86_unary_operator_ok (NEG, SImode, operands)"
9261   "neg{l}\t%0"
9262   [(set_attr "type" "negnot")
9263    (set_attr "mode" "SI")])
9265 ;; Combine is quite creative about this pattern.
9266 (define_insn "*negsi2_1_zext"
9267   [(set (match_operand:DI 0 "register_operand" "=r")
9268         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9269                                         (const_int 32)))
9270                      (const_int 32)))
9271    (clobber (reg:CC FLAGS_REG))]
9272   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9273   "neg{l}\t%k0"
9274   [(set_attr "type" "negnot")
9275    (set_attr "mode" "SI")])
9277 ;; The problem with neg is that it does not perform (compare x 0),
9278 ;; it really performs (compare 0 x), which leaves us with the zero
9279 ;; flag being the only useful item.
9281 (define_insn "*negsi2_cmpz"
9282   [(set (reg:CCZ FLAGS_REG)
9283         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9284                      (const_int 0)))
9285    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9286         (neg:SI (match_dup 1)))]
9287   "ix86_unary_operator_ok (NEG, SImode, operands)"
9288   "neg{l}\t%0"
9289   [(set_attr "type" "negnot")
9290    (set_attr "mode" "SI")])
9292 (define_insn "*negsi2_cmpz_zext"
9293   [(set (reg:CCZ FLAGS_REG)
9294         (compare:CCZ (lshiftrt:DI
9295                        (neg:DI (ashift:DI
9296                                  (match_operand:DI 1 "register_operand" "0")
9297                                  (const_int 32)))
9298                        (const_int 32))
9299                      (const_int 0)))
9300    (set (match_operand:DI 0 "register_operand" "=r")
9301         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9302                                         (const_int 32)))
9303                      (const_int 32)))]
9304   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9305   "neg{l}\t%k0"
9306   [(set_attr "type" "negnot")
9307    (set_attr "mode" "SI")])
9309 (define_expand "neghi2"
9310   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9311                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9312               (clobber (reg:CC FLAGS_REG))])]
9313   "TARGET_HIMODE_MATH"
9314   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9316 (define_insn "*neghi2_1"
9317   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9318         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9319    (clobber (reg:CC FLAGS_REG))]
9320   "ix86_unary_operator_ok (NEG, HImode, operands)"
9321   "neg{w}\t%0"
9322   [(set_attr "type" "negnot")
9323    (set_attr "mode" "HI")])
9325 (define_insn "*neghi2_cmpz"
9326   [(set (reg:CCZ FLAGS_REG)
9327         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9328                      (const_int 0)))
9329    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9330         (neg:HI (match_dup 1)))]
9331   "ix86_unary_operator_ok (NEG, HImode, operands)"
9332   "neg{w}\t%0"
9333   [(set_attr "type" "negnot")
9334    (set_attr "mode" "HI")])
9336 (define_expand "negqi2"
9337   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9338                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9339               (clobber (reg:CC FLAGS_REG))])]
9340   "TARGET_QIMODE_MATH"
9341   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9343 (define_insn "*negqi2_1"
9344   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9345         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9346    (clobber (reg:CC FLAGS_REG))]
9347   "ix86_unary_operator_ok (NEG, QImode, operands)"
9348   "neg{b}\t%0"
9349   [(set_attr "type" "negnot")
9350    (set_attr "mode" "QI")])
9352 (define_insn "*negqi2_cmpz"
9353   [(set (reg:CCZ FLAGS_REG)
9354         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9355                      (const_int 0)))
9356    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9357         (neg:QI (match_dup 1)))]
9358   "ix86_unary_operator_ok (NEG, QImode, operands)"
9359   "neg{b}\t%0"
9360   [(set_attr "type" "negnot")
9361    (set_attr "mode" "QI")])
9363 ;; Changing of sign for FP values is doable using integer unit too.
9365 (define_expand "negsf2"
9366   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9367         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9368   "TARGET_80387 || TARGET_SSE_MATH"
9369   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9371 (define_expand "abssf2"
9372   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9373         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9374   "TARGET_80387 || TARGET_SSE_MATH"
9375   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9377 (define_insn "*absnegsf2_mixed"
9378   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9379         (match_operator:SF 3 "absneg_operator"
9380           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9381    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9382    (clobber (reg:CC FLAGS_REG))]
9383   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9384    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9385   "#")
9387 (define_insn "*absnegsf2_sse"
9388   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9389         (match_operator:SF 3 "absneg_operator"
9390           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9391    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9392    (clobber (reg:CC FLAGS_REG))]
9393   "TARGET_SSE_MATH
9394    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9395   "#")
9397 (define_insn "*absnegsf2_i387"
9398   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9399         (match_operator:SF 3 "absneg_operator"
9400           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9401    (use (match_operand 2 "" ""))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "TARGET_80387 && !TARGET_SSE_MATH
9404    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9405   "#")
9407 (define_expand "copysignsf3"
9408   [(match_operand:SF 0 "register_operand" "")
9409    (match_operand:SF 1 "nonmemory_operand" "")
9410    (match_operand:SF 2 "register_operand" "")]
9411   "TARGET_SSE_MATH"
9413   ix86_expand_copysign (operands);
9414   DONE;
9417 (define_insn_and_split "copysignsf3_const"
9418   [(set (match_operand:SF 0 "register_operand"          "=x")
9419         (unspec:SF
9420           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9421            (match_operand:SF 2 "register_operand"       "0")
9422            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9423           UNSPEC_COPYSIGN))]
9424   "TARGET_SSE_MATH"
9425   "#"
9426   "&& reload_completed"
9427   [(const_int 0)]
9429   ix86_split_copysign_const (operands);
9430   DONE;
9433 (define_insn "copysignsf3_var"
9434   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9435         (unspec:SF
9436           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9437            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9438            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9439            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9440           UNSPEC_COPYSIGN))
9441    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9442   "TARGET_SSE_MATH"
9443   "#")
9445 (define_split
9446   [(set (match_operand:SF 0 "register_operand" "")
9447         (unspec:SF
9448           [(match_operand:SF 2 "register_operand" "")
9449            (match_operand:SF 3 "register_operand" "")
9450            (match_operand:V4SF 4 "" "")
9451            (match_operand:V4SF 5 "" "")]
9452           UNSPEC_COPYSIGN))
9453    (clobber (match_scratch:V4SF 1 ""))]
9454   "TARGET_SSE_MATH && reload_completed"
9455   [(const_int 0)]
9457   ix86_split_copysign_var (operands);
9458   DONE;
9461 (define_expand "negdf2"
9462   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9463         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9464   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9465   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9467 (define_expand "absdf2"
9468   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9469         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9470   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9471   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9473 (define_insn "*absnegdf2_mixed"
9474   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9475         (match_operator:DF 3 "absneg_operator"
9476           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9477    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9478    (clobber (reg:CC FLAGS_REG))]
9479   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9480    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9481   "#")
9483 (define_insn "*absnegdf2_sse"
9484   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9485         (match_operator:DF 3 "absneg_operator"
9486           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9487    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9488    (clobber (reg:CC FLAGS_REG))]
9489   "TARGET_SSE2 && TARGET_SSE_MATH
9490    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9491   "#")
9493 (define_insn "*absnegdf2_i387"
9494   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9495         (match_operator:DF 3 "absneg_operator"
9496           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9497    (use (match_operand 2 "" ""))
9498    (clobber (reg:CC FLAGS_REG))]
9499   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9500    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9501   "#")
9503 (define_expand "copysigndf3"
9504   [(match_operand:DF 0 "register_operand" "")
9505    (match_operand:DF 1 "nonmemory_operand" "")
9506    (match_operand:DF 2 "register_operand" "")]
9507   "TARGET_SSE2 && TARGET_SSE_MATH"
9509   ix86_expand_copysign (operands);
9510   DONE;
9513 (define_insn_and_split "copysigndf3_const"
9514   [(set (match_operand:DF 0 "register_operand"          "=x")
9515         (unspec:DF
9516           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9517            (match_operand:DF 2 "register_operand"       "0")
9518            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9519           UNSPEC_COPYSIGN))]
9520   "TARGET_SSE2 && TARGET_SSE_MATH"
9521   "#"
9522   "&& reload_completed"
9523   [(const_int 0)]
9525   ix86_split_copysign_const (operands);
9526   DONE;
9529 (define_insn "copysigndf3_var"
9530   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9531         (unspec:DF
9532           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9533            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9534            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9535            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9536           UNSPEC_COPYSIGN))
9537    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9538   "TARGET_SSE2 && TARGET_SSE_MATH"
9539   "#")
9541 (define_split
9542   [(set (match_operand:DF 0 "register_operand" "")
9543         (unspec:DF
9544           [(match_operand:DF 2 "register_operand" "")
9545            (match_operand:DF 3 "register_operand" "")
9546            (match_operand:V2DF 4 "" "")
9547            (match_operand:V2DF 5 "" "")]
9548           UNSPEC_COPYSIGN))
9549    (clobber (match_scratch:V2DF 1 ""))]
9550   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9551   [(const_int 0)]
9553   ix86_split_copysign_var (operands);
9554   DONE;
9557 (define_expand "negxf2"
9558   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9559         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9560   "TARGET_80387"
9561   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9563 (define_expand "absxf2"
9564   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9565         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9566   "TARGET_80387"
9567   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9569 (define_insn "*absnegxf2_i387"
9570   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9571         (match_operator:XF 3 "absneg_operator"
9572           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9573    (use (match_operand 2 "" ""))
9574    (clobber (reg:CC FLAGS_REG))]
9575   "TARGET_80387
9576    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9577   "#")
9579 ;; Splitters for fp abs and neg.
9581 (define_split
9582   [(set (match_operand 0 "fp_register_operand" "")
9583         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9584    (use (match_operand 2 "" ""))
9585    (clobber (reg:CC FLAGS_REG))]
9586   "reload_completed"
9587   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9589 (define_split
9590   [(set (match_operand 0 "register_operand" "")
9591         (match_operator 3 "absneg_operator"
9592           [(match_operand 1 "register_operand" "")]))
9593    (use (match_operand 2 "nonimmediate_operand" ""))
9594    (clobber (reg:CC FLAGS_REG))]
9595   "reload_completed && SSE_REG_P (operands[0])"
9596   [(set (match_dup 0) (match_dup 3))]
9598   enum machine_mode mode = GET_MODE (operands[0]);
9599   enum machine_mode vmode = GET_MODE (operands[2]);
9600   rtx tmp;
9601   
9602   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9603   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9604   if (operands_match_p (operands[0], operands[2]))
9605     {
9606       tmp = operands[1];
9607       operands[1] = operands[2];
9608       operands[2] = tmp;
9609     }
9610   if (GET_CODE (operands[3]) == ABS)
9611     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9612   else
9613     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9614   operands[3] = tmp;
9617 (define_split
9618   [(set (match_operand:SF 0 "register_operand" "")
9619         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9620    (use (match_operand:V4SF 2 "" ""))
9621    (clobber (reg:CC FLAGS_REG))]
9622   "reload_completed"
9623   [(parallel [(set (match_dup 0) (match_dup 1))
9624               (clobber (reg:CC FLAGS_REG))])]
9626   rtx tmp;
9627   operands[0] = gen_lowpart (SImode, operands[0]);
9628   if (GET_CODE (operands[1]) == ABS)
9629     {
9630       tmp = gen_int_mode (0x7fffffff, SImode);
9631       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9632     }
9633   else
9634     {
9635       tmp = gen_int_mode (0x80000000, SImode);
9636       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9637     }
9638   operands[1] = tmp;
9641 (define_split
9642   [(set (match_operand:DF 0 "register_operand" "")
9643         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9644    (use (match_operand 2 "" ""))
9645    (clobber (reg:CC FLAGS_REG))]
9646   "reload_completed"
9647   [(parallel [(set (match_dup 0) (match_dup 1))
9648               (clobber (reg:CC FLAGS_REG))])]
9650   rtx tmp;
9651   if (TARGET_64BIT)
9652     {
9653       tmp = gen_lowpart (DImode, operands[0]);
9654       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9655       operands[0] = tmp;
9657       if (GET_CODE (operands[1]) == ABS)
9658         tmp = const0_rtx;
9659       else
9660         tmp = gen_rtx_NOT (DImode, tmp);
9661     }
9662   else
9663     {
9664       operands[0] = gen_highpart (SImode, operands[0]);
9665       if (GET_CODE (operands[1]) == ABS)
9666         {
9667           tmp = gen_int_mode (0x7fffffff, SImode);
9668           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9669         }
9670       else
9671         {
9672           tmp = gen_int_mode (0x80000000, SImode);
9673           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9674         }
9675     }
9676   operands[1] = tmp;
9679 (define_split
9680   [(set (match_operand:XF 0 "register_operand" "")
9681         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9682    (use (match_operand 2 "" ""))
9683    (clobber (reg:CC FLAGS_REG))]
9684   "reload_completed"
9685   [(parallel [(set (match_dup 0) (match_dup 1))
9686               (clobber (reg:CC FLAGS_REG))])]
9688   rtx tmp;
9689   operands[0] = gen_rtx_REG (SImode,
9690                              true_regnum (operands[0])
9691                              + (TARGET_64BIT ? 1 : 2));
9692   if (GET_CODE (operands[1]) == ABS)
9693     {
9694       tmp = GEN_INT (0x7fff);
9695       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9696     }
9697   else
9698     {
9699       tmp = GEN_INT (0x8000);
9700       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9701     }
9702   operands[1] = tmp;
9705 (define_split
9706   [(set (match_operand 0 "memory_operand" "")
9707         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9708    (use (match_operand 2 "" ""))
9709    (clobber (reg:CC FLAGS_REG))]
9710   "reload_completed"
9711   [(parallel [(set (match_dup 0) (match_dup 1))
9712               (clobber (reg:CC FLAGS_REG))])]
9714   enum machine_mode mode = GET_MODE (operands[0]);
9715   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9716   rtx tmp;
9718   operands[0] = adjust_address (operands[0], QImode, size - 1);
9719   if (GET_CODE (operands[1]) == ABS)
9720     {
9721       tmp = gen_int_mode (0x7f, QImode);
9722       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9723     }
9724   else
9725     {
9726       tmp = gen_int_mode (0x80, QImode);
9727       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9728     }
9729   operands[1] = tmp;
9732 ;; Conditionalize these after reload. If they match before reload, we 
9733 ;; lose the clobber and ability to use integer instructions.
9735 (define_insn "*negsf2_1"
9736   [(set (match_operand:SF 0 "register_operand" "=f")
9737         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9738   "TARGET_80387 && reload_completed"
9739   "fchs"
9740   [(set_attr "type" "fsgn")
9741    (set_attr "mode" "SF")])
9743 (define_insn "*negdf2_1"
9744   [(set (match_operand:DF 0 "register_operand" "=f")
9745         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9746   "TARGET_80387 && reload_completed"
9747   "fchs"
9748   [(set_attr "type" "fsgn")
9749    (set_attr "mode" "DF")])
9751 (define_insn "*negxf2_1"
9752   [(set (match_operand:XF 0 "register_operand" "=f")
9753         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9754   "TARGET_80387 && reload_completed"
9755   "fchs"
9756   [(set_attr "type" "fsgn")
9757    (set_attr "mode" "XF")])
9759 (define_insn "*abssf2_1"
9760   [(set (match_operand:SF 0 "register_operand" "=f")
9761         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9762   "TARGET_80387 && reload_completed"
9763   "fabs"
9764   [(set_attr "type" "fsgn")
9765    (set_attr "mode" "SF")])
9767 (define_insn "*absdf2_1"
9768   [(set (match_operand:DF 0 "register_operand" "=f")
9769         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9770   "TARGET_80387 && reload_completed"
9771   "fabs"
9772   [(set_attr "type" "fsgn")
9773    (set_attr "mode" "DF")])
9775 (define_insn "*absxf2_1"
9776   [(set (match_operand:XF 0 "register_operand" "=f")
9777         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9778   "TARGET_80387 && reload_completed"
9779   "fabs"
9780   [(set_attr "type" "fsgn")
9781    (set_attr "mode" "DF")])
9783 (define_insn "*negextendsfdf2"
9784   [(set (match_operand:DF 0 "register_operand" "=f")
9785         (neg:DF (float_extend:DF
9786                   (match_operand:SF 1 "register_operand" "0"))))]
9787   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9788   "fchs"
9789   [(set_attr "type" "fsgn")
9790    (set_attr "mode" "DF")])
9792 (define_insn "*negextenddfxf2"
9793   [(set (match_operand:XF 0 "register_operand" "=f")
9794         (neg:XF (float_extend:XF
9795                   (match_operand:DF 1 "register_operand" "0"))))]
9796   "TARGET_80387"
9797   "fchs"
9798   [(set_attr "type" "fsgn")
9799    (set_attr "mode" "XF")])
9801 (define_insn "*negextendsfxf2"
9802   [(set (match_operand:XF 0 "register_operand" "=f")
9803         (neg:XF (float_extend:XF
9804                   (match_operand:SF 1 "register_operand" "0"))))]
9805   "TARGET_80387"
9806   "fchs"
9807   [(set_attr "type" "fsgn")
9808    (set_attr "mode" "XF")])
9810 (define_insn "*absextendsfdf2"
9811   [(set (match_operand:DF 0 "register_operand" "=f")
9812         (abs:DF (float_extend:DF
9813                   (match_operand:SF 1 "register_operand" "0"))))]
9814   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9815   "fabs"
9816   [(set_attr "type" "fsgn")
9817    (set_attr "mode" "DF")])
9819 (define_insn "*absextenddfxf2"
9820   [(set (match_operand:XF 0 "register_operand" "=f")
9821         (abs:XF (float_extend:XF
9822           (match_operand:DF 1 "register_operand" "0"))))]
9823   "TARGET_80387"
9824   "fabs"
9825   [(set_attr "type" "fsgn")
9826    (set_attr "mode" "XF")])
9828 (define_insn "*absextendsfxf2"
9829   [(set (match_operand:XF 0 "register_operand" "=f")
9830         (abs:XF (float_extend:XF
9831           (match_operand:SF 1 "register_operand" "0"))))]
9832   "TARGET_80387"
9833   "fabs"
9834   [(set_attr "type" "fsgn")
9835    (set_attr "mode" "XF")])
9837 ;; One complement instructions
9839 (define_expand "one_cmpldi2"
9840   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9841         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9842   "TARGET_64BIT"
9843   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9845 (define_insn "*one_cmpldi2_1_rex64"
9846   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9847         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9848   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9849   "not{q}\t%0"
9850   [(set_attr "type" "negnot")
9851    (set_attr "mode" "DI")])
9853 (define_insn "*one_cmpldi2_2_rex64"
9854   [(set (reg FLAGS_REG)
9855         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9856                  (const_int 0)))
9857    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9858         (not:DI (match_dup 1)))]
9859   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9860    && ix86_unary_operator_ok (NOT, DImode, operands)"
9861   "#"
9862   [(set_attr "type" "alu1")
9863    (set_attr "mode" "DI")])
9865 (define_split
9866   [(set (match_operand 0 "flags_reg_operand" "")
9867         (match_operator 2 "compare_operator"
9868           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9869            (const_int 0)]))
9870    (set (match_operand:DI 1 "nonimmediate_operand" "")
9871         (not:DI (match_dup 3)))]
9872   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9873   [(parallel [(set (match_dup 0)
9874                    (match_op_dup 2
9875                      [(xor:DI (match_dup 3) (const_int -1))
9876                       (const_int 0)]))
9877               (set (match_dup 1)
9878                    (xor:DI (match_dup 3) (const_int -1)))])]
9879   "")
9881 (define_expand "one_cmplsi2"
9882   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9883         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9884   ""
9885   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9887 (define_insn "*one_cmplsi2_1"
9888   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9889         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9890   "ix86_unary_operator_ok (NOT, SImode, operands)"
9891   "not{l}\t%0"
9892   [(set_attr "type" "negnot")
9893    (set_attr "mode" "SI")])
9895 ;; ??? Currently never generated - xor is used instead.
9896 (define_insn "*one_cmplsi2_1_zext"
9897   [(set (match_operand:DI 0 "register_operand" "=r")
9898         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9899   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9900   "not{l}\t%k0"
9901   [(set_attr "type" "negnot")
9902    (set_attr "mode" "SI")])
9904 (define_insn "*one_cmplsi2_2"
9905   [(set (reg FLAGS_REG)
9906         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9907                  (const_int 0)))
9908    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9909         (not:SI (match_dup 1)))]
9910   "ix86_match_ccmode (insn, CCNOmode)
9911    && ix86_unary_operator_ok (NOT, SImode, operands)"
9912   "#"
9913   [(set_attr "type" "alu1")
9914    (set_attr "mode" "SI")])
9916 (define_split
9917   [(set (match_operand 0 "flags_reg_operand" "")
9918         (match_operator 2 "compare_operator"
9919           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9920            (const_int 0)]))
9921    (set (match_operand:SI 1 "nonimmediate_operand" "")
9922         (not:SI (match_dup 3)))]
9923   "ix86_match_ccmode (insn, CCNOmode)"
9924   [(parallel [(set (match_dup 0)
9925                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9926                                     (const_int 0)]))
9927               (set (match_dup 1)
9928                    (xor:SI (match_dup 3) (const_int -1)))])]
9929   "")
9931 ;; ??? Currently never generated - xor is used instead.
9932 (define_insn "*one_cmplsi2_2_zext"
9933   [(set (reg FLAGS_REG)
9934         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9935                  (const_int 0)))
9936    (set (match_operand:DI 0 "register_operand" "=r")
9937         (zero_extend:DI (not:SI (match_dup 1))))]
9938   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9939    && ix86_unary_operator_ok (NOT, SImode, operands)"
9940   "#"
9941   [(set_attr "type" "alu1")
9942    (set_attr "mode" "SI")])
9944 (define_split
9945   [(set (match_operand 0 "flags_reg_operand" "")
9946         (match_operator 2 "compare_operator"
9947           [(not:SI (match_operand:SI 3 "register_operand" ""))
9948            (const_int 0)]))
9949    (set (match_operand:DI 1 "register_operand" "")
9950         (zero_extend:DI (not:SI (match_dup 3))))]
9951   "ix86_match_ccmode (insn, CCNOmode)"
9952   [(parallel [(set (match_dup 0)
9953                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9954                                     (const_int 0)]))
9955               (set (match_dup 1)
9956                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9957   "")
9959 (define_expand "one_cmplhi2"
9960   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9961         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9962   "TARGET_HIMODE_MATH"
9963   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9965 (define_insn "*one_cmplhi2_1"
9966   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9967         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9968   "ix86_unary_operator_ok (NOT, HImode, operands)"
9969   "not{w}\t%0"
9970   [(set_attr "type" "negnot")
9971    (set_attr "mode" "HI")])
9973 (define_insn "*one_cmplhi2_2"
9974   [(set (reg FLAGS_REG)
9975         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9976                  (const_int 0)))
9977    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9978         (not:HI (match_dup 1)))]
9979   "ix86_match_ccmode (insn, CCNOmode)
9980    && ix86_unary_operator_ok (NEG, HImode, operands)"
9981   "#"
9982   [(set_attr "type" "alu1")
9983    (set_attr "mode" "HI")])
9985 (define_split
9986   [(set (match_operand 0 "flags_reg_operand" "")
9987         (match_operator 2 "compare_operator"
9988           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9989            (const_int 0)]))
9990    (set (match_operand:HI 1 "nonimmediate_operand" "")
9991         (not:HI (match_dup 3)))]
9992   "ix86_match_ccmode (insn, CCNOmode)"
9993   [(parallel [(set (match_dup 0)
9994                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
9995                                     (const_int 0)]))
9996               (set (match_dup 1)
9997                    (xor:HI (match_dup 3) (const_int -1)))])]
9998   "")
10000 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10001 (define_expand "one_cmplqi2"
10002   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10003         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10004   "TARGET_QIMODE_MATH"
10005   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10007 (define_insn "*one_cmplqi2_1"
10008   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10009         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10010   "ix86_unary_operator_ok (NOT, QImode, operands)"
10011   "@
10012    not{b}\t%0
10013    not{l}\t%k0"
10014   [(set_attr "type" "negnot")
10015    (set_attr "mode" "QI,SI")])
10017 (define_insn "*one_cmplqi2_2"
10018   [(set (reg FLAGS_REG)
10019         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10020                  (const_int 0)))
10021    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10022         (not:QI (match_dup 1)))]
10023   "ix86_match_ccmode (insn, CCNOmode)
10024    && ix86_unary_operator_ok (NOT, QImode, operands)"
10025   "#"
10026   [(set_attr "type" "alu1")
10027    (set_attr "mode" "QI")])
10029 (define_split
10030   [(set (match_operand 0 "flags_reg_operand" "")
10031         (match_operator 2 "compare_operator"
10032           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10033            (const_int 0)]))
10034    (set (match_operand:QI 1 "nonimmediate_operand" "")
10035         (not:QI (match_dup 3)))]
10036   "ix86_match_ccmode (insn, CCNOmode)"
10037   [(parallel [(set (match_dup 0)
10038                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10039                                     (const_int 0)]))
10040               (set (match_dup 1)
10041                    (xor:QI (match_dup 3) (const_int -1)))])]
10042   "")
10044 ;; Arithmetic shift instructions
10046 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10047 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10048 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10049 ;; from the assembler input.
10051 ;; This instruction shifts the target reg/mem as usual, but instead of
10052 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10053 ;; is a left shift double, bits are taken from the high order bits of
10054 ;; reg, else if the insn is a shift right double, bits are taken from the
10055 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10056 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10058 ;; Since sh[lr]d does not change the `reg' operand, that is done
10059 ;; separately, making all shifts emit pairs of shift double and normal
10060 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10061 ;; support a 63 bit shift, each shift where the count is in a reg expands
10062 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10064 ;; If the shift count is a constant, we need never emit more than one
10065 ;; shift pair, instead using moves and sign extension for counts greater
10066 ;; than 31.
10068 (define_expand "ashldi3"
10069   [(set (match_operand:DI 0 "shiftdi_operand" "")
10070         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10071                    (match_operand:QI 2 "nonmemory_operand" "")))]
10072   ""
10073   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10075 (define_insn "*ashldi3_1_rex64"
10076   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10077         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10078                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10079    (clobber (reg:CC FLAGS_REG))]
10080   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10082   switch (get_attr_type (insn))
10083     {
10084     case TYPE_ALU:
10085       if (operands[2] != const1_rtx)
10086         abort ();
10087       if (!rtx_equal_p (operands[0], operands[1]))
10088         abort ();
10089       return "add{q}\t{%0, %0|%0, %0}";
10091     case TYPE_LEA:
10092       if (GET_CODE (operands[2]) != CONST_INT
10093           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10094         abort ();
10095       operands[1] = gen_rtx_MULT (DImode, operands[1],
10096                                   GEN_INT (1 << INTVAL (operands[2])));
10097       return "lea{q}\t{%a1, %0|%0, %a1}";
10099     default:
10100       if (REG_P (operands[2]))
10101         return "sal{q}\t{%b2, %0|%0, %b2}";
10102       else if (operands[2] == const1_rtx
10103                && (TARGET_SHIFT1 || optimize_size))
10104         return "sal{q}\t%0";
10105       else
10106         return "sal{q}\t{%2, %0|%0, %2}";
10107     }
10109   [(set (attr "type")
10110      (cond [(eq_attr "alternative" "1")
10111               (const_string "lea")
10112             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10113                           (const_int 0))
10114                       (match_operand 0 "register_operand" ""))
10115                  (match_operand 2 "const1_operand" ""))
10116               (const_string "alu")
10117            ]
10118            (const_string "ishift")))
10119    (set_attr "mode" "DI")])
10121 ;; Convert lea to the lea pattern to avoid flags dependency.
10122 (define_split
10123   [(set (match_operand:DI 0 "register_operand" "")
10124         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10125                    (match_operand:QI 2 "immediate_operand" "")))
10126    (clobber (reg:CC FLAGS_REG))]
10127   "TARGET_64BIT && reload_completed
10128    && true_regnum (operands[0]) != true_regnum (operands[1])"
10129   [(set (match_dup 0)
10130         (mult:DI (match_dup 1)
10131                  (match_dup 2)))]
10132   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10134 ;; This pattern can't accept a variable shift count, since shifts by
10135 ;; zero don't affect the flags.  We assume that shifts by constant
10136 ;; zero are optimized away.
10137 (define_insn "*ashldi3_cmp_rex64"
10138   [(set (reg FLAGS_REG)
10139         (compare
10140           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10141                      (match_operand:QI 2 "immediate_operand" "e"))
10142           (const_int 0)))
10143    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10144         (ashift:DI (match_dup 1) (match_dup 2)))]
10145   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10146    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10148   switch (get_attr_type (insn))
10149     {
10150     case TYPE_ALU:
10151       if (operands[2] != const1_rtx)
10152         abort ();
10153       return "add{q}\t{%0, %0|%0, %0}";
10155     default:
10156       if (REG_P (operands[2]))
10157         return "sal{q}\t{%b2, %0|%0, %b2}";
10158       else if (operands[2] == const1_rtx
10159                && (TARGET_SHIFT1 || optimize_size))
10160         return "sal{q}\t%0";
10161       else
10162         return "sal{q}\t{%2, %0|%0, %2}";
10163     }
10165   [(set (attr "type")
10166      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10167                           (const_int 0))
10168                       (match_operand 0 "register_operand" ""))
10169                  (match_operand 2 "const1_operand" ""))
10170               (const_string "alu")
10171            ]
10172            (const_string "ishift")))
10173    (set_attr "mode" "DI")])
10175 (define_insn "*ashldi3_1"
10176   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10177         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10178                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10179    (clobber (reg:CC FLAGS_REG))]
10180   "!TARGET_64BIT"
10181   "#"
10182   [(set_attr "type" "multi")])
10184 ;; By default we don't ask for a scratch register, because when DImode
10185 ;; values are manipulated, registers are already at a premium.  But if
10186 ;; we have one handy, we won't turn it away.
10187 (define_peephole2
10188   [(match_scratch:SI 3 "r")
10189    (parallel [(set (match_operand:DI 0 "register_operand" "")
10190                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10191                               (match_operand:QI 2 "nonmemory_operand" "")))
10192               (clobber (reg:CC FLAGS_REG))])
10193    (match_dup 3)]
10194   "!TARGET_64BIT && TARGET_CMOVE"
10195   [(const_int 0)]
10196   "ix86_split_ashldi (operands, operands[3]); DONE;")
10198 (define_split
10199   [(set (match_operand:DI 0 "register_operand" "")
10200         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10201                    (match_operand:QI 2 "nonmemory_operand" "")))
10202    (clobber (reg:CC FLAGS_REG))]
10203   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10204   [(const_int 0)]
10205   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10207 (define_insn "x86_shld_1"
10208   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10209         (ior:SI (ashift:SI (match_dup 0)
10210                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10211                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10212                   (minus:QI (const_int 32) (match_dup 2)))))
10213    (clobber (reg:CC FLAGS_REG))]
10214   ""
10215   "@
10216    shld{l}\t{%2, %1, %0|%0, %1, %2}
10217    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10218   [(set_attr "type" "ishift")
10219    (set_attr "prefix_0f" "1")
10220    (set_attr "mode" "SI")
10221    (set_attr "pent_pair" "np")
10222    (set_attr "athlon_decode" "vector")])
10224 (define_expand "x86_shift_adj_1"
10225   [(set (reg:CCZ FLAGS_REG)
10226         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10227                              (const_int 32))
10228                      (const_int 0)))
10229    (set (match_operand:SI 0 "register_operand" "")
10230         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10231                          (match_operand:SI 1 "register_operand" "")
10232                          (match_dup 0)))
10233    (set (match_dup 1)
10234         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10235                          (match_operand:SI 3 "register_operand" "r")
10236                          (match_dup 1)))]
10237   "TARGET_CMOVE"
10238   "")
10240 (define_expand "x86_shift_adj_2"
10241   [(use (match_operand:SI 0 "register_operand" ""))
10242    (use (match_operand:SI 1 "register_operand" ""))
10243    (use (match_operand:QI 2 "register_operand" ""))]
10244   ""
10246   rtx label = gen_label_rtx ();
10247   rtx tmp;
10249   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10251   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10252   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10253   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10254                               gen_rtx_LABEL_REF (VOIDmode, label),
10255                               pc_rtx);
10256   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10257   JUMP_LABEL (tmp) = label;
10259   emit_move_insn (operands[0], operands[1]);
10260   ix86_expand_clear (operands[1]);
10262   emit_label (label);
10263   LABEL_NUSES (label) = 1;
10265   DONE;
10268 (define_expand "ashlsi3"
10269   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10270         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10271                    (match_operand:QI 2 "nonmemory_operand" "")))
10272    (clobber (reg:CC FLAGS_REG))]
10273   ""
10274   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10276 (define_insn "*ashlsi3_1"
10277   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10278         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10279                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10280    (clobber (reg:CC FLAGS_REG))]
10281   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10283   switch (get_attr_type (insn))
10284     {
10285     case TYPE_ALU:
10286       if (operands[2] != const1_rtx)
10287         abort ();
10288       if (!rtx_equal_p (operands[0], operands[1]))
10289         abort ();
10290       return "add{l}\t{%0, %0|%0, %0}";
10292     case TYPE_LEA:
10293       return "#";
10295     default:
10296       if (REG_P (operands[2]))
10297         return "sal{l}\t{%b2, %0|%0, %b2}";
10298       else if (operands[2] == const1_rtx
10299                && (TARGET_SHIFT1 || optimize_size))
10300         return "sal{l}\t%0";
10301       else
10302         return "sal{l}\t{%2, %0|%0, %2}";
10303     }
10305   [(set (attr "type")
10306      (cond [(eq_attr "alternative" "1")
10307               (const_string "lea")
10308             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10309                           (const_int 0))
10310                       (match_operand 0 "register_operand" ""))
10311                  (match_operand 2 "const1_operand" ""))
10312               (const_string "alu")
10313            ]
10314            (const_string "ishift")))
10315    (set_attr "mode" "SI")])
10317 ;; Convert lea to the lea pattern to avoid flags dependency.
10318 (define_split
10319   [(set (match_operand 0 "register_operand" "")
10320         (ashift (match_operand 1 "index_register_operand" "")
10321                 (match_operand:QI 2 "const_int_operand" "")))
10322    (clobber (reg:CC FLAGS_REG))]
10323   "reload_completed
10324    && true_regnum (operands[0]) != true_regnum (operands[1])
10325    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10326   [(const_int 0)]
10328   rtx pat;
10329   enum machine_mode mode = GET_MODE (operands[0]);
10331   if (GET_MODE_SIZE (mode) < 4)
10332     operands[0] = gen_lowpart (SImode, operands[0]);
10333   if (mode != Pmode)
10334     operands[1] = gen_lowpart (Pmode, operands[1]);
10335   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10337   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10338   if (Pmode != SImode)
10339     pat = gen_rtx_SUBREG (SImode, pat, 0);
10340   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10341   DONE;
10344 ;; Rare case of shifting RSP is handled by generating move and shift
10345 (define_split
10346   [(set (match_operand 0 "register_operand" "")
10347         (ashift (match_operand 1 "register_operand" "")
10348                 (match_operand:QI 2 "const_int_operand" "")))
10349    (clobber (reg:CC FLAGS_REG))]
10350   "reload_completed
10351    && true_regnum (operands[0]) != true_regnum (operands[1])"
10352   [(const_int 0)]
10354   rtx pat, clob;
10355   emit_move_insn (operands[1], operands[0]);
10356   pat = gen_rtx_SET (VOIDmode, operands[0],
10357                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10358                                      operands[0], operands[2]));
10359   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10360   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10361   DONE;
10364 (define_insn "*ashlsi3_1_zext"
10365   [(set (match_operand:DI 0 "register_operand" "=r,r")
10366         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10367                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10368    (clobber (reg:CC FLAGS_REG))]
10369   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10371   switch (get_attr_type (insn))
10372     {
10373     case TYPE_ALU:
10374       if (operands[2] != const1_rtx)
10375         abort ();
10376       return "add{l}\t{%k0, %k0|%k0, %k0}";
10378     case TYPE_LEA:
10379       return "#";
10381     default:
10382       if (REG_P (operands[2]))
10383         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10384       else if (operands[2] == const1_rtx
10385                && (TARGET_SHIFT1 || optimize_size))
10386         return "sal{l}\t%k0";
10387       else
10388         return "sal{l}\t{%2, %k0|%k0, %2}";
10389     }
10391   [(set (attr "type")
10392      (cond [(eq_attr "alternative" "1")
10393               (const_string "lea")
10394             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10395                      (const_int 0))
10396                  (match_operand 2 "const1_operand" ""))
10397               (const_string "alu")
10398            ]
10399            (const_string "ishift")))
10400    (set_attr "mode" "SI")])
10402 ;; Convert lea to the lea pattern to avoid flags dependency.
10403 (define_split
10404   [(set (match_operand:DI 0 "register_operand" "")
10405         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10406                                 (match_operand:QI 2 "const_int_operand" ""))))
10407    (clobber (reg:CC FLAGS_REG))]
10408   "TARGET_64BIT && reload_completed
10409    && true_regnum (operands[0]) != true_regnum (operands[1])"
10410   [(set (match_dup 0) (zero_extend:DI
10411                         (subreg:SI (mult:SI (match_dup 1)
10412                                             (match_dup 2)) 0)))]
10414   operands[1] = gen_lowpart (Pmode, operands[1]);
10415   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10418 ;; This pattern can't accept a variable shift count, since shifts by
10419 ;; zero don't affect the flags.  We assume that shifts by constant
10420 ;; zero are optimized away.
10421 (define_insn "*ashlsi3_cmp"
10422   [(set (reg FLAGS_REG)
10423         (compare
10424           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10425                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10426           (const_int 0)))
10427    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10428         (ashift:SI (match_dup 1) (match_dup 2)))]
10429   "ix86_match_ccmode (insn, CCGOCmode)
10430    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10432   switch (get_attr_type (insn))
10433     {
10434     case TYPE_ALU:
10435       if (operands[2] != const1_rtx)
10436         abort ();
10437       return "add{l}\t{%0, %0|%0, %0}";
10439     default:
10440       if (REG_P (operands[2]))
10441         return "sal{l}\t{%b2, %0|%0, %b2}";
10442       else if (operands[2] == const1_rtx
10443                && (TARGET_SHIFT1 || optimize_size))
10444         return "sal{l}\t%0";
10445       else
10446         return "sal{l}\t{%2, %0|%0, %2}";
10447     }
10449   [(set (attr "type")
10450      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10451                           (const_int 0))
10452                       (match_operand 0 "register_operand" ""))
10453                  (match_operand 2 "const1_operand" ""))
10454               (const_string "alu")
10455            ]
10456            (const_string "ishift")))
10457    (set_attr "mode" "SI")])
10459 (define_insn "*ashlsi3_cmp_zext"
10460   [(set (reg FLAGS_REG)
10461         (compare
10462           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10463                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10464           (const_int 0)))
10465    (set (match_operand:DI 0 "register_operand" "=r")
10466         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10467   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10468    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10470   switch (get_attr_type (insn))
10471     {
10472     case TYPE_ALU:
10473       if (operands[2] != const1_rtx)
10474         abort ();
10475       return "add{l}\t{%k0, %k0|%k0, %k0}";
10477     default:
10478       if (REG_P (operands[2]))
10479         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10480       else if (operands[2] == const1_rtx
10481                && (TARGET_SHIFT1 || optimize_size))
10482         return "sal{l}\t%k0";
10483       else
10484         return "sal{l}\t{%2, %k0|%k0, %2}";
10485     }
10487   [(set (attr "type")
10488      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10489                      (const_int 0))
10490                  (match_operand 2 "const1_operand" ""))
10491               (const_string "alu")
10492            ]
10493            (const_string "ishift")))
10494    (set_attr "mode" "SI")])
10496 (define_expand "ashlhi3"
10497   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10498         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10499                    (match_operand:QI 2 "nonmemory_operand" "")))
10500    (clobber (reg:CC FLAGS_REG))]
10501   "TARGET_HIMODE_MATH"
10502   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10504 (define_insn "*ashlhi3_1_lea"
10505   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10506         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10507                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10508    (clobber (reg:CC FLAGS_REG))]
10509   "!TARGET_PARTIAL_REG_STALL
10510    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10512   switch (get_attr_type (insn))
10513     {
10514     case TYPE_LEA:
10515       return "#";
10516     case TYPE_ALU:
10517       if (operands[2] != const1_rtx)
10518         abort ();
10519       return "add{w}\t{%0, %0|%0, %0}";
10521     default:
10522       if (REG_P (operands[2]))
10523         return "sal{w}\t{%b2, %0|%0, %b2}";
10524       else if (operands[2] == const1_rtx
10525                && (TARGET_SHIFT1 || optimize_size))
10526         return "sal{w}\t%0";
10527       else
10528         return "sal{w}\t{%2, %0|%0, %2}";
10529     }
10531   [(set (attr "type")
10532      (cond [(eq_attr "alternative" "1")
10533               (const_string "lea")
10534             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10535                           (const_int 0))
10536                       (match_operand 0 "register_operand" ""))
10537                  (match_operand 2 "const1_operand" ""))
10538               (const_string "alu")
10539            ]
10540            (const_string "ishift")))
10541    (set_attr "mode" "HI,SI")])
10543 (define_insn "*ashlhi3_1"
10544   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10545         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10546                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10547    (clobber (reg:CC FLAGS_REG))]
10548   "TARGET_PARTIAL_REG_STALL
10549    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10551   switch (get_attr_type (insn))
10552     {
10553     case TYPE_ALU:
10554       if (operands[2] != const1_rtx)
10555         abort ();
10556       return "add{w}\t{%0, %0|%0, %0}";
10558     default:
10559       if (REG_P (operands[2]))
10560         return "sal{w}\t{%b2, %0|%0, %b2}";
10561       else if (operands[2] == const1_rtx
10562                && (TARGET_SHIFT1 || optimize_size))
10563         return "sal{w}\t%0";
10564       else
10565         return "sal{w}\t{%2, %0|%0, %2}";
10566     }
10568   [(set (attr "type")
10569      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10570                           (const_int 0))
10571                       (match_operand 0 "register_operand" ""))
10572                  (match_operand 2 "const1_operand" ""))
10573               (const_string "alu")
10574            ]
10575            (const_string "ishift")))
10576    (set_attr "mode" "HI")])
10578 ;; This pattern can't accept a variable shift count, since shifts by
10579 ;; zero don't affect the flags.  We assume that shifts by constant
10580 ;; zero are optimized away.
10581 (define_insn "*ashlhi3_cmp"
10582   [(set (reg FLAGS_REG)
10583         (compare
10584           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10585                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10586           (const_int 0)))
10587    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10588         (ashift:HI (match_dup 1) (match_dup 2)))]
10589   "ix86_match_ccmode (insn, CCGOCmode)
10590    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10592   switch (get_attr_type (insn))
10593     {
10594     case TYPE_ALU:
10595       if (operands[2] != const1_rtx)
10596         abort ();
10597       return "add{w}\t{%0, %0|%0, %0}";
10599     default:
10600       if (REG_P (operands[2]))
10601         return "sal{w}\t{%b2, %0|%0, %b2}";
10602       else if (operands[2] == const1_rtx
10603                && (TARGET_SHIFT1 || optimize_size))
10604         return "sal{w}\t%0";
10605       else
10606         return "sal{w}\t{%2, %0|%0, %2}";
10607     }
10609   [(set (attr "type")
10610      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10611                           (const_int 0))
10612                       (match_operand 0 "register_operand" ""))
10613                  (match_operand 2 "const1_operand" ""))
10614               (const_string "alu")
10615            ]
10616            (const_string "ishift")))
10617    (set_attr "mode" "HI")])
10619 (define_expand "ashlqi3"
10620   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10621         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10622                    (match_operand:QI 2 "nonmemory_operand" "")))
10623    (clobber (reg:CC FLAGS_REG))]
10624   "TARGET_QIMODE_MATH"
10625   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10627 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10629 (define_insn "*ashlqi3_1_lea"
10630   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10631         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10632                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10633    (clobber (reg:CC FLAGS_REG))]
10634   "!TARGET_PARTIAL_REG_STALL
10635    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10637   switch (get_attr_type (insn))
10638     {
10639     case TYPE_LEA:
10640       return "#";
10641     case TYPE_ALU:
10642       if (operands[2] != const1_rtx)
10643         abort ();
10644       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10645         return "add{l}\t{%k0, %k0|%k0, %k0}";
10646       else
10647         return "add{b}\t{%0, %0|%0, %0}";
10649     default:
10650       if (REG_P (operands[2]))
10651         {
10652           if (get_attr_mode (insn) == MODE_SI)
10653             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10654           else
10655             return "sal{b}\t{%b2, %0|%0, %b2}";
10656         }
10657       else if (operands[2] == const1_rtx
10658                && (TARGET_SHIFT1 || optimize_size))
10659         {
10660           if (get_attr_mode (insn) == MODE_SI)
10661             return "sal{l}\t%0";
10662           else
10663             return "sal{b}\t%0";
10664         }
10665       else
10666         {
10667           if (get_attr_mode (insn) == MODE_SI)
10668             return "sal{l}\t{%2, %k0|%k0, %2}";
10669           else
10670             return "sal{b}\t{%2, %0|%0, %2}";
10671         }
10672     }
10674   [(set (attr "type")
10675      (cond [(eq_attr "alternative" "2")
10676               (const_string "lea")
10677             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10678                           (const_int 0))
10679                       (match_operand 0 "register_operand" ""))
10680                  (match_operand 2 "const1_operand" ""))
10681               (const_string "alu")
10682            ]
10683            (const_string "ishift")))
10684    (set_attr "mode" "QI,SI,SI")])
10686 (define_insn "*ashlqi3_1"
10687   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10688         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10689                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10690    (clobber (reg:CC FLAGS_REG))]
10691   "TARGET_PARTIAL_REG_STALL
10692    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10694   switch (get_attr_type (insn))
10695     {
10696     case TYPE_ALU:
10697       if (operands[2] != const1_rtx)
10698         abort ();
10699       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10700         return "add{l}\t{%k0, %k0|%k0, %k0}";
10701       else
10702         return "add{b}\t{%0, %0|%0, %0}";
10704     default:
10705       if (REG_P (operands[2]))
10706         {
10707           if (get_attr_mode (insn) == MODE_SI)
10708             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10709           else
10710             return "sal{b}\t{%b2, %0|%0, %b2}";
10711         }
10712       else if (operands[2] == const1_rtx
10713                && (TARGET_SHIFT1 || optimize_size))
10714         {
10715           if (get_attr_mode (insn) == MODE_SI)
10716             return "sal{l}\t%0";
10717           else
10718             return "sal{b}\t%0";
10719         }
10720       else
10721         {
10722           if (get_attr_mode (insn) == MODE_SI)
10723             return "sal{l}\t{%2, %k0|%k0, %2}";
10724           else
10725             return "sal{b}\t{%2, %0|%0, %2}";
10726         }
10727     }
10729   [(set (attr "type")
10730      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10731                           (const_int 0))
10732                       (match_operand 0 "register_operand" ""))
10733                  (match_operand 2 "const1_operand" ""))
10734               (const_string "alu")
10735            ]
10736            (const_string "ishift")))
10737    (set_attr "mode" "QI,SI")])
10739 ;; This pattern can't accept a variable shift count, since shifts by
10740 ;; zero don't affect the flags.  We assume that shifts by constant
10741 ;; zero are optimized away.
10742 (define_insn "*ashlqi3_cmp"
10743   [(set (reg FLAGS_REG)
10744         (compare
10745           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10746                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10747           (const_int 0)))
10748    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10749         (ashift:QI (match_dup 1) (match_dup 2)))]
10750   "ix86_match_ccmode (insn, CCGOCmode)
10751    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10753   switch (get_attr_type (insn))
10754     {
10755     case TYPE_ALU:
10756       if (operands[2] != const1_rtx)
10757         abort ();
10758       return "add{b}\t{%0, %0|%0, %0}";
10760     default:
10761       if (REG_P (operands[2]))
10762         return "sal{b}\t{%b2, %0|%0, %b2}";
10763       else if (operands[2] == const1_rtx
10764                && (TARGET_SHIFT1 || optimize_size))
10765         return "sal{b}\t%0";
10766       else
10767         return "sal{b}\t{%2, %0|%0, %2}";
10768     }
10770   [(set (attr "type")
10771      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10772                           (const_int 0))
10773                       (match_operand 0 "register_operand" ""))
10774                  (match_operand 2 "const1_operand" ""))
10775               (const_string "alu")
10776            ]
10777            (const_string "ishift")))
10778    (set_attr "mode" "QI")])
10780 ;; See comment above `ashldi3' about how this works.
10782 (define_expand "ashrdi3"
10783   [(set (match_operand:DI 0 "shiftdi_operand" "")
10784         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10785                      (match_operand:QI 2 "nonmemory_operand" "")))]
10786   ""
10787   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10789 (define_insn "*ashrdi3_63_rex64"
10790   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10791         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10792                      (match_operand:DI 2 "const_int_operand" "i,i")))
10793    (clobber (reg:CC FLAGS_REG))]
10794   "TARGET_64BIT && INTVAL (operands[2]) == 63
10795    && (TARGET_USE_CLTD || optimize_size)
10796    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10797   "@
10798    {cqto|cqo}
10799    sar{q}\t{%2, %0|%0, %2}"
10800   [(set_attr "type" "imovx,ishift")
10801    (set_attr "prefix_0f" "0,*")
10802    (set_attr "length_immediate" "0,*")
10803    (set_attr "modrm" "0,1")
10804    (set_attr "mode" "DI")])
10806 (define_insn "*ashrdi3_1_one_bit_rex64"
10807   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10808         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10809                      (match_operand:QI 2 "const1_operand" "")))
10810    (clobber (reg:CC FLAGS_REG))]
10811   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10812    && (TARGET_SHIFT1 || optimize_size)"
10813   "sar{q}\t%0"
10814   [(set_attr "type" "ishift")
10815    (set (attr "length") 
10816      (if_then_else (match_operand:DI 0 "register_operand" "") 
10817         (const_string "2")
10818         (const_string "*")))])
10820 (define_insn "*ashrdi3_1_rex64"
10821   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10822         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10823                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10824    (clobber (reg:CC FLAGS_REG))]
10825   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10826   "@
10827    sar{q}\t{%2, %0|%0, %2}
10828    sar{q}\t{%b2, %0|%0, %b2}"
10829   [(set_attr "type" "ishift")
10830    (set_attr "mode" "DI")])
10832 ;; This pattern can't accept a variable shift count, since shifts by
10833 ;; zero don't affect the flags.  We assume that shifts by constant
10834 ;; zero are optimized away.
10835 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10836   [(set (reg FLAGS_REG)
10837         (compare
10838           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10839                        (match_operand:QI 2 "const1_operand" ""))
10840           (const_int 0)))
10841    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10842         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10843   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10844    && (TARGET_SHIFT1 || optimize_size)
10845    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10846   "sar{q}\t%0"
10847   [(set_attr "type" "ishift")
10848    (set (attr "length") 
10849      (if_then_else (match_operand:DI 0 "register_operand" "") 
10850         (const_string "2")
10851         (const_string "*")))])
10853 ;; This pattern can't accept a variable shift count, since shifts by
10854 ;; zero don't affect the flags.  We assume that shifts by constant
10855 ;; zero are optimized away.
10856 (define_insn "*ashrdi3_cmp_rex64"
10857   [(set (reg FLAGS_REG)
10858         (compare
10859           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10860                        (match_operand:QI 2 "const_int_operand" "n"))
10861           (const_int 0)))
10862    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10863         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10864   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10865    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10866   "sar{q}\t{%2, %0|%0, %2}"
10867   [(set_attr "type" "ishift")
10868    (set_attr "mode" "DI")])
10870 (define_insn "*ashrdi3_1"
10871   [(set (match_operand:DI 0 "register_operand" "=r")
10872         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10873                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10874    (clobber (reg:CC FLAGS_REG))]
10875   "!TARGET_64BIT"
10876   "#"
10877   [(set_attr "type" "multi")])
10879 ;; By default we don't ask for a scratch register, because when DImode
10880 ;; values are manipulated, registers are already at a premium.  But if
10881 ;; we have one handy, we won't turn it away.
10882 (define_peephole2
10883   [(match_scratch:SI 3 "r")
10884    (parallel [(set (match_operand:DI 0 "register_operand" "")
10885                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10886                                 (match_operand:QI 2 "nonmemory_operand" "")))
10887               (clobber (reg:CC FLAGS_REG))])
10888    (match_dup 3)]
10889   "!TARGET_64BIT && TARGET_CMOVE"
10890   [(const_int 0)]
10891   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10893 (define_split
10894   [(set (match_operand:DI 0 "register_operand" "")
10895         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10896                      (match_operand:QI 2 "nonmemory_operand" "")))
10897    (clobber (reg:CC FLAGS_REG))]
10898   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10899   [(const_int 0)]
10900   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10902 (define_insn "x86_shrd_1"
10903   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10904         (ior:SI (ashiftrt:SI (match_dup 0)
10905                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10906                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10907                   (minus:QI (const_int 32) (match_dup 2)))))
10908    (clobber (reg:CC FLAGS_REG))]
10909   ""
10910   "@
10911    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10912    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10913   [(set_attr "type" "ishift")
10914    (set_attr "prefix_0f" "1")
10915    (set_attr "pent_pair" "np")
10916    (set_attr "mode" "SI")])
10918 (define_expand "x86_shift_adj_3"
10919   [(use (match_operand:SI 0 "register_operand" ""))
10920    (use (match_operand:SI 1 "register_operand" ""))
10921    (use (match_operand:QI 2 "register_operand" ""))]
10922   ""
10924   rtx label = gen_label_rtx ();
10925   rtx tmp;
10927   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10929   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10930   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10931   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10932                               gen_rtx_LABEL_REF (VOIDmode, label),
10933                               pc_rtx);
10934   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10935   JUMP_LABEL (tmp) = label;
10937   emit_move_insn (operands[0], operands[1]);
10938   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10940   emit_label (label);
10941   LABEL_NUSES (label) = 1;
10943   DONE;
10946 (define_insn "ashrsi3_31"
10947   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10948         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10949                      (match_operand:SI 2 "const_int_operand" "i,i")))
10950    (clobber (reg:CC FLAGS_REG))]
10951   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10952    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10953   "@
10954    {cltd|cdq}
10955    sar{l}\t{%2, %0|%0, %2}"
10956   [(set_attr "type" "imovx,ishift")
10957    (set_attr "prefix_0f" "0,*")
10958    (set_attr "length_immediate" "0,*")
10959    (set_attr "modrm" "0,1")
10960    (set_attr "mode" "SI")])
10962 (define_insn "*ashrsi3_31_zext"
10963   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10964         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10965                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10966    (clobber (reg:CC FLAGS_REG))]
10967   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10968    && INTVAL (operands[2]) == 31
10969    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10970   "@
10971    {cltd|cdq}
10972    sar{l}\t{%2, %k0|%k0, %2}"
10973   [(set_attr "type" "imovx,ishift")
10974    (set_attr "prefix_0f" "0,*")
10975    (set_attr "length_immediate" "0,*")
10976    (set_attr "modrm" "0,1")
10977    (set_attr "mode" "SI")])
10979 (define_expand "ashrsi3"
10980   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10981         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10982                      (match_operand:QI 2 "nonmemory_operand" "")))
10983    (clobber (reg:CC FLAGS_REG))]
10984   ""
10985   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10987 (define_insn "*ashrsi3_1_one_bit"
10988   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10989         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10990                      (match_operand:QI 2 "const1_operand" "")))
10991    (clobber (reg:CC FLAGS_REG))]
10992   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10993    && (TARGET_SHIFT1 || optimize_size)"
10994   "sar{l}\t%0"
10995   [(set_attr "type" "ishift")
10996    (set (attr "length") 
10997      (if_then_else (match_operand:SI 0 "register_operand" "") 
10998         (const_string "2")
10999         (const_string "*")))])
11001 (define_insn "*ashrsi3_1_one_bit_zext"
11002   [(set (match_operand:DI 0 "register_operand" "=r")
11003         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11004                                      (match_operand:QI 2 "const1_operand" ""))))
11005    (clobber (reg:CC FLAGS_REG))]
11006   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11007    && (TARGET_SHIFT1 || optimize_size)"
11008   "sar{l}\t%k0"
11009   [(set_attr "type" "ishift")
11010    (set_attr "length" "2")])
11012 (define_insn "*ashrsi3_1"
11013   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11014         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11015                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11016    (clobber (reg:CC FLAGS_REG))]
11017   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11018   "@
11019    sar{l}\t{%2, %0|%0, %2}
11020    sar{l}\t{%b2, %0|%0, %b2}"
11021   [(set_attr "type" "ishift")
11022    (set_attr "mode" "SI")])
11024 (define_insn "*ashrsi3_1_zext"
11025   [(set (match_operand:DI 0 "register_operand" "=r,r")
11026         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11027                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11028    (clobber (reg:CC FLAGS_REG))]
11029   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11030   "@
11031    sar{l}\t{%2, %k0|%k0, %2}
11032    sar{l}\t{%b2, %k0|%k0, %b2}"
11033   [(set_attr "type" "ishift")
11034    (set_attr "mode" "SI")])
11036 ;; This pattern can't accept a variable shift count, since shifts by
11037 ;; zero don't affect the flags.  We assume that shifts by constant
11038 ;; zero are optimized away.
11039 (define_insn "*ashrsi3_one_bit_cmp"
11040   [(set (reg FLAGS_REG)
11041         (compare
11042           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11043                        (match_operand:QI 2 "const1_operand" ""))
11044           (const_int 0)))
11045    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11046         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11047   "ix86_match_ccmode (insn, CCGOCmode)
11048    && (TARGET_SHIFT1 || optimize_size)
11049    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11050   "sar{l}\t%0"
11051   [(set_attr "type" "ishift")
11052    (set (attr "length") 
11053      (if_then_else (match_operand:SI 0 "register_operand" "") 
11054         (const_string "2")
11055         (const_string "*")))])
11057 (define_insn "*ashrsi3_one_bit_cmp_zext"
11058   [(set (reg FLAGS_REG)
11059         (compare
11060           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11061                        (match_operand:QI 2 "const1_operand" ""))
11062           (const_int 0)))
11063    (set (match_operand:DI 0 "register_operand" "=r")
11064         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11065   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11066    && (TARGET_SHIFT1 || optimize_size)
11067    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11068   "sar{l}\t%k0"
11069   [(set_attr "type" "ishift")
11070    (set_attr "length" "2")])
11072 ;; This pattern can't accept a variable shift count, since shifts by
11073 ;; zero don't affect the flags.  We assume that shifts by constant
11074 ;; zero are optimized away.
11075 (define_insn "*ashrsi3_cmp"
11076   [(set (reg FLAGS_REG)
11077         (compare
11078           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11079                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11080           (const_int 0)))
11081    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11082         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11083   "ix86_match_ccmode (insn, CCGOCmode)
11084    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11085   "sar{l}\t{%2, %0|%0, %2}"
11086   [(set_attr "type" "ishift")
11087    (set_attr "mode" "SI")])
11089 (define_insn "*ashrsi3_cmp_zext"
11090   [(set (reg FLAGS_REG)
11091         (compare
11092           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11093                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11094           (const_int 0)))
11095    (set (match_operand:DI 0 "register_operand" "=r")
11096         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11097   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11098    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11099   "sar{l}\t{%2, %k0|%k0, %2}"
11100   [(set_attr "type" "ishift")
11101    (set_attr "mode" "SI")])
11103 (define_expand "ashrhi3"
11104   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11105         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11106                      (match_operand:QI 2 "nonmemory_operand" "")))
11107    (clobber (reg:CC FLAGS_REG))]
11108   "TARGET_HIMODE_MATH"
11109   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11111 (define_insn "*ashrhi3_1_one_bit"
11112   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11113         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11114                      (match_operand:QI 2 "const1_operand" "")))
11115    (clobber (reg:CC FLAGS_REG))]
11116   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11117    && (TARGET_SHIFT1 || optimize_size)"
11118   "sar{w}\t%0"
11119   [(set_attr "type" "ishift")
11120    (set (attr "length") 
11121      (if_then_else (match_operand 0 "register_operand" "") 
11122         (const_string "2")
11123         (const_string "*")))])
11125 (define_insn "*ashrhi3_1"
11126   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11127         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11128                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11129    (clobber (reg:CC FLAGS_REG))]
11130   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11131   "@
11132    sar{w}\t{%2, %0|%0, %2}
11133    sar{w}\t{%b2, %0|%0, %b2}"
11134   [(set_attr "type" "ishift")
11135    (set_attr "mode" "HI")])
11137 ;; This pattern can't accept a variable shift count, since shifts by
11138 ;; zero don't affect the flags.  We assume that shifts by constant
11139 ;; zero are optimized away.
11140 (define_insn "*ashrhi3_one_bit_cmp"
11141   [(set (reg FLAGS_REG)
11142         (compare
11143           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11144                        (match_operand:QI 2 "const1_operand" ""))
11145           (const_int 0)))
11146    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11147         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11148   "ix86_match_ccmode (insn, CCGOCmode)
11149    && (TARGET_SHIFT1 || optimize_size)
11150    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11151   "sar{w}\t%0"
11152   [(set_attr "type" "ishift")
11153    (set (attr "length") 
11154      (if_then_else (match_operand 0 "register_operand" "") 
11155         (const_string "2")
11156         (const_string "*")))])
11158 ;; This pattern can't accept a variable shift count, since shifts by
11159 ;; zero don't affect the flags.  We assume that shifts by constant
11160 ;; zero are optimized away.
11161 (define_insn "*ashrhi3_cmp"
11162   [(set (reg FLAGS_REG)
11163         (compare
11164           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11165                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11166           (const_int 0)))
11167    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11168         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11169   "ix86_match_ccmode (insn, CCGOCmode)
11170    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11171   "sar{w}\t{%2, %0|%0, %2}"
11172   [(set_attr "type" "ishift")
11173    (set_attr "mode" "HI")])
11175 (define_expand "ashrqi3"
11176   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11177         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11178                      (match_operand:QI 2 "nonmemory_operand" "")))
11179    (clobber (reg:CC FLAGS_REG))]
11180   "TARGET_QIMODE_MATH"
11181   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11183 (define_insn "*ashrqi3_1_one_bit"
11184   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11185         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11186                      (match_operand:QI 2 "const1_operand" "")))
11187    (clobber (reg:CC FLAGS_REG))]
11188   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11189    && (TARGET_SHIFT1 || optimize_size)"
11190   "sar{b}\t%0"
11191   [(set_attr "type" "ishift")
11192    (set (attr "length") 
11193      (if_then_else (match_operand 0 "register_operand" "") 
11194         (const_string "2")
11195         (const_string "*")))])
11197 (define_insn "*ashrqi3_1_one_bit_slp"
11198   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11199         (ashiftrt:QI (match_dup 0)
11200                      (match_operand:QI 1 "const1_operand" "")))
11201    (clobber (reg:CC FLAGS_REG))]
11202   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11203    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11204    && (TARGET_SHIFT1 || optimize_size)"
11205   "sar{b}\t%0"
11206   [(set_attr "type" "ishift1")
11207    (set (attr "length") 
11208      (if_then_else (match_operand 0 "register_operand" "") 
11209         (const_string "2")
11210         (const_string "*")))])
11212 (define_insn "*ashrqi3_1"
11213   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11214         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11215                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11216    (clobber (reg:CC FLAGS_REG))]
11217   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11218   "@
11219    sar{b}\t{%2, %0|%0, %2}
11220    sar{b}\t{%b2, %0|%0, %b2}"
11221   [(set_attr "type" "ishift")
11222    (set_attr "mode" "QI")])
11224 (define_insn "*ashrqi3_1_slp"
11225   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11226         (ashiftrt:QI (match_dup 0)
11227                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11228    (clobber (reg:CC FLAGS_REG))]
11229   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11230    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11231   "@
11232    sar{b}\t{%1, %0|%0, %1}
11233    sar{b}\t{%b1, %0|%0, %b1}"
11234   [(set_attr "type" "ishift1")
11235    (set_attr "mode" "QI")])
11237 ;; This pattern can't accept a variable shift count, since shifts by
11238 ;; zero don't affect the flags.  We assume that shifts by constant
11239 ;; zero are optimized away.
11240 (define_insn "*ashrqi3_one_bit_cmp"
11241   [(set (reg FLAGS_REG)
11242         (compare
11243           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11244                        (match_operand:QI 2 "const1_operand" "I"))
11245           (const_int 0)))
11246    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11247         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11248   "ix86_match_ccmode (insn, CCGOCmode)
11249    && (TARGET_SHIFT1 || optimize_size)
11250    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11251   "sar{b}\t%0"
11252   [(set_attr "type" "ishift")
11253    (set (attr "length") 
11254      (if_then_else (match_operand 0 "register_operand" "") 
11255         (const_string "2")
11256         (const_string "*")))])
11258 ;; This pattern can't accept a variable shift count, since shifts by
11259 ;; zero don't affect the flags.  We assume that shifts by constant
11260 ;; zero are optimized away.
11261 (define_insn "*ashrqi3_cmp"
11262   [(set (reg FLAGS_REG)
11263         (compare
11264           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11265                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11266           (const_int 0)))
11267    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11268         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11269   "ix86_match_ccmode (insn, CCGOCmode)
11270    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11271   "sar{b}\t{%2, %0|%0, %2}"
11272   [(set_attr "type" "ishift")
11273    (set_attr "mode" "QI")])
11275 ;; Logical shift instructions
11277 ;; See comment above `ashldi3' about how this works.
11279 (define_expand "lshrdi3"
11280   [(set (match_operand:DI 0 "shiftdi_operand" "")
11281         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11282                      (match_operand:QI 2 "nonmemory_operand" "")))]
11283   ""
11284   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11286 (define_insn "*lshrdi3_1_one_bit_rex64"
11287   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11288         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11289                      (match_operand:QI 2 "const1_operand" "")))
11290    (clobber (reg:CC FLAGS_REG))]
11291   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11292    && (TARGET_SHIFT1 || optimize_size)"
11293   "shr{q}\t%0"
11294   [(set_attr "type" "ishift")
11295    (set (attr "length") 
11296      (if_then_else (match_operand:DI 0 "register_operand" "") 
11297         (const_string "2")
11298         (const_string "*")))])
11300 (define_insn "*lshrdi3_1_rex64"
11301   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11302         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11303                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11304    (clobber (reg:CC FLAGS_REG))]
11305   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11306   "@
11307    shr{q}\t{%2, %0|%0, %2}
11308    shr{q}\t{%b2, %0|%0, %b2}"
11309   [(set_attr "type" "ishift")
11310    (set_attr "mode" "DI")])
11312 ;; This pattern can't accept a variable shift count, since shifts by
11313 ;; zero don't affect the flags.  We assume that shifts by constant
11314 ;; zero are optimized away.
11315 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11316   [(set (reg FLAGS_REG)
11317         (compare
11318           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11319                        (match_operand:QI 2 "const1_operand" ""))
11320           (const_int 0)))
11321    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11322         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11323   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11324    && (TARGET_SHIFT1 || optimize_size)
11325    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11326   "shr{q}\t%0"
11327   [(set_attr "type" "ishift")
11328    (set (attr "length") 
11329      (if_then_else (match_operand:DI 0 "register_operand" "") 
11330         (const_string "2")
11331         (const_string "*")))])
11333 ;; This pattern can't accept a variable shift count, since shifts by
11334 ;; zero don't affect the flags.  We assume that shifts by constant
11335 ;; zero are optimized away.
11336 (define_insn "*lshrdi3_cmp_rex64"
11337   [(set (reg FLAGS_REG)
11338         (compare
11339           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11340                        (match_operand:QI 2 "const_int_operand" "e"))
11341           (const_int 0)))
11342    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11343         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11344   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11345    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11346   "shr{q}\t{%2, %0|%0, %2}"
11347   [(set_attr "type" "ishift")
11348    (set_attr "mode" "DI")])
11350 (define_insn "*lshrdi3_1"
11351   [(set (match_operand:DI 0 "register_operand" "=r")
11352         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11353                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11354    (clobber (reg:CC FLAGS_REG))]
11355   "!TARGET_64BIT"
11356   "#"
11357   [(set_attr "type" "multi")])
11359 ;; By default we don't ask for a scratch register, because when DImode
11360 ;; values are manipulated, registers are already at a premium.  But if
11361 ;; we have one handy, we won't turn it away.
11362 (define_peephole2
11363   [(match_scratch:SI 3 "r")
11364    (parallel [(set (match_operand:DI 0 "register_operand" "")
11365                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11366                                 (match_operand:QI 2 "nonmemory_operand" "")))
11367               (clobber (reg:CC FLAGS_REG))])
11368    (match_dup 3)]
11369   "!TARGET_64BIT && TARGET_CMOVE"
11370   [(const_int 0)]
11371   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11373 (define_split 
11374   [(set (match_operand:DI 0 "register_operand" "")
11375         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11376                      (match_operand:QI 2 "nonmemory_operand" "")))
11377    (clobber (reg:CC FLAGS_REG))]
11378   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11379   [(const_int 0)]
11380   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11382 (define_expand "lshrsi3"
11383   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11384         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11385                      (match_operand:QI 2 "nonmemory_operand" "")))
11386    (clobber (reg:CC FLAGS_REG))]
11387   ""
11388   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11390 (define_insn "*lshrsi3_1_one_bit"
11391   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11392         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11393                      (match_operand:QI 2 "const1_operand" "")))
11394    (clobber (reg:CC FLAGS_REG))]
11395   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11396    && (TARGET_SHIFT1 || optimize_size)"
11397   "shr{l}\t%0"
11398   [(set_attr "type" "ishift")
11399    (set (attr "length") 
11400      (if_then_else (match_operand:SI 0 "register_operand" "") 
11401         (const_string "2")
11402         (const_string "*")))])
11404 (define_insn "*lshrsi3_1_one_bit_zext"
11405   [(set (match_operand:DI 0 "register_operand" "=r")
11406         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11407                      (match_operand:QI 2 "const1_operand" "")))
11408    (clobber (reg:CC FLAGS_REG))]
11409   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11410    && (TARGET_SHIFT1 || optimize_size)"
11411   "shr{l}\t%k0"
11412   [(set_attr "type" "ishift")
11413    (set_attr "length" "2")])
11415 (define_insn "*lshrsi3_1"
11416   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11417         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11418                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11419    (clobber (reg:CC FLAGS_REG))]
11420   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11421   "@
11422    shr{l}\t{%2, %0|%0, %2}
11423    shr{l}\t{%b2, %0|%0, %b2}"
11424   [(set_attr "type" "ishift")
11425    (set_attr "mode" "SI")])
11427 (define_insn "*lshrsi3_1_zext"
11428   [(set (match_operand:DI 0 "register_operand" "=r,r")
11429         (zero_extend:DI
11430           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11431                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11432    (clobber (reg:CC FLAGS_REG))]
11433   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11434   "@
11435    shr{l}\t{%2, %k0|%k0, %2}
11436    shr{l}\t{%b2, %k0|%k0, %b2}"
11437   [(set_attr "type" "ishift")
11438    (set_attr "mode" "SI")])
11440 ;; This pattern can't accept a variable shift count, since shifts by
11441 ;; zero don't affect the flags.  We assume that shifts by constant
11442 ;; zero are optimized away.
11443 (define_insn "*lshrsi3_one_bit_cmp"
11444   [(set (reg FLAGS_REG)
11445         (compare
11446           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11447                        (match_operand:QI 2 "const1_operand" ""))
11448           (const_int 0)))
11449    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11450         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11451   "ix86_match_ccmode (insn, CCGOCmode)
11452    && (TARGET_SHIFT1 || optimize_size)
11453    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11454   "shr{l}\t%0"
11455   [(set_attr "type" "ishift")
11456    (set (attr "length") 
11457      (if_then_else (match_operand:SI 0 "register_operand" "") 
11458         (const_string "2")
11459         (const_string "*")))])
11461 (define_insn "*lshrsi3_cmp_one_bit_zext"
11462   [(set (reg FLAGS_REG)
11463         (compare
11464           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11465                        (match_operand:QI 2 "const1_operand" ""))
11466           (const_int 0)))
11467    (set (match_operand:DI 0 "register_operand" "=r")
11468         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11469   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11470    && (TARGET_SHIFT1 || optimize_size)
11471    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11472   "shr{l}\t%k0"
11473   [(set_attr "type" "ishift")
11474    (set_attr "length" "2")])
11476 ;; This pattern can't accept a variable shift count, since shifts by
11477 ;; zero don't affect the flags.  We assume that shifts by constant
11478 ;; zero are optimized away.
11479 (define_insn "*lshrsi3_cmp"
11480   [(set (reg FLAGS_REG)
11481         (compare
11482           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11483                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11484           (const_int 0)))
11485    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11486         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11487   "ix86_match_ccmode (insn, CCGOCmode)
11488    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11489   "shr{l}\t{%2, %0|%0, %2}"
11490   [(set_attr "type" "ishift")
11491    (set_attr "mode" "SI")])
11493 (define_insn "*lshrsi3_cmp_zext"
11494   [(set (reg FLAGS_REG)
11495         (compare
11496           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11497                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11498           (const_int 0)))
11499    (set (match_operand:DI 0 "register_operand" "=r")
11500         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11501   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11502    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11503   "shr{l}\t{%2, %k0|%k0, %2}"
11504   [(set_attr "type" "ishift")
11505    (set_attr "mode" "SI")])
11507 (define_expand "lshrhi3"
11508   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11509         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11510                      (match_operand:QI 2 "nonmemory_operand" "")))
11511    (clobber (reg:CC FLAGS_REG))]
11512   "TARGET_HIMODE_MATH"
11513   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11515 (define_insn "*lshrhi3_1_one_bit"
11516   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11517         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11518                      (match_operand:QI 2 "const1_operand" "")))
11519    (clobber (reg:CC FLAGS_REG))]
11520   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11521    && (TARGET_SHIFT1 || optimize_size)"
11522   "shr{w}\t%0"
11523   [(set_attr "type" "ishift")
11524    (set (attr "length") 
11525      (if_then_else (match_operand 0 "register_operand" "") 
11526         (const_string "2")
11527         (const_string "*")))])
11529 (define_insn "*lshrhi3_1"
11530   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11531         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11532                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11533    (clobber (reg:CC FLAGS_REG))]
11534   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11535   "@
11536    shr{w}\t{%2, %0|%0, %2}
11537    shr{w}\t{%b2, %0|%0, %b2}"
11538   [(set_attr "type" "ishift")
11539    (set_attr "mode" "HI")])
11541 ;; This pattern can't accept a variable shift count, since shifts by
11542 ;; zero don't affect the flags.  We assume that shifts by constant
11543 ;; zero are optimized away.
11544 (define_insn "*lshrhi3_one_bit_cmp"
11545   [(set (reg FLAGS_REG)
11546         (compare
11547           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11548                        (match_operand:QI 2 "const1_operand" ""))
11549           (const_int 0)))
11550    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11551         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11552   "ix86_match_ccmode (insn, CCGOCmode)
11553    && (TARGET_SHIFT1 || optimize_size)
11554    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11555   "shr{w}\t%0"
11556   [(set_attr "type" "ishift")
11557    (set (attr "length") 
11558      (if_then_else (match_operand:SI 0 "register_operand" "") 
11559         (const_string "2")
11560         (const_string "*")))])
11562 ;; This pattern can't accept a variable shift count, since shifts by
11563 ;; zero don't affect the flags.  We assume that shifts by constant
11564 ;; zero are optimized away.
11565 (define_insn "*lshrhi3_cmp"
11566   [(set (reg FLAGS_REG)
11567         (compare
11568           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11569                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11570           (const_int 0)))
11571    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11572         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11573   "ix86_match_ccmode (insn, CCGOCmode)
11574    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11575   "shr{w}\t{%2, %0|%0, %2}"
11576   [(set_attr "type" "ishift")
11577    (set_attr "mode" "HI")])
11579 (define_expand "lshrqi3"
11580   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11581         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11582                      (match_operand:QI 2 "nonmemory_operand" "")))
11583    (clobber (reg:CC FLAGS_REG))]
11584   "TARGET_QIMODE_MATH"
11585   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11587 (define_insn "*lshrqi3_1_one_bit"
11588   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11589         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11590                      (match_operand:QI 2 "const1_operand" "")))
11591    (clobber (reg:CC FLAGS_REG))]
11592   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11593    && (TARGET_SHIFT1 || optimize_size)"
11594   "shr{b}\t%0"
11595   [(set_attr "type" "ishift")
11596    (set (attr "length") 
11597      (if_then_else (match_operand 0 "register_operand" "") 
11598         (const_string "2")
11599         (const_string "*")))])
11601 (define_insn "*lshrqi3_1_one_bit_slp"
11602   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11603         (lshiftrt:QI (match_dup 0)
11604                      (match_operand:QI 1 "const1_operand" "")))
11605    (clobber (reg:CC FLAGS_REG))]
11606   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11607    && (TARGET_SHIFT1 || optimize_size)"
11608   "shr{b}\t%0"
11609   [(set_attr "type" "ishift1")
11610    (set (attr "length") 
11611      (if_then_else (match_operand 0 "register_operand" "") 
11612         (const_string "2")
11613         (const_string "*")))])
11615 (define_insn "*lshrqi3_1"
11616   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11617         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11618                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11619    (clobber (reg:CC FLAGS_REG))]
11620   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11621   "@
11622    shr{b}\t{%2, %0|%0, %2}
11623    shr{b}\t{%b2, %0|%0, %b2}"
11624   [(set_attr "type" "ishift")
11625    (set_attr "mode" "QI")])
11627 (define_insn "*lshrqi3_1_slp"
11628   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11629         (lshiftrt:QI (match_dup 0)
11630                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11631    (clobber (reg:CC FLAGS_REG))]
11632   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11633    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11634   "@
11635    shr{b}\t{%1, %0|%0, %1}
11636    shr{b}\t{%b1, %0|%0, %b1}"
11637   [(set_attr "type" "ishift1")
11638    (set_attr "mode" "QI")])
11640 ;; This pattern can't accept a variable shift count, since shifts by
11641 ;; zero don't affect the flags.  We assume that shifts by constant
11642 ;; zero are optimized away.
11643 (define_insn "*lshrqi2_one_bit_cmp"
11644   [(set (reg FLAGS_REG)
11645         (compare
11646           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11647                        (match_operand:QI 2 "const1_operand" ""))
11648           (const_int 0)))
11649    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11650         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11651   "ix86_match_ccmode (insn, CCGOCmode)
11652    && (TARGET_SHIFT1 || optimize_size)
11653    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11654   "shr{b}\t%0"
11655   [(set_attr "type" "ishift")
11656    (set (attr "length") 
11657      (if_then_else (match_operand:SI 0 "register_operand" "") 
11658         (const_string "2")
11659         (const_string "*")))])
11661 ;; This pattern can't accept a variable shift count, since shifts by
11662 ;; zero don't affect the flags.  We assume that shifts by constant
11663 ;; zero are optimized away.
11664 (define_insn "*lshrqi2_cmp"
11665   [(set (reg FLAGS_REG)
11666         (compare
11667           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11668                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11669           (const_int 0)))
11670    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11671         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11672   "ix86_match_ccmode (insn, CCGOCmode)
11673    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11674   "shr{b}\t{%2, %0|%0, %2}"
11675   [(set_attr "type" "ishift")
11676    (set_attr "mode" "QI")])
11678 ;; Rotate instructions
11680 (define_expand "rotldi3"
11681   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11682         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11683                    (match_operand:QI 2 "nonmemory_operand" "")))
11684    (clobber (reg:CC FLAGS_REG))]
11685   "TARGET_64BIT"
11686   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11688 (define_insn "*rotlsi3_1_one_bit_rex64"
11689   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11690         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11691                    (match_operand:QI 2 "const1_operand" "")))
11692    (clobber (reg:CC FLAGS_REG))]
11693   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11694    && (TARGET_SHIFT1 || optimize_size)"
11695   "rol{q}\t%0"
11696   [(set_attr "type" "rotate")
11697    (set (attr "length") 
11698      (if_then_else (match_operand:DI 0 "register_operand" "") 
11699         (const_string "2")
11700         (const_string "*")))])
11702 (define_insn "*rotldi3_1_rex64"
11703   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11704         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11705                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11706    (clobber (reg:CC FLAGS_REG))]
11707   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11708   "@
11709    rol{q}\t{%2, %0|%0, %2}
11710    rol{q}\t{%b2, %0|%0, %b2}"
11711   [(set_attr "type" "rotate")
11712    (set_attr "mode" "DI")])
11714 (define_expand "rotlsi3"
11715   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11716         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11717                    (match_operand:QI 2 "nonmemory_operand" "")))
11718    (clobber (reg:CC FLAGS_REG))]
11719   ""
11720   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11722 (define_insn "*rotlsi3_1_one_bit"
11723   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11724         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11725                    (match_operand:QI 2 "const1_operand" "")))
11726    (clobber (reg:CC FLAGS_REG))]
11727   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11728    && (TARGET_SHIFT1 || optimize_size)"
11729   "rol{l}\t%0"
11730   [(set_attr "type" "rotate")
11731    (set (attr "length") 
11732      (if_then_else (match_operand:SI 0 "register_operand" "") 
11733         (const_string "2")
11734         (const_string "*")))])
11736 (define_insn "*rotlsi3_1_one_bit_zext"
11737   [(set (match_operand:DI 0 "register_operand" "=r")
11738         (zero_extend:DI
11739           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11740                      (match_operand:QI 2 "const1_operand" ""))))
11741    (clobber (reg:CC FLAGS_REG))]
11742   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11743    && (TARGET_SHIFT1 || optimize_size)"
11744   "rol{l}\t%k0"
11745   [(set_attr "type" "rotate")
11746    (set_attr "length" "2")])
11748 (define_insn "*rotlsi3_1"
11749   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11750         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11751                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11752    (clobber (reg:CC FLAGS_REG))]
11753   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11754   "@
11755    rol{l}\t{%2, %0|%0, %2}
11756    rol{l}\t{%b2, %0|%0, %b2}"
11757   [(set_attr "type" "rotate")
11758    (set_attr "mode" "SI")])
11760 (define_insn "*rotlsi3_1_zext"
11761   [(set (match_operand:DI 0 "register_operand" "=r,r")
11762         (zero_extend:DI
11763           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11764                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11765    (clobber (reg:CC FLAGS_REG))]
11766   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11767   "@
11768    rol{l}\t{%2, %k0|%k0, %2}
11769    rol{l}\t{%b2, %k0|%k0, %b2}"
11770   [(set_attr "type" "rotate")
11771    (set_attr "mode" "SI")])
11773 (define_expand "rotlhi3"
11774   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11775         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11776                    (match_operand:QI 2 "nonmemory_operand" "")))
11777    (clobber (reg:CC FLAGS_REG))]
11778   "TARGET_HIMODE_MATH"
11779   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11781 (define_insn "*rotlhi3_1_one_bit"
11782   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11783         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11784                    (match_operand:QI 2 "const1_operand" "")))
11785    (clobber (reg:CC FLAGS_REG))]
11786   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11787    && (TARGET_SHIFT1 || optimize_size)"
11788   "rol{w}\t%0"
11789   [(set_attr "type" "rotate")
11790    (set (attr "length") 
11791      (if_then_else (match_operand 0 "register_operand" "") 
11792         (const_string "2")
11793         (const_string "*")))])
11795 (define_insn "*rotlhi3_1"
11796   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11797         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11798                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11799    (clobber (reg:CC FLAGS_REG))]
11800   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11801   "@
11802    rol{w}\t{%2, %0|%0, %2}
11803    rol{w}\t{%b2, %0|%0, %b2}"
11804   [(set_attr "type" "rotate")
11805    (set_attr "mode" "HI")])
11807 (define_expand "rotlqi3"
11808   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11809         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11810                    (match_operand:QI 2 "nonmemory_operand" "")))
11811    (clobber (reg:CC FLAGS_REG))]
11812   "TARGET_QIMODE_MATH"
11813   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11815 (define_insn "*rotlqi3_1_one_bit_slp"
11816   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11817         (rotate:QI (match_dup 0)
11818                    (match_operand:QI 1 "const1_operand" "")))
11819    (clobber (reg:CC FLAGS_REG))]
11820   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11821    && (TARGET_SHIFT1 || optimize_size)"
11822   "rol{b}\t%0"
11823   [(set_attr "type" "rotate1")
11824    (set (attr "length") 
11825      (if_then_else (match_operand 0 "register_operand" "") 
11826         (const_string "2")
11827         (const_string "*")))])
11829 (define_insn "*rotlqi3_1_one_bit"
11830   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11831         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11832                    (match_operand:QI 2 "const1_operand" "")))
11833    (clobber (reg:CC FLAGS_REG))]
11834   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11835    && (TARGET_SHIFT1 || optimize_size)"
11836   "rol{b}\t%0"
11837   [(set_attr "type" "rotate")
11838    (set (attr "length") 
11839      (if_then_else (match_operand 0 "register_operand" "") 
11840         (const_string "2")
11841         (const_string "*")))])
11843 (define_insn "*rotlqi3_1_slp"
11844   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11845         (rotate:QI (match_dup 0)
11846                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11847    (clobber (reg:CC FLAGS_REG))]
11848   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11849    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11850   "@
11851    rol{b}\t{%1, %0|%0, %1}
11852    rol{b}\t{%b1, %0|%0, %b1}"
11853   [(set_attr "type" "rotate1")
11854    (set_attr "mode" "QI")])
11856 (define_insn "*rotlqi3_1"
11857   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11858         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11859                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11860    (clobber (reg:CC FLAGS_REG))]
11861   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11862   "@
11863    rol{b}\t{%2, %0|%0, %2}
11864    rol{b}\t{%b2, %0|%0, %b2}"
11865   [(set_attr "type" "rotate")
11866    (set_attr "mode" "QI")])
11868 (define_expand "rotrdi3"
11869   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11870         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11871                      (match_operand:QI 2 "nonmemory_operand" "")))
11872    (clobber (reg:CC FLAGS_REG))]
11873   "TARGET_64BIT"
11874   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11876 (define_insn "*rotrdi3_1_one_bit_rex64"
11877   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11878         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11879                      (match_operand:QI 2 "const1_operand" "")))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11882    && (TARGET_SHIFT1 || optimize_size)"
11883   "ror{q}\t%0"
11884   [(set_attr "type" "rotate")
11885    (set (attr "length") 
11886      (if_then_else (match_operand:DI 0 "register_operand" "") 
11887         (const_string "2")
11888         (const_string "*")))])
11890 (define_insn "*rotrdi3_1_rex64"
11891   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11892         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11893                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11894    (clobber (reg:CC FLAGS_REG))]
11895   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11896   "@
11897    ror{q}\t{%2, %0|%0, %2}
11898    ror{q}\t{%b2, %0|%0, %b2}"
11899   [(set_attr "type" "rotate")
11900    (set_attr "mode" "DI")])
11902 (define_expand "rotrsi3"
11903   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11904         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11905                      (match_operand:QI 2 "nonmemory_operand" "")))
11906    (clobber (reg:CC FLAGS_REG))]
11907   ""
11908   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11910 (define_insn "*rotrsi3_1_one_bit"
11911   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11912         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11913                      (match_operand:QI 2 "const1_operand" "")))
11914    (clobber (reg:CC FLAGS_REG))]
11915   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11916    && (TARGET_SHIFT1 || optimize_size)"
11917   "ror{l}\t%0"
11918   [(set_attr "type" "rotate")
11919    (set (attr "length") 
11920      (if_then_else (match_operand:SI 0 "register_operand" "") 
11921         (const_string "2")
11922         (const_string "*")))])
11924 (define_insn "*rotrsi3_1_one_bit_zext"
11925   [(set (match_operand:DI 0 "register_operand" "=r")
11926         (zero_extend:DI
11927           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11928                        (match_operand:QI 2 "const1_operand" ""))))
11929    (clobber (reg:CC FLAGS_REG))]
11930   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11931    && (TARGET_SHIFT1 || optimize_size)"
11932   "ror{l}\t%k0"
11933   [(set_attr "type" "rotate")
11934    (set (attr "length") 
11935      (if_then_else (match_operand:SI 0 "register_operand" "") 
11936         (const_string "2")
11937         (const_string "*")))])
11939 (define_insn "*rotrsi3_1"
11940   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11941         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11942                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11943    (clobber (reg:CC FLAGS_REG))]
11944   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11945   "@
11946    ror{l}\t{%2, %0|%0, %2}
11947    ror{l}\t{%b2, %0|%0, %b2}"
11948   [(set_attr "type" "rotate")
11949    (set_attr "mode" "SI")])
11951 (define_insn "*rotrsi3_1_zext"
11952   [(set (match_operand:DI 0 "register_operand" "=r,r")
11953         (zero_extend:DI
11954           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11955                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11956    (clobber (reg:CC FLAGS_REG))]
11957   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11958   "@
11959    ror{l}\t{%2, %k0|%k0, %2}
11960    ror{l}\t{%b2, %k0|%k0, %b2}"
11961   [(set_attr "type" "rotate")
11962    (set_attr "mode" "SI")])
11964 (define_expand "rotrhi3"
11965   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11966         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11967                      (match_operand:QI 2 "nonmemory_operand" "")))
11968    (clobber (reg:CC FLAGS_REG))]
11969   "TARGET_HIMODE_MATH"
11970   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11972 (define_insn "*rotrhi3_one_bit"
11973   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11974         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11975                      (match_operand:QI 2 "const1_operand" "")))
11976    (clobber (reg:CC FLAGS_REG))]
11977   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11978    && (TARGET_SHIFT1 || optimize_size)"
11979   "ror{w}\t%0"
11980   [(set_attr "type" "rotate")
11981    (set (attr "length") 
11982      (if_then_else (match_operand 0 "register_operand" "") 
11983         (const_string "2")
11984         (const_string "*")))])
11986 (define_insn "*rotrhi3"
11987   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11988         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11989                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11990    (clobber (reg:CC FLAGS_REG))]
11991   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11992   "@
11993    ror{w}\t{%2, %0|%0, %2}
11994    ror{w}\t{%b2, %0|%0, %b2}"
11995   [(set_attr "type" "rotate")
11996    (set_attr "mode" "HI")])
11998 (define_expand "rotrqi3"
11999   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12000         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12001                      (match_operand:QI 2 "nonmemory_operand" "")))
12002    (clobber (reg:CC FLAGS_REG))]
12003   "TARGET_QIMODE_MATH"
12004   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12006 (define_insn "*rotrqi3_1_one_bit"
12007   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12008         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12009                      (match_operand:QI 2 "const1_operand" "")))
12010    (clobber (reg:CC FLAGS_REG))]
12011   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12012    && (TARGET_SHIFT1 || optimize_size)"
12013   "ror{b}\t%0"
12014   [(set_attr "type" "rotate")
12015    (set (attr "length") 
12016      (if_then_else (match_operand 0 "register_operand" "") 
12017         (const_string "2")
12018         (const_string "*")))])
12020 (define_insn "*rotrqi3_1_one_bit_slp"
12021   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12022         (rotatert:QI (match_dup 0)
12023                      (match_operand:QI 1 "const1_operand" "")))
12024    (clobber (reg:CC FLAGS_REG))]
12025   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12026    && (TARGET_SHIFT1 || optimize_size)"
12027   "ror{b}\t%0"
12028   [(set_attr "type" "rotate1")
12029    (set (attr "length") 
12030      (if_then_else (match_operand 0 "register_operand" "") 
12031         (const_string "2")
12032         (const_string "*")))])
12034 (define_insn "*rotrqi3_1"
12035   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12036         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12037                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12038    (clobber (reg:CC FLAGS_REG))]
12039   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12040   "@
12041    ror{b}\t{%2, %0|%0, %2}
12042    ror{b}\t{%b2, %0|%0, %b2}"
12043   [(set_attr "type" "rotate")
12044    (set_attr "mode" "QI")])
12046 (define_insn "*rotrqi3_1_slp"
12047   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12048         (rotatert:QI (match_dup 0)
12049                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12050    (clobber (reg:CC FLAGS_REG))]
12051   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12052    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12053   "@
12054    ror{b}\t{%1, %0|%0, %1}
12055    ror{b}\t{%b1, %0|%0, %b1}"
12056   [(set_attr "type" "rotate1")
12057    (set_attr "mode" "QI")])
12059 ;; Bit set / bit test instructions
12061 (define_expand "extv"
12062   [(set (match_operand:SI 0 "register_operand" "")
12063         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12064                          (match_operand:SI 2 "immediate_operand" "")
12065                          (match_operand:SI 3 "immediate_operand" "")))]
12066   ""
12068   /* Handle extractions from %ah et al.  */
12069   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12070     FAIL;
12072   /* From mips.md: extract_bit_field doesn't verify that our source
12073      matches the predicate, so check it again here.  */
12074   if (! ext_register_operand (operands[1], VOIDmode))
12075     FAIL;
12078 (define_expand "extzv"
12079   [(set (match_operand:SI 0 "register_operand" "")
12080         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12081                          (match_operand:SI 2 "immediate_operand" "")
12082                          (match_operand:SI 3 "immediate_operand" "")))]
12083   ""
12085   /* Handle extractions from %ah et al.  */
12086   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12087     FAIL;
12089   /* From mips.md: extract_bit_field doesn't verify that our source
12090      matches the predicate, so check it again here.  */
12091   if (! ext_register_operand (operands[1], VOIDmode))
12092     FAIL;
12095 (define_expand "insv"
12096   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12097                       (match_operand 1 "immediate_operand" "")
12098                       (match_operand 2 "immediate_operand" ""))
12099         (match_operand 3 "register_operand" ""))]
12100   ""
12102   /* Handle extractions from %ah et al.  */
12103   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12104     FAIL;
12106   /* From mips.md: insert_bit_field doesn't verify that our source
12107      matches the predicate, so check it again here.  */
12108   if (! ext_register_operand (operands[0], VOIDmode))
12109     FAIL;
12111   if (TARGET_64BIT)
12112     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12113   else
12114     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12116   DONE;
12119 ;; %%% bts, btr, btc, bt.
12120 ;; In general these instructions are *slow* when applied to memory,
12121 ;; since they enforce atomic operation.  When applied to registers,
12122 ;; it depends on the cpu implementation.  They're never faster than
12123 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12124 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12125 ;; within the instruction itself, so operating on bits in the high
12126 ;; 32-bits of a register becomes easier.
12128 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12129 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12130 ;; negdf respectively, so they can never be disabled entirely.
12132 (define_insn "*btsq"
12133   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12134                          (const_int 1)
12135                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12136         (const_int 1))
12137    (clobber (reg:CC FLAGS_REG))]
12138   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12139   "bts{q} %1,%0"
12140   [(set_attr "type" "alu1")])
12142 (define_insn "*btrq"
12143   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12144                          (const_int 1)
12145                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12146         (const_int 0))
12147    (clobber (reg:CC FLAGS_REG))]
12148   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12149   "btr{q} %1,%0"
12150   [(set_attr "type" "alu1")])
12152 (define_insn "*btcq"
12153   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12154                          (const_int 1)
12155                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12156         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12157    (clobber (reg:CC FLAGS_REG))]
12158   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12159   "btc{q} %1,%0"
12160   [(set_attr "type" "alu1")])
12162 ;; Allow Nocona to avoid these instructions if a register is available.
12164 (define_peephole2
12165   [(match_scratch:DI 2 "r")
12166    (parallel [(set (zero_extract:DI
12167                      (match_operand:DI 0 "register_operand" "")
12168                      (const_int 1)
12169                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12170                    (const_int 1))
12171               (clobber (reg:CC FLAGS_REG))])]
12172   "TARGET_64BIT && !TARGET_USE_BT"
12173   [(const_int 0)]
12175   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12176   rtx op1;
12178   if (HOST_BITS_PER_WIDE_INT >= 64)
12179     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12180   else if (i < HOST_BITS_PER_WIDE_INT)
12181     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12182   else
12183     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12185   op1 = immed_double_const (lo, hi, DImode);
12186   if (i >= 31)
12187     {
12188       emit_move_insn (operands[2], op1);
12189       op1 = operands[2];
12190     }
12192   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12193   DONE;
12196 (define_peephole2
12197   [(match_scratch:DI 2 "r")
12198    (parallel [(set (zero_extract:DI
12199                      (match_operand:DI 0 "register_operand" "")
12200                      (const_int 1)
12201                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12202                    (const_int 0))
12203               (clobber (reg:CC FLAGS_REG))])]
12204   "TARGET_64BIT && !TARGET_USE_BT"
12205   [(const_int 0)]
12207   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12208   rtx op1;
12210   if (HOST_BITS_PER_WIDE_INT >= 64)
12211     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12212   else if (i < HOST_BITS_PER_WIDE_INT)
12213     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12214   else
12215     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12217   op1 = immed_double_const (~lo, ~hi, DImode);
12218   if (i >= 32)
12219     {
12220       emit_move_insn (operands[2], op1);
12221       op1 = operands[2];
12222     }
12224   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12225   DONE;
12228 (define_peephole2
12229   [(match_scratch:DI 2 "r")
12230    (parallel [(set (zero_extract:DI
12231                      (match_operand:DI 0 "register_operand" "")
12232                      (const_int 1)
12233                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12234               (not:DI (zero_extract:DI
12235                         (match_dup 0) (const_int 1) (match_dup 1))))
12236               (clobber (reg:CC FLAGS_REG))])]
12237   "TARGET_64BIT && !TARGET_USE_BT"
12238   [(const_int 0)]
12240   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12241   rtx op1;
12243   if (HOST_BITS_PER_WIDE_INT >= 64)
12244     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12245   else if (i < HOST_BITS_PER_WIDE_INT)
12246     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12247   else
12248     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12250   op1 = immed_double_const (lo, hi, DImode);
12251   if (i >= 31)
12252     {
12253       emit_move_insn (operands[2], op1);
12254       op1 = operands[2];
12255     }
12257   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12258   DONE;
12261 ;; Store-flag instructions.
12263 ;; For all sCOND expanders, also expand the compare or test insn that
12264 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12266 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12267 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12268 ;; way, which can later delete the movzx if only QImode is needed.
12270 (define_expand "seq"
12271   [(set (match_operand:QI 0 "register_operand" "")
12272         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12273   ""
12274   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12276 (define_expand "sne"
12277   [(set (match_operand:QI 0 "register_operand" "")
12278         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12279   ""
12280   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12282 (define_expand "sgt"
12283   [(set (match_operand:QI 0 "register_operand" "")
12284         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12285   ""
12286   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12288 (define_expand "sgtu"
12289   [(set (match_operand:QI 0 "register_operand" "")
12290         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12291   ""
12292   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12294 (define_expand "slt"
12295   [(set (match_operand:QI 0 "register_operand" "")
12296         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12297   ""
12298   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12300 (define_expand "sltu"
12301   [(set (match_operand:QI 0 "register_operand" "")
12302         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12303   ""
12304   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12306 (define_expand "sge"
12307   [(set (match_operand:QI 0 "register_operand" "")
12308         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12309   ""
12310   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12312 (define_expand "sgeu"
12313   [(set (match_operand:QI 0 "register_operand" "")
12314         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12315   ""
12316   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12318 (define_expand "sle"
12319   [(set (match_operand:QI 0 "register_operand" "")
12320         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12321   ""
12322   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12324 (define_expand "sleu"
12325   [(set (match_operand:QI 0 "register_operand" "")
12326         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12327   ""
12328   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12330 (define_expand "sunordered"
12331   [(set (match_operand:QI 0 "register_operand" "")
12332         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12333   "TARGET_80387 || TARGET_SSE"
12334   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12336 (define_expand "sordered"
12337   [(set (match_operand:QI 0 "register_operand" "")
12338         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12339   "TARGET_80387"
12340   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12342 (define_expand "suneq"
12343   [(set (match_operand:QI 0 "register_operand" "")
12344         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12345   "TARGET_80387 || TARGET_SSE"
12346   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12348 (define_expand "sunge"
12349   [(set (match_operand:QI 0 "register_operand" "")
12350         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12351   "TARGET_80387 || TARGET_SSE"
12352   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12354 (define_expand "sungt"
12355   [(set (match_operand:QI 0 "register_operand" "")
12356         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12357   "TARGET_80387 || TARGET_SSE"
12358   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12360 (define_expand "sunle"
12361   [(set (match_operand:QI 0 "register_operand" "")
12362         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12363   "TARGET_80387 || TARGET_SSE"
12364   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12366 (define_expand "sunlt"
12367   [(set (match_operand:QI 0 "register_operand" "")
12368         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12369   "TARGET_80387 || TARGET_SSE"
12370   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12372 (define_expand "sltgt"
12373   [(set (match_operand:QI 0 "register_operand" "")
12374         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12375   "TARGET_80387 || TARGET_SSE"
12376   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12378 (define_insn "*setcc_1"
12379   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12380         (match_operator:QI 1 "ix86_comparison_operator"
12381           [(reg FLAGS_REG) (const_int 0)]))]
12382   ""
12383   "set%C1\t%0"
12384   [(set_attr "type" "setcc")
12385    (set_attr "mode" "QI")])
12387 (define_insn "*setcc_2"
12388   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12389         (match_operator:QI 1 "ix86_comparison_operator"
12390           [(reg FLAGS_REG) (const_int 0)]))]
12391   ""
12392   "set%C1\t%0"
12393   [(set_attr "type" "setcc")
12394    (set_attr "mode" "QI")])
12396 ;; In general it is not safe to assume too much about CCmode registers,
12397 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12398 ;; conditions this is safe on x86, so help combine not create
12400 ;;      seta    %al
12401 ;;      testb   %al, %al
12402 ;;      sete    %al
12404 (define_split 
12405   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12406         (ne:QI (match_operator 1 "ix86_comparison_operator"
12407                  [(reg FLAGS_REG) (const_int 0)])
12408             (const_int 0)))]
12409   ""
12410   [(set (match_dup 0) (match_dup 1))]
12412   PUT_MODE (operands[1], QImode);
12415 (define_split 
12416   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12417         (ne:QI (match_operator 1 "ix86_comparison_operator"
12418                  [(reg FLAGS_REG) (const_int 0)])
12419             (const_int 0)))]
12420   ""
12421   [(set (match_dup 0) (match_dup 1))]
12423   PUT_MODE (operands[1], QImode);
12426 (define_split 
12427   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12428         (eq:QI (match_operator 1 "ix86_comparison_operator"
12429                  [(reg FLAGS_REG) (const_int 0)])
12430             (const_int 0)))]
12431   ""
12432   [(set (match_dup 0) (match_dup 1))]
12434   rtx new_op1 = copy_rtx (operands[1]);
12435   operands[1] = new_op1;
12436   PUT_MODE (new_op1, QImode);
12437   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12438                                              GET_MODE (XEXP (new_op1, 0))));
12440   /* Make sure that (a) the CCmode we have for the flags is strong
12441      enough for the reversed compare or (b) we have a valid FP compare.  */
12442   if (! ix86_comparison_operator (new_op1, VOIDmode))
12443     FAIL;
12446 (define_split 
12447   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12448         (eq:QI (match_operator 1 "ix86_comparison_operator"
12449                  [(reg FLAGS_REG) (const_int 0)])
12450             (const_int 0)))]
12451   ""
12452   [(set (match_dup 0) (match_dup 1))]
12454   rtx new_op1 = copy_rtx (operands[1]);
12455   operands[1] = new_op1;
12456   PUT_MODE (new_op1, QImode);
12457   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12458                                              GET_MODE (XEXP (new_op1, 0))));
12460   /* Make sure that (a) the CCmode we have for the flags is strong
12461      enough for the reversed compare or (b) we have a valid FP compare.  */
12462   if (! ix86_comparison_operator (new_op1, VOIDmode))
12463     FAIL;
12466 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12467 ;; subsequent logical operations are used to imitate conditional moves.
12468 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12469 ;; it directly.
12471 (define_insn "*sse_setccsf"
12472   [(set (match_operand:SF 0 "register_operand" "=x")
12473         (match_operator:SF 1 "sse_comparison_operator"
12474           [(match_operand:SF 2 "register_operand" "0")
12475            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12476   "TARGET_SSE"
12477   "cmp%D1ss\t{%3, %0|%0, %3}"
12478   [(set_attr "type" "ssecmp")
12479    (set_attr "mode" "SF")])
12481 (define_insn "*sse_setccdf"
12482   [(set (match_operand:DF 0 "register_operand" "=Y")
12483         (match_operator:DF 1 "sse_comparison_operator"
12484           [(match_operand:DF 2 "register_operand" "0")
12485            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12486   "TARGET_SSE2"
12487   "cmp%D1sd\t{%3, %0|%0, %3}"
12488   [(set_attr "type" "ssecmp")
12489    (set_attr "mode" "DF")])
12491 ;; Basic conditional jump instructions.
12492 ;; We ignore the overflow flag for signed branch instructions.
12494 ;; For all bCOND expanders, also expand the compare or test insn that
12495 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12497 (define_expand "beq"
12498   [(set (pc)
12499         (if_then_else (match_dup 1)
12500                       (label_ref (match_operand 0 "" ""))
12501                       (pc)))]
12502   ""
12503   "ix86_expand_branch (EQ, operands[0]); DONE;")
12505 (define_expand "bne"
12506   [(set (pc)
12507         (if_then_else (match_dup 1)
12508                       (label_ref (match_operand 0 "" ""))
12509                       (pc)))]
12510   ""
12511   "ix86_expand_branch (NE, operands[0]); DONE;")
12513 (define_expand "bgt"
12514   [(set (pc)
12515         (if_then_else (match_dup 1)
12516                       (label_ref (match_operand 0 "" ""))
12517                       (pc)))]
12518   ""
12519   "ix86_expand_branch (GT, operands[0]); DONE;")
12521 (define_expand "bgtu"
12522   [(set (pc)
12523         (if_then_else (match_dup 1)
12524                       (label_ref (match_operand 0 "" ""))
12525                       (pc)))]
12526   ""
12527   "ix86_expand_branch (GTU, operands[0]); DONE;")
12529 (define_expand "blt"
12530   [(set (pc)
12531         (if_then_else (match_dup 1)
12532                       (label_ref (match_operand 0 "" ""))
12533                       (pc)))]
12534   ""
12535   "ix86_expand_branch (LT, operands[0]); DONE;")
12537 (define_expand "bltu"
12538   [(set (pc)
12539         (if_then_else (match_dup 1)
12540                       (label_ref (match_operand 0 "" ""))
12541                       (pc)))]
12542   ""
12543   "ix86_expand_branch (LTU, operands[0]); DONE;")
12545 (define_expand "bge"
12546   [(set (pc)
12547         (if_then_else (match_dup 1)
12548                       (label_ref (match_operand 0 "" ""))
12549                       (pc)))]
12550   ""
12551   "ix86_expand_branch (GE, operands[0]); DONE;")
12553 (define_expand "bgeu"
12554   [(set (pc)
12555         (if_then_else (match_dup 1)
12556                       (label_ref (match_operand 0 "" ""))
12557                       (pc)))]
12558   ""
12559   "ix86_expand_branch (GEU, operands[0]); DONE;")
12561 (define_expand "ble"
12562   [(set (pc)
12563         (if_then_else (match_dup 1)
12564                       (label_ref (match_operand 0 "" ""))
12565                       (pc)))]
12566   ""
12567   "ix86_expand_branch (LE, operands[0]); DONE;")
12569 (define_expand "bleu"
12570   [(set (pc)
12571         (if_then_else (match_dup 1)
12572                       (label_ref (match_operand 0 "" ""))
12573                       (pc)))]
12574   ""
12575   "ix86_expand_branch (LEU, operands[0]); DONE;")
12577 (define_expand "bunordered"
12578   [(set (pc)
12579         (if_then_else (match_dup 1)
12580                       (label_ref (match_operand 0 "" ""))
12581                       (pc)))]
12582   "TARGET_80387 || TARGET_SSE_MATH"
12583   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12585 (define_expand "bordered"
12586   [(set (pc)
12587         (if_then_else (match_dup 1)
12588                       (label_ref (match_operand 0 "" ""))
12589                       (pc)))]
12590   "TARGET_80387 || TARGET_SSE_MATH"
12591   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12593 (define_expand "buneq"
12594   [(set (pc)
12595         (if_then_else (match_dup 1)
12596                       (label_ref (match_operand 0 "" ""))
12597                       (pc)))]
12598   "TARGET_80387 || TARGET_SSE_MATH"
12599   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12601 (define_expand "bunge"
12602   [(set (pc)
12603         (if_then_else (match_dup 1)
12604                       (label_ref (match_operand 0 "" ""))
12605                       (pc)))]
12606   "TARGET_80387 || TARGET_SSE_MATH"
12607   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12609 (define_expand "bungt"
12610   [(set (pc)
12611         (if_then_else (match_dup 1)
12612                       (label_ref (match_operand 0 "" ""))
12613                       (pc)))]
12614   "TARGET_80387 || TARGET_SSE_MATH"
12615   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12617 (define_expand "bunle"
12618   [(set (pc)
12619         (if_then_else (match_dup 1)
12620                       (label_ref (match_operand 0 "" ""))
12621                       (pc)))]
12622   "TARGET_80387 || TARGET_SSE_MATH"
12623   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12625 (define_expand "bunlt"
12626   [(set (pc)
12627         (if_then_else (match_dup 1)
12628                       (label_ref (match_operand 0 "" ""))
12629                       (pc)))]
12630   "TARGET_80387 || TARGET_SSE_MATH"
12631   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12633 (define_expand "bltgt"
12634   [(set (pc)
12635         (if_then_else (match_dup 1)
12636                       (label_ref (match_operand 0 "" ""))
12637                       (pc)))]
12638   "TARGET_80387 || TARGET_SSE_MATH"
12639   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12641 (define_insn "*jcc_1"
12642   [(set (pc)
12643         (if_then_else (match_operator 1 "ix86_comparison_operator"
12644                                       [(reg FLAGS_REG) (const_int 0)])
12645                       (label_ref (match_operand 0 "" ""))
12646                       (pc)))]
12647   ""
12648   "%+j%C1\t%l0"
12649   [(set_attr "type" "ibr")
12650    (set_attr "modrm" "0")
12651    (set (attr "length")
12652            (if_then_else (and (ge (minus (match_dup 0) (pc))
12653                                   (const_int -126))
12654                               (lt (minus (match_dup 0) (pc))
12655                                   (const_int 128)))
12656              (const_int 2)
12657              (const_int 6)))])
12659 (define_insn "*jcc_2"
12660   [(set (pc)
12661         (if_then_else (match_operator 1 "ix86_comparison_operator"
12662                                       [(reg FLAGS_REG) (const_int 0)])
12663                       (pc)
12664                       (label_ref (match_operand 0 "" ""))))]
12665   ""
12666   "%+j%c1\t%l0"
12667   [(set_attr "type" "ibr")
12668    (set_attr "modrm" "0")
12669    (set (attr "length")
12670            (if_then_else (and (ge (minus (match_dup 0) (pc))
12671                                   (const_int -126))
12672                               (lt (minus (match_dup 0) (pc))
12673                                   (const_int 128)))
12674              (const_int 2)
12675              (const_int 6)))])
12677 ;; In general it is not safe to assume too much about CCmode registers,
12678 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12679 ;; conditions this is safe on x86, so help combine not create
12681 ;;      seta    %al
12682 ;;      testb   %al, %al
12683 ;;      je      Lfoo
12685 (define_split 
12686   [(set (pc)
12687         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12688                                       [(reg FLAGS_REG) (const_int 0)])
12689                           (const_int 0))
12690                       (label_ref (match_operand 1 "" ""))
12691                       (pc)))]
12692   ""
12693   [(set (pc)
12694         (if_then_else (match_dup 0)
12695                       (label_ref (match_dup 1))
12696                       (pc)))]
12698   PUT_MODE (operands[0], VOIDmode);
12700   
12701 (define_split 
12702   [(set (pc)
12703         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12704                                       [(reg FLAGS_REG) (const_int 0)])
12705                           (const_int 0))
12706                       (label_ref (match_operand 1 "" ""))
12707                       (pc)))]
12708   ""
12709   [(set (pc)
12710         (if_then_else (match_dup 0)
12711                       (label_ref (match_dup 1))
12712                       (pc)))]
12714   rtx new_op0 = copy_rtx (operands[0]);
12715   operands[0] = new_op0;
12716   PUT_MODE (new_op0, VOIDmode);
12717   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12718                                              GET_MODE (XEXP (new_op0, 0))));
12720   /* Make sure that (a) the CCmode we have for the flags is strong
12721      enough for the reversed compare or (b) we have a valid FP compare.  */
12722   if (! ix86_comparison_operator (new_op0, VOIDmode))
12723     FAIL;
12726 ;; Define combination compare-and-branch fp compare instructions to use
12727 ;; during early optimization.  Splitting the operation apart early makes
12728 ;; for bad code when we want to reverse the operation.
12730 (define_insn "*fp_jcc_1_mixed"
12731   [(set (pc)
12732         (if_then_else (match_operator 0 "comparison_operator"
12733                         [(match_operand 1 "register_operand" "f#x,x#f")
12734                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12735           (label_ref (match_operand 3 "" ""))
12736           (pc)))
12737    (clobber (reg:CCFP FPSR_REG))
12738    (clobber (reg:CCFP FLAGS_REG))]
12739   "TARGET_MIX_SSE_I387
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_1_sse"
12746   [(set (pc)
12747         (if_then_else (match_operator 0 "comparison_operator"
12748                         [(match_operand 1 "register_operand" "x")
12749                          (match_operand 2 "nonimmediate_operand" "xm")])
12750           (label_ref (match_operand 3 "" ""))
12751           (pc)))
12752    (clobber (reg:CCFP FPSR_REG))
12753    (clobber (reg:CCFP FLAGS_REG))]
12754   "TARGET_SSE_MATH
12755    && SSE_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_1_387"
12761   [(set (pc)
12762         (if_then_else (match_operator 0 "comparison_operator"
12763                         [(match_operand 1 "register_operand" "f")
12764                          (match_operand 2 "register_operand" "f")])
12765           (label_ref (match_operand 3 "" ""))
12766           (pc)))
12767    (clobber (reg:CCFP FPSR_REG))
12768    (clobber (reg:CCFP FLAGS_REG))]
12769   "TARGET_CMOVE && TARGET_80387
12770    && FLOAT_MODE_P (GET_MODE (operands[1]))
12771    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12772    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12773   "#")
12775 (define_insn "*fp_jcc_2_mixed"
12776   [(set (pc)
12777         (if_then_else (match_operator 0 "comparison_operator"
12778                         [(match_operand 1 "register_operand" "f#x,x#f")
12779                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12780           (pc)
12781           (label_ref (match_operand 3 "" ""))))
12782    (clobber (reg:CCFP FPSR_REG))
12783    (clobber (reg:CCFP FLAGS_REG))]
12784   "TARGET_MIX_SSE_I387
12785    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12786    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12787    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12788   "#")
12790 (define_insn "*fp_jcc_2_sse"
12791   [(set (pc)
12792         (if_then_else (match_operator 0 "comparison_operator"
12793                         [(match_operand 1 "register_operand" "x")
12794                          (match_operand 2 "nonimmediate_operand" "xm")])
12795           (pc)
12796           (label_ref (match_operand 3 "" ""))))
12797    (clobber (reg:CCFP FPSR_REG))
12798    (clobber (reg:CCFP FLAGS_REG))]
12799   "TARGET_SSE_MATH
12800    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12801    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12802    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12803   "#")
12805 (define_insn "*fp_jcc_2_387"
12806   [(set (pc)
12807         (if_then_else (match_operator 0 "comparison_operator"
12808                         [(match_operand 1 "register_operand" "f")
12809                          (match_operand 2 "register_operand" "f")])
12810           (pc)
12811           (label_ref (match_operand 3 "" ""))))
12812    (clobber (reg:CCFP FPSR_REG))
12813    (clobber (reg:CCFP FLAGS_REG))]
12814   "TARGET_CMOVE && TARGET_80387
12815    && FLOAT_MODE_P (GET_MODE (operands[1]))
12816    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12817    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12818   "#")
12820 (define_insn "*fp_jcc_3_387"
12821   [(set (pc)
12822         (if_then_else (match_operator 0 "comparison_operator"
12823                         [(match_operand 1 "register_operand" "f")
12824                          (match_operand 2 "nonimmediate_operand" "fm")])
12825           (label_ref (match_operand 3 "" ""))
12826           (pc)))
12827    (clobber (reg:CCFP FPSR_REG))
12828    (clobber (reg:CCFP FLAGS_REG))
12829    (clobber (match_scratch:HI 4 "=a"))]
12830   "TARGET_80387
12831    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12832    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12833    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12834    && SELECT_CC_MODE (GET_CODE (operands[0]),
12835                       operands[1], operands[2]) == CCFPmode
12836    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12837   "#")
12839 (define_insn "*fp_jcc_4_387"
12840   [(set (pc)
12841         (if_then_else (match_operator 0 "comparison_operator"
12842                         [(match_operand 1 "register_operand" "f")
12843                          (match_operand 2 "nonimmediate_operand" "fm")])
12844           (pc)
12845           (label_ref (match_operand 3 "" ""))))
12846    (clobber (reg:CCFP FPSR_REG))
12847    (clobber (reg:CCFP FLAGS_REG))
12848    (clobber (match_scratch:HI 4 "=a"))]
12849   "TARGET_80387
12850    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12851    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12852    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12853    && SELECT_CC_MODE (GET_CODE (operands[0]),
12854                       operands[1], operands[2]) == CCFPmode
12855    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12856   "#")
12858 (define_insn "*fp_jcc_5_387"
12859   [(set (pc)
12860         (if_then_else (match_operator 0 "comparison_operator"
12861                         [(match_operand 1 "register_operand" "f")
12862                          (match_operand 2 "register_operand" "f")])
12863           (label_ref (match_operand 3 "" ""))
12864           (pc)))
12865    (clobber (reg:CCFP FPSR_REG))
12866    (clobber (reg:CCFP FLAGS_REG))
12867    (clobber (match_scratch:HI 4 "=a"))]
12868   "TARGET_80387
12869    && FLOAT_MODE_P (GET_MODE (operands[1]))
12870    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12871    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12872   "#")
12874 (define_insn "*fp_jcc_6_387"
12875   [(set (pc)
12876         (if_then_else (match_operator 0 "comparison_operator"
12877                         [(match_operand 1 "register_operand" "f")
12878                          (match_operand 2 "register_operand" "f")])
12879           (pc)
12880           (label_ref (match_operand 3 "" ""))))
12881    (clobber (reg:CCFP FPSR_REG))
12882    (clobber (reg:CCFP FLAGS_REG))
12883    (clobber (match_scratch:HI 4 "=a"))]
12884   "TARGET_80387
12885    && FLOAT_MODE_P (GET_MODE (operands[1]))
12886    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12887    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12888   "#")
12890 (define_insn "*fp_jcc_7_387"
12891   [(set (pc)
12892         (if_then_else (match_operator 0 "comparison_operator"
12893                         [(match_operand 1 "register_operand" "f")
12894                          (match_operand 2 "const0_operand" "X")])
12895           (label_ref (match_operand 3 "" ""))
12896           (pc)))
12897    (clobber (reg:CCFP FPSR_REG))
12898    (clobber (reg:CCFP FLAGS_REG))
12899    (clobber (match_scratch:HI 4 "=a"))]
12900   "TARGET_80387
12901    && FLOAT_MODE_P (GET_MODE (operands[1]))
12902    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12903    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12904    && SELECT_CC_MODE (GET_CODE (operands[0]),
12905                       operands[1], operands[2]) == CCFPmode
12906    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12907   "#")
12909 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12910 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12911 ;; with a precedence over other operators and is always put in the first
12912 ;; place. Swap condition and operands to match ficom instruction.
12914 (define_insn "*fp_jcc_8<mode>_387"
12915   [(set (pc)
12916         (if_then_else (match_operator 0 "comparison_operator"
12917                         [(match_operator 1 "float_operator"
12918                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12919                            (match_operand 3 "register_operand" "f,f")])
12920           (label_ref (match_operand 4 "" ""))
12921           (pc)))
12922    (clobber (reg:CCFP FPSR_REG))
12923    (clobber (reg:CCFP FLAGS_REG))
12924    (clobber (match_scratch:HI 5 "=a,a"))]
12925   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
12926    && FLOAT_MODE_P (GET_MODE (operands[3]))
12927    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12928    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12929    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12930    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12931   "#")
12933 (define_split
12934   [(set (pc)
12935         (if_then_else (match_operator 0 "comparison_operator"
12936                         [(match_operand 1 "register_operand" "")
12937                          (match_operand 2 "nonimmediate_operand" "")])
12938           (match_operand 3 "" "")
12939           (match_operand 4 "" "")))
12940    (clobber (reg:CCFP FPSR_REG))
12941    (clobber (reg:CCFP FLAGS_REG))]
12942   "reload_completed"
12943   [(const_int 0)]
12945   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12946                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12947   DONE;
12950 (define_split
12951   [(set (pc)
12952         (if_then_else (match_operator 0 "comparison_operator"
12953                         [(match_operand 1 "register_operand" "")
12954                          (match_operand 2 "general_operand" "")])
12955           (match_operand 3 "" "")
12956           (match_operand 4 "" "")))
12957    (clobber (reg:CCFP FPSR_REG))
12958    (clobber (reg:CCFP FLAGS_REG))
12959    (clobber (match_scratch:HI 5 "=a"))]
12960   "reload_completed"
12961   [(const_int 0)]
12963   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12964                         operands[3], operands[4], operands[5], NULL_RTX);
12965   DONE;
12968 (define_split
12969   [(set (pc)
12970         (if_then_else (match_operator 0 "comparison_operator"
12971                         [(match_operator 1 "float_operator"
12972                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
12973                            (match_operand 3 "register_operand" "")])
12974           (match_operand 4 "" "")
12975           (match_operand 5 "" "")))
12976    (clobber (reg:CCFP FPSR_REG))
12977    (clobber (reg:CCFP FLAGS_REG))
12978    (clobber (match_scratch:HI 6 "=a"))]
12979   "reload_completed"
12980   [(const_int 0)]
12982   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12983   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12984                         operands[3], operands[7],
12985                         operands[4], operands[5], operands[6], NULL_RTX);
12986   DONE;
12989 ;; %%% Kill this when reload knows how to do it.
12990 (define_split
12991   [(set (pc)
12992         (if_then_else (match_operator 0 "comparison_operator"
12993                         [(match_operator 1 "float_operator"
12994                            [(match_operand:X87MODEI12 2 "register_operand" "")])
12995                            (match_operand 3 "register_operand" "")])
12996           (match_operand 4 "" "")
12997           (match_operand 5 "" "")))
12998    (clobber (reg:CCFP FPSR_REG))
12999    (clobber (reg:CCFP FLAGS_REG))
13000    (clobber (match_scratch:HI 6 "=a"))]
13001   "reload_completed"
13002   [(const_int 0)]
13004   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13005   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13006   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13007                         operands[3], operands[7],
13008                         operands[4], operands[5], operands[6], operands[2]);
13009   DONE;
13012 ;; Unconditional and other jump instructions
13014 (define_insn "jump"
13015   [(set (pc)
13016         (label_ref (match_operand 0 "" "")))]
13017   ""
13018   "jmp\t%l0"
13019   [(set_attr "type" "ibr")
13020    (set (attr "length")
13021            (if_then_else (and (ge (minus (match_dup 0) (pc))
13022                                   (const_int -126))
13023                               (lt (minus (match_dup 0) (pc))
13024                                   (const_int 128)))
13025              (const_int 2)
13026              (const_int 5)))
13027    (set_attr "modrm" "0")])
13029 (define_expand "indirect_jump"
13030   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13031   ""
13032   "")
13034 (define_insn "*indirect_jump"
13035   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13036   "!TARGET_64BIT"
13037   "jmp\t%A0"
13038   [(set_attr "type" "ibr")
13039    (set_attr "length_immediate" "0")])
13041 (define_insn "*indirect_jump_rtx64"
13042   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13043   "TARGET_64BIT"
13044   "jmp\t%A0"
13045   [(set_attr "type" "ibr")
13046    (set_attr "length_immediate" "0")])
13048 (define_expand "tablejump"
13049   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13050               (use (label_ref (match_operand 1 "" "")))])]
13051   ""
13053   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13054      relative.  Convert the relative address to an absolute address.  */
13055   if (flag_pic)
13056     {
13057       rtx op0, op1;
13058       enum rtx_code code;
13060       if (TARGET_64BIT)
13061         {
13062           code = PLUS;
13063           op0 = operands[0];
13064           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13065         }
13066       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13067         {
13068           code = PLUS;
13069           op0 = operands[0];
13070           op1 = pic_offset_table_rtx;
13071         }
13072       else
13073         {
13074           code = MINUS;
13075           op0 = pic_offset_table_rtx;
13076           op1 = operands[0];
13077         }
13079       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13080                                          OPTAB_DIRECT);
13081     }
13084 (define_insn "*tablejump_1"
13085   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13086    (use (label_ref (match_operand 1 "" "")))]
13087   "!TARGET_64BIT"
13088   "jmp\t%A0"
13089   [(set_attr "type" "ibr")
13090    (set_attr "length_immediate" "0")])
13092 (define_insn "*tablejump_1_rtx64"
13093   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13094    (use (label_ref (match_operand 1 "" "")))]
13095   "TARGET_64BIT"
13096   "jmp\t%A0"
13097   [(set_attr "type" "ibr")
13098    (set_attr "length_immediate" "0")])
13100 ;; Loop instruction
13102 ;; This is all complicated by the fact that since this is a jump insn
13103 ;; we must handle our own reloads.
13105 (define_expand "doloop_end"
13106   [(use (match_operand 0 "" ""))        ; loop pseudo
13107    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13108    (use (match_operand 2 "" ""))        ; max iterations
13109    (use (match_operand 3 "" ""))        ; loop level 
13110    (use (match_operand 4 "" ""))]       ; label
13111   "!TARGET_64BIT && TARGET_USE_LOOP"
13112   "                                 
13114   /* Only use cloop on innermost loops.  */
13115   if (INTVAL (operands[3]) > 1)
13116     FAIL;
13117   if (GET_MODE (operands[0]) != SImode)
13118     FAIL;
13119   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13120                                            operands[0]));
13121   DONE;
13124 (define_insn "doloop_end_internal"
13125   [(set (pc)
13126         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13127                           (const_int 1))
13128                       (label_ref (match_operand 0 "" ""))
13129                       (pc)))
13130    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13131         (plus:SI (match_dup 1)
13132                  (const_int -1)))
13133    (clobber (match_scratch:SI 3 "=X,X,r"))
13134    (clobber (reg:CC FLAGS_REG))]
13135   "!TARGET_64BIT && TARGET_USE_LOOP
13136    && (reload_in_progress || reload_completed
13137        || register_operand (operands[2], VOIDmode))"
13139   if (which_alternative != 0)
13140     return "#";
13141   if (get_attr_length (insn) == 2)
13142     return "%+loop\t%l0";
13143   else
13144     return "dec{l}\t%1\;%+jne\t%l0";
13146   [(set (attr "length")
13147         (if_then_else (and (eq_attr "alternative" "0")
13148                            (and (ge (minus (match_dup 0) (pc))
13149                                     (const_int -126))
13150                                 (lt (minus (match_dup 0) (pc))
13151                                     (const_int 128))))
13152                       (const_int 2)
13153                       (const_int 16)))
13154    ;; We don't know the type before shorten branches.  Optimistically expect
13155    ;; the loop instruction to match.
13156    (set (attr "type") (const_string "ibr"))])
13158 (define_split
13159   [(set (pc)
13160         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13161                           (const_int 1))
13162                       (match_operand 0 "" "")
13163                       (pc)))
13164    (set (match_dup 1)
13165         (plus:SI (match_dup 1)
13166                  (const_int -1)))
13167    (clobber (match_scratch:SI 2 ""))
13168    (clobber (reg:CC FLAGS_REG))]
13169   "!TARGET_64BIT && TARGET_USE_LOOP
13170    && reload_completed
13171    && REGNO (operands[1]) != 2"
13172   [(parallel [(set (reg:CCZ FLAGS_REG)
13173                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13174                                  (const_int 0)))
13175               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13176    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13177                            (match_dup 0)
13178                            (pc)))]
13179   "")
13180   
13181 (define_split
13182   [(set (pc)
13183         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13184                           (const_int 1))
13185                       (match_operand 0 "" "")
13186                       (pc)))
13187    (set (match_operand:SI 2 "nonimmediate_operand" "")
13188         (plus:SI (match_dup 1)
13189                  (const_int -1)))
13190    (clobber (match_scratch:SI 3 ""))
13191    (clobber (reg:CC FLAGS_REG))]
13192   "!TARGET_64BIT && TARGET_USE_LOOP
13193    && reload_completed
13194    && (! REG_P (operands[2])
13195        || ! rtx_equal_p (operands[1], operands[2]))"
13196   [(set (match_dup 3) (match_dup 1))
13197    (parallel [(set (reg:CCZ FLAGS_REG)
13198                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13199                                 (const_int 0)))
13200               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13201    (set (match_dup 2) (match_dup 3))
13202    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13203                            (match_dup 0)
13204                            (pc)))]
13205   "")
13207 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13209 (define_peephole2
13210   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13211    (set (match_operand:QI 1 "register_operand" "")
13212         (match_operator:QI 2 "ix86_comparison_operator"
13213           [(reg FLAGS_REG) (const_int 0)]))
13214    (set (match_operand 3 "q_regs_operand" "")
13215         (zero_extend (match_dup 1)))]
13216   "(peep2_reg_dead_p (3, operands[1])
13217     || operands_match_p (operands[1], operands[3]))
13218    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13219   [(set (match_dup 4) (match_dup 0))
13220    (set (strict_low_part (match_dup 5))
13221         (match_dup 2))]
13223   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13224   operands[5] = gen_lowpart (QImode, operands[3]);
13225   ix86_expand_clear (operands[3]);
13228 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13230 (define_peephole2
13231   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13232    (set (match_operand:QI 1 "register_operand" "")
13233         (match_operator:QI 2 "ix86_comparison_operator"
13234           [(reg FLAGS_REG) (const_int 0)]))
13235    (parallel [(set (match_operand 3 "q_regs_operand" "")
13236                    (zero_extend (match_dup 1)))
13237               (clobber (reg:CC FLAGS_REG))])]
13238   "(peep2_reg_dead_p (3, operands[1])
13239     || operands_match_p (operands[1], operands[3]))
13240    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13241   [(set (match_dup 4) (match_dup 0))
13242    (set (strict_low_part (match_dup 5))
13243         (match_dup 2))]
13245   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13246   operands[5] = gen_lowpart (QImode, operands[3]);
13247   ix86_expand_clear (operands[3]);
13250 ;; Call instructions.
13252 ;; The predicates normally associated with named expanders are not properly
13253 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13254 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13256 ;; Call subroutine returning no value.
13258 (define_expand "call_pop"
13259   [(parallel [(call (match_operand:QI 0 "" "")
13260                     (match_operand:SI 1 "" ""))
13261               (set (reg:SI SP_REG)
13262                    (plus:SI (reg:SI SP_REG)
13263                             (match_operand:SI 3 "" "")))])]
13264   "!TARGET_64BIT"
13266   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13267   DONE;
13270 (define_insn "*call_pop_0"
13271   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13272          (match_operand:SI 1 "" ""))
13273    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13274                             (match_operand:SI 2 "immediate_operand" "")))]
13275   "!TARGET_64BIT"
13277   if (SIBLING_CALL_P (insn))
13278     return "jmp\t%P0";
13279   else
13280     return "call\t%P0";
13282   [(set_attr "type" "call")])
13283   
13284 (define_insn "*call_pop_1"
13285   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13286          (match_operand:SI 1 "" ""))
13287    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13288                             (match_operand:SI 2 "immediate_operand" "i")))]
13289   "!TARGET_64BIT"
13291   if (constant_call_address_operand (operands[0], Pmode))
13292     {
13293       if (SIBLING_CALL_P (insn))
13294         return "jmp\t%P0";
13295       else
13296         return "call\t%P0";
13297     }
13298   if (SIBLING_CALL_P (insn))
13299     return "jmp\t%A0";
13300   else
13301     return "call\t%A0";
13303   [(set_attr "type" "call")])
13305 (define_expand "call"
13306   [(call (match_operand:QI 0 "" "")
13307          (match_operand 1 "" ""))
13308    (use (match_operand 2 "" ""))]
13309   ""
13311   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13312   DONE;
13315 (define_expand "sibcall"
13316   [(call (match_operand:QI 0 "" "")
13317          (match_operand 1 "" ""))
13318    (use (match_operand 2 "" ""))]
13319   ""
13321   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13322   DONE;
13325 (define_insn "*call_0"
13326   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13327          (match_operand 1 "" ""))]
13328   ""
13330   if (SIBLING_CALL_P (insn))
13331     return "jmp\t%P0";
13332   else
13333     return "call\t%P0";
13335   [(set_attr "type" "call")])
13337 (define_insn "*call_1"
13338   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13339          (match_operand 1 "" ""))]
13340   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13342   if (constant_call_address_operand (operands[0], Pmode))
13343     return "call\t%P0";
13344   return "call\t%A0";
13346   [(set_attr "type" "call")])
13348 (define_insn "*sibcall_1"
13349   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13350          (match_operand 1 "" ""))]
13351   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13353   if (constant_call_address_operand (operands[0], Pmode))
13354     return "jmp\t%P0";
13355   return "jmp\t%A0";
13357   [(set_attr "type" "call")])
13359 (define_insn "*call_1_rex64"
13360   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13361          (match_operand 1 "" ""))]
13362   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13364   if (constant_call_address_operand (operands[0], Pmode))
13365     return "call\t%P0";
13366   return "call\t%A0";
13368   [(set_attr "type" "call")])
13370 (define_insn "*sibcall_1_rex64"
13371   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13372          (match_operand 1 "" ""))]
13373   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13374   "jmp\t%P0"
13375   [(set_attr "type" "call")])
13377 (define_insn "*sibcall_1_rex64_v"
13378   [(call (mem:QI (reg:DI 40))
13379          (match_operand 0 "" ""))]
13380   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13381   "jmp\t*%%r11"
13382   [(set_attr "type" "call")])
13385 ;; Call subroutine, returning value in operand 0
13387 (define_expand "call_value_pop"
13388   [(parallel [(set (match_operand 0 "" "")
13389                    (call (match_operand:QI 1 "" "")
13390                          (match_operand:SI 2 "" "")))
13391               (set (reg:SI SP_REG)
13392                    (plus:SI (reg:SI SP_REG)
13393                             (match_operand:SI 4 "" "")))])]
13394   "!TARGET_64BIT"
13396   ix86_expand_call (operands[0], operands[1], operands[2],
13397                     operands[3], operands[4], 0);
13398   DONE;
13401 (define_expand "call_value"
13402   [(set (match_operand 0 "" "")
13403         (call (match_operand:QI 1 "" "")
13404               (match_operand:SI 2 "" "")))
13405    (use (match_operand:SI 3 "" ""))]
13406   ;; Operand 2 not used on the i386.
13407   ""
13409   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13410   DONE;
13413 (define_expand "sibcall_value"
13414   [(set (match_operand 0 "" "")
13415         (call (match_operand:QI 1 "" "")
13416               (match_operand:SI 2 "" "")))
13417    (use (match_operand:SI 3 "" ""))]
13418   ;; Operand 2 not used on the i386.
13419   ""
13421   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13422   DONE;
13425 ;; Call subroutine returning any type.
13427 (define_expand "untyped_call"
13428   [(parallel [(call (match_operand 0 "" "")
13429                     (const_int 0))
13430               (match_operand 1 "" "")
13431               (match_operand 2 "" "")])]
13432   ""
13434   int i;
13436   /* In order to give reg-stack an easier job in validating two
13437      coprocessor registers as containing a possible return value,
13438      simply pretend the untyped call returns a complex long double
13439      value.  */
13441   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13442                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13443                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13444                     NULL, 0);
13446   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13447     {
13448       rtx set = XVECEXP (operands[2], 0, i);
13449       emit_move_insn (SET_DEST (set), SET_SRC (set));
13450     }
13452   /* The optimizer does not know that the call sets the function value
13453      registers we stored in the result block.  We avoid problems by
13454      claiming that all hard registers are used and clobbered at this
13455      point.  */
13456   emit_insn (gen_blockage (const0_rtx));
13458   DONE;
13461 ;; Prologue and epilogue instructions
13463 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13464 ;; all of memory.  This blocks insns from being moved across this point.
13466 (define_insn "blockage"
13467   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13468   ""
13469   ""
13470   [(set_attr "length" "0")])
13472 ;; Insn emitted into the body of a function to return from a function.
13473 ;; This is only done if the function's epilogue is known to be simple.
13474 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13476 (define_expand "return"
13477   [(return)]
13478   "ix86_can_use_return_insn_p ()"
13480   if (current_function_pops_args)
13481     {
13482       rtx popc = GEN_INT (current_function_pops_args);
13483       emit_jump_insn (gen_return_pop_internal (popc));
13484       DONE;
13485     }
13488 (define_insn "return_internal"
13489   [(return)]
13490   "reload_completed"
13491   "ret"
13492   [(set_attr "length" "1")
13493    (set_attr "length_immediate" "0")
13494    (set_attr "modrm" "0")])
13496 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13497 ;; instruction Athlon and K8 have.
13499 (define_insn "return_internal_long"
13500   [(return)
13501    (unspec [(const_int 0)] UNSPEC_REP)]
13502   "reload_completed"
13503   "rep {;} ret"
13504   [(set_attr "length" "1")
13505    (set_attr "length_immediate" "0")
13506    (set_attr "prefix_rep" "1")
13507    (set_attr "modrm" "0")])
13509 (define_insn "return_pop_internal"
13510   [(return)
13511    (use (match_operand:SI 0 "const_int_operand" ""))]
13512   "reload_completed"
13513   "ret\t%0"
13514   [(set_attr "length" "3")
13515    (set_attr "length_immediate" "2")
13516    (set_attr "modrm" "0")])
13518 (define_insn "return_indirect_internal"
13519   [(return)
13520    (use (match_operand:SI 0 "register_operand" "r"))]
13521   "reload_completed"
13522   "jmp\t%A0"
13523   [(set_attr "type" "ibr")
13524    (set_attr "length_immediate" "0")])
13526 (define_insn "nop"
13527   [(const_int 0)]
13528   ""
13529   "nop"
13530   [(set_attr "length" "1")
13531    (set_attr "length_immediate" "0")
13532    (set_attr "modrm" "0")])
13534 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13535 ;; branch prediction penalty for the third jump in a 16-byte
13536 ;; block on K8.
13538 (define_insn "align"
13539   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13540   ""
13542 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13543   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13544 #else
13545   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13546      The align insn is used to avoid 3 jump instructions in the row to improve
13547      branch prediction and the benefits hardly outweight the cost of extra 8
13548      nops on the average inserted by full alignment pseudo operation.  */
13549 #endif
13550   return "";
13552   [(set_attr "length" "16")])
13554 (define_expand "prologue"
13555   [(const_int 1)]
13556   ""
13557   "ix86_expand_prologue (); DONE;")
13559 (define_insn "set_got"
13560   [(set (match_operand:SI 0 "register_operand" "=r")
13561         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13562    (clobber (reg:CC FLAGS_REG))]
13563   "!TARGET_64BIT"
13564   { return output_set_got (operands[0]); }
13565   [(set_attr "type" "multi")
13566    (set_attr "length" "12")])
13568 (define_expand "epilogue"
13569   [(const_int 1)]
13570   ""
13571   "ix86_expand_epilogue (1); DONE;")
13573 (define_expand "sibcall_epilogue"
13574   [(const_int 1)]
13575   ""
13576   "ix86_expand_epilogue (0); DONE;")
13578 (define_expand "eh_return"
13579   [(use (match_operand 0 "register_operand" ""))]
13580   ""
13582   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13584   /* Tricky bit: we write the address of the handler to which we will
13585      be returning into someone else's stack frame, one word below the
13586      stack address we wish to restore.  */
13587   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13588   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13589   tmp = gen_rtx_MEM (Pmode, tmp);
13590   emit_move_insn (tmp, ra);
13592   if (Pmode == SImode)
13593     emit_jump_insn (gen_eh_return_si (sa));
13594   else
13595     emit_jump_insn (gen_eh_return_di (sa));
13596   emit_barrier ();
13597   DONE;
13600 (define_insn_and_split "eh_return_si"
13601   [(set (pc) 
13602         (unspec [(match_operand:SI 0 "register_operand" "c")]
13603                  UNSPEC_EH_RETURN))]
13604   "!TARGET_64BIT"
13605   "#"
13606   "reload_completed"
13607   [(const_int 1)]
13608   "ix86_expand_epilogue (2); DONE;")
13610 (define_insn_and_split "eh_return_di"
13611   [(set (pc) 
13612         (unspec [(match_operand:DI 0 "register_operand" "c")]
13613                  UNSPEC_EH_RETURN))]
13614   "TARGET_64BIT"
13615   "#"
13616   "reload_completed"
13617   [(const_int 1)]
13618   "ix86_expand_epilogue (2); DONE;")
13620 (define_insn "leave"
13621   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13622    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13623    (clobber (mem:BLK (scratch)))]
13624   "!TARGET_64BIT"
13625   "leave"
13626   [(set_attr "type" "leave")])
13628 (define_insn "leave_rex64"
13629   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13630    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13631    (clobber (mem:BLK (scratch)))]
13632   "TARGET_64BIT"
13633   "leave"
13634   [(set_attr "type" "leave")])
13636 (define_expand "ffssi2"
13637   [(parallel
13638      [(set (match_operand:SI 0 "register_operand" "") 
13639            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13640       (clobber (match_scratch:SI 2 ""))
13641       (clobber (reg:CC FLAGS_REG))])]
13642   ""
13643   "")
13645 (define_insn_and_split "*ffs_cmove"
13646   [(set (match_operand:SI 0 "register_operand" "=r") 
13647         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13648    (clobber (match_scratch:SI 2 "=&r"))
13649    (clobber (reg:CC FLAGS_REG))]
13650   "TARGET_CMOVE"
13651   "#"
13652   "&& reload_completed"
13653   [(set (match_dup 2) (const_int -1))
13654    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13655               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13656    (set (match_dup 0) (if_then_else:SI
13657                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13658                         (match_dup 2)
13659                         (match_dup 0)))
13660    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13661               (clobber (reg:CC FLAGS_REG))])]
13662   "")
13664 (define_insn_and_split "*ffs_no_cmove"
13665   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13666         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13667    (clobber (match_scratch:SI 2 "=&q"))
13668    (clobber (reg:CC FLAGS_REG))]
13669   ""
13670   "#"
13671   "reload_completed"
13672   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13673               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13674    (set (strict_low_part (match_dup 3))
13675         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13676    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13677               (clobber (reg:CC FLAGS_REG))])
13678    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13679               (clobber (reg:CC FLAGS_REG))])
13680    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13681               (clobber (reg:CC FLAGS_REG))])]
13683   operands[3] = gen_lowpart (QImode, operands[2]);
13684   ix86_expand_clear (operands[2]);
13687 (define_insn "*ffssi_1"
13688   [(set (reg:CCZ FLAGS_REG)
13689         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13690                      (const_int 0)))
13691    (set (match_operand:SI 0 "register_operand" "=r")
13692         (ctz:SI (match_dup 1)))]
13693   ""
13694   "bsf{l}\t{%1, %0|%0, %1}"
13695   [(set_attr "prefix_0f" "1")])
13697 (define_expand "ffsdi2"
13698   [(parallel
13699      [(set (match_operand:DI 0 "register_operand" "") 
13700            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13701       (clobber (match_scratch:DI 2 ""))
13702       (clobber (reg:CC FLAGS_REG))])]
13703   "TARGET_64BIT && TARGET_CMOVE"
13704   "")
13706 (define_insn_and_split "*ffs_rex64"
13707   [(set (match_operand:DI 0 "register_operand" "=r") 
13708         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13709    (clobber (match_scratch:DI 2 "=&r"))
13710    (clobber (reg:CC FLAGS_REG))]
13711   "TARGET_64BIT && TARGET_CMOVE"
13712   "#"
13713   "&& reload_completed"
13714   [(set (match_dup 2) (const_int -1))
13715    (parallel [(set (reg:CCZ FLAGS_REG)
13716                    (compare:CCZ (match_dup 1) (const_int 0)))
13717               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13718    (set (match_dup 0) (if_then_else:DI
13719                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13720                         (match_dup 2)
13721                         (match_dup 0)))
13722    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13723               (clobber (reg:CC FLAGS_REG))])]
13724   "")
13726 (define_insn "*ffsdi_1"
13727   [(set (reg:CCZ FLAGS_REG)
13728         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13729                      (const_int 0)))
13730    (set (match_operand:DI 0 "register_operand" "=r")
13731         (ctz:DI (match_dup 1)))]
13732   "TARGET_64BIT"
13733   "bsf{q}\t{%1, %0|%0, %1}"
13734   [(set_attr "prefix_0f" "1")])
13736 (define_insn "ctzsi2"
13737   [(set (match_operand:SI 0 "register_operand" "=r")
13738         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13739    (clobber (reg:CC FLAGS_REG))]
13740   ""
13741   "bsf{l}\t{%1, %0|%0, %1}"
13742   [(set_attr "prefix_0f" "1")])
13744 (define_insn "ctzdi2"
13745   [(set (match_operand:DI 0 "register_operand" "=r")
13746         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13747    (clobber (reg:CC FLAGS_REG))]
13748   "TARGET_64BIT"
13749   "bsf{q}\t{%1, %0|%0, %1}"
13750   [(set_attr "prefix_0f" "1")])
13752 (define_expand "clzsi2"
13753   [(parallel
13754      [(set (match_operand:SI 0 "register_operand" "")
13755            (minus:SI (const_int 31)
13756                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13757       (clobber (reg:CC FLAGS_REG))])
13758    (parallel
13759      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13760       (clobber (reg:CC FLAGS_REG))])]
13761   ""
13762   "")
13764 (define_insn "*bsr"
13765   [(set (match_operand:SI 0 "register_operand" "=r")
13766         (minus:SI (const_int 31)
13767                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13768    (clobber (reg:CC FLAGS_REG))]
13769   ""
13770   "bsr{l}\t{%1, %0|%0, %1}"
13771   [(set_attr "prefix_0f" "1")])
13773 (define_expand "clzdi2"
13774   [(parallel
13775      [(set (match_operand:DI 0 "register_operand" "")
13776            (minus:DI (const_int 63)
13777                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13778       (clobber (reg:CC FLAGS_REG))])
13779    (parallel
13780      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13781       (clobber (reg:CC FLAGS_REG))])]
13782   "TARGET_64BIT"
13783   "")
13785 (define_insn "*bsr_rex64"
13786   [(set (match_operand:DI 0 "register_operand" "=r")
13787         (minus:DI (const_int 63)
13788                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13789    (clobber (reg:CC FLAGS_REG))]
13790   "TARGET_64BIT"
13791   "bsr{q}\t{%1, %0|%0, %1}"
13792   [(set_attr "prefix_0f" "1")])
13794 ;; Thread-local storage patterns for ELF.
13796 ;; Note that these code sequences must appear exactly as shown
13797 ;; in order to allow linker relaxation.
13799 (define_insn "*tls_global_dynamic_32_gnu"
13800   [(set (match_operand:SI 0 "register_operand" "=a")
13801         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13802                     (match_operand:SI 2 "tls_symbolic_operand" "")
13803                     (match_operand:SI 3 "call_insn_operand" "")]
13804                     UNSPEC_TLS_GD))
13805    (clobber (match_scratch:SI 4 "=d"))
13806    (clobber (match_scratch:SI 5 "=c"))
13807    (clobber (reg:CC FLAGS_REG))]
13808   "!TARGET_64BIT && TARGET_GNU_TLS"
13809   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13810   [(set_attr "type" "multi")
13811    (set_attr "length" "12")])
13813 (define_insn "*tls_global_dynamic_32_sun"
13814   [(set (match_operand:SI 0 "register_operand" "=a")
13815         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13816                     (match_operand:SI 2 "tls_symbolic_operand" "")
13817                     (match_operand:SI 3 "call_insn_operand" "")]
13818                     UNSPEC_TLS_GD))
13819    (clobber (match_scratch:SI 4 "=d"))
13820    (clobber (match_scratch:SI 5 "=c"))
13821    (clobber (reg:CC FLAGS_REG))]
13822   "!TARGET_64BIT && TARGET_SUN_TLS"
13823   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13824         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13825   [(set_attr "type" "multi")
13826    (set_attr "length" "14")])
13828 (define_expand "tls_global_dynamic_32"
13829   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13830                    (unspec:SI
13831                     [(match_dup 2)
13832                      (match_operand:SI 1 "tls_symbolic_operand" "")
13833                      (match_dup 3)]
13834                     UNSPEC_TLS_GD))
13835               (clobber (match_scratch:SI 4 ""))
13836               (clobber (match_scratch:SI 5 ""))
13837               (clobber (reg:CC FLAGS_REG))])]
13838   ""
13840   if (flag_pic)
13841     operands[2] = pic_offset_table_rtx;
13842   else
13843     {
13844       operands[2] = gen_reg_rtx (Pmode);
13845       emit_insn (gen_set_got (operands[2]));
13846     }
13847   operands[3] = ix86_tls_get_addr ();
13850 (define_insn "*tls_global_dynamic_64"
13851   [(set (match_operand:DI 0 "register_operand" "=a")
13852         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13853                       (match_operand:DI 3 "" "")))
13854    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13855               UNSPEC_TLS_GD)]
13856   "TARGET_64BIT"
13857   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13858   [(set_attr "type" "multi")
13859    (set_attr "length" "16")])
13861 (define_expand "tls_global_dynamic_64"
13862   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13863                    (call (mem:QI (match_dup 2)) (const_int 0)))
13864               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13865                          UNSPEC_TLS_GD)])]
13866   ""
13868   operands[2] = ix86_tls_get_addr ();
13871 (define_insn "*tls_local_dynamic_base_32_gnu"
13872   [(set (match_operand:SI 0 "register_operand" "=a")
13873         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13874                     (match_operand:SI 2 "call_insn_operand" "")]
13875                    UNSPEC_TLS_LD_BASE))
13876    (clobber (match_scratch:SI 3 "=d"))
13877    (clobber (match_scratch:SI 4 "=c"))
13878    (clobber (reg:CC FLAGS_REG))]
13879   "!TARGET_64BIT && TARGET_GNU_TLS"
13880   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13881   [(set_attr "type" "multi")
13882    (set_attr "length" "11")])
13884 (define_insn "*tls_local_dynamic_base_32_sun"
13885   [(set (match_operand:SI 0 "register_operand" "=a")
13886         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13887                     (match_operand:SI 2 "call_insn_operand" "")]
13888                    UNSPEC_TLS_LD_BASE))
13889    (clobber (match_scratch:SI 3 "=d"))
13890    (clobber (match_scratch:SI 4 "=c"))
13891    (clobber (reg:CC FLAGS_REG))]
13892   "!TARGET_64BIT && TARGET_SUN_TLS"
13893   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13894         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13895   [(set_attr "type" "multi")
13896    (set_attr "length" "13")])
13898 (define_expand "tls_local_dynamic_base_32"
13899   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13900                    (unspec:SI [(match_dup 1) (match_dup 2)]
13901                               UNSPEC_TLS_LD_BASE))
13902               (clobber (match_scratch:SI 3 ""))
13903               (clobber (match_scratch:SI 4 ""))
13904               (clobber (reg:CC FLAGS_REG))])]
13905   ""
13907   if (flag_pic)
13908     operands[1] = pic_offset_table_rtx;
13909   else
13910     {
13911       operands[1] = gen_reg_rtx (Pmode);
13912       emit_insn (gen_set_got (operands[1]));
13913     }
13914   operands[2] = ix86_tls_get_addr ();
13917 (define_insn "*tls_local_dynamic_base_64"
13918   [(set (match_operand:DI 0 "register_operand" "=a")
13919         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13920                       (match_operand:DI 2 "" "")))
13921    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13922   "TARGET_64BIT"
13923   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13924   [(set_attr "type" "multi")
13925    (set_attr "length" "12")])
13927 (define_expand "tls_local_dynamic_base_64"
13928   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13929                    (call (mem:QI (match_dup 1)) (const_int 0)))
13930               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13931   ""
13933   operands[1] = ix86_tls_get_addr ();
13936 ;; Local dynamic of a single variable is a lose.  Show combine how
13937 ;; to convert that back to global dynamic.
13939 (define_insn_and_split "*tls_local_dynamic_32_once"
13940   [(set (match_operand:SI 0 "register_operand" "=a")
13941         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13942                              (match_operand:SI 2 "call_insn_operand" "")]
13943                             UNSPEC_TLS_LD_BASE)
13944                  (const:SI (unspec:SI
13945                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13946                             UNSPEC_DTPOFF))))
13947    (clobber (match_scratch:SI 4 "=d"))
13948    (clobber (match_scratch:SI 5 "=c"))
13949    (clobber (reg:CC FLAGS_REG))]
13950   ""
13951   "#"
13952   ""
13953   [(parallel [(set (match_dup 0)
13954                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13955                               UNSPEC_TLS_GD))
13956               (clobber (match_dup 4))
13957               (clobber (match_dup 5))
13958               (clobber (reg:CC FLAGS_REG))])]
13959   "")
13961 ;; Load and add the thread base pointer from %gs:0.
13963 (define_insn "*load_tp_si"
13964   [(set (match_operand:SI 0 "register_operand" "=r")
13965         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13966   "!TARGET_64BIT"
13967   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13968   [(set_attr "type" "imov")
13969    (set_attr "modrm" "0")
13970    (set_attr "length" "7")
13971    (set_attr "memory" "load")
13972    (set_attr "imm_disp" "false")])
13974 (define_insn "*add_tp_si"
13975   [(set (match_operand:SI 0 "register_operand" "=r")
13976         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13977                  (match_operand:SI 1 "register_operand" "0")))
13978    (clobber (reg:CC FLAGS_REG))]
13979   "!TARGET_64BIT"
13980   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13981   [(set_attr "type" "alu")
13982    (set_attr "modrm" "0")
13983    (set_attr "length" "7")
13984    (set_attr "memory" "load")
13985    (set_attr "imm_disp" "false")])
13987 (define_insn "*load_tp_di"
13988   [(set (match_operand:DI 0 "register_operand" "=r")
13989         (unspec:DI [(const_int 0)] UNSPEC_TP))]
13990   "TARGET_64BIT"
13991   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13992   [(set_attr "type" "imov")
13993    (set_attr "modrm" "0")
13994    (set_attr "length" "7")
13995    (set_attr "memory" "load")
13996    (set_attr "imm_disp" "false")])
13998 (define_insn "*add_tp_di"
13999   [(set (match_operand:DI 0 "register_operand" "=r")
14000         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14001                  (match_operand:DI 1 "register_operand" "0")))
14002    (clobber (reg:CC FLAGS_REG))]
14003   "TARGET_64BIT"
14004   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14005   [(set_attr "type" "alu")
14006    (set_attr "modrm" "0")
14007    (set_attr "length" "7")
14008    (set_attr "memory" "load")
14009    (set_attr "imm_disp" "false")])
14011 ;; These patterns match the binary 387 instructions for addM3, subM3,
14012 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14013 ;; SFmode.  The first is the normal insn, the second the same insn but
14014 ;; with one operand a conversion, and the third the same insn but with
14015 ;; the other operand a conversion.  The conversion may be SFmode or
14016 ;; SImode if the target mode DFmode, but only SImode if the target mode
14017 ;; is SFmode.
14019 ;; Gcc is slightly more smart about handling normal two address instructions
14020 ;; so use special patterns for add and mull.
14022 (define_insn "*fop_sf_comm_mixed"
14023   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14024         (match_operator:SF 3 "binary_fp_operator"
14025                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14026                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14027   "TARGET_MIX_SSE_I387
14028    && COMMUTATIVE_ARITH_P (operands[3])
14029    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14030   "* return output_387_binary_op (insn, operands);"
14031   [(set (attr "type") 
14032         (if_then_else (eq_attr "alternative" "1")
14033            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14034               (const_string "ssemul")
14035               (const_string "sseadd"))
14036            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14037               (const_string "fmul")
14038               (const_string "fop"))))
14039    (set_attr "mode" "SF")])
14041 (define_insn "*fop_sf_comm_sse"
14042   [(set (match_operand:SF 0 "register_operand" "=x")
14043         (match_operator:SF 3 "binary_fp_operator"
14044                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14045                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14046   "TARGET_SSE_MATH
14047    && COMMUTATIVE_ARITH_P (operands[3])
14048    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14049   "* return output_387_binary_op (insn, operands);"
14050   [(set (attr "type") 
14051         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14052            (const_string "ssemul")
14053            (const_string "sseadd")))
14054    (set_attr "mode" "SF")])
14056 (define_insn "*fop_sf_comm_i387"
14057   [(set (match_operand:SF 0 "register_operand" "=f")
14058         (match_operator:SF 3 "binary_fp_operator"
14059                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14060                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14061   "TARGET_80387
14062    && COMMUTATIVE_ARITH_P (operands[3])
14063    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14064   "* return output_387_binary_op (insn, operands);"
14065   [(set (attr "type") 
14066         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14067            (const_string "fmul")
14068            (const_string "fop")))
14069    (set_attr "mode" "SF")])
14071 (define_insn "*fop_sf_1_mixed"
14072   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14073         (match_operator:SF 3 "binary_fp_operator"
14074                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14075                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14076   "TARGET_MIX_SSE_I387
14077    && !COMMUTATIVE_ARITH_P (operands[3])
14078    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14079   "* return output_387_binary_op (insn, operands);"
14080   [(set (attr "type") 
14081         (cond [(and (eq_attr "alternative" "2")
14082                     (match_operand:SF 3 "mult_operator" ""))
14083                  (const_string "ssemul")
14084                (and (eq_attr "alternative" "2")
14085                     (match_operand:SF 3 "div_operator" ""))
14086                  (const_string "ssediv")
14087                (eq_attr "alternative" "2")
14088                  (const_string "sseadd")
14089                (match_operand:SF 3 "mult_operator" "") 
14090                  (const_string "fmul")
14091                (match_operand:SF 3 "div_operator" "") 
14092                  (const_string "fdiv")
14093               ]
14094               (const_string "fop")))
14095    (set_attr "mode" "SF")])
14097 (define_insn "*fop_sf_1_sse"
14098   [(set (match_operand:SF 0 "register_operand" "=x")
14099         (match_operator:SF 3 "binary_fp_operator"
14100                         [(match_operand:SF 1 "register_operand" "0")
14101                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14102   "TARGET_SSE_MATH
14103    && !COMMUTATIVE_ARITH_P (operands[3])"
14104   "* return output_387_binary_op (insn, operands);"
14105   [(set (attr "type") 
14106         (cond [(match_operand:SF 3 "mult_operator" "")
14107                  (const_string "ssemul")
14108                (match_operand:SF 3 "div_operator" "")
14109                  (const_string "ssediv")
14110               ]
14111               (const_string "sseadd")))
14112    (set_attr "mode" "SF")])
14114 ;; This pattern is not fully shadowed by the pattern above.
14115 (define_insn "*fop_sf_1_i387"
14116   [(set (match_operand:SF 0 "register_operand" "=f,f")
14117         (match_operator:SF 3 "binary_fp_operator"
14118                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14119                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14120   "TARGET_80387 && !TARGET_SSE_MATH
14121    && !COMMUTATIVE_ARITH_P (operands[3])
14122    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14123   "* return output_387_binary_op (insn, operands);"
14124   [(set (attr "type") 
14125         (cond [(match_operand:SF 3 "mult_operator" "") 
14126                  (const_string "fmul")
14127                (match_operand:SF 3 "div_operator" "") 
14128                  (const_string "fdiv")
14129               ]
14130               (const_string "fop")))
14131    (set_attr "mode" "SF")])
14133 ;; ??? Add SSE splitters for these!
14134 (define_insn "*fop_sf_2<mode>_i387"
14135   [(set (match_operand:SF 0 "register_operand" "=f,f")
14136         (match_operator:SF 3 "binary_fp_operator"
14137           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14138            (match_operand:SF 2 "register_operand" "0,0")]))]
14139   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14140   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14141   [(set (attr "type") 
14142         (cond [(match_operand:SF 3 "mult_operator" "") 
14143                  (const_string "fmul")
14144                (match_operand:SF 3 "div_operator" "") 
14145                  (const_string "fdiv")
14146               ]
14147               (const_string "fop")))
14148    (set_attr "fp_int_src" "true")
14149    (set_attr "mode" "<MODE>")])
14151 (define_insn "*fop_sf_3<mode>_i387"
14152   [(set (match_operand:SF 0 "register_operand" "=f,f")
14153         (match_operator:SF 3 "binary_fp_operator"
14154           [(match_operand:SF 1 "register_operand" "0,0")
14155            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14156   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14157   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14158   [(set (attr "type") 
14159         (cond [(match_operand:SF 3 "mult_operator" "") 
14160                  (const_string "fmul")
14161                (match_operand:SF 3 "div_operator" "") 
14162                  (const_string "fdiv")
14163               ]
14164               (const_string "fop")))
14165    (set_attr "fp_int_src" "true")
14166    (set_attr "mode" "<MODE>")])
14168 (define_insn "*fop_df_comm_mixed"
14169   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14170         (match_operator:DF 3 "binary_fp_operator"
14171                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14172                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14173   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14174    && COMMUTATIVE_ARITH_P (operands[3])
14175    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14176   "* return output_387_binary_op (insn, operands);"
14177   [(set (attr "type") 
14178         (if_then_else (eq_attr "alternative" "1")
14179            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14180               (const_string "ssemul")
14181               (const_string "sseadd"))
14182            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14183               (const_string "fmul")
14184               (const_string "fop"))))
14185    (set_attr "mode" "DF")])
14187 (define_insn "*fop_df_comm_sse"
14188   [(set (match_operand:DF 0 "register_operand" "=Y")
14189         (match_operator:DF 3 "binary_fp_operator"
14190                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14191                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14192   "TARGET_SSE2 && TARGET_SSE_MATH
14193    && COMMUTATIVE_ARITH_P (operands[3])
14194    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14195   "* return output_387_binary_op (insn, operands);"
14196   [(set (attr "type") 
14197         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14198            (const_string "ssemul")
14199            (const_string "sseadd")))
14200    (set_attr "mode" "DF")])
14202 (define_insn "*fop_df_comm_i387"
14203   [(set (match_operand:DF 0 "register_operand" "=f")
14204         (match_operator:DF 3 "binary_fp_operator"
14205                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14206                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14207   "TARGET_80387
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         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14213            (const_string "fmul")
14214            (const_string "fop")))
14215    (set_attr "mode" "DF")])
14217 (define_insn "*fop_df_1_mixed"
14218   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14219         (match_operator:DF 3 "binary_fp_operator"
14220                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14221                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14222   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14223    && !COMMUTATIVE_ARITH_P (operands[3])
14224    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14225   "* return output_387_binary_op (insn, operands);"
14226   [(set (attr "type") 
14227         (cond [(and (eq_attr "alternative" "2")
14228                     (match_operand:SF 3 "mult_operator" ""))
14229                  (const_string "ssemul")
14230                (and (eq_attr "alternative" "2")
14231                     (match_operand:SF 3 "div_operator" ""))
14232                  (const_string "ssediv")
14233                (eq_attr "alternative" "2")
14234                  (const_string "sseadd")
14235                (match_operand:DF 3 "mult_operator" "") 
14236                  (const_string "fmul")
14237                (match_operand:DF 3 "div_operator" "") 
14238                  (const_string "fdiv")
14239               ]
14240               (const_string "fop")))
14241    (set_attr "mode" "DF")])
14243 (define_insn "*fop_df_1_sse"
14244   [(set (match_operand:DF 0 "register_operand" "=Y")
14245         (match_operator:DF 3 "binary_fp_operator"
14246                         [(match_operand:DF 1 "register_operand" "0")
14247                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14248   "TARGET_SSE2 && TARGET_SSE_MATH
14249    && !COMMUTATIVE_ARITH_P (operands[3])"
14250   "* return output_387_binary_op (insn, operands);"
14251   [(set_attr "mode" "DF")
14252    (set (attr "type") 
14253         (cond [(match_operand:SF 3 "mult_operator" "")
14254                  (const_string "ssemul")
14255                (match_operand:SF 3 "div_operator" "")
14256                  (const_string "ssediv")
14257               ]
14258               (const_string "sseadd")))])
14260 ;; This pattern is not fully shadowed by the pattern above.
14261 (define_insn "*fop_df_1_i387"
14262   [(set (match_operand:DF 0 "register_operand" "=f,f")
14263         (match_operator:DF 3 "binary_fp_operator"
14264                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14265                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14266   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14267    && !COMMUTATIVE_ARITH_P (operands[3])
14268    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14269   "* return output_387_binary_op (insn, operands);"
14270   [(set (attr "type") 
14271         (cond [(match_operand:DF 3 "mult_operator" "") 
14272                  (const_string "fmul")
14273                (match_operand:DF 3 "div_operator" "")
14274                  (const_string "fdiv")
14275               ]
14276               (const_string "fop")))
14277    (set_attr "mode" "DF")])
14279 ;; ??? Add SSE splitters for these!
14280 (define_insn "*fop_df_2<mode>_i387"
14281   [(set (match_operand:DF 0 "register_operand" "=f,f")
14282         (match_operator:DF 3 "binary_fp_operator"
14283            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14284             (match_operand:DF 2 "register_operand" "0,0")]))]
14285   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14286    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14287   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14288   [(set (attr "type") 
14289         (cond [(match_operand:DF 3 "mult_operator" "") 
14290                  (const_string "fmul")
14291                (match_operand:DF 3 "div_operator" "") 
14292                  (const_string "fdiv")
14293               ]
14294               (const_string "fop")))
14295    (set_attr "fp_int_src" "true")
14296    (set_attr "mode" "<MODE>")])
14298 (define_insn "*fop_df_3<mode>_i387"
14299   [(set (match_operand:DF 0 "register_operand" "=f,f")
14300         (match_operator:DF 3 "binary_fp_operator"
14301            [(match_operand:DF 1 "register_operand" "0,0")
14302             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14303   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14304    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14305   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14306   [(set (attr "type") 
14307         (cond [(match_operand:DF 3 "mult_operator" "") 
14308                  (const_string "fmul")
14309                (match_operand:DF 3 "div_operator" "") 
14310                  (const_string "fdiv")
14311               ]
14312               (const_string "fop")))
14313    (set_attr "fp_int_src" "true")
14314    (set_attr "mode" "<MODE>")])
14316 (define_insn "*fop_df_4_i387"
14317   [(set (match_operand:DF 0 "register_operand" "=f,f")
14318         (match_operator:DF 3 "binary_fp_operator"
14319            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14320             (match_operand:DF 2 "register_operand" "0,f")]))]
14321   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14322    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14323   "* return output_387_binary_op (insn, operands);"
14324   [(set (attr "type") 
14325         (cond [(match_operand:DF 3 "mult_operator" "") 
14326                  (const_string "fmul")
14327                (match_operand:DF 3 "div_operator" "") 
14328                  (const_string "fdiv")
14329               ]
14330               (const_string "fop")))
14331    (set_attr "mode" "SF")])
14333 (define_insn "*fop_df_5_i387"
14334   [(set (match_operand:DF 0 "register_operand" "=f,f")
14335         (match_operator:DF 3 "binary_fp_operator"
14336           [(match_operand:DF 1 "register_operand" "0,f")
14337            (float_extend:DF
14338             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14339   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14340   "* return output_387_binary_op (insn, operands);"
14341   [(set (attr "type") 
14342         (cond [(match_operand:DF 3 "mult_operator" "") 
14343                  (const_string "fmul")
14344                (match_operand:DF 3 "div_operator" "") 
14345                  (const_string "fdiv")
14346               ]
14347               (const_string "fop")))
14348    (set_attr "mode" "SF")])
14350 (define_insn "*fop_df_6_i387"
14351   [(set (match_operand:DF 0 "register_operand" "=f,f")
14352         (match_operator:DF 3 "binary_fp_operator"
14353           [(float_extend:DF
14354             (match_operand:SF 1 "register_operand" "0,f"))
14355            (float_extend:DF
14356             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14357   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14358   "* return output_387_binary_op (insn, operands);"
14359   [(set (attr "type") 
14360         (cond [(match_operand:DF 3 "mult_operator" "") 
14361                  (const_string "fmul")
14362                (match_operand:DF 3 "div_operator" "") 
14363                  (const_string "fdiv")
14364               ]
14365               (const_string "fop")))
14366    (set_attr "mode" "SF")])
14368 (define_insn "*fop_xf_comm_i387"
14369   [(set (match_operand:XF 0 "register_operand" "=f")
14370         (match_operator:XF 3 "binary_fp_operator"
14371                         [(match_operand:XF 1 "register_operand" "%0")
14372                          (match_operand:XF 2 "register_operand" "f")]))]
14373   "TARGET_80387
14374    && COMMUTATIVE_ARITH_P (operands[3])"
14375   "* return output_387_binary_op (insn, operands);"
14376   [(set (attr "type") 
14377         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14378            (const_string "fmul")
14379            (const_string "fop")))
14380    (set_attr "mode" "XF")])
14382 (define_insn "*fop_xf_1_i387"
14383   [(set (match_operand:XF 0 "register_operand" "=f,f")
14384         (match_operator:XF 3 "binary_fp_operator"
14385                         [(match_operand:XF 1 "register_operand" "0,f")
14386                          (match_operand:XF 2 "register_operand" "f,0")]))]
14387   "TARGET_80387
14388    && !COMMUTATIVE_ARITH_P (operands[3])"
14389   "* return output_387_binary_op (insn, operands);"
14390   [(set (attr "type") 
14391         (cond [(match_operand:XF 3 "mult_operator" "") 
14392                  (const_string "fmul")
14393                (match_operand:XF 3 "div_operator" "") 
14394                  (const_string "fdiv")
14395               ]
14396               (const_string "fop")))
14397    (set_attr "mode" "XF")])
14399 (define_insn "*fop_xf_2<mode>_i387"
14400   [(set (match_operand:XF 0 "register_operand" "=f,f")
14401         (match_operator:XF 3 "binary_fp_operator"
14402            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14403             (match_operand:XF 2 "register_operand" "0,0")]))]
14404   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14405   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14406   [(set (attr "type") 
14407         (cond [(match_operand:XF 3 "mult_operator" "") 
14408                  (const_string "fmul")
14409                (match_operand:XF 3 "div_operator" "") 
14410                  (const_string "fdiv")
14411               ]
14412               (const_string "fop")))
14413    (set_attr "fp_int_src" "true")
14414    (set_attr "mode" "<MODE>")])
14416 (define_insn "*fop_xf_3<mode>_i387"
14417   [(set (match_operand:XF 0 "register_operand" "=f,f")
14418         (match_operator:XF 3 "binary_fp_operator"
14419           [(match_operand:XF 1 "register_operand" "0,0")
14420            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14421   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14422   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14423   [(set (attr "type") 
14424         (cond [(match_operand:XF 3 "mult_operator" "") 
14425                  (const_string "fmul")
14426                (match_operand:XF 3 "div_operator" "") 
14427                  (const_string "fdiv")
14428               ]
14429               (const_string "fop")))
14430    (set_attr "fp_int_src" "true")
14431    (set_attr "mode" "<MODE>")])
14433 (define_insn "*fop_xf_4_i387"
14434   [(set (match_operand:XF 0 "register_operand" "=f,f")
14435         (match_operator:XF 3 "binary_fp_operator"
14436            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14437             (match_operand:XF 2 "register_operand" "0,f")]))]
14438   "TARGET_80387"
14439   "* return output_387_binary_op (insn, operands);"
14440   [(set (attr "type") 
14441         (cond [(match_operand:XF 3 "mult_operator" "") 
14442                  (const_string "fmul")
14443                (match_operand:XF 3 "div_operator" "") 
14444                  (const_string "fdiv")
14445               ]
14446               (const_string "fop")))
14447    (set_attr "mode" "SF")])
14449 (define_insn "*fop_xf_5_i387"
14450   [(set (match_operand:XF 0 "register_operand" "=f,f")
14451         (match_operator:XF 3 "binary_fp_operator"
14452           [(match_operand:XF 1 "register_operand" "0,f")
14453            (float_extend:XF
14454             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14455   "TARGET_80387"
14456   "* return output_387_binary_op (insn, operands);"
14457   [(set (attr "type") 
14458         (cond [(match_operand:XF 3 "mult_operator" "") 
14459                  (const_string "fmul")
14460                (match_operand:XF 3 "div_operator" "") 
14461                  (const_string "fdiv")
14462               ]
14463               (const_string "fop")))
14464    (set_attr "mode" "SF")])
14466 (define_insn "*fop_xf_6_i387"
14467   [(set (match_operand:XF 0 "register_operand" "=f,f")
14468         (match_operator:XF 3 "binary_fp_operator"
14469           [(float_extend:XF
14470             (match_operand 1 "register_operand" "0,f"))
14471            (float_extend:XF
14472             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14473   "TARGET_80387"
14474   "* return output_387_binary_op (insn, operands);"
14475   [(set (attr "type") 
14476         (cond [(match_operand:XF 3 "mult_operator" "") 
14477                  (const_string "fmul")
14478                (match_operand:XF 3 "div_operator" "") 
14479                  (const_string "fdiv")
14480               ]
14481               (const_string "fop")))
14482    (set_attr "mode" "SF")])
14484 (define_split
14485   [(set (match_operand 0 "register_operand" "")
14486         (match_operator 3 "binary_fp_operator"
14487            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14488             (match_operand 2 "register_operand" "")]))]
14489   "TARGET_80387 && reload_completed
14490    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14491   [(const_int 0)]
14493   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14494   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14495   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14496                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14497                                           GET_MODE (operands[3]),
14498                                           operands[4],
14499                                           operands[2])));
14500   ix86_free_from_memory (GET_MODE (operands[1]));
14501   DONE;
14504 (define_split
14505   [(set (match_operand 0 "register_operand" "")
14506         (match_operator 3 "binary_fp_operator"
14507            [(match_operand 1 "register_operand" "")
14508             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14509   "TARGET_80387 && reload_completed
14510    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14511   [(const_int 0)]
14513   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14514   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14515   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14516                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14517                                           GET_MODE (operands[3]),
14518                                           operands[1],
14519                                           operands[4])));
14520   ix86_free_from_memory (GET_MODE (operands[2]));
14521   DONE;
14524 ;; FPU special functions.
14526 (define_expand "sqrtsf2"
14527   [(set (match_operand:SF 0 "register_operand" "")
14528         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14529   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14531   if (!TARGET_SSE_MATH)
14532     operands[1] = force_reg (SFmode, operands[1]);
14535 (define_insn "*sqrtsf2_mixed"
14536   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14537         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14538   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14539   "@
14540    fsqrt
14541    sqrtss\t{%1, %0|%0, %1}"
14542   [(set_attr "type" "fpspc,sse")
14543    (set_attr "mode" "SF,SF")
14544    (set_attr "athlon_decode" "direct,*")])
14546 (define_insn "*sqrtsf2_sse"
14547   [(set (match_operand:SF 0 "register_operand" "=x")
14548         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14549   "TARGET_SSE_MATH"
14550   "sqrtss\t{%1, %0|%0, %1}"
14551   [(set_attr "type" "sse")
14552    (set_attr "mode" "SF")
14553    (set_attr "athlon_decode" "*")])
14555 (define_insn "*sqrtsf2_i387"
14556   [(set (match_operand:SF 0 "register_operand" "=f")
14557         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14558   "TARGET_USE_FANCY_MATH_387"
14559   "fsqrt"
14560   [(set_attr "type" "fpspc")
14561    (set_attr "mode" "SF")
14562    (set_attr "athlon_decode" "direct")])
14564 (define_expand "sqrtdf2"
14565   [(set (match_operand:DF 0 "register_operand" "")
14566         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14567   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14569   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14570     operands[1] = force_reg (DFmode, operands[1]);
14573 (define_insn "*sqrtdf2_mixed"
14574   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14575         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14576   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14577   "@
14578    fsqrt
14579    sqrtsd\t{%1, %0|%0, %1}"
14580   [(set_attr "type" "fpspc,sse")
14581    (set_attr "mode" "DF,DF")
14582    (set_attr "athlon_decode" "direct,*")])
14584 (define_insn "*sqrtdf2_sse"
14585   [(set (match_operand:DF 0 "register_operand" "=Y")
14586         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14587   "TARGET_SSE2 && TARGET_SSE_MATH"
14588   "sqrtsd\t{%1, %0|%0, %1}"
14589   [(set_attr "type" "sse")
14590    (set_attr "mode" "DF")
14591    (set_attr "athlon_decode" "*")])
14593 (define_insn "*sqrtdf2_i387"
14594   [(set (match_operand:DF 0 "register_operand" "=f")
14595         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14596   "TARGET_USE_FANCY_MATH_387"
14597   "fsqrt"
14598   [(set_attr "type" "fpspc")
14599    (set_attr "mode" "DF")
14600    (set_attr "athlon_decode" "direct")])
14602 (define_insn "*sqrtextendsfdf2_i387"
14603   [(set (match_operand:DF 0 "register_operand" "=f")
14604         (sqrt:DF (float_extend:DF
14605                   (match_operand:SF 1 "register_operand" "0"))))]
14606   "TARGET_USE_FANCY_MATH_387
14607    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14608   "fsqrt"
14609   [(set_attr "type" "fpspc")
14610    (set_attr "mode" "DF")
14611    (set_attr "athlon_decode" "direct")])
14613 (define_insn "sqrtxf2"
14614   [(set (match_operand:XF 0 "register_operand" "=f")
14615         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14616   "TARGET_USE_FANCY_MATH_387 
14617    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14618   "fsqrt"
14619   [(set_attr "type" "fpspc")
14620    (set_attr "mode" "XF")
14621    (set_attr "athlon_decode" "direct")])
14623 (define_insn "*sqrtextendsfxf2_i387"
14624   [(set (match_operand:XF 0 "register_operand" "=f")
14625         (sqrt:XF (float_extend:XF
14626                   (match_operand:SF 1 "register_operand" "0"))))]
14627   "TARGET_USE_FANCY_MATH_387"
14628   "fsqrt"
14629   [(set_attr "type" "fpspc")
14630    (set_attr "mode" "XF")
14631    (set_attr "athlon_decode" "direct")])
14633 (define_insn "*sqrtextenddfxf2_i387"
14634   [(set (match_operand:XF 0 "register_operand" "=f")
14635         (sqrt:XF (float_extend:XF
14636                   (match_operand:DF 1 "register_operand" "0"))))]
14637   "TARGET_USE_FANCY_MATH_387"
14638   "fsqrt"
14639   [(set_attr "type" "fpspc")
14640    (set_attr "mode" "XF")
14641    (set_attr "athlon_decode" "direct")])
14643 (define_insn "fpremxf4"
14644   [(set (match_operand:XF 0 "register_operand" "=f")
14645         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14646                     (match_operand:XF 3 "register_operand" "1")]
14647                    UNSPEC_FPREM_F))
14648    (set (match_operand:XF 1 "register_operand" "=u")
14649         (unspec:XF [(match_dup 2) (match_dup 3)]
14650                    UNSPEC_FPREM_U))
14651    (set (reg:CCFP FPSR_REG)
14652         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14653   "TARGET_USE_FANCY_MATH_387
14654    && flag_unsafe_math_optimizations"
14655   "fprem"
14656   [(set_attr "type" "fpspc")
14657    (set_attr "mode" "XF")])
14659 (define_expand "fmodsf3"
14660   [(use (match_operand:SF 0 "register_operand" ""))
14661    (use (match_operand:SF 1 "register_operand" ""))
14662    (use (match_operand:SF 2 "register_operand" ""))]
14663   "TARGET_USE_FANCY_MATH_387
14664    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14665    && flag_unsafe_math_optimizations"
14667   rtx label = gen_label_rtx ();
14669   rtx op1 = gen_reg_rtx (XFmode);
14670   rtx op2 = gen_reg_rtx (XFmode);
14672   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14673   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14675   emit_label (label);
14677   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14678   ix86_emit_fp_unordered_jump (label);
14680   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14681   DONE;
14684 (define_expand "fmoddf3"
14685   [(use (match_operand:DF 0 "register_operand" ""))
14686    (use (match_operand:DF 1 "register_operand" ""))
14687    (use (match_operand:DF 2 "register_operand" ""))]
14688   "TARGET_USE_FANCY_MATH_387
14689    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14690    && flag_unsafe_math_optimizations"
14692   rtx label = gen_label_rtx ();
14694   rtx op1 = gen_reg_rtx (XFmode);
14695   rtx op2 = gen_reg_rtx (XFmode);
14697   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14698   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14700   emit_label (label);
14702   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14703   ix86_emit_fp_unordered_jump (label);
14705   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14706   DONE;
14709 (define_expand "fmodxf3"
14710   [(use (match_operand:XF 0 "register_operand" ""))
14711    (use (match_operand:XF 1 "register_operand" ""))
14712    (use (match_operand:XF 2 "register_operand" ""))]
14713   "TARGET_USE_FANCY_MATH_387
14714    && flag_unsafe_math_optimizations"
14716   rtx label = gen_label_rtx ();
14718   emit_label (label);
14720   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14721                            operands[1], operands[2]));
14722   ix86_emit_fp_unordered_jump (label);
14724   emit_move_insn (operands[0], operands[1]);
14725   DONE;
14728 (define_insn "fprem1xf4"
14729   [(set (match_operand:XF 0 "register_operand" "=f")
14730         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14731                     (match_operand:XF 3 "register_operand" "1")]
14732                    UNSPEC_FPREM1_F))
14733    (set (match_operand:XF 1 "register_operand" "=u")
14734         (unspec:XF [(match_dup 2) (match_dup 3)]
14735                    UNSPEC_FPREM1_U))
14736    (set (reg:CCFP FPSR_REG)
14737         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14738   "TARGET_USE_FANCY_MATH_387
14739    && flag_unsafe_math_optimizations"
14740   "fprem1"
14741   [(set_attr "type" "fpspc")
14742    (set_attr "mode" "XF")])
14744 (define_expand "dremsf3"
14745   [(use (match_operand:SF 0 "register_operand" ""))
14746    (use (match_operand:SF 1 "register_operand" ""))
14747    (use (match_operand:SF 2 "register_operand" ""))]
14748   "TARGET_USE_FANCY_MATH_387
14749    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14750    && flag_unsafe_math_optimizations"
14752   rtx label = gen_label_rtx ();
14754   rtx op1 = gen_reg_rtx (XFmode);
14755   rtx op2 = gen_reg_rtx (XFmode);
14757   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14758   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14760   emit_label (label);
14762   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14763   ix86_emit_fp_unordered_jump (label);
14765   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14766   DONE;
14769 (define_expand "dremdf3"
14770   [(use (match_operand:DF 0 "register_operand" ""))
14771    (use (match_operand:DF 1 "register_operand" ""))
14772    (use (match_operand:DF 2 "register_operand" ""))]
14773   "TARGET_USE_FANCY_MATH_387
14774    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14775    && flag_unsafe_math_optimizations"
14777   rtx label = gen_label_rtx ();
14779   rtx op1 = gen_reg_rtx (XFmode);
14780   rtx op2 = gen_reg_rtx (XFmode);
14782   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14783   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14785   emit_label (label);
14787   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14788   ix86_emit_fp_unordered_jump (label);
14790   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14791   DONE;
14794 (define_expand "dremxf3"
14795   [(use (match_operand:XF 0 "register_operand" ""))
14796    (use (match_operand:XF 1 "register_operand" ""))
14797    (use (match_operand:XF 2 "register_operand" ""))]
14798   "TARGET_USE_FANCY_MATH_387
14799    && flag_unsafe_math_optimizations"
14801   rtx label = gen_label_rtx ();
14803   emit_label (label);
14805   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14806                             operands[1], operands[2]));
14807   ix86_emit_fp_unordered_jump (label);
14809   emit_move_insn (operands[0], operands[1]);
14810   DONE;
14813 (define_insn "*sindf2"
14814   [(set (match_operand:DF 0 "register_operand" "=f")
14815         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14816   "TARGET_USE_FANCY_MATH_387
14817    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14818    && flag_unsafe_math_optimizations"
14819   "fsin"
14820   [(set_attr "type" "fpspc")
14821    (set_attr "mode" "DF")])
14823 (define_insn "*sinsf2"
14824   [(set (match_operand:SF 0 "register_operand" "=f")
14825         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14826   "TARGET_USE_FANCY_MATH_387
14827    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14828    && flag_unsafe_math_optimizations"
14829   "fsin"
14830   [(set_attr "type" "fpspc")
14831    (set_attr "mode" "SF")])
14833 (define_insn "*sinextendsfdf2"
14834   [(set (match_operand:DF 0 "register_operand" "=f")
14835         (unspec:DF [(float_extend:DF
14836                      (match_operand:SF 1 "register_operand" "0"))]
14837                    UNSPEC_SIN))]
14838   "TARGET_USE_FANCY_MATH_387
14839    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14840    && flag_unsafe_math_optimizations"
14841   "fsin"
14842   [(set_attr "type" "fpspc")
14843    (set_attr "mode" "DF")])
14845 (define_insn "*sinxf2"
14846   [(set (match_operand:XF 0 "register_operand" "=f")
14847         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14848   "TARGET_USE_FANCY_MATH_387
14849    && flag_unsafe_math_optimizations"
14850   "fsin"
14851   [(set_attr "type" "fpspc")
14852    (set_attr "mode" "XF")])
14854 (define_insn "*cosdf2"
14855   [(set (match_operand:DF 0 "register_operand" "=f")
14856         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14857   "TARGET_USE_FANCY_MATH_387
14858    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14859    && flag_unsafe_math_optimizations"
14860   "fcos"
14861   [(set_attr "type" "fpspc")
14862    (set_attr "mode" "DF")])
14864 (define_insn "*cossf2"
14865   [(set (match_operand:SF 0 "register_operand" "=f")
14866         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14867   "TARGET_USE_FANCY_MATH_387
14868    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14869    && flag_unsafe_math_optimizations"
14870   "fcos"
14871   [(set_attr "type" "fpspc")
14872    (set_attr "mode" "SF")])
14874 (define_insn "*cosextendsfdf2"
14875   [(set (match_operand:DF 0 "register_operand" "=f")
14876         (unspec:DF [(float_extend:DF
14877                      (match_operand:SF 1 "register_operand" "0"))]
14878                    UNSPEC_COS))]
14879   "TARGET_USE_FANCY_MATH_387
14880    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14881    && flag_unsafe_math_optimizations"
14882   "fcos"
14883   [(set_attr "type" "fpspc")
14884    (set_attr "mode" "DF")])
14886 (define_insn "*cosxf2"
14887   [(set (match_operand:XF 0 "register_operand" "=f")
14888         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14889   "TARGET_USE_FANCY_MATH_387
14890    && flag_unsafe_math_optimizations"
14891   "fcos"
14892   [(set_attr "type" "fpspc")
14893    (set_attr "mode" "XF")])
14895 ;; With sincos pattern defined, sin and cos builtin function will be
14896 ;; expanded to sincos pattern with one of its outputs left unused. 
14897 ;; Cse pass  will detected, if two sincos patterns can be combined,
14898 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14899 ;; depending on the unused output.
14901 (define_insn "sincosdf3"
14902   [(set (match_operand:DF 0 "register_operand" "=f")
14903         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14904                    UNSPEC_SINCOS_COS))
14905    (set (match_operand:DF 1 "register_operand" "=u")
14906         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14907   "TARGET_USE_FANCY_MATH_387
14908    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14909    && flag_unsafe_math_optimizations"
14910   "fsincos"
14911   [(set_attr "type" "fpspc")
14912    (set_attr "mode" "DF")])
14914 (define_split
14915   [(set (match_operand:DF 0 "register_operand" "")
14916         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14917                    UNSPEC_SINCOS_COS))
14918    (set (match_operand:DF 1 "register_operand" "")
14919         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14920   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14921    && !reload_completed && !reload_in_progress"
14922   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14923   "")
14925 (define_split
14926   [(set (match_operand:DF 0 "register_operand" "")
14927         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14928                    UNSPEC_SINCOS_COS))
14929    (set (match_operand:DF 1 "register_operand" "")
14930         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14931   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14932    && !reload_completed && !reload_in_progress"
14933   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14934   "")
14936 (define_insn "sincossf3"
14937   [(set (match_operand:SF 0 "register_operand" "=f")
14938         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14939                    UNSPEC_SINCOS_COS))
14940    (set (match_operand:SF 1 "register_operand" "=u")
14941         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14942   "TARGET_USE_FANCY_MATH_387
14943    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14944    && flag_unsafe_math_optimizations"
14945   "fsincos"
14946   [(set_attr "type" "fpspc")
14947    (set_attr "mode" "SF")])
14949 (define_split
14950   [(set (match_operand:SF 0 "register_operand" "")
14951         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14952                    UNSPEC_SINCOS_COS))
14953    (set (match_operand:SF 1 "register_operand" "")
14954         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14955   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14956    && !reload_completed && !reload_in_progress"
14957   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14958   "")
14960 (define_split
14961   [(set (match_operand:SF 0 "register_operand" "")
14962         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14963                    UNSPEC_SINCOS_COS))
14964    (set (match_operand:SF 1 "register_operand" "")
14965         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14966   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14967    && !reload_completed && !reload_in_progress"
14968   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14969   "")
14971 (define_insn "*sincosextendsfdf3"
14972   [(set (match_operand:DF 0 "register_operand" "=f")
14973         (unspec:DF [(float_extend:DF
14974                      (match_operand:SF 2 "register_operand" "0"))]
14975                    UNSPEC_SINCOS_COS))
14976    (set (match_operand:DF 1 "register_operand" "=u")
14977         (unspec:DF [(float_extend:DF
14978                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14979   "TARGET_USE_FANCY_MATH_387
14980    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14981    && flag_unsafe_math_optimizations"
14982   "fsincos"
14983   [(set_attr "type" "fpspc")
14984    (set_attr "mode" "DF")])
14986 (define_split
14987   [(set (match_operand:DF 0 "register_operand" "")
14988         (unspec:DF [(float_extend:DF
14989                      (match_operand:SF 2 "register_operand" ""))]
14990                    UNSPEC_SINCOS_COS))
14991    (set (match_operand:DF 1 "register_operand" "")
14992         (unspec:DF [(float_extend:DF
14993                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14994   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14995    && !reload_completed && !reload_in_progress"
14996   [(set (match_dup 1) (unspec:DF [(float_extend:DF
14997                                    (match_dup 2))] UNSPEC_SIN))]
14998   "")
15000 (define_split
15001   [(set (match_operand:DF 0 "register_operand" "")
15002         (unspec:DF [(float_extend:DF
15003                      (match_operand:SF 2 "register_operand" ""))]
15004                    UNSPEC_SINCOS_COS))
15005    (set (match_operand:DF 1 "register_operand" "")
15006         (unspec:DF [(float_extend:DF
15007                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15008   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15009    && !reload_completed && !reload_in_progress"
15010   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15011                                    (match_dup 2))] UNSPEC_COS))]
15012   "")
15014 (define_insn "sincosxf3"
15015   [(set (match_operand:XF 0 "register_operand" "=f")
15016         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15017                    UNSPEC_SINCOS_COS))
15018    (set (match_operand:XF 1 "register_operand" "=u")
15019         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15020   "TARGET_USE_FANCY_MATH_387
15021    && flag_unsafe_math_optimizations"
15022   "fsincos"
15023   [(set_attr "type" "fpspc")
15024    (set_attr "mode" "XF")])
15026 (define_split
15027   [(set (match_operand:XF 0 "register_operand" "")
15028         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15029                    UNSPEC_SINCOS_COS))
15030    (set (match_operand:XF 1 "register_operand" "")
15031         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15032   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15033    && !reload_completed && !reload_in_progress"
15034   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15035   "")
15037 (define_split
15038   [(set (match_operand:XF 0 "register_operand" "")
15039         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15040                    UNSPEC_SINCOS_COS))
15041    (set (match_operand:XF 1 "register_operand" "")
15042         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15043   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15044    && !reload_completed && !reload_in_progress"
15045   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15046   "")
15048 (define_insn "*tandf3_1"
15049   [(set (match_operand:DF 0 "register_operand" "=f")
15050         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15051                    UNSPEC_TAN_ONE))
15052    (set (match_operand:DF 1 "register_operand" "=u")
15053         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15054   "TARGET_USE_FANCY_MATH_387
15055    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15056    && flag_unsafe_math_optimizations"
15057   "fptan"
15058   [(set_attr "type" "fpspc")
15059    (set_attr "mode" "DF")])
15061 ;; optimize sequence: fptan
15062 ;;                    fstp    %st(0)
15063 ;;                    fld1
15064 ;; into fptan insn.
15066 (define_peephole2
15067   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15068                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15069                              UNSPEC_TAN_ONE))
15070              (set (match_operand:DF 1 "register_operand" "")
15071                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15072    (set (match_dup 0)
15073         (match_operand:DF 3 "immediate_operand" ""))]
15074   "standard_80387_constant_p (operands[3]) == 2"
15075   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15076              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15077   "")
15079 (define_expand "tandf2"
15080   [(parallel [(set (match_dup 2)
15081                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15082                               UNSPEC_TAN_ONE))
15083               (set (match_operand:DF 0 "register_operand" "")
15084                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15085   "TARGET_USE_FANCY_MATH_387
15086    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15087    && flag_unsafe_math_optimizations"
15089   operands[2] = gen_reg_rtx (DFmode);
15092 (define_insn "*tansf3_1"
15093   [(set (match_operand:SF 0 "register_operand" "=f")
15094         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15095                    UNSPEC_TAN_ONE))
15096    (set (match_operand:SF 1 "register_operand" "=u")
15097         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15098   "TARGET_USE_FANCY_MATH_387
15099    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15100    && flag_unsafe_math_optimizations"
15101   "fptan"
15102   [(set_attr "type" "fpspc")
15103    (set_attr "mode" "SF")])
15105 ;; optimize sequence: fptan
15106 ;;                    fstp    %st(0)
15107 ;;                    fld1
15108 ;; into fptan insn.
15110 (define_peephole2
15111   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15112                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15113                              UNSPEC_TAN_ONE))
15114              (set (match_operand:SF 1 "register_operand" "")
15115                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15116    (set (match_dup 0)
15117         (match_operand:SF 3 "immediate_operand" ""))]
15118   "standard_80387_constant_p (operands[3]) == 2"
15119   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15120              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15121   "")
15123 (define_expand "tansf2"
15124   [(parallel [(set (match_dup 2)
15125                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15126                               UNSPEC_TAN_ONE))
15127               (set (match_operand:SF 0 "register_operand" "")
15128                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15129   "TARGET_USE_FANCY_MATH_387
15130    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15131    && flag_unsafe_math_optimizations"
15133   operands[2] = gen_reg_rtx (SFmode);
15136 (define_insn "*tanxf3_1"
15137   [(set (match_operand:XF 0 "register_operand" "=f")
15138         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15139                    UNSPEC_TAN_ONE))
15140    (set (match_operand:XF 1 "register_operand" "=u")
15141         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15142   "TARGET_USE_FANCY_MATH_387
15143    && flag_unsafe_math_optimizations"
15144   "fptan"
15145   [(set_attr "type" "fpspc")
15146    (set_attr "mode" "XF")])
15148 ;; optimize sequence: fptan
15149 ;;                    fstp    %st(0)
15150 ;;                    fld1
15151 ;; into fptan insn.
15153 (define_peephole2
15154   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15155                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15156                              UNSPEC_TAN_ONE))
15157              (set (match_operand:XF 1 "register_operand" "")
15158                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15159    (set (match_dup 0)
15160         (match_operand:XF 3 "immediate_operand" ""))]
15161   "standard_80387_constant_p (operands[3]) == 2"
15162   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15163              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15164   "")
15166 (define_expand "tanxf2"
15167   [(parallel [(set (match_dup 2)
15168                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15169                               UNSPEC_TAN_ONE))
15170               (set (match_operand:XF 0 "register_operand" "")
15171                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15172   "TARGET_USE_FANCY_MATH_387
15173    && flag_unsafe_math_optimizations"
15175   operands[2] = gen_reg_rtx (XFmode);
15178 (define_insn "atan2df3_1"
15179   [(set (match_operand:DF 0 "register_operand" "=f")
15180         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15181                     (match_operand:DF 1 "register_operand" "u")]
15182                    UNSPEC_FPATAN))
15183    (clobber (match_scratch:DF 3 "=1"))]
15184   "TARGET_USE_FANCY_MATH_387
15185    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15186    && flag_unsafe_math_optimizations"
15187   "fpatan"
15188   [(set_attr "type" "fpspc")
15189    (set_attr "mode" "DF")])
15191 (define_expand "atan2df3"
15192   [(use (match_operand:DF 0 "register_operand" ""))
15193    (use (match_operand:DF 2 "register_operand" ""))
15194    (use (match_operand:DF 1 "register_operand" ""))]
15195   "TARGET_USE_FANCY_MATH_387
15196    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15197    && flag_unsafe_math_optimizations"
15199   rtx copy = gen_reg_rtx (DFmode);
15200   emit_move_insn (copy, operands[1]);
15201   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15202   DONE;
15205 (define_expand "atandf2"
15206   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15207                    (unspec:DF [(match_dup 2)
15208                                (match_operand:DF 1 "register_operand" "")]
15209                     UNSPEC_FPATAN))
15210               (clobber (match_scratch:DF 3 ""))])]
15211   "TARGET_USE_FANCY_MATH_387
15212    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15213    && flag_unsafe_math_optimizations"
15215   operands[2] = gen_reg_rtx (DFmode);
15216   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15219 (define_insn "atan2sf3_1"
15220   [(set (match_operand:SF 0 "register_operand" "=f")
15221         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15222                     (match_operand:SF 1 "register_operand" "u")]
15223                    UNSPEC_FPATAN))
15224    (clobber (match_scratch:SF 3 "=1"))]
15225   "TARGET_USE_FANCY_MATH_387
15226    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15227    && flag_unsafe_math_optimizations"
15228   "fpatan"
15229   [(set_attr "type" "fpspc")
15230    (set_attr "mode" "SF")])
15232 (define_expand "atan2sf3"
15233   [(use (match_operand:SF 0 "register_operand" ""))
15234    (use (match_operand:SF 2 "register_operand" ""))
15235    (use (match_operand:SF 1 "register_operand" ""))]
15236   "TARGET_USE_FANCY_MATH_387
15237    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15238    && flag_unsafe_math_optimizations"
15240   rtx copy = gen_reg_rtx (SFmode);
15241   emit_move_insn (copy, operands[1]);
15242   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15243   DONE;
15246 (define_expand "atansf2"
15247   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15248                    (unspec:SF [(match_dup 2)
15249                                (match_operand:SF 1 "register_operand" "")]
15250                     UNSPEC_FPATAN))
15251               (clobber (match_scratch:SF 3 ""))])]
15252   "TARGET_USE_FANCY_MATH_387
15253    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15254    && flag_unsafe_math_optimizations"
15256   operands[2] = gen_reg_rtx (SFmode);
15257   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15260 (define_insn "atan2xf3_1"
15261   [(set (match_operand:XF 0 "register_operand" "=f")
15262         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15263                     (match_operand:XF 1 "register_operand" "u")]
15264                    UNSPEC_FPATAN))
15265    (clobber (match_scratch:XF 3 "=1"))]
15266   "TARGET_USE_FANCY_MATH_387
15267    && flag_unsafe_math_optimizations"
15268   "fpatan"
15269   [(set_attr "type" "fpspc")
15270    (set_attr "mode" "XF")])
15272 (define_expand "atan2xf3"
15273   [(use (match_operand:XF 0 "register_operand" ""))
15274    (use (match_operand:XF 2 "register_operand" ""))
15275    (use (match_operand:XF 1 "register_operand" ""))]
15276   "TARGET_USE_FANCY_MATH_387
15277    && flag_unsafe_math_optimizations"
15279   rtx copy = gen_reg_rtx (XFmode);
15280   emit_move_insn (copy, operands[1]);
15281   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15282   DONE;
15285 (define_expand "atanxf2"
15286   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15287                    (unspec:XF [(match_dup 2)
15288                                (match_operand:XF 1 "register_operand" "")]
15289                     UNSPEC_FPATAN))
15290               (clobber (match_scratch:XF 3 ""))])]
15291   "TARGET_USE_FANCY_MATH_387
15292    && flag_unsafe_math_optimizations"
15294   operands[2] = gen_reg_rtx (XFmode);
15295   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15298 (define_expand "asindf2"
15299   [(set (match_dup 2)
15300         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15301    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15302    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15303    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15304    (parallel [(set (match_dup 7)
15305                    (unspec:XF [(match_dup 6) (match_dup 2)]
15306                               UNSPEC_FPATAN))
15307               (clobber (match_scratch:XF 8 ""))])
15308    (set (match_operand:DF 0 "register_operand" "")
15309         (float_truncate:DF (match_dup 7)))]
15310   "TARGET_USE_FANCY_MATH_387
15311    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15312    && flag_unsafe_math_optimizations"
15314   int i;
15316   for (i=2; i<8; i++)
15317     operands[i] = gen_reg_rtx (XFmode);
15319   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15322 (define_expand "asinsf2"
15323   [(set (match_dup 2)
15324         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15325    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15326    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15327    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15328    (parallel [(set (match_dup 7)
15329                    (unspec:XF [(match_dup 6) (match_dup 2)]
15330                               UNSPEC_FPATAN))
15331               (clobber (match_scratch:XF 8 ""))])
15332    (set (match_operand:SF 0 "register_operand" "")
15333         (float_truncate:SF (match_dup 7)))]
15334   "TARGET_USE_FANCY_MATH_387
15335    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15336    && flag_unsafe_math_optimizations"
15338   int i;
15340   for (i=2; i<8; i++)
15341     operands[i] = gen_reg_rtx (XFmode);
15343   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15346 (define_expand "asinxf2"
15347   [(set (match_dup 2)
15348         (mult:XF (match_operand:XF 1 "register_operand" "")
15349                  (match_dup 1)))
15350    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15351    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15352    (parallel [(set (match_operand:XF 0 "register_operand" "")
15353                    (unspec:XF [(match_dup 5) (match_dup 1)]
15354                               UNSPEC_FPATAN))
15355               (clobber (match_scratch:XF 6 ""))])]
15356   "TARGET_USE_FANCY_MATH_387
15357    && flag_unsafe_math_optimizations"
15359   int i;
15361   for (i=2; i<6; i++)
15362     operands[i] = gen_reg_rtx (XFmode);
15364   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15367 (define_expand "acosdf2"
15368   [(set (match_dup 2)
15369         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15370    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15371    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15372    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15373    (parallel [(set (match_dup 7)
15374                    (unspec:XF [(match_dup 2) (match_dup 6)]
15375                               UNSPEC_FPATAN))
15376               (clobber (match_scratch:XF 8 ""))])
15377    (set (match_operand:DF 0 "register_operand" "")
15378         (float_truncate:DF (match_dup 7)))]
15379   "TARGET_USE_FANCY_MATH_387
15380    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15381    && flag_unsafe_math_optimizations"
15383   int i;
15385   for (i=2; i<8; i++)
15386     operands[i] = gen_reg_rtx (XFmode);
15388   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15391 (define_expand "acossf2"
15392   [(set (match_dup 2)
15393         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15394    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15395    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15396    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15397    (parallel [(set (match_dup 7)
15398                    (unspec:XF [(match_dup 2) (match_dup 6)]
15399                               UNSPEC_FPATAN))
15400               (clobber (match_scratch:XF 8 ""))])
15401    (set (match_operand:SF 0 "register_operand" "")
15402         (float_truncate:SF (match_dup 7)))]
15403   "TARGET_USE_FANCY_MATH_387
15404    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15405    && flag_unsafe_math_optimizations"
15407   int i;
15409   for (i=2; i<8; i++)
15410     operands[i] = gen_reg_rtx (XFmode);
15412   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15415 (define_expand "acosxf2"
15416   [(set (match_dup 2)
15417         (mult:XF (match_operand:XF 1 "register_operand" "")
15418                  (match_dup 1)))
15419    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15420    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15421    (parallel [(set (match_operand:XF 0 "register_operand" "")
15422                    (unspec:XF [(match_dup 1) (match_dup 5)]
15423                               UNSPEC_FPATAN))
15424               (clobber (match_scratch:XF 6 ""))])]
15425   "TARGET_USE_FANCY_MATH_387
15426    && flag_unsafe_math_optimizations"
15428   int i;
15430   for (i=2; i<6; i++)
15431     operands[i] = gen_reg_rtx (XFmode);
15433   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15436 (define_insn "fyl2x_xf3"
15437   [(set (match_operand:XF 0 "register_operand" "=f")
15438         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15439                     (match_operand:XF 1 "register_operand" "u")]
15440                    UNSPEC_FYL2X))
15441    (clobber (match_scratch:XF 3 "=1"))]
15442   "TARGET_USE_FANCY_MATH_387
15443    && flag_unsafe_math_optimizations"
15444   "fyl2x"
15445   [(set_attr "type" "fpspc")
15446    (set_attr "mode" "XF")])
15448 (define_expand "logsf2"
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 (4); /* fldln2 */
15468   emit_move_insn (operands[3], temp);
15471 (define_expand "logdf2"
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 (4); /* fldln2 */
15491   emit_move_insn (operands[3], temp);
15494 (define_expand "logxf2"
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 (4); /* fldln2 */
15506   emit_move_insn (operands[2], temp);
15509 (define_expand "log10sf2"
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   rtx temp;
15524   operands[2] = gen_reg_rtx (XFmode);
15525   operands[3] = gen_reg_rtx (XFmode);
15526   operands[4] = gen_reg_rtx (XFmode);
15528   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15529   emit_move_insn (operands[3], temp);
15532 (define_expand "log10df2"
15533   [(set (match_dup 2)
15534         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15535    (parallel [(set (match_dup 4)
15536                    (unspec:XF [(match_dup 2)
15537                                (match_dup 3)] UNSPEC_FYL2X))
15538               (clobber (match_scratch:XF 5 ""))])
15539    (set (match_operand:DF 0 "register_operand" "")
15540         (float_truncate:DF (match_dup 4)))]
15541   "TARGET_USE_FANCY_MATH_387
15542    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15543    && flag_unsafe_math_optimizations"
15545   rtx temp;
15547   operands[2] = gen_reg_rtx (XFmode);
15548   operands[3] = gen_reg_rtx (XFmode);
15549   operands[4] = gen_reg_rtx (XFmode);
15551   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15552   emit_move_insn (operands[3], temp);
15555 (define_expand "log10xf2"
15556   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15557                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15558                                (match_dup 2)] UNSPEC_FYL2X))
15559               (clobber (match_scratch:XF 3 ""))])]
15560   "TARGET_USE_FANCY_MATH_387
15561    && flag_unsafe_math_optimizations"
15563   rtx temp;
15565   operands[2] = gen_reg_rtx (XFmode);
15566   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15567   emit_move_insn (operands[2], temp);
15570 (define_expand "log2sf2"
15571   [(set (match_dup 2)
15572         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15573    (parallel [(set (match_dup 4)
15574                    (unspec:XF [(match_dup 2)
15575                                (match_dup 3)] UNSPEC_FYL2X))
15576               (clobber (match_scratch:XF 5 ""))])
15577    (set (match_operand:SF 0 "register_operand" "")
15578         (float_truncate:SF (match_dup 4)))]
15579   "TARGET_USE_FANCY_MATH_387
15580    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15581    && flag_unsafe_math_optimizations"
15583   operands[2] = gen_reg_rtx (XFmode);
15584   operands[3] = gen_reg_rtx (XFmode);
15585   operands[4] = gen_reg_rtx (XFmode);
15587   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15590 (define_expand "log2df2"
15591   [(set (match_dup 2)
15592         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15593    (parallel [(set (match_dup 4)
15594                    (unspec:XF [(match_dup 2)
15595                                (match_dup 3)] UNSPEC_FYL2X))
15596               (clobber (match_scratch:XF 5 ""))])
15597    (set (match_operand:DF 0 "register_operand" "")
15598         (float_truncate:DF (match_dup 4)))]
15599   "TARGET_USE_FANCY_MATH_387
15600    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15601    && flag_unsafe_math_optimizations"
15603   operands[2] = gen_reg_rtx (XFmode);
15604   operands[3] = gen_reg_rtx (XFmode);
15605   operands[4] = gen_reg_rtx (XFmode);
15607   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15610 (define_expand "log2xf2"
15611   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15612                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15613                                (match_dup 2)] UNSPEC_FYL2X))
15614               (clobber (match_scratch:XF 3 ""))])]
15615   "TARGET_USE_FANCY_MATH_387
15616    && flag_unsafe_math_optimizations"
15618   operands[2] = gen_reg_rtx (XFmode);
15619   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15622 (define_insn "fyl2xp1_xf3"
15623   [(set (match_operand:XF 0 "register_operand" "=f")
15624         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15625                     (match_operand:XF 1 "register_operand" "u")]
15626                    UNSPEC_FYL2XP1))
15627    (clobber (match_scratch:XF 3 "=1"))]
15628   "TARGET_USE_FANCY_MATH_387
15629    && flag_unsafe_math_optimizations"
15630   "fyl2xp1"
15631   [(set_attr "type" "fpspc")
15632    (set_attr "mode" "XF")])
15634 (define_expand "log1psf2"
15635   [(use (match_operand:SF 0 "register_operand" ""))
15636    (use (match_operand:SF 1 "register_operand" ""))]
15637   "TARGET_USE_FANCY_MATH_387
15638    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15639    && flag_unsafe_math_optimizations"
15641   rtx op0 = gen_reg_rtx (XFmode);
15642   rtx op1 = gen_reg_rtx (XFmode);
15644   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15645   ix86_emit_i387_log1p (op0, op1);
15646   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15647   DONE;
15650 (define_expand "log1pdf2"
15651   [(use (match_operand:DF 0 "register_operand" ""))
15652    (use (match_operand:DF 1 "register_operand" ""))]
15653   "TARGET_USE_FANCY_MATH_387
15654    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15655    && flag_unsafe_math_optimizations"
15657   rtx op0 = gen_reg_rtx (XFmode);
15658   rtx op1 = gen_reg_rtx (XFmode);
15660   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15661   ix86_emit_i387_log1p (op0, op1);
15662   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15663   DONE;
15666 (define_expand "log1pxf2"
15667   [(use (match_operand:XF 0 "register_operand" ""))
15668    (use (match_operand:XF 1 "register_operand" ""))]
15669   "TARGET_USE_FANCY_MATH_387
15670    && flag_unsafe_math_optimizations"
15672   ix86_emit_i387_log1p (operands[0], operands[1]);
15673   DONE;
15676 (define_insn "*fxtractxf3"
15677   [(set (match_operand:XF 0 "register_operand" "=f")
15678         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15679                    UNSPEC_XTRACT_FRACT))
15680    (set (match_operand:XF 1 "register_operand" "=u")
15681         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15682   "TARGET_USE_FANCY_MATH_387
15683    && flag_unsafe_math_optimizations"
15684   "fxtract"
15685   [(set_attr "type" "fpspc")
15686    (set_attr "mode" "XF")])
15688 (define_expand "logbsf2"
15689   [(set (match_dup 2)
15690         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15691    (parallel [(set (match_dup 3)
15692                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15693               (set (match_dup 4)
15694                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15695    (set (match_operand:SF 0 "register_operand" "")
15696         (float_truncate:SF (match_dup 4)))]
15697   "TARGET_USE_FANCY_MATH_387
15698    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15699    && flag_unsafe_math_optimizations"
15701   operands[2] = gen_reg_rtx (XFmode);
15702   operands[3] = gen_reg_rtx (XFmode);
15703   operands[4] = gen_reg_rtx (XFmode);
15706 (define_expand "logbdf2"
15707   [(set (match_dup 2)
15708         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15709    (parallel [(set (match_dup 3)
15710                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15711               (set (match_dup 4)
15712                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15713    (set (match_operand:DF 0 "register_operand" "")
15714         (float_truncate:DF (match_dup 4)))]
15715   "TARGET_USE_FANCY_MATH_387
15716    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15717    && flag_unsafe_math_optimizations"
15719   operands[2] = gen_reg_rtx (XFmode);
15720   operands[3] = gen_reg_rtx (XFmode);
15721   operands[4] = gen_reg_rtx (XFmode);
15724 (define_expand "logbxf2"
15725   [(parallel [(set (match_dup 2)
15726                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15727                               UNSPEC_XTRACT_FRACT))
15728               (set (match_operand:XF 0 "register_operand" "")
15729                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15730   "TARGET_USE_FANCY_MATH_387
15731    && flag_unsafe_math_optimizations"
15733   operands[2] = gen_reg_rtx (XFmode);
15736 (define_expand "ilogbsi2"
15737   [(parallel [(set (match_dup 2)
15738                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15739                               UNSPEC_XTRACT_FRACT))
15740               (set (match_operand:XF 3 "register_operand" "")
15741                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15742    (parallel [(set (match_operand:SI 0 "register_operand" "")
15743                    (fix:SI (match_dup 3)))
15744               (clobber (reg:CC FLAGS_REG))])]
15745   "TARGET_USE_FANCY_MATH_387
15746    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15747    && flag_unsafe_math_optimizations"
15749   operands[2] = gen_reg_rtx (XFmode);
15750   operands[3] = gen_reg_rtx (XFmode);
15753 (define_insn "*f2xm1xf2"
15754   [(set (match_operand:XF 0 "register_operand" "=f")
15755         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15756          UNSPEC_F2XM1))]
15757   "TARGET_USE_FANCY_MATH_387
15758    && flag_unsafe_math_optimizations"
15759   "f2xm1"
15760   [(set_attr "type" "fpspc")
15761    (set_attr "mode" "XF")])
15763 (define_insn "*fscalexf4"
15764   [(set (match_operand:XF 0 "register_operand" "=f")
15765         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15766                     (match_operand:XF 3 "register_operand" "1")]
15767                    UNSPEC_FSCALE_FRACT))
15768    (set (match_operand:XF 1 "register_operand" "=u")
15769         (unspec:XF [(match_dup 2) (match_dup 3)]
15770                    UNSPEC_FSCALE_EXP))]
15771   "TARGET_USE_FANCY_MATH_387
15772    && flag_unsafe_math_optimizations"
15773   "fscale"
15774   [(set_attr "type" "fpspc")
15775    (set_attr "mode" "XF")])
15777 (define_expand "expsf2"
15778   [(set (match_dup 2)
15779         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15780    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15781    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15782    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15783    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15784    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15785    (parallel [(set (match_dup 10)
15786                    (unspec:XF [(match_dup 9) (match_dup 5)]
15787                               UNSPEC_FSCALE_FRACT))
15788               (set (match_dup 11)
15789                    (unspec:XF [(match_dup 9) (match_dup 5)]
15790                               UNSPEC_FSCALE_EXP))])
15791    (set (match_operand:SF 0 "register_operand" "")
15792         (float_truncate:SF (match_dup 10)))]
15793   "TARGET_USE_FANCY_MATH_387
15794    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15795    && flag_unsafe_math_optimizations"
15797   rtx temp;
15798   int i;
15800   for (i=2; i<12; i++)
15801     operands[i] = gen_reg_rtx (XFmode);
15802   temp = standard_80387_constant_rtx (5); /* fldl2e */
15803   emit_move_insn (operands[3], temp);
15804   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15807 (define_expand "expdf2"
15808   [(set (match_dup 2)
15809         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15810    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15811    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15812    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15813    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15814    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15815    (parallel [(set (match_dup 10)
15816                    (unspec:XF [(match_dup 9) (match_dup 5)]
15817                               UNSPEC_FSCALE_FRACT))
15818               (set (match_dup 11)
15819                    (unspec:XF [(match_dup 9) (match_dup 5)]
15820                               UNSPEC_FSCALE_EXP))])
15821    (set (match_operand:DF 0 "register_operand" "")
15822         (float_truncate:DF (match_dup 10)))]
15823   "TARGET_USE_FANCY_MATH_387
15824    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15825    && flag_unsafe_math_optimizations"
15827   rtx temp;
15828   int i;
15830   for (i=2; i<12; i++)
15831     operands[i] = gen_reg_rtx (XFmode);
15832   temp = standard_80387_constant_rtx (5); /* fldl2e */
15833   emit_move_insn (operands[3], temp);
15834   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15837 (define_expand "expxf2"
15838   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15839                                (match_dup 2)))
15840    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15841    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15842    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15843    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15844    (parallel [(set (match_operand:XF 0 "register_operand" "")
15845                    (unspec:XF [(match_dup 8) (match_dup 4)]
15846                               UNSPEC_FSCALE_FRACT))
15847               (set (match_dup 9)
15848                    (unspec:XF [(match_dup 8) (match_dup 4)]
15849                               UNSPEC_FSCALE_EXP))])]
15850   "TARGET_USE_FANCY_MATH_387
15851    && flag_unsafe_math_optimizations"
15853   rtx temp;
15854   int i;
15856   for (i=2; i<10; i++)
15857     operands[i] = gen_reg_rtx (XFmode);
15858   temp = standard_80387_constant_rtx (5); /* fldl2e */
15859   emit_move_insn (operands[2], temp);
15860   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15863 (define_expand "exp10sf2"
15864   [(set (match_dup 2)
15865         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15866    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15867    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15868    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15869    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15870    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15871    (parallel [(set (match_dup 10)
15872                    (unspec:XF [(match_dup 9) (match_dup 5)]
15873                               UNSPEC_FSCALE_FRACT))
15874               (set (match_dup 11)
15875                    (unspec:XF [(match_dup 9) (match_dup 5)]
15876                               UNSPEC_FSCALE_EXP))])
15877    (set (match_operand:SF 0 "register_operand" "")
15878         (float_truncate:SF (match_dup 10)))]
15879   "TARGET_USE_FANCY_MATH_387
15880    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15881    && flag_unsafe_math_optimizations"
15883   rtx temp;
15884   int i;
15886   for (i=2; i<12; i++)
15887     operands[i] = gen_reg_rtx (XFmode);
15888   temp = standard_80387_constant_rtx (6); /* fldl2t */
15889   emit_move_insn (operands[3], temp);
15890   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15893 (define_expand "exp10df2"
15894   [(set (match_dup 2)
15895         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15896    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15897    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15898    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15899    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15900    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15901    (parallel [(set (match_dup 10)
15902                    (unspec:XF [(match_dup 9) (match_dup 5)]
15903                               UNSPEC_FSCALE_FRACT))
15904               (set (match_dup 11)
15905                    (unspec:XF [(match_dup 9) (match_dup 5)]
15906                               UNSPEC_FSCALE_EXP))])
15907    (set (match_operand:DF 0 "register_operand" "")
15908         (float_truncate:DF (match_dup 10)))]
15909   "TARGET_USE_FANCY_MATH_387
15910    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15911    && flag_unsafe_math_optimizations"
15913   rtx temp;
15914   int i;
15916   for (i=2; i<12; i++)
15917     operands[i] = gen_reg_rtx (XFmode);
15918   temp = standard_80387_constant_rtx (6); /* fldl2t */
15919   emit_move_insn (operands[3], temp);
15920   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15923 (define_expand "exp10xf2"
15924   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15925                                (match_dup 2)))
15926    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15927    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15928    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15929    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15930    (parallel [(set (match_operand:XF 0 "register_operand" "")
15931                    (unspec:XF [(match_dup 8) (match_dup 4)]
15932                               UNSPEC_FSCALE_FRACT))
15933               (set (match_dup 9)
15934                    (unspec:XF [(match_dup 8) (match_dup 4)]
15935                               UNSPEC_FSCALE_EXP))])]
15936   "TARGET_USE_FANCY_MATH_387
15937    && flag_unsafe_math_optimizations"
15939   rtx temp;
15940   int i;
15942   for (i=2; i<10; i++)
15943     operands[i] = gen_reg_rtx (XFmode);
15944   temp = standard_80387_constant_rtx (6); /* fldl2t */
15945   emit_move_insn (operands[2], temp);
15946   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15949 (define_expand "exp2sf2"
15950   [(set (match_dup 2)
15951         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15952    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15953    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15954    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15955    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15956    (parallel [(set (match_dup 8)
15957                    (unspec:XF [(match_dup 7) (match_dup 3)]
15958                               UNSPEC_FSCALE_FRACT))
15959               (set (match_dup 9)
15960                    (unspec:XF [(match_dup 7) (match_dup 3)]
15961                               UNSPEC_FSCALE_EXP))])
15962    (set (match_operand:SF 0 "register_operand" "")
15963         (float_truncate:SF (match_dup 8)))]
15964   "TARGET_USE_FANCY_MATH_387
15965    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15966    && flag_unsafe_math_optimizations"
15968   int i;
15970   for (i=2; i<10; i++)
15971     operands[i] = gen_reg_rtx (XFmode);
15972   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15975 (define_expand "exp2df2"
15976   [(set (match_dup 2)
15977         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15978    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15979    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15980    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15981    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15982    (parallel [(set (match_dup 8)
15983                    (unspec:XF [(match_dup 7) (match_dup 3)]
15984                               UNSPEC_FSCALE_FRACT))
15985               (set (match_dup 9)
15986                    (unspec:XF [(match_dup 7) (match_dup 3)]
15987                               UNSPEC_FSCALE_EXP))])
15988    (set (match_operand:DF 0 "register_operand" "")
15989         (float_truncate:DF (match_dup 8)))]
15990   "TARGET_USE_FANCY_MATH_387
15991    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15992    && flag_unsafe_math_optimizations"
15994   int i;
15996   for (i=2; i<10; i++)
15997     operands[i] = gen_reg_rtx (XFmode);
15998   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16001 (define_expand "exp2xf2"
16002   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16003    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16004    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16005    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16006    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16007    (parallel [(set (match_operand:XF 0 "register_operand" "")
16008                    (unspec:XF [(match_dup 7) (match_dup 3)]
16009                               UNSPEC_FSCALE_FRACT))
16010               (set (match_dup 8)
16011                    (unspec:XF [(match_dup 7) (match_dup 3)]
16012                               UNSPEC_FSCALE_EXP))])]
16013   "TARGET_USE_FANCY_MATH_387
16014    && flag_unsafe_math_optimizations"
16016   int i;
16018   for (i=2; i<9; i++)
16019     operands[i] = gen_reg_rtx (XFmode);
16020   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16023 (define_expand "expm1df2"
16024   [(set (match_dup 2)
16025         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16026    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16027    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16028    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16029    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16030    (parallel [(set (match_dup 8)
16031                    (unspec:XF [(match_dup 7) (match_dup 5)]
16032                               UNSPEC_FSCALE_FRACT))
16033                    (set (match_dup 9)
16034                    (unspec:XF [(match_dup 7) (match_dup 5)]
16035                               UNSPEC_FSCALE_EXP))])
16036    (parallel [(set (match_dup 11)
16037                    (unspec:XF [(match_dup 10) (match_dup 9)]
16038                               UNSPEC_FSCALE_FRACT))
16039               (set (match_dup 12)
16040                    (unspec:XF [(match_dup 10) (match_dup 9)]
16041                               UNSPEC_FSCALE_EXP))])
16042    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16043    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16044    (set (match_operand:DF 0 "register_operand" "")
16045         (float_truncate:DF (match_dup 14)))]
16046   "TARGET_USE_FANCY_MATH_387
16047    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16048    && flag_unsafe_math_optimizations"
16050   rtx temp;
16051   int i;
16053   for (i=2; i<15; i++)
16054     operands[i] = gen_reg_rtx (XFmode);
16055   temp = standard_80387_constant_rtx (5); /* fldl2e */
16056   emit_move_insn (operands[3], temp);
16057   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16060 (define_expand "expm1sf2"
16061   [(set (match_dup 2)
16062         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16063    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16064    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16065    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16066    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16067    (parallel [(set (match_dup 8)
16068                    (unspec:XF [(match_dup 7) (match_dup 5)]
16069                               UNSPEC_FSCALE_FRACT))
16070                    (set (match_dup 9)
16071                    (unspec:XF [(match_dup 7) (match_dup 5)]
16072                               UNSPEC_FSCALE_EXP))])
16073    (parallel [(set (match_dup 11)
16074                    (unspec:XF [(match_dup 10) (match_dup 9)]
16075                               UNSPEC_FSCALE_FRACT))
16076               (set (match_dup 12)
16077                    (unspec:XF [(match_dup 10) (match_dup 9)]
16078                               UNSPEC_FSCALE_EXP))])
16079    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16080    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16081    (set (match_operand:SF 0 "register_operand" "")
16082         (float_truncate:SF (match_dup 14)))]
16083   "TARGET_USE_FANCY_MATH_387
16084    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16085    && flag_unsafe_math_optimizations"
16087   rtx temp;
16088   int i;
16090   for (i=2; i<15; i++)
16091     operands[i] = gen_reg_rtx (XFmode);
16092   temp = standard_80387_constant_rtx (5); /* fldl2e */
16093   emit_move_insn (operands[3], temp);
16094   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16097 (define_expand "expm1xf2"
16098   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16099                                (match_dup 2)))
16100    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16101    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16102    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16103    (parallel [(set (match_dup 7)
16104                    (unspec:XF [(match_dup 6) (match_dup 4)]
16105                               UNSPEC_FSCALE_FRACT))
16106                    (set (match_dup 8)
16107                    (unspec:XF [(match_dup 6) (match_dup 4)]
16108                               UNSPEC_FSCALE_EXP))])
16109    (parallel [(set (match_dup 10)
16110                    (unspec:XF [(match_dup 9) (match_dup 8)]
16111                               UNSPEC_FSCALE_FRACT))
16112               (set (match_dup 11)
16113                    (unspec:XF [(match_dup 9) (match_dup 8)]
16114                               UNSPEC_FSCALE_EXP))])
16115    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16116    (set (match_operand:XF 0 "register_operand" "")
16117         (plus:XF (match_dup 12) (match_dup 7)))]
16118   "TARGET_USE_FANCY_MATH_387
16119    && flag_unsafe_math_optimizations"
16121   rtx temp;
16122   int i;
16124   for (i=2; i<13; i++)
16125     operands[i] = gen_reg_rtx (XFmode);
16126   temp = standard_80387_constant_rtx (5); /* fldl2e */
16127   emit_move_insn (operands[2], temp);
16128   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16131 (define_expand "ldexpdf3"
16132   [(set (match_dup 3)
16133         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16134    (set (match_dup 4)
16135         (float:XF (match_operand:SI 2 "register_operand" "")))
16136    (parallel [(set (match_dup 5)
16137                    (unspec:XF [(match_dup 3) (match_dup 4)]
16138                               UNSPEC_FSCALE_FRACT))
16139               (set (match_dup 6)
16140                    (unspec:XF [(match_dup 3) (match_dup 4)]
16141                               UNSPEC_FSCALE_EXP))])
16142    (set (match_operand:DF 0 "register_operand" "")
16143         (float_truncate:DF (match_dup 5)))]
16144   "TARGET_USE_FANCY_MATH_387
16145    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16146    && flag_unsafe_math_optimizations"
16148   int i;
16150   for (i=3; i<7; i++)
16151     operands[i] = gen_reg_rtx (XFmode);
16154 (define_expand "ldexpsf3"
16155   [(set (match_dup 3)
16156         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16157    (set (match_dup 4)
16158         (float:XF (match_operand:SI 2 "register_operand" "")))
16159    (parallel [(set (match_dup 5)
16160                    (unspec:XF [(match_dup 3) (match_dup 4)]
16161                               UNSPEC_FSCALE_FRACT))
16162               (set (match_dup 6)
16163                    (unspec:XF [(match_dup 3) (match_dup 4)]
16164                               UNSPEC_FSCALE_EXP))])
16165    (set (match_operand:SF 0 "register_operand" "")
16166         (float_truncate:SF (match_dup 5)))]
16167   "TARGET_USE_FANCY_MATH_387
16168    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16169    && flag_unsafe_math_optimizations"
16171   int i;
16173   for (i=3; i<7; i++)
16174     operands[i] = gen_reg_rtx (XFmode);
16177 (define_expand "ldexpxf3"
16178   [(set (match_dup 3)
16179         (float:XF (match_operand:SI 2 "register_operand" "")))
16180    (parallel [(set (match_operand:XF 0 " register_operand" "")
16181                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16182                                (match_dup 3)]
16183                               UNSPEC_FSCALE_FRACT))
16184               (set (match_dup 4)
16185                    (unspec:XF [(match_dup 1) (match_dup 3)]
16186                               UNSPEC_FSCALE_EXP))])]
16187   "TARGET_USE_FANCY_MATH_387
16188    && flag_unsafe_math_optimizations"
16190   int i;
16192   for (i=3; i<5; i++)
16193     operands[i] = gen_reg_rtx (XFmode);
16197 (define_insn "frndintxf2"
16198   [(set (match_operand:XF 0 "register_operand" "=f")
16199         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16200          UNSPEC_FRNDINT))]
16201   "TARGET_USE_FANCY_MATH_387
16202    && flag_unsafe_math_optimizations"
16203   "frndint"
16204   [(set_attr "type" "fpspc")
16205    (set_attr "mode" "XF")])
16207 (define_expand "rintdf2"
16208   [(use (match_operand:DF 0 "register_operand" ""))
16209    (use (match_operand:DF 1 "register_operand" ""))]
16210   "TARGET_USE_FANCY_MATH_387
16211    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16212    && flag_unsafe_math_optimizations"
16214   rtx op0 = gen_reg_rtx (XFmode);
16215   rtx op1 = gen_reg_rtx (XFmode);
16217   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16218   emit_insn (gen_frndintxf2 (op0, op1));
16220   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16221   DONE;
16224 (define_expand "rintsf2"
16225   [(use (match_operand:SF 0 "register_operand" ""))
16226    (use (match_operand:SF 1 "register_operand" ""))]
16227   "TARGET_USE_FANCY_MATH_387
16228    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16229    && flag_unsafe_math_optimizations"
16231   rtx op0 = gen_reg_rtx (XFmode);
16232   rtx op1 = gen_reg_rtx (XFmode);
16234   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16235   emit_insn (gen_frndintxf2 (op0, op1));
16237   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16238   DONE;
16241 (define_expand "rintxf2"
16242   [(use (match_operand:XF 0 "register_operand" ""))
16243    (use (match_operand:XF 1 "register_operand" ""))]
16244   "TARGET_USE_FANCY_MATH_387
16245    && flag_unsafe_math_optimizations"
16247   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16248   DONE;
16251 (define_insn "fistdi2"
16252   [(set (match_operand:DI 0 "memory_operand" "=m")
16253         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16254          UNSPEC_FIST))
16255    (clobber (match_scratch:XF 2 "=&1f"))]
16256   "TARGET_USE_FANCY_MATH_387
16257    && flag_unsafe_math_optimizations"
16258   "* return output_fix_trunc (insn, operands, 0);"
16259   [(set_attr "type" "fpspc")
16260    (set_attr "mode" "DI")])
16262 (define_insn "fistdi2_with_temp"
16263   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16264         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16265          UNSPEC_FIST))
16266    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16267    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16268   "TARGET_USE_FANCY_MATH_387
16269    && flag_unsafe_math_optimizations"
16270   "#"
16271   [(set_attr "type" "fpspc")
16272    (set_attr "mode" "DI")])
16274 (define_split 
16275   [(set (match_operand:DI 0 "register_operand" "")
16276         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16277          UNSPEC_FIST))
16278    (clobber (match_operand:DI 2 "memory_operand" ""))
16279    (clobber (match_scratch 3 ""))]
16280   "reload_completed"
16281   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16282               (clobber (match_dup 3))])
16283    (set (match_dup 0) (match_dup 2))]
16284   "")
16286 (define_split 
16287   [(set (match_operand:DI 0 "memory_operand" "")
16288         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16289          UNSPEC_FIST))
16290    (clobber (match_operand:DI 2 "memory_operand" ""))
16291    (clobber (match_scratch 3 ""))]
16292   "reload_completed"
16293   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16294               (clobber (match_dup 3))])]
16295   "")
16297 (define_insn "fist<mode>2"
16298   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16299         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16300          UNSPEC_FIST))]
16301   "TARGET_USE_FANCY_MATH_387
16302    && flag_unsafe_math_optimizations"
16303   "* return output_fix_trunc (insn, operands, 0);"
16304   [(set_attr "type" "fpspc")
16305    (set_attr "mode" "<MODE>")])
16307 (define_insn "fist<mode>2_with_temp"
16308   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16309         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16310          UNSPEC_FIST))
16311    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16312   "TARGET_USE_FANCY_MATH_387
16313    && flag_unsafe_math_optimizations"
16314   "#"
16315   [(set_attr "type" "fpspc")
16316    (set_attr "mode" "<MODE>")])
16318 (define_split 
16319   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16320         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16321          UNSPEC_FIST))
16322    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16323   "reload_completed"
16324   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16325                        UNSPEC_FIST))
16326    (set (match_dup 0) (match_dup 2))]
16327   "")
16329 (define_split 
16330   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16331         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16332          UNSPEC_FIST))
16333    (clobber (match_scratch 2 ""))]
16334   "reload_completed"
16335   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16336                        UNSPEC_FIST))]
16337   "")
16339 (define_expand "lrint<mode>2"
16340   [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16341    (use (match_operand:XF 1 "register_operand" ""))]
16342   "TARGET_USE_FANCY_MATH_387
16343    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16344    && flag_unsafe_math_optimizations"
16346   if (memory_operand (operands[0], VOIDmode))
16347     emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16348   else
16349     {
16350       operands[2] = assign_386_stack_local (<MODE>mode, 0);
16351       emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16352                                             operands[2]));
16353     }
16354   DONE;
16357 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16358 (define_insn_and_split "frndintxf2_floor"
16359   [(set (match_operand:XF 0 "register_operand" "=f")
16360         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16361          UNSPEC_FRNDINT_FLOOR))
16362    (clobber (reg:CC FLAGS_REG))]
16363   "TARGET_USE_FANCY_MATH_387
16364    && flag_unsafe_math_optimizations
16365    && !(reload_completed || reload_in_progress)"
16366   "#"
16367   "&& 1"
16368   [(const_int 0)]
16370   ix86_optimize_mode_switching = 1;
16372   operands[2] = assign_386_stack_local (HImode, 1);
16373   operands[3] = assign_386_stack_local (HImode, 2);
16375   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16376                                         operands[2], operands[3]));
16377   DONE;
16379   [(set_attr "type" "frndint")
16380    (set_attr "i387_cw" "floor")
16381    (set_attr "mode" "XF")])
16383 (define_insn "frndintxf2_floor_i387"
16384   [(set (match_operand:XF 0 "register_operand" "=f")
16385         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16386          UNSPEC_FRNDINT_FLOOR))
16387    (use (match_operand:HI 2 "memory_operand" "m"))
16388    (use (match_operand:HI 3 "memory_operand" "m"))]
16389   "TARGET_USE_FANCY_MATH_387
16390    && flag_unsafe_math_optimizations"
16391   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16392   [(set_attr "type" "frndint")
16393    (set_attr "i387_cw" "floor")
16394    (set_attr "mode" "XF")])
16396 (define_expand "floorxf2"
16397   [(use (match_operand:XF 0 "register_operand" ""))
16398    (use (match_operand:XF 1 "register_operand" ""))]
16399   "TARGET_USE_FANCY_MATH_387
16400    && flag_unsafe_math_optimizations"
16402   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16403   DONE;
16406 (define_expand "floordf2"
16407   [(use (match_operand:DF 0 "register_operand" ""))
16408    (use (match_operand:DF 1 "register_operand" ""))]
16409   "TARGET_USE_FANCY_MATH_387
16410    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16411    && flag_unsafe_math_optimizations"
16413   rtx op0 = gen_reg_rtx (XFmode);
16414   rtx op1 = gen_reg_rtx (XFmode);
16416   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16417   emit_insn (gen_frndintxf2_floor (op0, op1));
16419   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16420   DONE;
16423 (define_expand "floorsf2"
16424   [(use (match_operand:SF 0 "register_operand" ""))
16425    (use (match_operand:SF 1 "register_operand" ""))]
16426   "TARGET_USE_FANCY_MATH_387
16427    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16428    && flag_unsafe_math_optimizations"
16430   rtx op0 = gen_reg_rtx (XFmode);
16431   rtx op1 = gen_reg_rtx (XFmode);
16433   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16434   emit_insn (gen_frndintxf2_floor (op0, op1));
16436   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16437   DONE;
16440 (define_insn_and_split "*fist<mode>2_floor_1"
16441   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16442         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16443          UNSPEC_FIST_FLOOR))
16444    (clobber (reg:CC FLAGS_REG))]
16445   "TARGET_USE_FANCY_MATH_387
16446    && flag_unsafe_math_optimizations
16447    && !(reload_completed || reload_in_progress)"
16448   "#"
16449   "&& 1"
16450   [(const_int 0)]
16452   ix86_optimize_mode_switching = 1;
16453   operands[2] = assign_386_stack_local (HImode, 1);
16454   operands[3] = assign_386_stack_local (HImode, 2);
16455   if (memory_operand (operands[0], VOIDmode))
16456     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16457                                       operands[2], operands[3]));
16458   else
16459     {
16460       operands[4] = assign_386_stack_local (<MODE>mode, 0);
16461       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16462                                                   operands[2], operands[3],
16463                                                   operands[4]));
16464     }
16465   DONE;
16467   [(set_attr "type" "fistp")
16468    (set_attr "i387_cw" "floor")
16469    (set_attr "mode" "<MODE>")])
16471 (define_insn "fistdi2_floor"
16472   [(set (match_operand:DI 0 "memory_operand" "=m")
16473         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16474          UNSPEC_FIST_FLOOR))
16475    (use (match_operand:HI 2 "memory_operand" "m"))
16476    (use (match_operand:HI 3 "memory_operand" "m"))
16477    (clobber (match_scratch:XF 4 "=&1f"))]
16478   "TARGET_USE_FANCY_MATH_387
16479    && flag_unsafe_math_optimizations"
16480   "* return output_fix_trunc (insn, operands, 0);"
16481   [(set_attr "type" "fistp")
16482    (set_attr "i387_cw" "floor")
16483    (set_attr "mode" "DI")])
16485 (define_insn "fistdi2_floor_with_temp"
16486   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16487         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16488          UNSPEC_FIST_FLOOR))
16489    (use (match_operand:HI 2 "memory_operand" "m,m"))
16490    (use (match_operand:HI 3 "memory_operand" "m,m"))
16491    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16492    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16493   "TARGET_USE_FANCY_MATH_387
16494    && flag_unsafe_math_optimizations"
16495   "#"
16496   [(set_attr "type" "fistp")
16497    (set_attr "i387_cw" "floor")
16498    (set_attr "mode" "DI")])
16500 (define_split 
16501   [(set (match_operand:DI 0 "register_operand" "")
16502         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16503          UNSPEC_FIST_FLOOR))
16504    (use (match_operand:HI 2 "memory_operand" ""))
16505    (use (match_operand:HI 3 "memory_operand" ""))
16506    (clobber (match_operand:DI 4 "memory_operand" ""))
16507    (clobber (match_scratch 5 ""))]
16508   "reload_completed"
16509   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16510               (use (match_dup 2))
16511               (use (match_dup 3))
16512               (clobber (match_dup 5))])
16513    (set (match_dup 0) (match_dup 4))]
16514   "")
16516 (define_split 
16517   [(set (match_operand:DI 0 "memory_operand" "")
16518         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16519          UNSPEC_FIST_FLOOR))
16520    (use (match_operand:HI 2 "memory_operand" ""))
16521    (use (match_operand:HI 3 "memory_operand" ""))
16522    (clobber (match_operand:DI 4 "memory_operand" ""))
16523    (clobber (match_scratch 5 ""))]
16524   "reload_completed"
16525   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16526               (use (match_dup 2))
16527               (use (match_dup 3))
16528               (clobber (match_dup 5))])]
16529   "")
16531 (define_insn "fist<mode>2_floor"
16532   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16533         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16534          UNSPEC_FIST_FLOOR))
16535    (use (match_operand:HI 2 "memory_operand" "m"))
16536    (use (match_operand:HI 3 "memory_operand" "m"))]
16537   "TARGET_USE_FANCY_MATH_387
16538    && flag_unsafe_math_optimizations"
16539   "* return output_fix_trunc (insn, operands, 0);"
16540   [(set_attr "type" "fistp")
16541    (set_attr "i387_cw" "floor")
16542    (set_attr "mode" "<MODE>")])
16544 (define_insn "fist<mode>2_floor_with_temp"
16545   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16546         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16547          UNSPEC_FIST_FLOOR))
16548    (use (match_operand:HI 2 "memory_operand" "m,m"))
16549    (use (match_operand:HI 3 "memory_operand" "m,m"))
16550    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16551   "TARGET_USE_FANCY_MATH_387
16552    && flag_unsafe_math_optimizations"
16553   "#"
16554   [(set_attr "type" "fistp")
16555    (set_attr "i387_cw" "floor")
16556    (set_attr "mode" "<MODE>")])
16558 (define_split 
16559   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16560         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16561          UNSPEC_FIST_FLOOR))
16562    (use (match_operand:HI 2 "memory_operand" ""))
16563    (use (match_operand:HI 3 "memory_operand" ""))
16564    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16565   "reload_completed"
16566   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16567                                   UNSPEC_FIST_FLOOR))
16568               (use (match_dup 2))
16569               (use (match_dup 3))])
16570    (set (match_dup 0) (match_dup 4))]
16571   "")
16573 (define_split 
16574   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16575         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16576          UNSPEC_FIST_FLOOR))
16577    (use (match_operand:HI 2 "memory_operand" ""))
16578    (use (match_operand:HI 3 "memory_operand" ""))
16579    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16580   "reload_completed"
16581   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16582                                   UNSPEC_FIST_FLOOR))
16583               (use (match_dup 2))
16584               (use (match_dup 3))])]
16585   "")
16587 (define_expand "lfloor<mode>2"
16588   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16589                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16590                     UNSPEC_FIST_FLOOR))
16591               (clobber (reg:CC FLAGS_REG))])]
16592   "TARGET_USE_FANCY_MATH_387
16593    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16594    && flag_unsafe_math_optimizations"
16595   "")
16597 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16598 (define_insn_and_split "frndintxf2_ceil"
16599   [(set (match_operand:XF 0 "register_operand" "=f")
16600         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16601          UNSPEC_FRNDINT_CEIL))
16602    (clobber (reg:CC FLAGS_REG))]
16603   "TARGET_USE_FANCY_MATH_387
16604    && flag_unsafe_math_optimizations
16605    && !(reload_completed || reload_in_progress)"
16606   "#"
16607   "&& 1"
16608   [(const_int 0)]
16610   ix86_optimize_mode_switching = 1;
16612   operands[2] = assign_386_stack_local (HImode, 1);
16613   operands[3] = assign_386_stack_local (HImode, 2);
16615   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16616                                        operands[2], operands[3]));
16617   DONE;
16619   [(set_attr "type" "frndint")
16620    (set_attr "i387_cw" "ceil")
16621    (set_attr "mode" "XF")])
16623 (define_insn "frndintxf2_ceil_i387"
16624   [(set (match_operand:XF 0 "register_operand" "=f")
16625         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16626          UNSPEC_FRNDINT_CEIL))
16627    (use (match_operand:HI 2 "memory_operand" "m"))
16628    (use (match_operand:HI 3 "memory_operand" "m"))]
16629   "TARGET_USE_FANCY_MATH_387
16630    && flag_unsafe_math_optimizations"
16631   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16632   [(set_attr "type" "frndint")
16633    (set_attr "i387_cw" "ceil")
16634    (set_attr "mode" "XF")])
16636 (define_expand "ceilxf2"
16637   [(use (match_operand:XF 0 "register_operand" ""))
16638    (use (match_operand:XF 1 "register_operand" ""))]
16639   "TARGET_USE_FANCY_MATH_387
16640    && flag_unsafe_math_optimizations"
16642   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16643   DONE;
16646 (define_expand "ceildf2"
16647   [(use (match_operand:DF 0 "register_operand" ""))
16648    (use (match_operand:DF 1 "register_operand" ""))]
16649   "TARGET_USE_FANCY_MATH_387
16650    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16651    && flag_unsafe_math_optimizations"
16653   rtx op0 = gen_reg_rtx (XFmode);
16654   rtx op1 = gen_reg_rtx (XFmode);
16656   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16657   emit_insn (gen_frndintxf2_ceil (op0, op1));
16659   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16660   DONE;
16663 (define_expand "ceilsf2"
16664   [(use (match_operand:SF 0 "register_operand" ""))
16665    (use (match_operand:SF 1 "register_operand" ""))]
16666   "TARGET_USE_FANCY_MATH_387
16667    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16668    && flag_unsafe_math_optimizations"
16670   rtx op0 = gen_reg_rtx (XFmode);
16671   rtx op1 = gen_reg_rtx (XFmode);
16673   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16674   emit_insn (gen_frndintxf2_ceil (op0, op1));
16676   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16677   DONE;
16680 (define_insn_and_split "*fist<mode>2_ceil_1"
16681   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16682         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16683          UNSPEC_FIST_CEIL))
16684    (clobber (reg:CC FLAGS_REG))]
16685   "TARGET_USE_FANCY_MATH_387
16686    && flag_unsafe_math_optimizations
16687    && !(reload_completed || reload_in_progress)"
16688   "#"
16689   "&& 1"
16690   [(const_int 0)]
16692   ix86_optimize_mode_switching = 1;
16693   operands[2] = assign_386_stack_local (HImode, 1);
16694   operands[3] = assign_386_stack_local (HImode, 2);
16695   if (memory_operand (operands[0], VOIDmode))
16696     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16697                                      operands[2], operands[3]));
16698   else
16699     {
16700       operands[4] = assign_386_stack_local (<MODE>mode, 0);
16701       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16702                                                  operands[2], operands[3],
16703                                                  operands[4]));
16704     }
16705   DONE;
16707   [(set_attr "type" "fistp")
16708    (set_attr "i387_cw" "ceil")
16709    (set_attr "mode" "<MODE>")])
16711 (define_insn "fistdi2_ceil"
16712   [(set (match_operand:DI 0 "memory_operand" "=m")
16713         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16714          UNSPEC_FIST_CEIL))
16715    (use (match_operand:HI 2 "memory_operand" "m"))
16716    (use (match_operand:HI 3 "memory_operand" "m"))
16717    (clobber (match_scratch:XF 4 "=&1f"))]
16718   "TARGET_USE_FANCY_MATH_387
16719    && flag_unsafe_math_optimizations"
16720   "* return output_fix_trunc (insn, operands, 0);"
16721   [(set_attr "type" "fistp")
16722    (set_attr "i387_cw" "ceil")
16723    (set_attr "mode" "DI")])
16725 (define_insn "fistdi2_ceil_with_temp"
16726   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16727         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16728          UNSPEC_FIST_CEIL))
16729    (use (match_operand:HI 2 "memory_operand" "m,m"))
16730    (use (match_operand:HI 3 "memory_operand" "m,m"))
16731    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16732    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16733   "TARGET_USE_FANCY_MATH_387
16734    && flag_unsafe_math_optimizations"
16735   "#"
16736   [(set_attr "type" "fistp")
16737    (set_attr "i387_cw" "ceil")
16738    (set_attr "mode" "DI")])
16740 (define_split 
16741   [(set (match_operand:DI 0 "register_operand" "")
16742         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16743          UNSPEC_FIST_CEIL))
16744    (use (match_operand:HI 2 "memory_operand" ""))
16745    (use (match_operand:HI 3 "memory_operand" ""))
16746    (clobber (match_operand:DI 4 "memory_operand" ""))
16747    (clobber (match_scratch 5 ""))]
16748   "reload_completed"
16749   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16750               (use (match_dup 2))
16751               (use (match_dup 3))
16752               (clobber (match_dup 5))])
16753    (set (match_dup 0) (match_dup 4))]
16754   "")
16756 (define_split 
16757   [(set (match_operand:DI 0 "memory_operand" "")
16758         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16759          UNSPEC_FIST_CEIL))
16760    (use (match_operand:HI 2 "memory_operand" ""))
16761    (use (match_operand:HI 3 "memory_operand" ""))
16762    (clobber (match_operand:DI 4 "memory_operand" ""))
16763    (clobber (match_scratch 5 ""))]
16764   "reload_completed"
16765   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16766               (use (match_dup 2))
16767               (use (match_dup 3))
16768               (clobber (match_dup 5))])]
16769   "")
16771 (define_insn "fist<mode>2_ceil"
16772   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16773         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16774          UNSPEC_FIST_CEIL))
16775    (use (match_operand:HI 2 "memory_operand" "m"))
16776    (use (match_operand:HI 3 "memory_operand" "m"))]
16777   "TARGET_USE_FANCY_MATH_387
16778    && flag_unsafe_math_optimizations"
16779   "* return output_fix_trunc (insn, operands, 0);"
16780   [(set_attr "type" "fistp")
16781    (set_attr "i387_cw" "ceil")
16782    (set_attr "mode" "<MODE>")])
16784 (define_insn "fist<mode>2_ceil_with_temp"
16785   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16786         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16787          UNSPEC_FIST_CEIL))
16788    (use (match_operand:HI 2 "memory_operand" "m,m"))
16789    (use (match_operand:HI 3 "memory_operand" "m,m"))
16790    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16791   "TARGET_USE_FANCY_MATH_387
16792    && flag_unsafe_math_optimizations"
16793   "#"
16794   [(set_attr "type" "fistp")
16795    (set_attr "i387_cw" "ceil")
16796    (set_attr "mode" "<MODE>")])
16798 (define_split 
16799   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16800         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16801          UNSPEC_FIST_CEIL))
16802    (use (match_operand:HI 2 "memory_operand" ""))
16803    (use (match_operand:HI 3 "memory_operand" ""))
16804    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16805   "reload_completed"
16806   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16807                                   UNSPEC_FIST_CEIL))
16808               (use (match_dup 2))
16809               (use (match_dup 3))])
16810    (set (match_dup 0) (match_dup 4))]
16811   "")
16813 (define_split 
16814   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16815         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16816          UNSPEC_FIST_CEIL))
16817    (use (match_operand:HI 2 "memory_operand" ""))
16818    (use (match_operand:HI 3 "memory_operand" ""))
16819    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16820   "reload_completed"
16821   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16822                                   UNSPEC_FIST_CEIL))
16823               (use (match_dup 2))
16824               (use (match_dup 3))])]
16825   "")
16827 (define_expand "lceil<mode>2"
16828   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16829                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16830                     UNSPEC_FIST_CEIL))
16831               (clobber (reg:CC FLAGS_REG))])]
16832   "TARGET_USE_FANCY_MATH_387
16833    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16834    && flag_unsafe_math_optimizations"
16835   "")
16837 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16838 (define_insn_and_split "frndintxf2_trunc"
16839   [(set (match_operand:XF 0 "register_operand" "=f")
16840         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16841          UNSPEC_FRNDINT_TRUNC))
16842    (clobber (reg:CC FLAGS_REG))]
16843   "TARGET_USE_FANCY_MATH_387
16844    && flag_unsafe_math_optimizations
16845    && !(reload_completed || reload_in_progress)"
16846   "#"
16847   "&& 1"
16848   [(const_int 0)]
16850   ix86_optimize_mode_switching = 1;
16852   operands[2] = assign_386_stack_local (HImode, 1);
16853   operands[3] = assign_386_stack_local (HImode, 2);
16855   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16856                                         operands[2], operands[3]));
16857   DONE;
16859   [(set_attr "type" "frndint")
16860    (set_attr "i387_cw" "trunc")
16861    (set_attr "mode" "XF")])
16863 (define_insn "frndintxf2_trunc_i387"
16864   [(set (match_operand:XF 0 "register_operand" "=f")
16865         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16866          UNSPEC_FRNDINT_TRUNC))
16867    (use (match_operand:HI 2 "memory_operand" "m"))
16868    (use (match_operand:HI 3 "memory_operand" "m"))]
16869   "TARGET_USE_FANCY_MATH_387
16870    && flag_unsafe_math_optimizations"
16871   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16872   [(set_attr "type" "frndint")
16873    (set_attr "i387_cw" "trunc")
16874    (set_attr "mode" "XF")])
16876 (define_expand "btruncxf2"
16877   [(use (match_operand:XF 0 "register_operand" ""))
16878    (use (match_operand:XF 1 "register_operand" ""))]
16879   "TARGET_USE_FANCY_MATH_387
16880    && flag_unsafe_math_optimizations"
16882   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16883   DONE;
16886 (define_expand "btruncdf2"
16887   [(use (match_operand:DF 0 "register_operand" ""))
16888    (use (match_operand:DF 1 "register_operand" ""))]
16889   "TARGET_USE_FANCY_MATH_387
16890    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16891    && flag_unsafe_math_optimizations"
16893   rtx op0 = gen_reg_rtx (XFmode);
16894   rtx op1 = gen_reg_rtx (XFmode);
16896   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16897   emit_insn (gen_frndintxf2_trunc (op0, op1));
16899   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16900   DONE;
16903 (define_expand "btruncsf2"
16904   [(use (match_operand:SF 0 "register_operand" ""))
16905    (use (match_operand:SF 1 "register_operand" ""))]
16906   "TARGET_USE_FANCY_MATH_387
16907    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16908    && flag_unsafe_math_optimizations"
16910   rtx op0 = gen_reg_rtx (XFmode);
16911   rtx op1 = gen_reg_rtx (XFmode);
16913   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16914   emit_insn (gen_frndintxf2_trunc (op0, op1));
16916   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16917   DONE;
16920 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16921 (define_insn_and_split "frndintxf2_mask_pm"
16922   [(set (match_operand:XF 0 "register_operand" "=f")
16923         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16924          UNSPEC_FRNDINT_MASK_PM))
16925    (clobber (reg:CC FLAGS_REG))]
16926   "TARGET_USE_FANCY_MATH_387
16927    && flag_unsafe_math_optimizations
16928    && !(reload_completed || reload_in_progress)"
16929   "#"
16930   "&& 1"
16931   [(const_int 0)]
16933   ix86_optimize_mode_switching = 1;
16935   operands[2] = assign_386_stack_local (HImode, 1);
16936   operands[3] = assign_386_stack_local (HImode, 2);
16938   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16939                                           operands[2], operands[3]));
16940   DONE;
16942   [(set_attr "type" "frndint")
16943    (set_attr "i387_cw" "mask_pm")
16944    (set_attr "mode" "XF")])
16946 (define_insn "frndintxf2_mask_pm_i387"
16947   [(set (match_operand:XF 0 "register_operand" "=f")
16948         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16949          UNSPEC_FRNDINT_MASK_PM))
16950    (use (match_operand:HI 2 "memory_operand" "m"))
16951    (use (match_operand:HI 3 "memory_operand" "m"))]
16952   "TARGET_USE_FANCY_MATH_387
16953    && flag_unsafe_math_optimizations"
16954   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16955   [(set_attr "type" "frndint")
16956    (set_attr "i387_cw" "mask_pm")
16957    (set_attr "mode" "XF")])
16959 (define_expand "nearbyintxf2"
16960   [(use (match_operand:XF 0 "register_operand" ""))
16961    (use (match_operand:XF 1 "register_operand" ""))]
16962   "TARGET_USE_FANCY_MATH_387
16963    && flag_unsafe_math_optimizations"
16965   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16967   DONE;
16970 (define_expand "nearbyintdf2"
16971   [(use (match_operand:DF 0 "register_operand" ""))
16972    (use (match_operand:DF 1 "register_operand" ""))]
16973   "TARGET_USE_FANCY_MATH_387
16974    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16975    && flag_unsafe_math_optimizations"
16977   rtx op0 = gen_reg_rtx (XFmode);
16978   rtx op1 = gen_reg_rtx (XFmode);
16980   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16981   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16983   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16984   DONE;
16987 (define_expand "nearbyintsf2"
16988   [(use (match_operand:SF 0 "register_operand" ""))
16989    (use (match_operand:SF 1 "register_operand" ""))]
16990   "TARGET_USE_FANCY_MATH_387
16991    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16992    && flag_unsafe_math_optimizations"
16994   rtx op0 = gen_reg_rtx (XFmode);
16995   rtx op1 = gen_reg_rtx (XFmode);
16997   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16998   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17000   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17001   DONE;
17005 ;; Block operation instructions
17007 (define_insn "cld"
17008  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17009  ""
17010  "cld"
17011   [(set_attr "type" "cld")])
17013 (define_expand "movmemsi"
17014   [(use (match_operand:BLK 0 "memory_operand" ""))
17015    (use (match_operand:BLK 1 "memory_operand" ""))
17016    (use (match_operand:SI 2 "nonmemory_operand" ""))
17017    (use (match_operand:SI 3 "const_int_operand" ""))]
17018   "! optimize_size"
17020  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17021    DONE;
17022  else
17023    FAIL;
17026 (define_expand "movmemdi"
17027   [(use (match_operand:BLK 0 "memory_operand" ""))
17028    (use (match_operand:BLK 1 "memory_operand" ""))
17029    (use (match_operand:DI 2 "nonmemory_operand" ""))
17030    (use (match_operand:DI 3 "const_int_operand" ""))]
17031   "TARGET_64BIT"
17033  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17034    DONE;
17035  else
17036    FAIL;
17039 ;; Most CPUs don't like single string operations
17040 ;; Handle this case here to simplify previous expander.
17042 (define_expand "strmov"
17043   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17044    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17045    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17046               (clobber (reg:CC FLAGS_REG))])
17047    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17048               (clobber (reg:CC FLAGS_REG))])]
17049   ""
17051   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17053   /* If .md ever supports :P for Pmode, these can be directly
17054      in the pattern above.  */
17055   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17056   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17058   if (TARGET_SINGLE_STRINGOP || optimize_size)
17059     {
17060       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17061                                       operands[2], operands[3],
17062                                       operands[5], operands[6]));
17063       DONE;
17064     }
17066   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17069 (define_expand "strmov_singleop"
17070   [(parallel [(set (match_operand 1 "memory_operand" "")
17071                    (match_operand 3 "memory_operand" ""))
17072               (set (match_operand 0 "register_operand" "")
17073                    (match_operand 4 "" ""))
17074               (set (match_operand 2 "register_operand" "")
17075                    (match_operand 5 "" ""))
17076               (use (reg:SI DIRFLAG_REG))])]
17077   "TARGET_SINGLE_STRINGOP || optimize_size"
17078   "")
17080 (define_insn "*strmovdi_rex_1"
17081   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17082         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17083    (set (match_operand:DI 0 "register_operand" "=D")
17084         (plus:DI (match_dup 2)
17085                  (const_int 8)))
17086    (set (match_operand:DI 1 "register_operand" "=S")
17087         (plus:DI (match_dup 3)
17088                  (const_int 8)))
17089    (use (reg:SI DIRFLAG_REG))]
17090   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17091   "movsq"
17092   [(set_attr "type" "str")
17093    (set_attr "mode" "DI")
17094    (set_attr "memory" "both")])
17096 (define_insn "*strmovsi_1"
17097   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17098         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17099    (set (match_operand:SI 0 "register_operand" "=D")
17100         (plus:SI (match_dup 2)
17101                  (const_int 4)))
17102    (set (match_operand:SI 1 "register_operand" "=S")
17103         (plus:SI (match_dup 3)
17104                  (const_int 4)))
17105    (use (reg:SI DIRFLAG_REG))]
17106   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17107   "{movsl|movsd}"
17108   [(set_attr "type" "str")
17109    (set_attr "mode" "SI")
17110    (set_attr "memory" "both")])
17112 (define_insn "*strmovsi_rex_1"
17113   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17114         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17115    (set (match_operand:DI 0 "register_operand" "=D")
17116         (plus:DI (match_dup 2)
17117                  (const_int 4)))
17118    (set (match_operand:DI 1 "register_operand" "=S")
17119         (plus:DI (match_dup 3)
17120                  (const_int 4)))
17121    (use (reg:SI DIRFLAG_REG))]
17122   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17123   "{movsl|movsd}"
17124   [(set_attr "type" "str")
17125    (set_attr "mode" "SI")
17126    (set_attr "memory" "both")])
17128 (define_insn "*strmovhi_1"
17129   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17130         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17131    (set (match_operand:SI 0 "register_operand" "=D")
17132         (plus:SI (match_dup 2)
17133                  (const_int 2)))
17134    (set (match_operand:SI 1 "register_operand" "=S")
17135         (plus:SI (match_dup 3)
17136                  (const_int 2)))
17137    (use (reg:SI DIRFLAG_REG))]
17138   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17139   "movsw"
17140   [(set_attr "type" "str")
17141    (set_attr "memory" "both")
17142    (set_attr "mode" "HI")])
17144 (define_insn "*strmovhi_rex_1"
17145   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17146         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17147    (set (match_operand:DI 0 "register_operand" "=D")
17148         (plus:DI (match_dup 2)
17149                  (const_int 2)))
17150    (set (match_operand:DI 1 "register_operand" "=S")
17151         (plus:DI (match_dup 3)
17152                  (const_int 2)))
17153    (use (reg:SI DIRFLAG_REG))]
17154   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17155   "movsw"
17156   [(set_attr "type" "str")
17157    (set_attr "memory" "both")
17158    (set_attr "mode" "HI")])
17160 (define_insn "*strmovqi_1"
17161   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17162         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17163    (set (match_operand:SI 0 "register_operand" "=D")
17164         (plus:SI (match_dup 2)
17165                  (const_int 1)))
17166    (set (match_operand:SI 1 "register_operand" "=S")
17167         (plus:SI (match_dup 3)
17168                  (const_int 1)))
17169    (use (reg:SI DIRFLAG_REG))]
17170   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17171   "movsb"
17172   [(set_attr "type" "str")
17173    (set_attr "memory" "both")
17174    (set_attr "mode" "QI")])
17176 (define_insn "*strmovqi_rex_1"
17177   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17178         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17179    (set (match_operand:DI 0 "register_operand" "=D")
17180         (plus:DI (match_dup 2)
17181                  (const_int 1)))
17182    (set (match_operand:DI 1 "register_operand" "=S")
17183         (plus:DI (match_dup 3)
17184                  (const_int 1)))
17185    (use (reg:SI DIRFLAG_REG))]
17186   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17187   "movsb"
17188   [(set_attr "type" "str")
17189    (set_attr "memory" "both")
17190    (set_attr "mode" "QI")])
17192 (define_expand "rep_mov"
17193   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17194               (set (match_operand 0 "register_operand" "")
17195                    (match_operand 5 "" ""))
17196               (set (match_operand 2 "register_operand" "")
17197                    (match_operand 6 "" ""))
17198               (set (match_operand 1 "memory_operand" "")
17199                    (match_operand 3 "memory_operand" ""))
17200               (use (match_dup 4))
17201               (use (reg:SI DIRFLAG_REG))])]
17202   ""
17203   "")
17205 (define_insn "*rep_movdi_rex64"
17206   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17207    (set (match_operand:DI 0 "register_operand" "=D") 
17208         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17209                             (const_int 3))
17210                  (match_operand:DI 3 "register_operand" "0")))
17211    (set (match_operand:DI 1 "register_operand" "=S") 
17212         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17213                  (match_operand:DI 4 "register_operand" "1")))
17214    (set (mem:BLK (match_dup 3))
17215         (mem:BLK (match_dup 4)))
17216    (use (match_dup 5))
17217    (use (reg:SI DIRFLAG_REG))]
17218   "TARGET_64BIT"
17219   "{rep\;movsq|rep movsq}"
17220   [(set_attr "type" "str")
17221    (set_attr "prefix_rep" "1")
17222    (set_attr "memory" "both")
17223    (set_attr "mode" "DI")])
17225 (define_insn "*rep_movsi"
17226   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17227    (set (match_operand:SI 0 "register_operand" "=D") 
17228         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17229                             (const_int 2))
17230                  (match_operand:SI 3 "register_operand" "0")))
17231    (set (match_operand:SI 1 "register_operand" "=S") 
17232         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17233                  (match_operand:SI 4 "register_operand" "1")))
17234    (set (mem:BLK (match_dup 3))
17235         (mem:BLK (match_dup 4)))
17236    (use (match_dup 5))
17237    (use (reg:SI DIRFLAG_REG))]
17238   "!TARGET_64BIT"
17239   "{rep\;movsl|rep movsd}"
17240   [(set_attr "type" "str")
17241    (set_attr "prefix_rep" "1")
17242    (set_attr "memory" "both")
17243    (set_attr "mode" "SI")])
17245 (define_insn "*rep_movsi_rex64"
17246   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17247    (set (match_operand:DI 0 "register_operand" "=D") 
17248         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17249                             (const_int 2))
17250                  (match_operand:DI 3 "register_operand" "0")))
17251    (set (match_operand:DI 1 "register_operand" "=S") 
17252         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17253                  (match_operand:DI 4 "register_operand" "1")))
17254    (set (mem:BLK (match_dup 3))
17255         (mem:BLK (match_dup 4)))
17256    (use (match_dup 5))
17257    (use (reg:SI DIRFLAG_REG))]
17258   "TARGET_64BIT"
17259   "{rep\;movsl|rep movsd}"
17260   [(set_attr "type" "str")
17261    (set_attr "prefix_rep" "1")
17262    (set_attr "memory" "both")
17263    (set_attr "mode" "SI")])
17265 (define_insn "*rep_movqi"
17266   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17267    (set (match_operand:SI 0 "register_operand" "=D") 
17268         (plus:SI (match_operand:SI 3 "register_operand" "0")
17269                  (match_operand:SI 5 "register_operand" "2")))
17270    (set (match_operand:SI 1 "register_operand" "=S") 
17271         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17272    (set (mem:BLK (match_dup 3))
17273         (mem:BLK (match_dup 4)))
17274    (use (match_dup 5))
17275    (use (reg:SI DIRFLAG_REG))]
17276   "!TARGET_64BIT"
17277   "{rep\;movsb|rep movsb}"
17278   [(set_attr "type" "str")
17279    (set_attr "prefix_rep" "1")
17280    (set_attr "memory" "both")
17281    (set_attr "mode" "SI")])
17283 (define_insn "*rep_movqi_rex64"
17284   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17285    (set (match_operand:DI 0 "register_operand" "=D") 
17286         (plus:DI (match_operand:DI 3 "register_operand" "0")
17287                  (match_operand:DI 5 "register_operand" "2")))
17288    (set (match_operand:DI 1 "register_operand" "=S") 
17289         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17290    (set (mem:BLK (match_dup 3))
17291         (mem:BLK (match_dup 4)))
17292    (use (match_dup 5))
17293    (use (reg:SI DIRFLAG_REG))]
17294   "TARGET_64BIT"
17295   "{rep\;movsb|rep movsb}"
17296   [(set_attr "type" "str")
17297    (set_attr "prefix_rep" "1")
17298    (set_attr "memory" "both")
17299    (set_attr "mode" "SI")])
17301 (define_expand "clrmemsi"
17302    [(use (match_operand:BLK 0 "memory_operand" ""))
17303     (use (match_operand:SI 1 "nonmemory_operand" ""))
17304     (use (match_operand 2 "const_int_operand" ""))]
17305   ""
17307  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17308    DONE;
17309  else
17310    FAIL;
17313 (define_expand "clrmemdi"
17314    [(use (match_operand:BLK 0 "memory_operand" ""))
17315     (use (match_operand:DI 1 "nonmemory_operand" ""))
17316     (use (match_operand 2 "const_int_operand" ""))]
17317   "TARGET_64BIT"
17319  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17320    DONE;
17321  else
17322    FAIL;
17325 ;; Most CPUs don't like single string operations
17326 ;; Handle this case here to simplify previous expander.
17328 (define_expand "strset"
17329   [(set (match_operand 1 "memory_operand" "")
17330         (match_operand 2 "register_operand" ""))
17331    (parallel [(set (match_operand 0 "register_operand" "")
17332                    (match_dup 3))
17333               (clobber (reg:CC FLAGS_REG))])]
17334   ""
17336   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17337     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17339   /* If .md ever supports :P for Pmode, this can be directly
17340      in the pattern above.  */
17341   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17342                               GEN_INT (GET_MODE_SIZE (GET_MODE
17343                                                       (operands[2]))));
17344   if (TARGET_SINGLE_STRINGOP || optimize_size)
17345     {
17346       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17347                                       operands[3]));
17348       DONE;
17349     }
17352 (define_expand "strset_singleop"
17353   [(parallel [(set (match_operand 1 "memory_operand" "")
17354                    (match_operand 2 "register_operand" ""))
17355               (set (match_operand 0 "register_operand" "")
17356                    (match_operand 3 "" ""))
17357               (use (reg:SI DIRFLAG_REG))])]
17358   "TARGET_SINGLE_STRINGOP || optimize_size"
17359   "")
17361 (define_insn "*strsetdi_rex_1"
17362   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17363         (match_operand:DI 2 "register_operand" "a"))
17364    (set (match_operand:DI 0 "register_operand" "=D")
17365         (plus:DI (match_dup 1)
17366                  (const_int 8)))
17367    (use (reg:SI DIRFLAG_REG))]
17368   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17369   "stosq"
17370   [(set_attr "type" "str")
17371    (set_attr "memory" "store")
17372    (set_attr "mode" "DI")])
17374 (define_insn "*strsetsi_1"
17375   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17376         (match_operand:SI 2 "register_operand" "a"))
17377    (set (match_operand:SI 0 "register_operand" "=D")
17378         (plus:SI (match_dup 1)
17379                  (const_int 4)))
17380    (use (reg:SI DIRFLAG_REG))]
17381   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17382   "{stosl|stosd}"
17383   [(set_attr "type" "str")
17384    (set_attr "memory" "store")
17385    (set_attr "mode" "SI")])
17387 (define_insn "*strsetsi_rex_1"
17388   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17389         (match_operand:SI 2 "register_operand" "a"))
17390    (set (match_operand:DI 0 "register_operand" "=D")
17391         (plus:DI (match_dup 1)
17392                  (const_int 4)))
17393    (use (reg:SI DIRFLAG_REG))]
17394   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17395   "{stosl|stosd}"
17396   [(set_attr "type" "str")
17397    (set_attr "memory" "store")
17398    (set_attr "mode" "SI")])
17400 (define_insn "*strsethi_1"
17401   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17402         (match_operand:HI 2 "register_operand" "a"))
17403    (set (match_operand:SI 0 "register_operand" "=D")
17404         (plus:SI (match_dup 1)
17405                  (const_int 2)))
17406    (use (reg:SI DIRFLAG_REG))]
17407   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17408   "stosw"
17409   [(set_attr "type" "str")
17410    (set_attr "memory" "store")
17411    (set_attr "mode" "HI")])
17413 (define_insn "*strsethi_rex_1"
17414   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17415         (match_operand:HI 2 "register_operand" "a"))
17416    (set (match_operand:DI 0 "register_operand" "=D")
17417         (plus:DI (match_dup 1)
17418                  (const_int 2)))
17419    (use (reg:SI DIRFLAG_REG))]
17420   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17421   "stosw"
17422   [(set_attr "type" "str")
17423    (set_attr "memory" "store")
17424    (set_attr "mode" "HI")])
17426 (define_insn "*strsetqi_1"
17427   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17428         (match_operand:QI 2 "register_operand" "a"))
17429    (set (match_operand:SI 0 "register_operand" "=D")
17430         (plus:SI (match_dup 1)
17431                  (const_int 1)))
17432    (use (reg:SI DIRFLAG_REG))]
17433   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17434   "stosb"
17435   [(set_attr "type" "str")
17436    (set_attr "memory" "store")
17437    (set_attr "mode" "QI")])
17439 (define_insn "*strsetqi_rex_1"
17440   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17441         (match_operand:QI 2 "register_operand" "a"))
17442    (set (match_operand:DI 0 "register_operand" "=D")
17443         (plus:DI (match_dup 1)
17444                  (const_int 1)))
17445    (use (reg:SI DIRFLAG_REG))]
17446   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17447   "stosb"
17448   [(set_attr "type" "str")
17449    (set_attr "memory" "store")
17450    (set_attr "mode" "QI")])
17452 (define_expand "rep_stos"
17453   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17454               (set (match_operand 0 "register_operand" "")
17455                    (match_operand 4 "" ""))
17456               (set (match_operand 2 "memory_operand" "") (const_int 0))
17457               (use (match_operand 3 "register_operand" ""))
17458               (use (match_dup 1))
17459               (use (reg:SI DIRFLAG_REG))])]
17460   ""
17461   "")
17463 (define_insn "*rep_stosdi_rex64"
17464   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17465    (set (match_operand:DI 0 "register_operand" "=D") 
17466         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17467                             (const_int 3))
17468                  (match_operand:DI 3 "register_operand" "0")))
17469    (set (mem:BLK (match_dup 3))
17470         (const_int 0))
17471    (use (match_operand:DI 2 "register_operand" "a"))
17472    (use (match_dup 4))
17473    (use (reg:SI DIRFLAG_REG))]
17474   "TARGET_64BIT"
17475   "{rep\;stosq|rep stosq}"
17476   [(set_attr "type" "str")
17477    (set_attr "prefix_rep" "1")
17478    (set_attr "memory" "store")
17479    (set_attr "mode" "DI")])
17481 (define_insn "*rep_stossi"
17482   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17483    (set (match_operand:SI 0 "register_operand" "=D") 
17484         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17485                             (const_int 2))
17486                  (match_operand:SI 3 "register_operand" "0")))
17487    (set (mem:BLK (match_dup 3))
17488         (const_int 0))
17489    (use (match_operand:SI 2 "register_operand" "a"))
17490    (use (match_dup 4))
17491    (use (reg:SI DIRFLAG_REG))]
17492   "!TARGET_64BIT"
17493   "{rep\;stosl|rep stosd}"
17494   [(set_attr "type" "str")
17495    (set_attr "prefix_rep" "1")
17496    (set_attr "memory" "store")
17497    (set_attr "mode" "SI")])
17499 (define_insn "*rep_stossi_rex64"
17500   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17501    (set (match_operand:DI 0 "register_operand" "=D") 
17502         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17503                             (const_int 2))
17504                  (match_operand:DI 3 "register_operand" "0")))
17505    (set (mem:BLK (match_dup 3))
17506         (const_int 0))
17507    (use (match_operand:SI 2 "register_operand" "a"))
17508    (use (match_dup 4))
17509    (use (reg:SI DIRFLAG_REG))]
17510   "TARGET_64BIT"
17511   "{rep\;stosl|rep stosd}"
17512   [(set_attr "type" "str")
17513    (set_attr "prefix_rep" "1")
17514    (set_attr "memory" "store")
17515    (set_attr "mode" "SI")])
17517 (define_insn "*rep_stosqi"
17518   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17519    (set (match_operand:SI 0 "register_operand" "=D") 
17520         (plus:SI (match_operand:SI 3 "register_operand" "0")
17521                  (match_operand:SI 4 "register_operand" "1")))
17522    (set (mem:BLK (match_dup 3))
17523         (const_int 0))
17524    (use (match_operand:QI 2 "register_operand" "a"))
17525    (use (match_dup 4))
17526    (use (reg:SI DIRFLAG_REG))]
17527   "!TARGET_64BIT"
17528   "{rep\;stosb|rep stosb}"
17529   [(set_attr "type" "str")
17530    (set_attr "prefix_rep" "1")
17531    (set_attr "memory" "store")
17532    (set_attr "mode" "QI")])
17534 (define_insn "*rep_stosqi_rex64"
17535   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17536    (set (match_operand:DI 0 "register_operand" "=D") 
17537         (plus:DI (match_operand:DI 3 "register_operand" "0")
17538                  (match_operand:DI 4 "register_operand" "1")))
17539    (set (mem:BLK (match_dup 3))
17540         (const_int 0))
17541    (use (match_operand:QI 2 "register_operand" "a"))
17542    (use (match_dup 4))
17543    (use (reg:SI DIRFLAG_REG))]
17544   "TARGET_64BIT"
17545   "{rep\;stosb|rep stosb}"
17546   [(set_attr "type" "str")
17547    (set_attr "prefix_rep" "1")
17548    (set_attr "memory" "store")
17549    (set_attr "mode" "QI")])
17551 (define_expand "cmpstrsi"
17552   [(set (match_operand:SI 0 "register_operand" "")
17553         (compare:SI (match_operand:BLK 1 "general_operand" "")
17554                     (match_operand:BLK 2 "general_operand" "")))
17555    (use (match_operand 3 "general_operand" ""))
17556    (use (match_operand 4 "immediate_operand" ""))]
17557   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17559   rtx addr1, addr2, out, outlow, count, countreg, align;
17561   /* Can't use this if the user has appropriated esi or edi.  */
17562   if (global_regs[4] || global_regs[5])
17563     FAIL;
17565   out = operands[0];
17566   if (GET_CODE (out) != REG)
17567     out = gen_reg_rtx (SImode);
17569   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17570   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17571   if (addr1 != XEXP (operands[1], 0))
17572     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17573   if (addr2 != XEXP (operands[2], 0))
17574     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17576   count = operands[3];
17577   countreg = ix86_zero_extend_to_Pmode (count);
17579   /* %%% Iff we are testing strict equality, we can use known alignment
17580      to good advantage.  This may be possible with combine, particularly
17581      once cc0 is dead.  */
17582   align = operands[4];
17584   emit_insn (gen_cld ());
17585   if (GET_CODE (count) == CONST_INT)
17586     {
17587       if (INTVAL (count) == 0)
17588         {
17589           emit_move_insn (operands[0], const0_rtx);
17590           DONE;
17591         }
17592       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17593                                     operands[1], operands[2]));
17594     }
17595   else
17596     {
17597       if (TARGET_64BIT)
17598         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17599       else
17600         emit_insn (gen_cmpsi_1 (countreg, countreg));
17601       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17602                                  operands[1], operands[2]));
17603     }
17605   outlow = gen_lowpart (QImode, out);
17606   emit_insn (gen_cmpintqi (outlow));
17607   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17609   if (operands[0] != out)
17610     emit_move_insn (operands[0], out);
17612   DONE;
17615 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17617 (define_expand "cmpintqi"
17618   [(set (match_dup 1)
17619         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17620    (set (match_dup 2)
17621         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17622    (parallel [(set (match_operand:QI 0 "register_operand" "")
17623                    (minus:QI (match_dup 1)
17624                              (match_dup 2)))
17625               (clobber (reg:CC FLAGS_REG))])]
17626   ""
17627   "operands[1] = gen_reg_rtx (QImode);
17628    operands[2] = gen_reg_rtx (QImode);")
17630 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17631 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17633 (define_expand "cmpstrqi_nz_1"
17634   [(parallel [(set (reg:CC FLAGS_REG)
17635                    (compare:CC (match_operand 4 "memory_operand" "")
17636                                (match_operand 5 "memory_operand" "")))
17637               (use (match_operand 2 "register_operand" ""))
17638               (use (match_operand:SI 3 "immediate_operand" ""))
17639               (use (reg:SI DIRFLAG_REG))
17640               (clobber (match_operand 0 "register_operand" ""))
17641               (clobber (match_operand 1 "register_operand" ""))
17642               (clobber (match_dup 2))])]
17643   ""
17644   "")
17646 (define_insn "*cmpstrqi_nz_1"
17647   [(set (reg:CC FLAGS_REG)
17648         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17649                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17650    (use (match_operand:SI 6 "register_operand" "2"))
17651    (use (match_operand:SI 3 "immediate_operand" "i"))
17652    (use (reg:SI DIRFLAG_REG))
17653    (clobber (match_operand:SI 0 "register_operand" "=S"))
17654    (clobber (match_operand:SI 1 "register_operand" "=D"))
17655    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17656   "!TARGET_64BIT"
17657   "repz{\;| }cmpsb"
17658   [(set_attr "type" "str")
17659    (set_attr "mode" "QI")
17660    (set_attr "prefix_rep" "1")])
17662 (define_insn "*cmpstrqi_nz_rex_1"
17663   [(set (reg:CC FLAGS_REG)
17664         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17665                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17666    (use (match_operand:DI 6 "register_operand" "2"))
17667    (use (match_operand:SI 3 "immediate_operand" "i"))
17668    (use (reg:SI DIRFLAG_REG))
17669    (clobber (match_operand:DI 0 "register_operand" "=S"))
17670    (clobber (match_operand:DI 1 "register_operand" "=D"))
17671    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17672   "TARGET_64BIT"
17673   "repz{\;| }cmpsb"
17674   [(set_attr "type" "str")
17675    (set_attr "mode" "QI")
17676    (set_attr "prefix_rep" "1")])
17678 ;; The same, but the count is not known to not be zero.
17680 (define_expand "cmpstrqi_1"
17681   [(parallel [(set (reg:CC FLAGS_REG)
17682                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17683                                      (const_int 0))
17684                   (compare:CC (match_operand 4 "memory_operand" "")
17685                               (match_operand 5 "memory_operand" ""))
17686                   (const_int 0)))
17687               (use (match_operand:SI 3 "immediate_operand" ""))
17688               (use (reg:CC FLAGS_REG))
17689               (use (reg:SI DIRFLAG_REG))
17690               (clobber (match_operand 0 "register_operand" ""))
17691               (clobber (match_operand 1 "register_operand" ""))
17692               (clobber (match_dup 2))])]
17693   ""
17694   "")
17696 (define_insn "*cmpstrqi_1"
17697   [(set (reg:CC FLAGS_REG)
17698         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17699                              (const_int 0))
17700           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17701                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17702           (const_int 0)))
17703    (use (match_operand:SI 3 "immediate_operand" "i"))
17704    (use (reg:CC FLAGS_REG))
17705    (use (reg:SI DIRFLAG_REG))
17706    (clobber (match_operand:SI 0 "register_operand" "=S"))
17707    (clobber (match_operand:SI 1 "register_operand" "=D"))
17708    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17709   "!TARGET_64BIT"
17710   "repz{\;| }cmpsb"
17711   [(set_attr "type" "str")
17712    (set_attr "mode" "QI")
17713    (set_attr "prefix_rep" "1")])
17715 (define_insn "*cmpstrqi_rex_1"
17716   [(set (reg:CC FLAGS_REG)
17717         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17718                              (const_int 0))
17719           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17720                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17721           (const_int 0)))
17722    (use (match_operand:SI 3 "immediate_operand" "i"))
17723    (use (reg:CC FLAGS_REG))
17724    (use (reg:SI DIRFLAG_REG))
17725    (clobber (match_operand:DI 0 "register_operand" "=S"))
17726    (clobber (match_operand:DI 1 "register_operand" "=D"))
17727    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17728   "TARGET_64BIT"
17729   "repz{\;| }cmpsb"
17730   [(set_attr "type" "str")
17731    (set_attr "mode" "QI")
17732    (set_attr "prefix_rep" "1")])
17734 (define_expand "strlensi"
17735   [(set (match_operand:SI 0 "register_operand" "")
17736         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17737                     (match_operand:QI 2 "immediate_operand" "")
17738                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17739   ""
17741  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17742    DONE;
17743  else
17744    FAIL;
17747 (define_expand "strlendi"
17748   [(set (match_operand:DI 0 "register_operand" "")
17749         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17750                     (match_operand:QI 2 "immediate_operand" "")
17751                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17752   ""
17754  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17755    DONE;
17756  else
17757    FAIL;
17760 (define_expand "strlenqi_1"
17761   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17762               (use (reg:SI DIRFLAG_REG))
17763               (clobber (match_operand 1 "register_operand" ""))
17764               (clobber (reg:CC FLAGS_REG))])]
17765   ""
17766   "")
17768 (define_insn "*strlenqi_1"
17769   [(set (match_operand:SI 0 "register_operand" "=&c")
17770         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17771                     (match_operand:QI 2 "register_operand" "a")
17772                     (match_operand:SI 3 "immediate_operand" "i")
17773                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17774    (use (reg:SI DIRFLAG_REG))
17775    (clobber (match_operand:SI 1 "register_operand" "=D"))
17776    (clobber (reg:CC FLAGS_REG))]
17777   "!TARGET_64BIT"
17778   "repnz{\;| }scasb"
17779   [(set_attr "type" "str")
17780    (set_attr "mode" "QI")
17781    (set_attr "prefix_rep" "1")])
17783 (define_insn "*strlenqi_rex_1"
17784   [(set (match_operand:DI 0 "register_operand" "=&c")
17785         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17786                     (match_operand:QI 2 "register_operand" "a")
17787                     (match_operand:DI 3 "immediate_operand" "i")
17788                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17789    (use (reg:SI DIRFLAG_REG))
17790    (clobber (match_operand:DI 1 "register_operand" "=D"))
17791    (clobber (reg:CC FLAGS_REG))]
17792   "TARGET_64BIT"
17793   "repnz{\;| }scasb"
17794   [(set_attr "type" "str")
17795    (set_attr "mode" "QI")
17796    (set_attr "prefix_rep" "1")])
17798 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17799 ;; handled in combine, but it is not currently up to the task.
17800 ;; When used for their truth value, the cmpstr* expanders generate
17801 ;; code like this:
17803 ;;   repz cmpsb
17804 ;;   seta       %al
17805 ;;   setb       %dl
17806 ;;   cmpb       %al, %dl
17807 ;;   jcc        label
17809 ;; The intermediate three instructions are unnecessary.
17811 ;; This one handles cmpstr*_nz_1...
17812 (define_peephole2
17813   [(parallel[
17814      (set (reg:CC FLAGS_REG)
17815           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17816                       (mem:BLK (match_operand 5 "register_operand" ""))))
17817      (use (match_operand 6 "register_operand" ""))
17818      (use (match_operand:SI 3 "immediate_operand" ""))
17819      (use (reg:SI DIRFLAG_REG))
17820      (clobber (match_operand 0 "register_operand" ""))
17821      (clobber (match_operand 1 "register_operand" ""))
17822      (clobber (match_operand 2 "register_operand" ""))])
17823    (set (match_operand:QI 7 "register_operand" "")
17824         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17825    (set (match_operand:QI 8 "register_operand" "")
17826         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17827    (set (reg FLAGS_REG)
17828         (compare (match_dup 7) (match_dup 8)))
17829   ]
17830   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17831   [(parallel[
17832      (set (reg:CC FLAGS_REG)
17833           (compare:CC (mem:BLK (match_dup 4))
17834                       (mem:BLK (match_dup 5))))
17835      (use (match_dup 6))
17836      (use (match_dup 3))
17837      (use (reg:SI DIRFLAG_REG))
17838      (clobber (match_dup 0))
17839      (clobber (match_dup 1))
17840      (clobber (match_dup 2))])]
17841   "")
17843 ;; ...and this one handles cmpstr*_1.
17844 (define_peephole2
17845   [(parallel[
17846      (set (reg:CC FLAGS_REG)
17847           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17848                                (const_int 0))
17849             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17850                         (mem:BLK (match_operand 5 "register_operand" "")))
17851             (const_int 0)))
17852      (use (match_operand:SI 3 "immediate_operand" ""))
17853      (use (reg:CC FLAGS_REG))
17854      (use (reg:SI DIRFLAG_REG))
17855      (clobber (match_operand 0 "register_operand" ""))
17856      (clobber (match_operand 1 "register_operand" ""))
17857      (clobber (match_operand 2 "register_operand" ""))])
17858    (set (match_operand:QI 7 "register_operand" "")
17859         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17860    (set (match_operand:QI 8 "register_operand" "")
17861         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17862    (set (reg FLAGS_REG)
17863         (compare (match_dup 7) (match_dup 8)))
17864   ]
17865   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17866   [(parallel[
17867      (set (reg:CC FLAGS_REG)
17868           (if_then_else:CC (ne (match_dup 6)
17869                                (const_int 0))
17870             (compare:CC (mem:BLK (match_dup 4))
17871                         (mem:BLK (match_dup 5)))
17872             (const_int 0)))
17873      (use (match_dup 3))
17874      (use (reg:CC FLAGS_REG))
17875      (use (reg:SI DIRFLAG_REG))
17876      (clobber (match_dup 0))
17877      (clobber (match_dup 1))
17878      (clobber (match_dup 2))])]
17879   "")
17883 ;; Conditional move instructions.
17885 (define_expand "movdicc"
17886   [(set (match_operand:DI 0 "register_operand" "")
17887         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17888                          (match_operand:DI 2 "general_operand" "")
17889                          (match_operand:DI 3 "general_operand" "")))]
17890   "TARGET_64BIT"
17891   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17893 (define_insn "x86_movdicc_0_m1_rex64"
17894   [(set (match_operand:DI 0 "register_operand" "=r")
17895         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17896           (const_int -1)
17897           (const_int 0)))
17898    (clobber (reg:CC FLAGS_REG))]
17899   "TARGET_64BIT"
17900   "sbb{q}\t%0, %0"
17901   ; Since we don't have the proper number of operands for an alu insn,
17902   ; fill in all the blanks.
17903   [(set_attr "type" "alu")
17904    (set_attr "pent_pair" "pu")
17905    (set_attr "memory" "none")
17906    (set_attr "imm_disp" "false")
17907    (set_attr "mode" "DI")
17908    (set_attr "length_immediate" "0")])
17910 (define_insn "*movdicc_c_rex64"
17911   [(set (match_operand:DI 0 "register_operand" "=r,r")
17912         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17913                                 [(reg FLAGS_REG) (const_int 0)])
17914                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17915                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17916   "TARGET_64BIT && TARGET_CMOVE
17917    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17918   "@
17919    cmov%O2%C1\t{%2, %0|%0, %2}
17920    cmov%O2%c1\t{%3, %0|%0, %3}"
17921   [(set_attr "type" "icmov")
17922    (set_attr "mode" "DI")])
17924 (define_expand "movsicc"
17925   [(set (match_operand:SI 0 "register_operand" "")
17926         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17927                          (match_operand:SI 2 "general_operand" "")
17928                          (match_operand:SI 3 "general_operand" "")))]
17929   ""
17930   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17932 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17933 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17934 ;; So just document what we're doing explicitly.
17936 (define_insn "x86_movsicc_0_m1"
17937   [(set (match_operand:SI 0 "register_operand" "=r")
17938         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17939           (const_int -1)
17940           (const_int 0)))
17941    (clobber (reg:CC FLAGS_REG))]
17942   ""
17943   "sbb{l}\t%0, %0"
17944   ; Since we don't have the proper number of operands for an alu insn,
17945   ; fill in all the blanks.
17946   [(set_attr "type" "alu")
17947    (set_attr "pent_pair" "pu")
17948    (set_attr "memory" "none")
17949    (set_attr "imm_disp" "false")
17950    (set_attr "mode" "SI")
17951    (set_attr "length_immediate" "0")])
17953 (define_insn "*movsicc_noc"
17954   [(set (match_operand:SI 0 "register_operand" "=r,r")
17955         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17956                                 [(reg FLAGS_REG) (const_int 0)])
17957                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17958                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17959   "TARGET_CMOVE
17960    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17961   "@
17962    cmov%O2%C1\t{%2, %0|%0, %2}
17963    cmov%O2%c1\t{%3, %0|%0, %3}"
17964   [(set_attr "type" "icmov")
17965    (set_attr "mode" "SI")])
17967 (define_expand "movhicc"
17968   [(set (match_operand:HI 0 "register_operand" "")
17969         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17970                          (match_operand:HI 2 "general_operand" "")
17971                          (match_operand:HI 3 "general_operand" "")))]
17972   "TARGET_HIMODE_MATH"
17973   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17975 (define_insn "*movhicc_noc"
17976   [(set (match_operand:HI 0 "register_operand" "=r,r")
17977         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17978                                 [(reg FLAGS_REG) (const_int 0)])
17979                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17980                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17981   "TARGET_CMOVE
17982    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17983   "@
17984    cmov%O2%C1\t{%2, %0|%0, %2}
17985    cmov%O2%c1\t{%3, %0|%0, %3}"
17986   [(set_attr "type" "icmov")
17987    (set_attr "mode" "HI")])
17989 (define_expand "movqicc"
17990   [(set (match_operand:QI 0 "register_operand" "")
17991         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17992                          (match_operand:QI 2 "general_operand" "")
17993                          (match_operand:QI 3 "general_operand" "")))]
17994   "TARGET_QIMODE_MATH"
17995   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17997 (define_insn_and_split "*movqicc_noc"
17998   [(set (match_operand:QI 0 "register_operand" "=r,r")
17999         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18000                                 [(match_operand 4 "flags_reg_operand" "")
18001                                  (const_int 0)])
18002                       (match_operand:QI 2 "register_operand" "r,0")
18003                       (match_operand:QI 3 "register_operand" "0,r")))]
18004   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18005   "#"
18006   "&& reload_completed"
18007   [(set (match_dup 0)
18008         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18009                       (match_dup 2)
18010                       (match_dup 3)))]
18011   "operands[0] = gen_lowpart (SImode, operands[0]);
18012    operands[2] = gen_lowpart (SImode, operands[2]);
18013    operands[3] = gen_lowpart (SImode, operands[3]);"
18014   [(set_attr "type" "icmov")
18015    (set_attr "mode" "SI")])
18017 (define_expand "movsfcc"
18018   [(set (match_operand:SF 0 "register_operand" "")
18019         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18020                          (match_operand:SF 2 "register_operand" "")
18021                          (match_operand:SF 3 "register_operand" "")))]
18022   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18023   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18025 (define_insn "*movsfcc_1_387"
18026   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18027         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18028                                 [(reg FLAGS_REG) (const_int 0)])
18029                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18030                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18031   "TARGET_80387 && TARGET_CMOVE
18032    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18033   "@
18034    fcmov%F1\t{%2, %0|%0, %2}
18035    fcmov%f1\t{%3, %0|%0, %3}
18036    cmov%O2%C1\t{%2, %0|%0, %2}
18037    cmov%O2%c1\t{%3, %0|%0, %3}"
18038   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18039    (set_attr "mode" "SF,SF,SI,SI")])
18041 (define_expand "movdfcc"
18042   [(set (match_operand:DF 0 "register_operand" "")
18043         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18044                          (match_operand:DF 2 "register_operand" "")
18045                          (match_operand:DF 3 "register_operand" "")))]
18046   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18047   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18049 (define_insn "*movdfcc_1"
18050   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18051         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18052                                 [(reg FLAGS_REG) (const_int 0)])
18053                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18054                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18055   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18056    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18057   "@
18058    fcmov%F1\t{%2, %0|%0, %2}
18059    fcmov%f1\t{%3, %0|%0, %3}
18060    #
18061    #"
18062   [(set_attr "type" "fcmov,fcmov,multi,multi")
18063    (set_attr "mode" "DF")])
18065 (define_insn "*movdfcc_1_rex64"
18066   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18067         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18068                                 [(reg FLAGS_REG) (const_int 0)])
18069                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18070                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18071   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18072    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18073   "@
18074    fcmov%F1\t{%2, %0|%0, %2}
18075    fcmov%f1\t{%3, %0|%0, %3}
18076    cmov%O2%C1\t{%2, %0|%0, %2}
18077    cmov%O2%c1\t{%3, %0|%0, %3}"
18078   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18079    (set_attr "mode" "DF")])
18081 (define_split
18082   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18083         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18084                                 [(match_operand 4 "flags_reg_operand" "")
18085                                  (const_int 0)])
18086                       (match_operand:DF 2 "nonimmediate_operand" "")
18087                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18088   "!TARGET_64BIT && reload_completed"
18089   [(set (match_dup 2)
18090         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18091                       (match_dup 5)
18092                       (match_dup 7)))
18093    (set (match_dup 3)
18094         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18095                       (match_dup 6)
18096                       (match_dup 8)))]
18097   "split_di (operands+2, 1, operands+5, operands+6);
18098    split_di (operands+3, 1, operands+7, operands+8);
18099    split_di (operands, 1, operands+2, operands+3);")
18101 (define_expand "movxfcc"
18102   [(set (match_operand:XF 0 "register_operand" "")
18103         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18104                          (match_operand:XF 2 "register_operand" "")
18105                          (match_operand:XF 3 "register_operand" "")))]
18106   "TARGET_80387 && TARGET_CMOVE"
18107   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18109 (define_insn "*movxfcc_1"
18110   [(set (match_operand:XF 0 "register_operand" "=f,f")
18111         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18112                                 [(reg FLAGS_REG) (const_int 0)])
18113                       (match_operand:XF 2 "register_operand" "f,0")
18114                       (match_operand:XF 3 "register_operand" "0,f")))]
18115   "TARGET_80387 && TARGET_CMOVE"
18116   "@
18117    fcmov%F1\t{%2, %0|%0, %2}
18118    fcmov%f1\t{%3, %0|%0, %3}"
18119   [(set_attr "type" "fcmov")
18120    (set_attr "mode" "XF")])
18122 ;; These versions of the min/max patterns are intentionally ignorant of
18123 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18124 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18125 ;; are undefined in this condition, we're certain this is correct.
18127 (define_insn "sminsf3"
18128   [(set (match_operand:SF 0 "register_operand" "=x")
18129         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18130                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18131   "TARGET_SSE_MATH"
18132   "minss\t{%2, %0|%0, %2}"
18133   [(set_attr "type" "sseadd")
18134    (set_attr "mode" "SF")])
18136 (define_insn "smaxsf3"
18137   [(set (match_operand:SF 0 "register_operand" "=x")
18138         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18139                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18140   "TARGET_SSE_MATH"
18141   "maxss\t{%2, %0|%0, %2}"
18142   [(set_attr "type" "sseadd")
18143    (set_attr "mode" "SF")])
18145 (define_insn "smindf3"
18146   [(set (match_operand:DF 0 "register_operand" "=x")
18147         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18148                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18149   "TARGET_SSE2 && TARGET_SSE_MATH"
18150   "minsd\t{%2, %0|%0, %2}"
18151   [(set_attr "type" "sseadd")
18152    (set_attr "mode" "DF")])
18154 (define_insn "smaxdf3"
18155   [(set (match_operand:DF 0 "register_operand" "=x")
18156         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18157                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18158   "TARGET_SSE2 && TARGET_SSE_MATH"
18159   "maxsd\t{%2, %0|%0, %2}"
18160   [(set_attr "type" "sseadd")
18161    (set_attr "mode" "DF")])
18163 ;; These versions of the min/max patterns implement exactly the operations
18164 ;;   min = (op1 < op2 ? op1 : op2)
18165 ;;   max = (!(op1 < op2) ? op1 : op2)
18166 ;; Their operands are not commutative, and thus they may be used in the
18167 ;; presence of -0.0 and NaN.
18169 (define_insn "*ieee_sminsf3"
18170   [(set (match_operand:SF 0 "register_operand" "=x")
18171         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18172                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18173                    UNSPEC_IEEE_MIN))]
18174   "TARGET_SSE_MATH"
18175   "minss\t{%2, %0|%0, %2}"
18176   [(set_attr "type" "sseadd")
18177    (set_attr "mode" "SF")])
18179 (define_insn "*ieee_smaxsf3"
18180   [(set (match_operand:SF 0 "register_operand" "=x")
18181         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18182                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18183                    UNSPEC_IEEE_MAX))]
18184   "TARGET_SSE_MATH"
18185   "maxss\t{%2, %0|%0, %2}"
18186   [(set_attr "type" "sseadd")
18187    (set_attr "mode" "SF")])
18189 (define_insn "*ieee_smindf3"
18190   [(set (match_operand:DF 0 "register_operand" "=x")
18191         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18192                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18193                    UNSPEC_IEEE_MIN))]
18194   "TARGET_SSE2 && TARGET_SSE_MATH"
18195   "minsd\t{%2, %0|%0, %2}"
18196   [(set_attr "type" "sseadd")
18197    (set_attr "mode" "DF")])
18199 (define_insn "*ieee_smaxdf3"
18200   [(set (match_operand:DF 0 "register_operand" "=x")
18201         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18202                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18203                    UNSPEC_IEEE_MAX))]
18204   "TARGET_SSE2 && TARGET_SSE_MATH"
18205   "maxsd\t{%2, %0|%0, %2}"
18206   [(set_attr "type" "sseadd")
18207    (set_attr "mode" "DF")])
18209 ;; Conditional addition patterns
18210 (define_expand "addqicc"
18211   [(match_operand:QI 0 "register_operand" "")
18212    (match_operand 1 "comparison_operator" "")
18213    (match_operand:QI 2 "register_operand" "")
18214    (match_operand:QI 3 "const_int_operand" "")]
18215   ""
18216   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18218 (define_expand "addhicc"
18219   [(match_operand:HI 0 "register_operand" "")
18220    (match_operand 1 "comparison_operator" "")
18221    (match_operand:HI 2 "register_operand" "")
18222    (match_operand:HI 3 "const_int_operand" "")]
18223   ""
18224   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18226 (define_expand "addsicc"
18227   [(match_operand:SI 0 "register_operand" "")
18228    (match_operand 1 "comparison_operator" "")
18229    (match_operand:SI 2 "register_operand" "")
18230    (match_operand:SI 3 "const_int_operand" "")]
18231   ""
18232   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18234 (define_expand "adddicc"
18235   [(match_operand:DI 0 "register_operand" "")
18236    (match_operand 1 "comparison_operator" "")
18237    (match_operand:DI 2 "register_operand" "")
18238    (match_operand:DI 3 "const_int_operand" "")]
18239   "TARGET_64BIT"
18240   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18243 ;; Misc patterns (?)
18245 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18246 ;; Otherwise there will be nothing to keep
18247 ;; 
18248 ;; [(set (reg ebp) (reg esp))]
18249 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18250 ;;  (clobber (eflags)]
18251 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18253 ;; in proper program order.
18254 (define_insn "pro_epilogue_adjust_stack_1"
18255   [(set (match_operand:SI 0 "register_operand" "=r,r")
18256         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18257                  (match_operand:SI 2 "immediate_operand" "i,i")))
18258    (clobber (reg:CC FLAGS_REG))
18259    (clobber (mem:BLK (scratch)))]
18260   "!TARGET_64BIT"
18262   switch (get_attr_type (insn))
18263     {
18264     case TYPE_IMOV:
18265       return "mov{l}\t{%1, %0|%0, %1}";
18267     case TYPE_ALU:
18268       if (GET_CODE (operands[2]) == CONST_INT
18269           && (INTVAL (operands[2]) == 128
18270               || (INTVAL (operands[2]) < 0
18271                   && INTVAL (operands[2]) != -128)))
18272         {
18273           operands[2] = GEN_INT (-INTVAL (operands[2]));
18274           return "sub{l}\t{%2, %0|%0, %2}";
18275         }
18276       return "add{l}\t{%2, %0|%0, %2}";
18278     case TYPE_LEA:
18279       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18280       return "lea{l}\t{%a2, %0|%0, %a2}";
18282     default:
18283       abort ();
18284     }
18286   [(set (attr "type")
18287         (cond [(eq_attr "alternative" "0")
18288                  (const_string "alu")
18289                (match_operand:SI 2 "const0_operand" "")
18290                  (const_string "imov")
18291               ]
18292               (const_string "lea")))
18293    (set_attr "mode" "SI")])
18295 (define_insn "pro_epilogue_adjust_stack_rex64"
18296   [(set (match_operand:DI 0 "register_operand" "=r,r")
18297         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18298                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18299    (clobber (reg:CC FLAGS_REG))
18300    (clobber (mem:BLK (scratch)))]
18301   "TARGET_64BIT"
18303   switch (get_attr_type (insn))
18304     {
18305     case TYPE_IMOV:
18306       return "mov{q}\t{%1, %0|%0, %1}";
18308     case TYPE_ALU:
18309       if (GET_CODE (operands[2]) == CONST_INT
18310           /* Avoid overflows.  */
18311           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18312           && (INTVAL (operands[2]) == 128
18313               || (INTVAL (operands[2]) < 0
18314                   && INTVAL (operands[2]) != -128)))
18315         {
18316           operands[2] = GEN_INT (-INTVAL (operands[2]));
18317           return "sub{q}\t{%2, %0|%0, %2}";
18318         }
18319       return "add{q}\t{%2, %0|%0, %2}";
18321     case TYPE_LEA:
18322       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18323       return "lea{q}\t{%a2, %0|%0, %a2}";
18325     default:
18326       abort ();
18327     }
18329   [(set (attr "type")
18330         (cond [(eq_attr "alternative" "0")
18331                  (const_string "alu")
18332                (match_operand:DI 2 "const0_operand" "")
18333                  (const_string "imov")
18334               ]
18335               (const_string "lea")))
18336    (set_attr "mode" "DI")])
18338 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18339   [(set (match_operand:DI 0 "register_operand" "=r,r")
18340         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18341                  (match_operand:DI 3 "immediate_operand" "i,i")))
18342    (use (match_operand:DI 2 "register_operand" "r,r"))
18343    (clobber (reg:CC FLAGS_REG))
18344    (clobber (mem:BLK (scratch)))]
18345   "TARGET_64BIT"
18347   switch (get_attr_type (insn))
18348     {
18349     case TYPE_ALU:
18350       return "add{q}\t{%2, %0|%0, %2}";
18352     case TYPE_LEA:
18353       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18354       return "lea{q}\t{%a2, %0|%0, %a2}";
18356     default:
18357       abort ();
18358     }
18360   [(set_attr "type" "alu,lea")
18361    (set_attr "mode" "DI")])
18363 (define_expand "allocate_stack_worker"
18364   [(match_operand:SI 0 "register_operand" "")]
18365   "TARGET_STACK_PROBE"
18367   if (reload_completed)
18368     {
18369       if (TARGET_64BIT)
18370         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18371       else
18372         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18373     }
18374   else
18375     {
18376       if (TARGET_64BIT)
18377         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18378       else
18379         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18380     }
18381   DONE;
18384 (define_insn "allocate_stack_worker_1"
18385   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18386     UNSPECV_STACK_PROBE)
18387    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18388    (clobber (match_scratch:SI 1 "=0"))
18389    (clobber (reg:CC FLAGS_REG))]
18390   "!TARGET_64BIT && TARGET_STACK_PROBE"
18391   "call\t__alloca"
18392   [(set_attr "type" "multi")
18393    (set_attr "length" "5")])
18395 (define_expand "allocate_stack_worker_postreload"
18396   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18397                                     UNSPECV_STACK_PROBE)
18398               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18399               (clobber (match_dup 0))
18400               (clobber (reg:CC FLAGS_REG))])]
18401   ""
18402   "")
18404 (define_insn "allocate_stack_worker_rex64"
18405   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18406     UNSPECV_STACK_PROBE)
18407    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18408    (clobber (match_scratch:DI 1 "=0"))
18409    (clobber (reg:CC FLAGS_REG))]
18410   "TARGET_64BIT && TARGET_STACK_PROBE"
18411   "call\t__alloca"
18412   [(set_attr "type" "multi")
18413    (set_attr "length" "5")])
18415 (define_expand "allocate_stack_worker_rex64_postreload"
18416   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18417                                     UNSPECV_STACK_PROBE)
18418               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18419               (clobber (match_dup 0))
18420               (clobber (reg:CC FLAGS_REG))])]
18421   ""
18422   "")
18424 (define_expand "allocate_stack"
18425   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18426                    (minus:SI (reg:SI SP_REG)
18427                              (match_operand:SI 1 "general_operand" "")))
18428               (clobber (reg:CC FLAGS_REG))])
18429    (parallel [(set (reg:SI SP_REG)
18430                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18431               (clobber (reg:CC FLAGS_REG))])]
18432   "TARGET_STACK_PROBE"
18434 #ifdef CHECK_STACK_LIMIT
18435   if (GET_CODE (operands[1]) == CONST_INT
18436       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18437     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18438                            operands[1]));
18439   else 
18440 #endif
18441     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18442                                                             operands[1])));
18444   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18445   DONE;
18448 (define_expand "builtin_setjmp_receiver"
18449   [(label_ref (match_operand 0 "" ""))]
18450   "!TARGET_64BIT && flag_pic"
18452   emit_insn (gen_set_got (pic_offset_table_rtx));
18453   DONE;
18456 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18458 (define_split
18459   [(set (match_operand 0 "register_operand" "")
18460         (match_operator 3 "promotable_binary_operator"
18461            [(match_operand 1 "register_operand" "")
18462             (match_operand 2 "aligned_operand" "")]))
18463    (clobber (reg:CC FLAGS_REG))]
18464   "! TARGET_PARTIAL_REG_STALL && reload_completed
18465    && ((GET_MODE (operands[0]) == HImode 
18466         && ((!optimize_size && !TARGET_FAST_PREFIX)
18467             || GET_CODE (operands[2]) != CONST_INT
18468             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18469        || (GET_MODE (operands[0]) == QImode 
18470            && (TARGET_PROMOTE_QImode || optimize_size)))"
18471   [(parallel [(set (match_dup 0)
18472                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18473               (clobber (reg:CC FLAGS_REG))])]
18474   "operands[0] = gen_lowpart (SImode, operands[0]);
18475    operands[1] = gen_lowpart (SImode, operands[1]);
18476    if (GET_CODE (operands[3]) != ASHIFT)
18477      operands[2] = gen_lowpart (SImode, operands[2]);
18478    PUT_MODE (operands[3], SImode);")
18480 ; Promote the QImode tests, as i386 has encoding of the AND
18481 ; instruction with 32-bit sign-extended immediate and thus the
18482 ; instruction size is unchanged, except in the %eax case for
18483 ; which it is increased by one byte, hence the ! optimize_size.
18484 (define_split
18485   [(set (match_operand 0 "flags_reg_operand" "")
18486         (match_operator 2 "compare_operator"
18487           [(and (match_operand 3 "aligned_operand" "")
18488                 (match_operand 4 "const_int_operand" ""))
18489            (const_int 0)]))
18490    (set (match_operand 1 "register_operand" "")
18491         (and (match_dup 3) (match_dup 4)))]
18492   "! TARGET_PARTIAL_REG_STALL && reload_completed
18493    /* Ensure that the operand will remain sign-extended immediate.  */
18494    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18495    && ! optimize_size
18496    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18497        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18498   [(parallel [(set (match_dup 0)
18499                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18500                                     (const_int 0)]))
18501               (set (match_dup 1)
18502                    (and:SI (match_dup 3) (match_dup 4)))])]
18504   operands[4]
18505     = gen_int_mode (INTVAL (operands[4])
18506                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18507   operands[1] = gen_lowpart (SImode, operands[1]);
18508   operands[3] = gen_lowpart (SImode, operands[3]);
18511 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18512 ; the TEST instruction with 32-bit sign-extended immediate and thus
18513 ; the instruction size would at least double, which is not what we
18514 ; want even with ! optimize_size.
18515 (define_split
18516   [(set (match_operand 0 "flags_reg_operand" "")
18517         (match_operator 1 "compare_operator"
18518           [(and (match_operand:HI 2 "aligned_operand" "")
18519                 (match_operand:HI 3 "const_int_operand" ""))
18520            (const_int 0)]))]
18521   "! TARGET_PARTIAL_REG_STALL && reload_completed
18522    /* Ensure that the operand will remain sign-extended immediate.  */
18523    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18524    && ! TARGET_FAST_PREFIX
18525    && ! optimize_size"
18526   [(set (match_dup 0)
18527         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18528                          (const_int 0)]))]
18530   operands[3]
18531     = gen_int_mode (INTVAL (operands[3])
18532                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18533   operands[2] = gen_lowpart (SImode, operands[2]);
18536 (define_split
18537   [(set (match_operand 0 "register_operand" "")
18538         (neg (match_operand 1 "register_operand" "")))
18539    (clobber (reg:CC FLAGS_REG))]
18540   "! TARGET_PARTIAL_REG_STALL && reload_completed
18541    && (GET_MODE (operands[0]) == HImode
18542        || (GET_MODE (operands[0]) == QImode 
18543            && (TARGET_PROMOTE_QImode || optimize_size)))"
18544   [(parallel [(set (match_dup 0)
18545                    (neg:SI (match_dup 1)))
18546               (clobber (reg:CC FLAGS_REG))])]
18547   "operands[0] = gen_lowpart (SImode, operands[0]);
18548    operands[1] = gen_lowpart (SImode, operands[1]);")
18550 (define_split
18551   [(set (match_operand 0 "register_operand" "")
18552         (not (match_operand 1 "register_operand" "")))]
18553   "! TARGET_PARTIAL_REG_STALL && reload_completed
18554    && (GET_MODE (operands[0]) == HImode
18555        || (GET_MODE (operands[0]) == QImode 
18556            && (TARGET_PROMOTE_QImode || optimize_size)))"
18557   [(set (match_dup 0)
18558         (not:SI (match_dup 1)))]
18559   "operands[0] = gen_lowpart (SImode, operands[0]);
18560    operands[1] = gen_lowpart (SImode, operands[1]);")
18562 (define_split 
18563   [(set (match_operand 0 "register_operand" "")
18564         (if_then_else (match_operator 1 "comparison_operator" 
18565                                 [(reg FLAGS_REG) (const_int 0)])
18566                       (match_operand 2 "register_operand" "")
18567                       (match_operand 3 "register_operand" "")))]
18568   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18569    && (GET_MODE (operands[0]) == HImode
18570        || (GET_MODE (operands[0]) == QImode 
18571            && (TARGET_PROMOTE_QImode || optimize_size)))"
18572   [(set (match_dup 0)
18573         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18574   "operands[0] = gen_lowpart (SImode, operands[0]);
18575    operands[2] = gen_lowpart (SImode, operands[2]);
18576    operands[3] = gen_lowpart (SImode, operands[3]);")
18577                         
18579 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18580 ;; transform a complex memory operation into two memory to register operations.
18582 ;; Don't push memory operands
18583 (define_peephole2
18584   [(set (match_operand:SI 0 "push_operand" "")
18585         (match_operand:SI 1 "memory_operand" ""))
18586    (match_scratch:SI 2 "r")]
18587   "! optimize_size && ! TARGET_PUSH_MEMORY"
18588   [(set (match_dup 2) (match_dup 1))
18589    (set (match_dup 0) (match_dup 2))]
18590   "")
18592 (define_peephole2
18593   [(set (match_operand:DI 0 "push_operand" "")
18594         (match_operand:DI 1 "memory_operand" ""))
18595    (match_scratch:DI 2 "r")]
18596   "! optimize_size && ! TARGET_PUSH_MEMORY"
18597   [(set (match_dup 2) (match_dup 1))
18598    (set (match_dup 0) (match_dup 2))]
18599   "")
18601 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18602 ;; SImode pushes.
18603 (define_peephole2
18604   [(set (match_operand:SF 0 "push_operand" "")
18605         (match_operand:SF 1 "memory_operand" ""))
18606    (match_scratch:SF 2 "r")]
18607   "! optimize_size && ! TARGET_PUSH_MEMORY"
18608   [(set (match_dup 2) (match_dup 1))
18609    (set (match_dup 0) (match_dup 2))]
18610   "")
18612 (define_peephole2
18613   [(set (match_operand:HI 0 "push_operand" "")
18614         (match_operand:HI 1 "memory_operand" ""))
18615    (match_scratch:HI 2 "r")]
18616   "! optimize_size && ! TARGET_PUSH_MEMORY"
18617   [(set (match_dup 2) (match_dup 1))
18618    (set (match_dup 0) (match_dup 2))]
18619   "")
18621 (define_peephole2
18622   [(set (match_operand:QI 0 "push_operand" "")
18623         (match_operand:QI 1 "memory_operand" ""))
18624    (match_scratch:QI 2 "q")]
18625   "! optimize_size && ! TARGET_PUSH_MEMORY"
18626   [(set (match_dup 2) (match_dup 1))
18627    (set (match_dup 0) (match_dup 2))]
18628   "")
18630 ;; Don't move an immediate directly to memory when the instruction
18631 ;; gets too big.
18632 (define_peephole2
18633   [(match_scratch:SI 1 "r")
18634    (set (match_operand:SI 0 "memory_operand" "")
18635         (const_int 0))]
18636   "! optimize_size
18637    && ! TARGET_USE_MOV0
18638    && TARGET_SPLIT_LONG_MOVES
18639    && get_attr_length (insn) >= ix86_cost->large_insn
18640    && peep2_regno_dead_p (0, FLAGS_REG)"
18641   [(parallel [(set (match_dup 1) (const_int 0))
18642               (clobber (reg:CC FLAGS_REG))])
18643    (set (match_dup 0) (match_dup 1))]
18644   "")
18646 (define_peephole2
18647   [(match_scratch:HI 1 "r")
18648    (set (match_operand:HI 0 "memory_operand" "")
18649         (const_int 0))]
18650   "! optimize_size
18651    && ! TARGET_USE_MOV0
18652    && TARGET_SPLIT_LONG_MOVES
18653    && get_attr_length (insn) >= ix86_cost->large_insn
18654    && peep2_regno_dead_p (0, FLAGS_REG)"
18655   [(parallel [(set (match_dup 2) (const_int 0))
18656               (clobber (reg:CC FLAGS_REG))])
18657    (set (match_dup 0) (match_dup 1))]
18658   "operands[2] = gen_lowpart (SImode, operands[1]);")
18660 (define_peephole2
18661   [(match_scratch:QI 1 "q")
18662    (set (match_operand:QI 0 "memory_operand" "")
18663         (const_int 0))]
18664   "! optimize_size
18665    && ! TARGET_USE_MOV0
18666    && TARGET_SPLIT_LONG_MOVES
18667    && get_attr_length (insn) >= ix86_cost->large_insn
18668    && peep2_regno_dead_p (0, FLAGS_REG)"
18669   [(parallel [(set (match_dup 2) (const_int 0))
18670               (clobber (reg:CC FLAGS_REG))])
18671    (set (match_dup 0) (match_dup 1))]
18672   "operands[2] = gen_lowpart (SImode, operands[1]);")
18674 (define_peephole2
18675   [(match_scratch:SI 2 "r")
18676    (set (match_operand:SI 0 "memory_operand" "")
18677         (match_operand:SI 1 "immediate_operand" ""))]
18678   "! optimize_size
18679    && get_attr_length (insn) >= ix86_cost->large_insn
18680    && TARGET_SPLIT_LONG_MOVES"
18681   [(set (match_dup 2) (match_dup 1))
18682    (set (match_dup 0) (match_dup 2))]
18683   "")
18685 (define_peephole2
18686   [(match_scratch:HI 2 "r")
18687    (set (match_operand:HI 0 "memory_operand" "")
18688         (match_operand:HI 1 "immediate_operand" ""))]
18689   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18690   && TARGET_SPLIT_LONG_MOVES"
18691   [(set (match_dup 2) (match_dup 1))
18692    (set (match_dup 0) (match_dup 2))]
18693   "")
18695 (define_peephole2
18696   [(match_scratch:QI 2 "q")
18697    (set (match_operand:QI 0 "memory_operand" "")
18698         (match_operand:QI 1 "immediate_operand" ""))]
18699   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18700   && TARGET_SPLIT_LONG_MOVES"
18701   [(set (match_dup 2) (match_dup 1))
18702    (set (match_dup 0) (match_dup 2))]
18703   "")
18705 ;; Don't compare memory with zero, load and use a test instead.
18706 (define_peephole2
18707   [(set (match_operand 0 "flags_reg_operand" "")
18708         (match_operator 1 "compare_operator"
18709           [(match_operand:SI 2 "memory_operand" "")
18710            (const_int 0)]))
18711    (match_scratch:SI 3 "r")]
18712   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18713   [(set (match_dup 3) (match_dup 2))
18714    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18715   "")
18717 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18718 ;; Don't split NOTs with a displacement operand, because resulting XOR
18719 ;; will not be pairable anyway.
18721 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18722 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18723 ;; so this split helps here as well.
18725 ;; Note: Can't do this as a regular split because we can't get proper
18726 ;; lifetime information then.
18728 (define_peephole2
18729   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18730         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18731   "!optimize_size
18732    && peep2_regno_dead_p (0, FLAGS_REG)
18733    && ((TARGET_PENTIUM 
18734         && (GET_CODE (operands[0]) != MEM
18735             || !memory_displacement_operand (operands[0], SImode)))
18736        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18737   [(parallel [(set (match_dup 0)
18738                    (xor:SI (match_dup 1) (const_int -1)))
18739               (clobber (reg:CC FLAGS_REG))])]
18740   "")
18742 (define_peephole2
18743   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18744         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18745   "!optimize_size
18746    && peep2_regno_dead_p (0, FLAGS_REG)
18747    && ((TARGET_PENTIUM 
18748         && (GET_CODE (operands[0]) != MEM
18749             || !memory_displacement_operand (operands[0], HImode)))
18750        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18751   [(parallel [(set (match_dup 0)
18752                    (xor:HI (match_dup 1) (const_int -1)))
18753               (clobber (reg:CC FLAGS_REG))])]
18754   "")
18756 (define_peephole2
18757   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18758         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18759   "!optimize_size
18760    && peep2_regno_dead_p (0, FLAGS_REG)
18761    && ((TARGET_PENTIUM 
18762         && (GET_CODE (operands[0]) != MEM
18763             || !memory_displacement_operand (operands[0], QImode)))
18764        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18765   [(parallel [(set (match_dup 0)
18766                    (xor:QI (match_dup 1) (const_int -1)))
18767               (clobber (reg:CC FLAGS_REG))])]
18768   "")
18770 ;; Non pairable "test imm, reg" instructions can be translated to
18771 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18772 ;; byte opcode instead of two, have a short form for byte operands),
18773 ;; so do it for other CPUs as well.  Given that the value was dead,
18774 ;; this should not create any new dependencies.  Pass on the sub-word
18775 ;; versions if we're concerned about partial register stalls.
18777 (define_peephole2
18778   [(set (match_operand 0 "flags_reg_operand" "")
18779         (match_operator 1 "compare_operator"
18780           [(and:SI (match_operand:SI 2 "register_operand" "")
18781                    (match_operand:SI 3 "immediate_operand" ""))
18782            (const_int 0)]))]
18783   "ix86_match_ccmode (insn, CCNOmode)
18784    && (true_regnum (operands[2]) != 0
18785        || (GET_CODE (operands[3]) == CONST_INT
18786            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18787    && peep2_reg_dead_p (1, operands[2])"
18788   [(parallel
18789      [(set (match_dup 0)
18790            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18791                             (const_int 0)]))
18792       (set (match_dup 2)
18793            (and:SI (match_dup 2) (match_dup 3)))])]
18794   "")
18796 ;; We don't need to handle HImode case, because it will be promoted to SImode
18797 ;; on ! TARGET_PARTIAL_REG_STALL
18799 (define_peephole2
18800   [(set (match_operand 0 "flags_reg_operand" "")
18801         (match_operator 1 "compare_operator"
18802           [(and:QI (match_operand:QI 2 "register_operand" "")
18803                    (match_operand:QI 3 "immediate_operand" ""))
18804            (const_int 0)]))]
18805   "! TARGET_PARTIAL_REG_STALL
18806    && ix86_match_ccmode (insn, CCNOmode)
18807    && true_regnum (operands[2]) != 0
18808    && peep2_reg_dead_p (1, operands[2])"
18809   [(parallel
18810      [(set (match_dup 0)
18811            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18812                             (const_int 0)]))
18813       (set (match_dup 2)
18814            (and:QI (match_dup 2) (match_dup 3)))])]
18815   "")
18817 (define_peephole2
18818   [(set (match_operand 0 "flags_reg_operand" "")
18819         (match_operator 1 "compare_operator"
18820           [(and:SI
18821              (zero_extract:SI
18822                (match_operand 2 "ext_register_operand" "")
18823                (const_int 8)
18824                (const_int 8))
18825              (match_operand 3 "const_int_operand" ""))
18826            (const_int 0)]))]
18827   "! TARGET_PARTIAL_REG_STALL
18828    && ix86_match_ccmode (insn, CCNOmode)
18829    && true_regnum (operands[2]) != 0
18830    && peep2_reg_dead_p (1, operands[2])"
18831   [(parallel [(set (match_dup 0)
18832                    (match_op_dup 1
18833                      [(and:SI
18834                         (zero_extract:SI
18835                           (match_dup 2)
18836                           (const_int 8)
18837                           (const_int 8))
18838                         (match_dup 3))
18839                       (const_int 0)]))
18840               (set (zero_extract:SI (match_dup 2)
18841                                     (const_int 8)
18842                                     (const_int 8))
18843                    (and:SI 
18844                      (zero_extract:SI
18845                        (match_dup 2)
18846                        (const_int 8)
18847                        (const_int 8))
18848                      (match_dup 3)))])]
18849   "")
18851 ;; Don't do logical operations with memory inputs.
18852 (define_peephole2
18853   [(match_scratch:SI 2 "r")
18854    (parallel [(set (match_operand:SI 0 "register_operand" "")
18855                    (match_operator:SI 3 "arith_or_logical_operator"
18856                      [(match_dup 0)
18857                       (match_operand:SI 1 "memory_operand" "")]))
18858               (clobber (reg:CC FLAGS_REG))])]
18859   "! optimize_size && ! TARGET_READ_MODIFY"
18860   [(set (match_dup 2) (match_dup 1))
18861    (parallel [(set (match_dup 0)
18862                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18863               (clobber (reg:CC FLAGS_REG))])]
18864   "")
18866 (define_peephole2
18867   [(match_scratch:SI 2 "r")
18868    (parallel [(set (match_operand:SI 0 "register_operand" "")
18869                    (match_operator:SI 3 "arith_or_logical_operator"
18870                      [(match_operand:SI 1 "memory_operand" "")
18871                       (match_dup 0)]))
18872               (clobber (reg:CC FLAGS_REG))])]
18873   "! optimize_size && ! TARGET_READ_MODIFY"
18874   [(set (match_dup 2) (match_dup 1))
18875    (parallel [(set (match_dup 0)
18876                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18877               (clobber (reg:CC FLAGS_REG))])]
18878   "")
18880 ; Don't do logical operations with memory outputs
18882 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18883 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18884 ; the same decoder scheduling characteristics as the original.
18886 (define_peephole2
18887   [(match_scratch:SI 2 "r")
18888    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18889                    (match_operator:SI 3 "arith_or_logical_operator"
18890                      [(match_dup 0)
18891                       (match_operand:SI 1 "nonmemory_operand" "")]))
18892               (clobber (reg:CC FLAGS_REG))])]
18893   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18894   [(set (match_dup 2) (match_dup 0))
18895    (parallel [(set (match_dup 2)
18896                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18897               (clobber (reg:CC FLAGS_REG))])
18898    (set (match_dup 0) (match_dup 2))]
18899   "")
18901 (define_peephole2
18902   [(match_scratch:SI 2 "r")
18903    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18904                    (match_operator:SI 3 "arith_or_logical_operator"
18905                      [(match_operand:SI 1 "nonmemory_operand" "")
18906                       (match_dup 0)]))
18907               (clobber (reg:CC FLAGS_REG))])]
18908   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18909   [(set (match_dup 2) (match_dup 0))
18910    (parallel [(set (match_dup 2)
18911                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18912               (clobber (reg:CC FLAGS_REG))])
18913    (set (match_dup 0) (match_dup 2))]
18914   "")
18916 ;; Attempt to always use XOR for zeroing registers.
18917 (define_peephole2
18918   [(set (match_operand 0 "register_operand" "")
18919         (match_operand 1 "const0_operand" ""))]
18920   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18921    && (! TARGET_USE_MOV0 || optimize_size)
18922    && GENERAL_REG_P (operands[0])
18923    && peep2_regno_dead_p (0, FLAGS_REG)"
18924   [(parallel [(set (match_dup 0) (const_int 0))
18925               (clobber (reg:CC FLAGS_REG))])]
18927   operands[0] = gen_lowpart (word_mode, operands[0]);
18930 (define_peephole2
18931   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18932         (const_int 0))]
18933   "(GET_MODE (operands[0]) == QImode
18934     || GET_MODE (operands[0]) == HImode)
18935    && (! TARGET_USE_MOV0 || optimize_size)
18936    && peep2_regno_dead_p (0, FLAGS_REG)"
18937   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18938               (clobber (reg:CC FLAGS_REG))])])
18940 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18941 (define_peephole2
18942   [(set (match_operand 0 "register_operand" "")
18943         (const_int -1))]
18944   "(GET_MODE (operands[0]) == HImode
18945     || GET_MODE (operands[0]) == SImode 
18946     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18947    && (optimize_size || TARGET_PENTIUM)
18948    && peep2_regno_dead_p (0, FLAGS_REG)"
18949   [(parallel [(set (match_dup 0) (const_int -1))
18950               (clobber (reg:CC FLAGS_REG))])]
18951   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18952                               operands[0]);")
18954 ;; Attempt to convert simple leas to adds. These can be created by
18955 ;; move expanders.
18956 (define_peephole2
18957   [(set (match_operand:SI 0 "register_operand" "")
18958         (plus:SI (match_dup 0)
18959                  (match_operand:SI 1 "nonmemory_operand" "")))]
18960   "peep2_regno_dead_p (0, FLAGS_REG)"
18961   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18962               (clobber (reg:CC FLAGS_REG))])]
18963   "")
18965 (define_peephole2
18966   [(set (match_operand:SI 0 "register_operand" "")
18967         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18968                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18969   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18970   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18971               (clobber (reg:CC FLAGS_REG))])]
18972   "operands[2] = gen_lowpart (SImode, operands[2]);")
18974 (define_peephole2
18975   [(set (match_operand:DI 0 "register_operand" "")
18976         (plus:DI (match_dup 0)
18977                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18978   "peep2_regno_dead_p (0, FLAGS_REG)"
18979   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18980               (clobber (reg:CC FLAGS_REG))])]
18981   "")
18983 (define_peephole2
18984   [(set (match_operand:SI 0 "register_operand" "")
18985         (mult:SI (match_dup 0)
18986                  (match_operand:SI 1 "const_int_operand" "")))]
18987   "exact_log2 (INTVAL (operands[1])) >= 0
18988    && peep2_regno_dead_p (0, FLAGS_REG)"
18989   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18990               (clobber (reg:CC FLAGS_REG))])]
18991   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18993 (define_peephole2
18994   [(set (match_operand:DI 0 "register_operand" "")
18995         (mult:DI (match_dup 0)
18996                  (match_operand:DI 1 "const_int_operand" "")))]
18997   "exact_log2 (INTVAL (operands[1])) >= 0
18998    && peep2_regno_dead_p (0, FLAGS_REG)"
18999   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19000               (clobber (reg:CC FLAGS_REG))])]
19001   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19003 (define_peephole2
19004   [(set (match_operand:SI 0 "register_operand" "")
19005         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19006                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19007   "exact_log2 (INTVAL (operands[2])) >= 0
19008    && REGNO (operands[0]) == REGNO (operands[1])
19009    && peep2_regno_dead_p (0, FLAGS_REG)"
19010   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19011               (clobber (reg:CC FLAGS_REG))])]
19012   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19014 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19015 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19016 ;; many CPUs it is also faster, since special hardware to avoid esp
19017 ;; dependencies is present.
19019 ;; While some of these conversions may be done using splitters, we use peepholes
19020 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19022 ;; Convert prologue esp subtractions to push.
19023 ;; We need register to push.  In order to keep verify_flow_info happy we have
19024 ;; two choices
19025 ;; - use scratch and clobber it in order to avoid dependencies
19026 ;; - use already live register
19027 ;; We can't use the second way right now, since there is no reliable way how to
19028 ;; verify that given register is live.  First choice will also most likely in
19029 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19030 ;; call clobbered registers are dead.  We may want to use base pointer as an
19031 ;; alternative when no register is available later.
19033 (define_peephole2
19034   [(match_scratch:SI 0 "r")
19035    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19036               (clobber (reg:CC FLAGS_REG))
19037               (clobber (mem:BLK (scratch)))])]
19038   "optimize_size || !TARGET_SUB_ESP_4"
19039   [(clobber (match_dup 0))
19040    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19041               (clobber (mem:BLK (scratch)))])])
19043 (define_peephole2
19044   [(match_scratch:SI 0 "r")
19045    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19046               (clobber (reg:CC FLAGS_REG))
19047               (clobber (mem:BLK (scratch)))])]
19048   "optimize_size || !TARGET_SUB_ESP_8"
19049   [(clobber (match_dup 0))
19050    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19051    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19052               (clobber (mem:BLK (scratch)))])])
19054 ;; Convert esp subtractions to push.
19055 (define_peephole2
19056   [(match_scratch:SI 0 "r")
19057    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19058               (clobber (reg:CC FLAGS_REG))])]
19059   "optimize_size || !TARGET_SUB_ESP_4"
19060   [(clobber (match_dup 0))
19061    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19063 (define_peephole2
19064   [(match_scratch:SI 0 "r")
19065    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19066               (clobber (reg:CC FLAGS_REG))])]
19067   "optimize_size || !TARGET_SUB_ESP_8"
19068   [(clobber (match_dup 0))
19069    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19070    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19072 ;; Convert epilogue deallocator to pop.
19073 (define_peephole2
19074   [(match_scratch:SI 0 "r")
19075    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19076               (clobber (reg:CC FLAGS_REG))
19077               (clobber (mem:BLK (scratch)))])]
19078   "optimize_size || !TARGET_ADD_ESP_4"
19079   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19080               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19081               (clobber (mem:BLK (scratch)))])]
19082   "")
19084 ;; Two pops case is tricky, since pop causes dependency on destination register.
19085 ;; We use two registers if available.
19086 (define_peephole2
19087   [(match_scratch:SI 0 "r")
19088    (match_scratch:SI 1 "r")
19089    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19090               (clobber (reg:CC FLAGS_REG))
19091               (clobber (mem:BLK (scratch)))])]
19092   "optimize_size || !TARGET_ADD_ESP_8"
19093   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19094               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19095               (clobber (mem:BLK (scratch)))])
19096    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19097               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19098   "")
19100 (define_peephole2
19101   [(match_scratch:SI 0 "r")
19102    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19103               (clobber (reg:CC FLAGS_REG))
19104               (clobber (mem:BLK (scratch)))])]
19105   "optimize_size"
19106   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19107               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19108               (clobber (mem:BLK (scratch)))])
19109    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19110               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19111   "")
19113 ;; Convert esp additions to pop.
19114 (define_peephole2
19115   [(match_scratch:SI 0 "r")
19116    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19117               (clobber (reg:CC FLAGS_REG))])]
19118   ""
19119   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19120               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19121   "")
19123 ;; Two pops case is tricky, since pop causes dependency on destination register.
19124 ;; We use two registers if available.
19125 (define_peephole2
19126   [(match_scratch:SI 0 "r")
19127    (match_scratch:SI 1 "r")
19128    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19129               (clobber (reg:CC FLAGS_REG))])]
19130   ""
19131   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19132               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19133    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19134               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19135   "")
19137 (define_peephole2
19138   [(match_scratch:SI 0 "r")
19139    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19140               (clobber (reg:CC FLAGS_REG))])]
19141   "optimize_size"
19142   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19143               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19144    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19145               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19146   "")
19148 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19149 ;; required and register dies.  Similarly for 128 to plus -128.
19150 (define_peephole2
19151   [(set (match_operand 0 "flags_reg_operand" "")
19152         (match_operator 1 "compare_operator"
19153           [(match_operand 2 "register_operand" "")
19154            (match_operand 3 "const_int_operand" "")]))]
19155   "(INTVAL (operands[3]) == -1
19156     || INTVAL (operands[3]) == 1
19157     || INTVAL (operands[3]) == 128)
19158    && ix86_match_ccmode (insn, CCGCmode)
19159    && peep2_reg_dead_p (1, operands[2])"
19160   [(parallel [(set (match_dup 0)
19161                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19162               (clobber (match_dup 2))])]
19163   "")
19165 (define_peephole2
19166   [(match_scratch:DI 0 "r")
19167    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19168               (clobber (reg:CC FLAGS_REG))
19169               (clobber (mem:BLK (scratch)))])]
19170   "optimize_size || !TARGET_SUB_ESP_4"
19171   [(clobber (match_dup 0))
19172    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19173               (clobber (mem:BLK (scratch)))])])
19175 (define_peephole2
19176   [(match_scratch:DI 0 "r")
19177    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19178               (clobber (reg:CC FLAGS_REG))
19179               (clobber (mem:BLK (scratch)))])]
19180   "optimize_size || !TARGET_SUB_ESP_8"
19181   [(clobber (match_dup 0))
19182    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19183    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19184               (clobber (mem:BLK (scratch)))])])
19186 ;; Convert esp subtractions to push.
19187 (define_peephole2
19188   [(match_scratch:DI 0 "r")
19189    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19190               (clobber (reg:CC FLAGS_REG))])]
19191   "optimize_size || !TARGET_SUB_ESP_4"
19192   [(clobber (match_dup 0))
19193    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19195 (define_peephole2
19196   [(match_scratch:DI 0 "r")
19197    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19198               (clobber (reg:CC FLAGS_REG))])]
19199   "optimize_size || !TARGET_SUB_ESP_8"
19200   [(clobber (match_dup 0))
19201    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19202    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19204 ;; Convert epilogue deallocator to pop.
19205 (define_peephole2
19206   [(match_scratch:DI 0 "r")
19207    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19208               (clobber (reg:CC FLAGS_REG))
19209               (clobber (mem:BLK (scratch)))])]
19210   "optimize_size || !TARGET_ADD_ESP_4"
19211   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19212               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19213               (clobber (mem:BLK (scratch)))])]
19214   "")
19216 ;; Two pops case is tricky, since pop causes dependency on destination register.
19217 ;; We use two registers if available.
19218 (define_peephole2
19219   [(match_scratch:DI 0 "r")
19220    (match_scratch:DI 1 "r")
19221    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19222               (clobber (reg:CC FLAGS_REG))
19223               (clobber (mem:BLK (scratch)))])]
19224   "optimize_size || !TARGET_ADD_ESP_8"
19225   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19226               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19227               (clobber (mem:BLK (scratch)))])
19228    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19229               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19230   "")
19232 (define_peephole2
19233   [(match_scratch:DI 0 "r")
19234    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19235               (clobber (reg:CC FLAGS_REG))
19236               (clobber (mem:BLK (scratch)))])]
19237   "optimize_size"
19238   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19239               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19240               (clobber (mem:BLK (scratch)))])
19241    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19242               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19243   "")
19245 ;; Convert esp additions to pop.
19246 (define_peephole2
19247   [(match_scratch:DI 0 "r")
19248    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19249               (clobber (reg:CC FLAGS_REG))])]
19250   ""
19251   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19252               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19253   "")
19255 ;; Two pops case is tricky, since pop causes dependency on destination register.
19256 ;; We use two registers if available.
19257 (define_peephole2
19258   [(match_scratch:DI 0 "r")
19259    (match_scratch:DI 1 "r")
19260    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19261               (clobber (reg:CC FLAGS_REG))])]
19262   ""
19263   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19264               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19265    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19266               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19267   "")
19269 (define_peephole2
19270   [(match_scratch:DI 0 "r")
19271    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19272               (clobber (reg:CC FLAGS_REG))])]
19273   "optimize_size"
19274   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19275               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19276    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19277               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19278   "")
19280 ;; Convert imul by three, five and nine into lea
19281 (define_peephole2
19282   [(parallel
19283     [(set (match_operand:SI 0 "register_operand" "")
19284           (mult:SI (match_operand:SI 1 "register_operand" "")
19285                    (match_operand:SI 2 "const_int_operand" "")))
19286      (clobber (reg:CC FLAGS_REG))])]
19287   "INTVAL (operands[2]) == 3
19288    || INTVAL (operands[2]) == 5
19289    || INTVAL (operands[2]) == 9"
19290   [(set (match_dup 0)
19291         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19292                  (match_dup 1)))]
19293   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19295 (define_peephole2
19296   [(parallel
19297     [(set (match_operand:SI 0 "register_operand" "")
19298           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19299                    (match_operand:SI 2 "const_int_operand" "")))
19300      (clobber (reg:CC FLAGS_REG))])]
19301   "!optimize_size 
19302    && (INTVAL (operands[2]) == 3
19303        || INTVAL (operands[2]) == 5
19304        || INTVAL (operands[2]) == 9)"
19305   [(set (match_dup 0) (match_dup 1))
19306    (set (match_dup 0)
19307         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19308                  (match_dup 0)))]
19309   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19311 (define_peephole2
19312   [(parallel
19313     [(set (match_operand:DI 0 "register_operand" "")
19314           (mult:DI (match_operand:DI 1 "register_operand" "")
19315                    (match_operand:DI 2 "const_int_operand" "")))
19316      (clobber (reg:CC FLAGS_REG))])]
19317   "TARGET_64BIT
19318    && (INTVAL (operands[2]) == 3
19319        || INTVAL (operands[2]) == 5
19320        || INTVAL (operands[2]) == 9)"
19321   [(set (match_dup 0)
19322         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19323                  (match_dup 1)))]
19324   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19326 (define_peephole2
19327   [(parallel
19328     [(set (match_operand:DI 0 "register_operand" "")
19329           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19330                    (match_operand:DI 2 "const_int_operand" "")))
19331      (clobber (reg:CC FLAGS_REG))])]
19332   "TARGET_64BIT
19333    && !optimize_size 
19334    && (INTVAL (operands[2]) == 3
19335        || INTVAL (operands[2]) == 5
19336        || INTVAL (operands[2]) == 9)"
19337   [(set (match_dup 0) (match_dup 1))
19338    (set (match_dup 0)
19339         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19340                  (match_dup 0)))]
19341   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19343 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19344 ;; imul $32bit_imm, reg, reg is direct decoded.
19345 (define_peephole2
19346   [(match_scratch:DI 3 "r")
19347    (parallel [(set (match_operand:DI 0 "register_operand" "")
19348                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19349                             (match_operand:DI 2 "immediate_operand" "")))
19350               (clobber (reg:CC FLAGS_REG))])]
19351   "TARGET_K8 && !optimize_size
19352    && (GET_CODE (operands[2]) != CONST_INT
19353        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19354   [(set (match_dup 3) (match_dup 1))
19355    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19356               (clobber (reg:CC FLAGS_REG))])]
19359 (define_peephole2
19360   [(match_scratch:SI 3 "r")
19361    (parallel [(set (match_operand:SI 0 "register_operand" "")
19362                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19363                             (match_operand:SI 2 "immediate_operand" "")))
19364               (clobber (reg:CC FLAGS_REG))])]
19365   "TARGET_K8 && !optimize_size
19366    && (GET_CODE (operands[2]) != CONST_INT
19367        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19368   [(set (match_dup 3) (match_dup 1))
19369    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19370               (clobber (reg:CC FLAGS_REG))])]
19373 (define_peephole2
19374   [(match_scratch:SI 3 "r")
19375    (parallel [(set (match_operand:DI 0 "register_operand" "")
19376                    (zero_extend:DI
19377                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19378                               (match_operand:SI 2 "immediate_operand" ""))))
19379               (clobber (reg:CC FLAGS_REG))])]
19380   "TARGET_K8 && !optimize_size
19381    && (GET_CODE (operands[2]) != CONST_INT
19382        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19383   [(set (match_dup 3) (match_dup 1))
19384    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19385               (clobber (reg:CC FLAGS_REG))])]
19388 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19389 ;; Convert it into imul reg, reg
19390 ;; It would be better to force assembler to encode instruction using long
19391 ;; immediate, but there is apparently no way to do so.
19392 (define_peephole2
19393   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19394                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19395                             (match_operand:DI 2 "const_int_operand" "")))
19396               (clobber (reg:CC FLAGS_REG))])
19397    (match_scratch:DI 3 "r")]
19398   "TARGET_K8 && !optimize_size
19399    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19400   [(set (match_dup 3) (match_dup 2))
19401    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19402               (clobber (reg:CC FLAGS_REG))])]
19404   if (!rtx_equal_p (operands[0], operands[1]))
19405     emit_move_insn (operands[0], operands[1]);
19408 (define_peephole2
19409   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19410                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19411                             (match_operand:SI 2 "const_int_operand" "")))
19412               (clobber (reg:CC FLAGS_REG))])
19413    (match_scratch:SI 3 "r")]
19414   "TARGET_K8 && !optimize_size
19415    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19416   [(set (match_dup 3) (match_dup 2))
19417    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19418               (clobber (reg:CC FLAGS_REG))])]
19420   if (!rtx_equal_p (operands[0], operands[1]))
19421     emit_move_insn (operands[0], operands[1]);
19424 (define_peephole2
19425   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19426                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19427                             (match_operand:HI 2 "immediate_operand" "")))
19428               (clobber (reg:CC FLAGS_REG))])
19429    (match_scratch:HI 3 "r")]
19430   "TARGET_K8 && !optimize_size"
19431   [(set (match_dup 3) (match_dup 2))
19432    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19433               (clobber (reg:CC FLAGS_REG))])]
19435   if (!rtx_equal_p (operands[0], operands[1]))
19436     emit_move_insn (operands[0], operands[1]);
19439 ;; Call-value patterns last so that the wildcard operand does not
19440 ;; disrupt insn-recog's switch tables.
19442 (define_insn "*call_value_pop_0"
19443   [(set (match_operand 0 "" "")
19444         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19445               (match_operand:SI 2 "" "")))
19446    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19447                             (match_operand:SI 3 "immediate_operand" "")))]
19448   "!TARGET_64BIT"
19450   if (SIBLING_CALL_P (insn))
19451     return "jmp\t%P1";
19452   else
19453     return "call\t%P1";
19455   [(set_attr "type" "callv")])
19457 (define_insn "*call_value_pop_1"
19458   [(set (match_operand 0 "" "")
19459         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19460               (match_operand:SI 2 "" "")))
19461    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19462                             (match_operand:SI 3 "immediate_operand" "i")))]
19463   "!TARGET_64BIT"
19465   if (constant_call_address_operand (operands[1], Pmode))
19466     {
19467       if (SIBLING_CALL_P (insn))
19468         return "jmp\t%P1";
19469       else
19470         return "call\t%P1";
19471     }
19472   if (SIBLING_CALL_P (insn))
19473     return "jmp\t%A1";
19474   else
19475     return "call\t%A1";
19477   [(set_attr "type" "callv")])
19479 (define_insn "*call_value_0"
19480   [(set (match_operand 0 "" "")
19481         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19482               (match_operand:SI 2 "" "")))]
19483   "!TARGET_64BIT"
19485   if (SIBLING_CALL_P (insn))
19486     return "jmp\t%P1";
19487   else
19488     return "call\t%P1";
19490   [(set_attr "type" "callv")])
19492 (define_insn "*call_value_0_rex64"
19493   [(set (match_operand 0 "" "")
19494         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19495               (match_operand:DI 2 "const_int_operand" "")))]
19496   "TARGET_64BIT"
19498   if (SIBLING_CALL_P (insn))
19499     return "jmp\t%P1";
19500   else
19501     return "call\t%P1";
19503   [(set_attr "type" "callv")])
19505 (define_insn "*call_value_1"
19506   [(set (match_operand 0 "" "")
19507         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19508               (match_operand:SI 2 "" "")))]
19509   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19511   if (constant_call_address_operand (operands[1], Pmode))
19512     return "call\t%P1";
19513   return "call\t%A1";
19515   [(set_attr "type" "callv")])
19517 (define_insn "*sibcall_value_1"
19518   [(set (match_operand 0 "" "")
19519         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19520               (match_operand:SI 2 "" "")))]
19521   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19523   if (constant_call_address_operand (operands[1], Pmode))
19524     return "jmp\t%P1";
19525   return "jmp\t%A1";
19527   [(set_attr "type" "callv")])
19529 (define_insn "*call_value_1_rex64"
19530   [(set (match_operand 0 "" "")
19531         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19532               (match_operand:DI 2 "" "")))]
19533   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19535   if (constant_call_address_operand (operands[1], Pmode))
19536     return "call\t%P1";
19537   return "call\t%A1";
19539   [(set_attr "type" "callv")])
19541 (define_insn "*sibcall_value_1_rex64"
19542   [(set (match_operand 0 "" "")
19543         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19544               (match_operand:DI 2 "" "")))]
19545   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19546   "jmp\t%P1"
19547   [(set_attr "type" "callv")])
19549 (define_insn "*sibcall_value_1_rex64_v"
19550   [(set (match_operand 0 "" "")
19551         (call (mem:QI (reg:DI 40))
19552               (match_operand:DI 1 "" "")))]
19553   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19554   "jmp\t*%%r11"
19555   [(set_attr "type" "callv")])
19557 (define_insn "trap"
19558   [(trap_if (const_int 1) (const_int 5))]
19559   ""
19560   "int\t$5")
19562 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19563 ;;; for the sake of bounds checking.  By emitting bounds checks as
19564 ;;; conditional traps rather than as conditional jumps around
19565 ;;; unconditional traps we avoid introducing spurious basic-block
19566 ;;; boundaries and facilitate elimination of redundant checks.  In
19567 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19568 ;;; interrupt 5.
19569 ;;; 
19570 ;;; FIXME: Static branch prediction rules for ix86 are such that
19571 ;;; forward conditional branches predict as untaken.  As implemented
19572 ;;; below, pseudo conditional traps violate that rule.  We should use
19573 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19574 ;;; section loaded at the end of the text segment and branch forward
19575 ;;; there on bounds-failure, and then jump back immediately (in case
19576 ;;; the system chooses to ignore bounds violations, or to report
19577 ;;; violations and continue execution).
19579 (define_expand "conditional_trap"
19580   [(trap_if (match_operator 0 "comparison_operator"
19581              [(match_dup 2) (const_int 0)])
19582             (match_operand 1 "const_int_operand" ""))]
19583   ""
19585   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19586                               ix86_expand_compare (GET_CODE (operands[0]),
19587                                                    NULL, NULL),
19588                               operands[1]));
19589   DONE;
19592 (define_insn "*conditional_trap_1"
19593   [(trap_if (match_operator 0 "comparison_operator"
19594              [(reg FLAGS_REG) (const_int 0)])
19595             (match_operand 1 "const_int_operand" ""))]
19596   ""
19598   operands[2] = gen_label_rtx ();
19599   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19600   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19601                              CODE_LABEL_NUMBER (operands[2]));
19602   RET;
19605 (define_expand "sse_prologue_save"
19606   [(parallel [(set (match_operand:BLK 0 "" "")
19607                    (unspec:BLK [(reg:DI 21)
19608                                 (reg:DI 22)
19609                                 (reg:DI 23)
19610                                 (reg:DI 24)
19611                                 (reg:DI 25)
19612                                 (reg:DI 26)
19613                                 (reg:DI 27)
19614                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19615               (use (match_operand:DI 1 "register_operand" ""))
19616               (use (match_operand:DI 2 "immediate_operand" ""))
19617               (use (label_ref:DI (match_operand 3 "" "")))])]
19618   "TARGET_64BIT"
19619   "")
19621 (define_insn "*sse_prologue_save_insn"
19622   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19623                           (match_operand:DI 4 "const_int_operand" "n")))
19624         (unspec:BLK [(reg:DI 21)
19625                      (reg:DI 22)
19626                      (reg:DI 23)
19627                      (reg:DI 24)
19628                      (reg:DI 25)
19629                      (reg:DI 26)
19630                      (reg:DI 27)
19631                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19632    (use (match_operand:DI 1 "register_operand" "r"))
19633    (use (match_operand:DI 2 "const_int_operand" "i"))
19634    (use (label_ref:DI (match_operand 3 "" "X")))]
19635   "TARGET_64BIT
19636    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19637    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19638   "*
19640   int i;
19641   operands[0] = gen_rtx_MEM (Pmode,
19642                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19643   output_asm_insn (\"jmp\\t%A1\", operands);
19644   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19645     {
19646       operands[4] = adjust_address (operands[0], DImode, i*16);
19647       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19648       PUT_MODE (operands[4], TImode);
19649       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19650         output_asm_insn (\"rex\", operands);
19651       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19652     }
19653   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19654                              CODE_LABEL_NUMBER (operands[3]));
19655   RET;
19657   "
19658   [(set_attr "type" "other")
19659    (set_attr "length_immediate" "0")
19660    (set_attr "length_address" "0")
19661    (set_attr "length" "135")
19662    (set_attr "memory" "store")
19663    (set_attr "modrm" "0")
19664    (set_attr "mode" "DI")])
19666 (define_expand "prefetch"
19667   [(prefetch (match_operand 0 "address_operand" "")
19668              (match_operand:SI 1 "const_int_operand" "")
19669              (match_operand:SI 2 "const_int_operand" ""))]
19670   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19672   int rw = INTVAL (operands[1]);
19673   int locality = INTVAL (operands[2]);
19675   if (rw != 0 && rw != 1)
19676     abort ();
19677   if (locality < 0 || locality > 3)
19678     abort ();
19679   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19680     abort ();
19682   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19683      supported by SSE counterpart or the SSE prefetch is not available
19684      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19685      of locality.  */
19686   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19687     operands[2] = GEN_INT (3);
19688   else
19689     operands[1] = const0_rtx;
19692 (define_insn "*prefetch_sse"
19693   [(prefetch (match_operand:SI 0 "address_operand" "p")
19694              (const_int 0)
19695              (match_operand:SI 1 "const_int_operand" ""))]
19696   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19698   static const char * const patterns[4] = {
19699    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19700   };
19702   int locality = INTVAL (operands[1]);
19703   if (locality < 0 || locality > 3)
19704     abort ();
19706   return patterns[locality];  
19708   [(set_attr "type" "sse")
19709    (set_attr "memory" "none")])
19711 (define_insn "*prefetch_sse_rex"
19712   [(prefetch (match_operand:DI 0 "address_operand" "p")
19713              (const_int 0)
19714              (match_operand:SI 1 "const_int_operand" ""))]
19715   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19717   static const char * const patterns[4] = {
19718    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19719   };
19721   int locality = INTVAL (operands[1]);
19722   if (locality < 0 || locality > 3)
19723     abort ();
19725   return patterns[locality];  
19727   [(set_attr "type" "sse")
19728    (set_attr "memory" "none")])
19730 (define_insn "*prefetch_3dnow"
19731   [(prefetch (match_operand:SI 0 "address_operand" "p")
19732              (match_operand:SI 1 "const_int_operand" "n")
19733              (const_int 3))]
19734   "TARGET_3DNOW && !TARGET_64BIT"
19736   if (INTVAL (operands[1]) == 0)
19737     return "prefetch\t%a0";
19738   else
19739     return "prefetchw\t%a0";
19741   [(set_attr "type" "mmx")
19742    (set_attr "memory" "none")])
19744 (define_insn "*prefetch_3dnow_rex"
19745   [(prefetch (match_operand:DI 0 "address_operand" "p")
19746              (match_operand:SI 1 "const_int_operand" "n")
19747              (const_int 3))]
19748   "TARGET_3DNOW && TARGET_64BIT"
19750   if (INTVAL (operands[1]) == 0)
19751     return "prefetch\t%a0";
19752   else
19753     return "prefetchw\t%a0";
19755   [(set_attr "type" "mmx")
19756    (set_attr "memory" "none")])
19758 (include "sse.md")
19759 (include "mmx.md")